4773 lines
167 KiB
C++
4773 lines
167 KiB
C++
![]() |
/////////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// FILE : AnimatedModelEntity.cpp
|
||
|
// PURPOSE :
|
||
|
// AUTHOR : Thomas French
|
||
|
//
|
||
|
/////////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
//Rage Headers
|
||
|
#include "cutfile/cutfobject.h"
|
||
|
#include "cutscene/cutsevent.h"
|
||
|
#include "cutscene/cutsmanager.h"
|
||
|
#include "cutscene/cutseventargs.h"
|
||
|
#include "cranimation/animation.h"
|
||
|
#include "fwanimation/animdirector.h"
|
||
|
#include "fwanimation/directorcomponentfacialrig.h"
|
||
|
|
||
|
//Game Headers
|
||
|
#include "animation/debug/AnimDebug.h"
|
||
|
#include "animation/debug/AnimViewer.h"
|
||
|
#include "animation/EventTags.h"
|
||
|
#include "animation/FacialData.h"
|
||
|
#include "animation/MovePed.h"
|
||
|
#include "animation/MoveObject.h"
|
||
|
#include "camera/CamInterface.h"
|
||
|
#include "camera/Cutscene/CutsceneDirector.h"
|
||
|
#include "camera/cutscene/AnimatedCamera.h"
|
||
|
#include "cutscene/CutSceneCameraEntity.h"
|
||
|
#include "cutscene/AnimatedModelEntity.h"
|
||
|
#include "Cutscene/cutscene_channel.h"
|
||
|
#include "cutscene/CutSceneAnimManager.h"
|
||
|
#include "cutscene/CutSceneManagerNew.h"
|
||
|
#include "cutscene/CutSceneDefine.h"
|
||
|
#include "cutscene/CutsceneCustomEvents.h"
|
||
|
#include "event/Events.h"
|
||
|
#include "Network/NetworkInterface.h"
|
||
|
#include "Objects/ObjectIntelligence.h"
|
||
|
#include "Objects/Door.h"
|
||
|
#include "Peds/PedFactory.h"
|
||
|
#include "peds/ped.h"
|
||
|
#include "Peds/PedHelmetComponent.h"
|
||
|
#include "peds/PedIntelligence.h"
|
||
|
#include "peds/rendering/PedVariationStream.h"
|
||
|
#include "peds/rendering/PedVariationPack.h"
|
||
|
#include "physics/gtaInst.h"
|
||
|
#include "physics/physics.h"
|
||
|
#include "physics/simulator.h"
|
||
|
#include "physics/Archetype.h"
|
||
|
#include "control/record.h"
|
||
|
#include "scene/entities/compEntity.h"
|
||
|
#include "scene/world/GameWorld.h"
|
||
|
#include "script/script.h"
|
||
|
#include "script/commands_object.h"
|
||
|
#include "script/Handlers/GameScriptEntity.h"
|
||
|
#include "task/motion/TaskMotionBase.h"
|
||
|
#include "task/system/TaskManager.h"
|
||
|
#include "task/System/Task.h"
|
||
|
#include "task/Animation/TaskAnims.h"
|
||
|
#include "task/Animation/TaskCutScene.h"
|
||
|
#include "task/system/TaskTypes.h"
|
||
|
#include "task/general/TaskBasic.h"
|
||
|
#include "vehicleAi/VehicleAILodManager.h"
|
||
|
#include "vehicleAI/VehicleIntelligence.h"
|
||
|
#include "vehicles/VehicleFactory.h"
|
||
|
#include "vehicles/train.h"
|
||
|
#include "weapons/inventory/PedInventoryLoadOut.h"
|
||
|
|
||
|
//ANIM_OPTIMISATIONS()
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
// Animated model entity
|
||
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
const fwMvPropertyId CCutsceneAnimatedModelEntity::ms_VisibleToScriptKey("VisibleToScript",0xF301E135);
|
||
|
u32 CCutsceneAnimatedModelEntity::ms_EventKey = ATSTRINGHASH("Event", 2915749078);
|
||
|
|
||
|
Mat34V identityMat(V_IDENTITY);
|
||
|
#if RECORDING_VERTS
|
||
|
namespace rage
|
||
|
{
|
||
|
extern dbgRecords<recordCustomClothEvent> g_DbgRecordCustomClothEvents;
|
||
|
|
||
|
EXT_PFD_DECLARE_ITEM( DebugRecords );
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
CCutsceneAnimatedModelEntity::CCutsceneAnimatedModelEntity(const cutfObject* pObject)
|
||
|
:cutsUniqueEntity()
|
||
|
, m_CollisionBound(NULL)
|
||
|
, m_bUpdateCollisionBound(false)
|
||
|
{
|
||
|
m_pCutfObject = pObject;
|
||
|
|
||
|
//create a real game side object (CPed, CObject or CVehicle) not a cut scene type object which all derive from CObject
|
||
|
m_bCreateGameObject = false;
|
||
|
|
||
|
if(pObject->GetType() == CUTSCENE_MODEL_OBJECT_TYPE)
|
||
|
{
|
||
|
const cutfModelObject* pModel = static_cast<const cutfModelObject*>(pObject);
|
||
|
|
||
|
if(pModel)
|
||
|
{
|
||
|
m_ModelNameHash = pModel->GetStreamingName();
|
||
|
m_SceneHandleHash = pModel->GetHandle();
|
||
|
}
|
||
|
|
||
|
if (m_SceneHandleHash.GetHash()==0)
|
||
|
{
|
||
|
m_SceneHandleHash = atHashString(atFinalizeHash(pModel->GetAnimStreamingBase()));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
cutsceneAssert(m_ModelNameHash.GetHash()>0);
|
||
|
|
||
|
//creation position
|
||
|
m_vCreatePos = CutSceneManager::GetInstance()->GetSceneOffset();
|
||
|
|
||
|
//Pointer to a game side object
|
||
|
m_pEntity = NULL;
|
||
|
|
||
|
//Pointer to a registered entity that is just hidden and repositioned by the cut scene
|
||
|
m_pEntityForRepositionOnly = NULL;
|
||
|
|
||
|
m_pClip = NULL;
|
||
|
|
||
|
m_vVelocity = VEC3_ZERO;
|
||
|
|
||
|
m_pCutSceneTask = NULL;
|
||
|
|
||
|
m_HasBeenDeletedByCutscene = false;
|
||
|
|
||
|
m_bWasInvincible = false;
|
||
|
|
||
|
m_fOriginalLODMultiplier = 1.0f;
|
||
|
m_fOriginalHairScale = 0.0f;
|
||
|
|
||
|
m_CurrentPosition = VEC3_ZERO;
|
||
|
m_CurrentHeading = 0.0f;
|
||
|
|
||
|
m_bComputeInitialVariationsForGameEntity = false;
|
||
|
m_bComputeVariationsForSkipForRepositionOnlyEntity = false;
|
||
|
|
||
|
m_bRequestRepositionOnlyEntity = false;
|
||
|
|
||
|
m_SectionAnimWasRecieved = 0;
|
||
|
|
||
|
m_bIsReadyForGame = false;
|
||
|
m_bStoppedCalled = false;
|
||
|
m_bIsRegisteredEntityScriptControlled = false;
|
||
|
m_bCreatedByCutscene = false;
|
||
|
m_bClearedOrSetAnimThisFrame = false;
|
||
|
m_bShouldProcessTags = false;
|
||
|
m_FrameTagsAreProcessed = 0;
|
||
|
m_OptionFlags.ClearAllFlags();
|
||
|
m_StreamingOptionFlags.ClearAllFlags();
|
||
|
|
||
|
#if !__NO_OUTPUT
|
||
|
m_bIsloggingEntityCalls = false;
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
CCutsceneAnimatedModelEntity::~CCutsceneAnimatedModelEntity()
|
||
|
{
|
||
|
bool bDeleteRegisteredEntities = CutSceneManager::GetInstancePtr() && CutSceneManager::GetInstance()->ShouldDeleteAllRegisteredEntites();
|
||
|
|
||
|
DeleteNonRegisteredEntities();
|
||
|
|
||
|
if (m_pEntity && m_pEntity->GetPortalTracker())
|
||
|
{
|
||
|
m_pEntity->GetPortalTracker()->SetIsCutsceneControlled(false);
|
||
|
}
|
||
|
|
||
|
if (bDeleteRegisteredEntities)
|
||
|
{
|
||
|
if (m_pEntity && (!m_pEntity->GetIsTypePed() || !((CPed*)m_pEntity.Get())->IsPlayer()))
|
||
|
RemoveEntityFromTheWorld(m_pEntity, true);
|
||
|
|
||
|
if (m_pEntityForRepositionOnly && (!m_pEntityForRepositionOnly->GetIsTypePed() || !((CPed*)m_pEntityForRepositionOnly.Get())->IsPlayer()))
|
||
|
RemoveEntityFromTheWorld(m_pEntityForRepositionOnly, true);
|
||
|
}
|
||
|
|
||
|
m_pEntity = NULL;
|
||
|
m_pEntityForRepositionOnly = NULL;
|
||
|
if(m_pClip != NULL)
|
||
|
{
|
||
|
m_pClip->Release();
|
||
|
m_pClip = NULL;
|
||
|
}
|
||
|
m_pCutSceneTask = NULL;
|
||
|
}
|
||
|
|
||
|
void CCutsceneAnimatedModelEntity::DeleteNonRegisteredEntities()
|
||
|
{
|
||
|
if(RemoveEntityFromTheWorld(m_pEntity))
|
||
|
{
|
||
|
m_pEntity = NULL;
|
||
|
}
|
||
|
|
||
|
if(RemoveEntityFromTheWorld(m_pEntityForRepositionOnly))
|
||
|
{
|
||
|
m_pEntityForRepositionOnly = NULL;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
void CCutsceneAnimatedModelEntity::RegisterPlayer(cutsManager* pManager, const cutfObject* pObject)
|
||
|
{
|
||
|
CutSceneManager* pCutsManager = static_cast<CutSceneManager*>(pManager);
|
||
|
|
||
|
//Register the player
|
||
|
if(pCutsManager->GetPlayerSceneId() == pObject->GetObjectId())
|
||
|
{
|
||
|
if(m_pEntity == NULL)
|
||
|
{
|
||
|
CPed *pPed = CGameWorld::FindLocalPlayer();
|
||
|
|
||
|
if(pPed)
|
||
|
{
|
||
|
if(pObject->GetType() == CUTSCENE_MODEL_OBJECT_TYPE)
|
||
|
{
|
||
|
pCutsManager->RegisterGameEntity(pPed, GetSceneHandleHash(), GetModelNameHash(), false, false);
|
||
|
|
||
|
m_bWasInvincible = pPed->m_nPhysicalFlags.bNotDamagedByAnything;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CCutsceneAnimatedModelEntity::SetVisibility(CEntity* pEnt, bool Visible)
|
||
|
{
|
||
|
if(pEnt)
|
||
|
{
|
||
|
#if !__NO_OUTPUT
|
||
|
CPhysical* phys = NULL;
|
||
|
bool reactivateLogging = false;
|
||
|
if(pEnt->GetIsPhysical())
|
||
|
{
|
||
|
phys = static_cast<CPhysical*>(pEnt);
|
||
|
if(phys && m_bIsloggingEntityCalls && phys->m_LogVisibiltyCalls)
|
||
|
{
|
||
|
phys->m_LogVisibiltyCalls = false;
|
||
|
reactivateLogging = true;
|
||
|
}
|
||
|
#endif //!__NO_OUTPUT
|
||
|
pEnt->SetIsVisibleForModule(SETISVISIBLE_MODULE_CUTSCENE, Visible);
|
||
|
|
||
|
#if !__NO_OUTPUT
|
||
|
if(phys && m_bIsloggingEntityCalls && reactivateLogging)
|
||
|
{
|
||
|
phys->m_LogVisibiltyCalls = true;
|
||
|
}
|
||
|
}
|
||
|
#endif //!__NO_OUTPUT
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CCutsceneAnimatedModelEntity::SetUpScriptRegisteredEntity(cutsManager* UNUSED_PARAM(pManager), const cutfObject* pObject)
|
||
|
{
|
||
|
//going to animate this version of the entity its has a valid scene handle and model hash
|
||
|
if (IsRegisteredWithScript())
|
||
|
{
|
||
|
//the id is stored as it could be used later for creating script required entities
|
||
|
m_RegisteredEntityFromScript.iSceneId = pObject->GetObjectId();
|
||
|
|
||
|
if(IsScriptRegisteredGameEntity())
|
||
|
{
|
||
|
if(m_RegisteredEntityFromScript.bAppearInScene == false)
|
||
|
{
|
||
|
//remove our initial entity its not going to be needed
|
||
|
if(m_pEntity)
|
||
|
{
|
||
|
if(m_pEntity->GetIsTypePed())
|
||
|
{
|
||
|
SetVisibility(m_pEntity, false);
|
||
|
cutsceneModelEntityDebugf2("CCutsceneAnimatedModelEntity::SetUpScriptRegisteredEntity1: Hiding entity (%s)", m_pEntity->GetModelName());
|
||
|
|
||
|
//have to add to the world to safely delete, though check its not already in the world
|
||
|
if( !m_pEntity->GetIsAddedToWorld() )
|
||
|
{
|
||
|
CGameWorld::Add((CPed*)m_pEntity.Get(), CGameWorld::OUTSIDE);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#if !__NO_OUTPUT
|
||
|
if(m_pEntity->GetIsPhysical() && m_bIsloggingEntityCalls)
|
||
|
{
|
||
|
((CPhysical*)m_pEntity.Get())->m_LogDeletions = false;
|
||
|
}
|
||
|
#endif
|
||
|
m_pEntity->FlagToDestroyWhenNextProcessed();
|
||
|
|
||
|
m_pEntity = NULL;
|
||
|
}
|
||
|
}
|
||
|
//animating the script given entity, not a CS version
|
||
|
else if(m_RegisteredEntityFromScript.pEnt )
|
||
|
{
|
||
|
//remove our initial entity its not going to be needed
|
||
|
if(m_pEntity)
|
||
|
{
|
||
|
if(m_pEntity->GetIsTypePed())
|
||
|
{
|
||
|
SetVisibility(m_pEntity, false);
|
||
|
cutsceneModelEntityDebugf2("CCutsceneAnimatedModelEntity::SetUpScriptRegisteredEntity2: Hiding entity (%s)", m_pEntity->GetModelName());
|
||
|
|
||
|
//have to add to the world to safely release
|
||
|
if( !m_pEntity->GetIsAddedToWorld() )
|
||
|
{
|
||
|
CGameWorld::Add((CPed*)m_pEntity.Get(), CGameWorld::OUTSIDE);
|
||
|
}
|
||
|
}
|
||
|
#if !__NO_OUTPUT
|
||
|
if(m_pEntity->GetIsPhysical() && m_bIsloggingEntityCalls)
|
||
|
{
|
||
|
((CPhysical*)m_pEntity.Get())->m_LogDeletions = false;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
m_pEntity->FlagToDestroyWhenNextProcessed();
|
||
|
m_pEntity = NULL;
|
||
|
}
|
||
|
|
||
|
|
||
|
//check that there is no game entity already
|
||
|
if(m_pEntity == NULL)
|
||
|
{
|
||
|
m_pEntity = m_RegisteredEntityFromScript.pEnt;
|
||
|
m_pEntity->GetPortalTracker()->SetIsCutsceneControlled(true);
|
||
|
if(m_pEntity->GetIsPhysical())
|
||
|
{
|
||
|
CPhysical* pPhys = static_cast<CPhysical*>(m_pEntity.Get());
|
||
|
m_bWasInvincible = pPhys->m_nPhysicalFlags.bNotDamagedByAnything;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
//check if its registered by scene handle only
|
||
|
if(IsScriptRegisteredRepositionOnlyEntity())
|
||
|
{
|
||
|
if(m_RegisteredEntityFromScript.pEnt)
|
||
|
{
|
||
|
//assign this reposition only, as this is a ig version of the cutscene
|
||
|
m_pEntityForRepositionOnly = m_RegisteredEntityFromScript.pEnt;
|
||
|
SetRepositionOnlyEntityReadyForCutscene();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#if !__NO_OUTPUT
|
||
|
|
||
|
void CCutsceneAnimatedModelEntity::CommonDebugStr(const cutfObject* pObject, char * debugStr)
|
||
|
{
|
||
|
if (!pObject)
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
CutSceneManager::CommonDebugStr(debugStr); // first write in cutscene manager debug
|
||
|
|
||
|
sprintf(debugStr, "%sModel Entity(%p, %d, %s), G-Ent(%p, %s), RO-Ent(%p, %s) - ",
|
||
|
debugStr,
|
||
|
pObject,
|
||
|
pObject->GetObjectId(),
|
||
|
m_SceneHandleHash.TryGetCStr(),
|
||
|
GetGameEntity(),
|
||
|
m_ModelNameHash.TryGetCStr(),
|
||
|
GetGameRepositionOnlyEntity(),
|
||
|
m_RegisteredEntityFromScript.ModelNameHash.TryGetCStr());
|
||
|
}
|
||
|
|
||
|
#endif // !__NO_OUTPUT
|
||
|
|
||
|
void CCutsceneAnimatedModelEntity::CreateRepositionOnlyGameEntityWhenModelLoaded(cutsManager* pManager, const cutfObject* pObject, bool bRequestVariations, bool bApplyVariations)
|
||
|
{
|
||
|
if(m_bRequestRepositionOnlyEntity && m_pEntityForRepositionOnly == NULL)
|
||
|
{
|
||
|
CutSceneManager* pCutsManager = static_cast<CutSceneManager*>(pManager);
|
||
|
|
||
|
//set the model index to invalid and then check that we have made a request, if not the model index will remain at zero
|
||
|
s32 iModelIndex = strLocalIndex::INVALID_INDEX;
|
||
|
pCutsManager->GetAssetManager()->GetModelStreamingRequestId(pObject->GetObjectId(), m_RegisteredEntityFromScript.ModelNameHash, iModelIndex);
|
||
|
if(iModelIndex != strLocalIndex::INVALID_INDEX)
|
||
|
{
|
||
|
if(pCutsManager->GetAssetManager()->HasRequestedModelLoaded(pObject->GetObjectId(), m_RegisteredEntityFromScript.ModelNameHash))
|
||
|
{
|
||
|
cutsceneModelEntityDebugf2("CreateRepositionOnlyGameEntity - Actor - bRequestVariations(%s), bApplyVariations(%s)", bRequestVariations ? "T" : "F", bApplyVariations ? "T" : "F");
|
||
|
|
||
|
CreateGameEntity(strLocalIndex(iModelIndex), true, bRequestVariations, bApplyVariations);
|
||
|
SetRepositionOnlyEntityReadyForCutscene();
|
||
|
m_RegisteredEntityFromScript.pEnt = m_pEntityForRepositionOnly;
|
||
|
pCutsManager->GetAssetManager()->RemoveStreamingRequest(pObject->GetObjectId(), true, MODEL_TYPE, m_RegisteredEntityFromScript.ModelNameHash);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
void CCutsceneAnimatedModelEntity::CreateAnimatedEntityWhenModelLoaded(cutsManager* pManager, const cutfObject* pObject, bool bRequestVariations, bool bApplyVariations)
|
||
|
{
|
||
|
if(m_RegisteredEntityFromScript.bAppearInScene)
|
||
|
{
|
||
|
CutSceneManager* pCutsManager = static_cast<CutSceneManager*>(pManager);
|
||
|
|
||
|
if (pCutsManager->GetAssetManager()->HasRequestedModelLoaded(pObject->GetObjectId(), m_ModelNameHash))
|
||
|
{
|
||
|
cutsceneModelEntityDebugf2("CreateAnimatedEntity - Actor - Model Loaded - bRequestVariations(%s), bApplyVariations(%s)", bRequestVariations ? "T" : "F", bApplyVariations ? "T" : "F");
|
||
|
|
||
|
//set the model index to invalid and then check that we have made a request, if not the model index will remain at zero
|
||
|
s32 iModelIndex = strLocalIndex::INVALID_INDEX;
|
||
|
|
||
|
//we are now creating our game entity just before we play an anim on it
|
||
|
if(pCutsManager->GetAssetManager()->GetModelStreamingRequestId(pObject->GetObjectId(), m_ModelNameHash, iModelIndex))
|
||
|
{
|
||
|
m_vCreatePos = pCutsManager->GetSceneOffset();
|
||
|
CreateGameEntity(strLocalIndex(iModelIndex), false, bRequestVariations, bApplyVariations);
|
||
|
|
||
|
if(m_RegisteredEntityFromScript.bCreatedForScript)
|
||
|
{
|
||
|
if(m_RegisteredEntityFromScript.pEnt == NULL)
|
||
|
{
|
||
|
if(IsScriptRegisteredGameEntity())
|
||
|
{
|
||
|
if(GetGameEntity())
|
||
|
{
|
||
|
m_RegisteredEntityFromScript.pEnt = m_pEntity;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if(IsScriptRegisteredRepositionOnlyEntity())
|
||
|
{
|
||
|
if(GetGameRepositionOnlyEntity())
|
||
|
{
|
||
|
m_RegisteredEntityFromScript.pEnt = m_pEntityForRepositionOnly;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
m_HasBeenDeletedByCutscene = false;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
CTaskCutScene* CCutsceneAnimatedModelEntity::GetCutsceneTaskForEntity()
|
||
|
{
|
||
|
CTask* pTask = NULL;
|
||
|
|
||
|
if(GetGameEntity())
|
||
|
{
|
||
|
if(GetGameEntity()->GetIsTypeObject())
|
||
|
{
|
||
|
const CObject* pObject = static_cast<CObject*>(GetGameEntity());
|
||
|
if(pObject->GetObjectIntelligence())
|
||
|
{
|
||
|
pTask = pObject->GetObjectIntelligence()->FindTaskByType(CTaskTypes::TASK_CUTSCENE);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if(GetGameEntity()->GetIsTypeVehicle())
|
||
|
{
|
||
|
const CVehicle* pVeh = static_cast<CVehicle*>(GetGameEntity());
|
||
|
|
||
|
if( pVeh->GetIntelligence() && pVeh->GetIntelligence()->GetTaskManager())
|
||
|
{
|
||
|
aiTask* CurrentVehicleTask = pVeh->GetIntelligence()->GetTaskManager()->GetTree(VEHICLE_TASK_TREE_SECONDARY)->GetTask(VEHICLE_TASK_SECONDARY_ANIM);
|
||
|
|
||
|
if(CurrentVehicleTask && CurrentVehicleTask->GetTaskType() == CTaskTypes::TASK_CUTSCENE)
|
||
|
{
|
||
|
pTask = static_cast<CTask*>(CurrentVehicleTask);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
if(GetGameEntity()->GetIsTypePed())
|
||
|
{
|
||
|
CPed* pPed = static_cast<CPed*>(GetGameEntity());
|
||
|
if(pPed->GetPedIntelligence())
|
||
|
{
|
||
|
pTask = pPed->GetPedIntelligence()->FindTaskByType(CTaskTypes::TASK_CUTSCENE);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
if(pTask)
|
||
|
{
|
||
|
CTaskCutScene* pCutScene = static_cast<CTaskCutScene*>(pTask);
|
||
|
return pCutScene;
|
||
|
}
|
||
|
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
void CCutsceneAnimatedModelEntity::DispatchEvent( cutsManager* pManager, const cutfObject* pObject, s32 iEventId, const cutfEventArgs* pEventArgs, const float UNUSED_PARAM(fTime), const u32 UNUSED_PARAM(StickyId) )
|
||
|
{
|
||
|
switch ( iEventId )
|
||
|
{
|
||
|
|
||
|
case CUTSCENE_START_OF_SCENE_EVENT:
|
||
|
{
|
||
|
|
||
|
CutSceneManager* pCutSceneManager = static_cast<CutSceneManager*> (pManager);
|
||
|
m_ExitSceneTime = pCutSceneManager->GetTotalSeconds();
|
||
|
|
||
|
//register the player
|
||
|
if (!NetworkInterface::IsGameInProgress())
|
||
|
RegisterPlayer(pManager, pObject);
|
||
|
|
||
|
//possibly need to set the object matrix to be the same as the local space
|
||
|
SetUpScriptRegisteredEntity(pManager, pObject);
|
||
|
|
||
|
//create any cutscene animated entities that were loaded before the cutscene starts
|
||
|
CreateAnimatedEntityWhenModelLoaded(pManager, pObject, true, true);
|
||
|
|
||
|
//create any reposition only entities that were loaded before the cutscene starts
|
||
|
//CreateRepositionOnlyGameEntityWhenModelLoaded(pManager, pObject, true, true);
|
||
|
|
||
|
//Set the entity game ready to enter the scene
|
||
|
SetGameEntityReadyForCutscene();
|
||
|
|
||
|
if (GetGameEntity() )
|
||
|
{
|
||
|
if (pObject)
|
||
|
{
|
||
|
cutsceneModelEntityDebugf2("CUTSCENE_START_OF_SCENE_EVENT");
|
||
|
}
|
||
|
|
||
|
//have a game side object
|
||
|
if(GetGameEntity())
|
||
|
{
|
||
|
if(m_pClip)
|
||
|
{
|
||
|
SetVisibility(GetGameEntity(), true);
|
||
|
cutsceneModelEntityDebugf2("CUTSCENE_START_OF_SCENE_EVENT: Showing GetGameEntity (%s)", GetGameEntity()->GetModelName());
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
SetVisibility(GetGameEntity(), false);
|
||
|
cutsceneModelEntityDebugf2("CUTSCENE_START_OF_SCENE_EVENT: Hiding GetGameEntity (%s)", GetGameEntity()->GetModelName());
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case CUTSCENE_SKIPPED_EVENT:
|
||
|
{
|
||
|
CutSceneManager* pCutSceneManager = static_cast<CutSceneManager*> (pManager);
|
||
|
|
||
|
// Is a reposition only entity model needed
|
||
|
RequestRepositionOnlyEntityModelWhenNeeded(pCutSceneManager, pObject);
|
||
|
|
||
|
if( GetGameEntity() && GetGameEntity()->GetIsTypePed() )
|
||
|
{
|
||
|
CPed* pPed = static_cast<CPed*>(GetGameEntity());
|
||
|
if( pPed )
|
||
|
{
|
||
|
for( int i = 0; i < PV_MAX_COMP; ++i )
|
||
|
{
|
||
|
if( pPed->m_CClothController[i] )
|
||
|
{
|
||
|
pPed->m_CClothController[i]->SetFlag( characterClothController::enIsQueuedPinning, true );
|
||
|
}
|
||
|
}
|
||
|
} // end if( pPed )
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case CUTSCENE_UPDATE_EVENT:
|
||
|
{
|
||
|
if( m_bUpdateCollisionBound )
|
||
|
{
|
||
|
CEntity* pEntity = GetGameEntity();
|
||
|
if( pEntity )
|
||
|
{
|
||
|
crSkeleton* pSkel = pEntity->GetSkeleton();
|
||
|
if( pSkel )
|
||
|
{
|
||
|
Mat34V rootBoneMat;
|
||
|
pSkel->GetGlobalMtx(0, rootBoneMat);
|
||
|
|
||
|
Vec3V col1 = rootBoneMat.GetCol1();
|
||
|
rootBoneMat.SetCol1( rootBoneMat.GetCol0() );
|
||
|
rootBoneMat.SetCol0( col1 );
|
||
|
|
||
|
Assert( m_CollisionBound );
|
||
|
m_CollisionBound->SetCurrentMatrix(0, rootBoneMat);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (m_bIsReadyForGame)
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
CutSceneManager* pCutSceneManager = static_cast<CutSceneManager*> (pManager);
|
||
|
|
||
|
// Is a reposition only entity model needed? Check if we are n seconds before the scene ends
|
||
|
if (pCutSceneManager->GetCutSceneCurrentTime() > (m_ExitSceneTime - DEFAULT_STREAMING_OFFSET))
|
||
|
{
|
||
|
RequestRepositionOnlyEntityModelWhenNeeded(pCutSceneManager, pObject);
|
||
|
}
|
||
|
|
||
|
// RequestRepositionOnlyEntityModel is called on skip or n seconds before the scene ends
|
||
|
// Created a reposition only game entity during the cutscene (as opposed to before the cutscene or after it ends)
|
||
|
CreateRepositionOnlyGameEntityWhenModelLoaded(pManager, pObject, true, true);
|
||
|
|
||
|
// Has the associated entity (ped/vehicle/prop) been created?
|
||
|
if(GetGameEntity())
|
||
|
{
|
||
|
m_CurrentPosition = VEC3V_TO_VECTOR3(m_pEntity->GetTransform().GetPosition());
|
||
|
m_CurrentHeading = m_pEntity->GetTransform().GetHeading();
|
||
|
atHashString modelHash(GetModelNameHash());
|
||
|
|
||
|
// the streaming request has been removed we can now delete the object managed by this entity
|
||
|
if (!pCutSceneManager->GetAssetManager()->IsModelInRequestList(pObject->GetObjectId(), modelHash))
|
||
|
{
|
||
|
if(!IsScriptRegisteredGameEntity() || (IsScriptRegisteredGameEntity() && m_RegisteredEntityFromScript.bDeleteBeforeEnd))
|
||
|
{
|
||
|
if(GetGameEntity()->GetIsTypeVehicle())
|
||
|
{
|
||
|
//set it to be ambient so it can be deleted by the population cont
|
||
|
CVehicle* pVeh = static_cast<CVehicle*>(GetGameEntity());
|
||
|
pVeh->PopTypeSet(POPTYPE_RANDOM_AMBIENT);
|
||
|
}
|
||
|
|
||
|
if(GetGameEntity()->GetIsTypePed())
|
||
|
{
|
||
|
//set it to be ambient so it can be deleted by the population cont
|
||
|
CPed* pPed = static_cast<CPed*>(GetGameEntity());
|
||
|
pPed->PopTypeSet(POPTYPE_RANDOM_AMBIENT);
|
||
|
}
|
||
|
|
||
|
cutsceneModelEntityDebugf2("CUTSCENE_UPDATE_EVENT - Deleting entity as its model is no longer in the request list.");
|
||
|
|
||
|
#if !__NO_OUTPUT
|
||
|
if(GetGameEntity()->GetIsPhysical() && m_bIsloggingEntityCalls)
|
||
|
{
|
||
|
((CPhysical*)GetGameEntity())->m_LogDeletions = false;
|
||
|
}
|
||
|
#endif
|
||
|
GetGameEntity()->FlagToDestroyWhenNextProcessed();
|
||
|
GetGameEntity()->DisableCollision();
|
||
|
SetVisibility(GetGameEntity(), false);
|
||
|
cutsceneModelEntityDebugf2("CUTSCENE_UPDATE_EVENT: Show GetGameEntity (%s)", GetGameEntity()->GetModelName());
|
||
|
m_pEntity = NULL;
|
||
|
m_pCutSceneTask = NULL;
|
||
|
|
||
|
m_HasBeenDeletedByCutscene = true;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
//
|
||
|
// The associated entity (ped/vehicle/prop) has not been created yet?
|
||
|
//
|
||
|
|
||
|
// Do script want us to create the associated entity (e.g. the character is dead and therefore not needed in the scene)
|
||
|
if(m_RegisteredEntityFromScript.bAppearInScene)
|
||
|
{
|
||
|
bool bCanCreate = false;
|
||
|
|
||
|
// If the script has not "registered" the game entity we can create the ped
|
||
|
if(!IsScriptRegisteredGameEntity())
|
||
|
{
|
||
|
bCanCreate = true;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// If the script has "registered" the game entity. Script can decide if they want
|
||
|
// the cutscene to create the reposition only entity or if they want to create it themselves
|
||
|
bCanCreate = m_RegisteredEntityFromScript.bCreatedForScript;
|
||
|
}
|
||
|
|
||
|
// Check we are not under script control (in the exit state)
|
||
|
if(!m_bIsRegisteredEntityScriptControlled)
|
||
|
{
|
||
|
if(cutsceneVerifyf(m_HasBeenDeletedByCutscene || bCanCreate, "The registered entity %s owned by the cutscene has been deleted whilst the scene active", pObject->GetDisplayName().c_str()))
|
||
|
{
|
||
|
// Created an animated actor during the cutscene (as opposed to before the cutscene or after it ends)
|
||
|
CreateAnimatedEntityWhenModelLoaded( pManager, pObject, true, true);
|
||
|
SetGameEntityReadyForCutscene();
|
||
|
|
||
|
//have a game side object
|
||
|
if(GetGameEntity())
|
||
|
{
|
||
|
if(m_pClip)
|
||
|
{
|
||
|
PlayClip(pCutSceneManager, m_pClip, pManager->GetSectionStartTime(pManager->GetCurrentSection()), m_AnimDict);
|
||
|
ComputeScriptVisibleTagsOnAnimSet(pCutSceneManager);
|
||
|
SetVisibility(GetGameEntity(), true);
|
||
|
cutsceneModelEntityDebugf2("CUTSCENE_UPDATE_EVENT: Showing GetGameEntity (%s)", GetGameEntity()->GetModelName());
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
SetVisibility(GetGameEntity(), false);
|
||
|
cutsceneModelEntityDebugf2("CUTSCENE_UPDATE_EVENT: Hiding GetGameEntity (%s)", GetGameEntity()->GetModelName());
|
||
|
}
|
||
|
|
||
|
cutsceneModelEntityDebugf2("CUTSCENE_UPDATE_EVENT - Created entity.");
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
ComputeScriptVisibleTagsOnUpdate(pCutSceneManager);
|
||
|
m_bClearedOrSetAnimThisFrame = false;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case CUTSCENE_DICTIONARY_LOADED_EVENT:
|
||
|
{
|
||
|
|
||
|
if (m_ExitSceneTime==pManager->GetTotalSeconds())
|
||
|
{
|
||
|
const cutsDictionaryLoadedEventArgs *pDictEventArgs = static_cast<const cutsDictionaryLoadedEventArgs *>( pEventArgs );
|
||
|
|
||
|
crClipDictionary* pDict = pDictEventArgs->GetDictionary();
|
||
|
if (pDict && pObject)
|
||
|
{
|
||
|
if(pObject->GetAnimStreamingType() == CUTSCENE_NAMED_STREAMED_ANIMATED_OBJECT )
|
||
|
{
|
||
|
const cutfNamedAnimatedStreamedObject* pAnimNamedStreamed = static_cast<const cutfNamedAnimatedStreamedObject*>(pObject);
|
||
|
|
||
|
u32 animBaseHash = pAnimNamedStreamed->GetAnimStreamingBase();
|
||
|
|
||
|
s32 iSectionIndex = pDictEventArgs->GetSection();
|
||
|
|
||
|
char indexBuff[8];
|
||
|
formatf(indexBuff, 8, "-%d", iSectionIndex);
|
||
|
atHashString FinalHash = atStringHash(indexBuff, animBaseHash);
|
||
|
|
||
|
|
||
|
crClip* pClip = pDict->GetClip(FinalHash);
|
||
|
if (pClip)
|
||
|
{
|
||
|
// search for the
|
||
|
const crTag* pTag = CClipEventTags::FindFirstEventTag(pClip, CClipEventTags::TagSyncBlendOut);
|
||
|
|
||
|
if(pTag)
|
||
|
{
|
||
|
CutSceneManager* pCutSceneManager = static_cast<CutSceneManager*> (pManager);
|
||
|
m_ExitSceneTime = pCutSceneManager->GetSectionStartTime(pDictEventArgs->GetSection()) + pClip->ConvertPhaseToTime(pTag->GetStart());
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case CUTSCENE_SET_CLIP_EVENT:
|
||
|
{
|
||
|
if (m_bIsReadyForGame)
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
CutSceneManager* pCutSceneManager = static_cast<CutSceneManager*> (pManager);
|
||
|
|
||
|
// set the clip and the initial playback time
|
||
|
if (pEventArgs && pEventArgs->GetType() == CUTSCENE_CLIP_EVENT_ARGS_TYPE )
|
||
|
{
|
||
|
const cutsClipEventArgs *pClipEventArgs = static_cast<const cutsClipEventArgs *>( pEventArgs );
|
||
|
//store the clip dictionary and anim dict we may not have an object to play an anim on yet
|
||
|
const crClip* pClip = pClipEventArgs->GetClip();
|
||
|
|
||
|
if(pClip != NULL)
|
||
|
{
|
||
|
pClip->AddRef();
|
||
|
}
|
||
|
|
||
|
if(m_pClip != NULL)
|
||
|
{
|
||
|
ComputeScriptVisibleTagsOnAnimClear(pCutSceneManager);
|
||
|
m_pClip->Release();
|
||
|
}
|
||
|
|
||
|
|
||
|
m_pClip = pClip;
|
||
|
|
||
|
m_SectionAnimWasRecieved = pCutSceneManager->GetCurrentSection();
|
||
|
|
||
|
formatf(m_AnimDict, sizeof(m_AnimDict), pClipEventArgs->GetAnimDict());
|
||
|
|
||
|
cutsceneAssertf(m_pClip, "CUTSCENE_SET_CLIP_EVENT has a null clip on %s, anim dict %s",
|
||
|
pObject->GetDisplayName().c_str(), pClipEventArgs->GetAnimDict());
|
||
|
//Here we have a created our own cut scene object
|
||
|
CutSceneManager* pCutManager = static_cast<CutSceneManager*>(pManager);
|
||
|
|
||
|
if(GetGameEntity())
|
||
|
{
|
||
|
PlayClip(pCutManager, pClipEventArgs->GetClip(), pManager->GetSectionStartTime(pManager->GetCurrentSection()), pClipEventArgs->GetAnimDict());
|
||
|
ComputeScriptVisibleTagsOnAnimSet(pCutManager);
|
||
|
SetVisibility(GetGameEntity(), true);
|
||
|
cutsceneModelEntityDebugf2("SET_CLIP_EVENT: Showing GetGameEntity (%s)", GetGameEntity()->GetModelName());
|
||
|
}
|
||
|
|
||
|
cutsceneModelEntityDebugf2("SET_CLIP_EVENT %s : pClip:%s", pClipEventArgs->GetAnimDict(), m_pClip ? m_pClip->GetName() : "Clip not found!");
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
cutsceneModelEntityDebugf2("NO_SET_CLIP_EVENT");
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case CUTSCENE_SCENE_ORIENTATION_CHANGED_EVENT:
|
||
|
{
|
||
|
if (m_bIsReadyForGame)
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
CTaskCutScene* pTask = GetCutsceneTaskForEntity();
|
||
|
|
||
|
if(pTask)
|
||
|
{
|
||
|
Matrix34 SceneMat;
|
||
|
pManager->GetSceneOrientationMatrix(SceneMat);
|
||
|
pTask->SetAnimOrigin(SceneMat);
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case CUTSCENE_CLEAR_ANIM_EVENT:
|
||
|
{
|
||
|
cutsceneModelEntityDebugf2("CUTSCENE_CLEAR_ANIM_EVENT");
|
||
|
CutSceneManager* pCutSceneManager = static_cast<CutSceneManager*> (pManager);
|
||
|
bool bDuringCutscene = (pCutSceneManager->GetCutSceneCurrentTime() > pCutSceneManager->GetStartTime()) && (pCutSceneManager->GetCutSceneCurrentTime() < pCutSceneManager->GetEndTime());
|
||
|
|
||
|
ComputeScriptVisibleTagsOnAnimClear(pCutSceneManager);
|
||
|
|
||
|
if(m_pClip != NULL)
|
||
|
{
|
||
|
m_pClip->Release();
|
||
|
m_pClip = NULL;
|
||
|
}
|
||
|
|
||
|
if (bDuringCutscene)
|
||
|
{
|
||
|
if (m_pCutSceneTask)
|
||
|
{
|
||
|
Matrix34 SceneMat;
|
||
|
pManager->GetSceneOrientationMatrix(SceneMat);
|
||
|
m_pCutSceneTask->SetClip(m_pClip,SceneMat, 0.0f);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (m_bIsReadyForGame)
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if(bDuringCutscene)
|
||
|
{
|
||
|
// stop event has been called already and the ped is being returned to the game don't set them to be invisible.
|
||
|
if(GetGameEntity() && !m_bStoppedCalled)
|
||
|
{
|
||
|
SetVisibility(GetGameEntity(), false);
|
||
|
cutsceneModelEntityDebugf2("CUTSCENE_CLEAR_ANIM_EVENT: Hiding GetGameEntity (%s)", GetGameEntity()->GetModelName());
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case CUTSCENE_END_OF_SCENE_EVENT:
|
||
|
{
|
||
|
m_CollisionBound = NULL;
|
||
|
m_bUpdateCollisionBound = false;
|
||
|
|
||
|
cutsceneModelEntityDebugf2("CUTSCENE_END_OF_SCENE_EVENT");
|
||
|
|
||
|
// make sure our entity has been returned to game mode if necessary
|
||
|
SetGameEntityReadyForGame(pManager);
|
||
|
DeleteNonRegisteredEntities();
|
||
|
|
||
|
// Force update the ai for the ped so we don't see the final frame twice
|
||
|
if (GetGameEntity() && GetCutsceneTaskForEntity())
|
||
|
{
|
||
|
cutsceneModelEntityDebugf2("CUTSCENE_END_OF_SCENE_EVENT - Force AI Update");
|
||
|
ForceUpdateAi(pManager);
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case CUTSCENE_STOP_EVENT:
|
||
|
{
|
||
|
cutsceneModelEntityDebugf3("CUTSCENE_STOP_EVENT");
|
||
|
m_bStoppedCalled = true;
|
||
|
}
|
||
|
break;
|
||
|
case CUTSCENE_RESTART_EVENT:
|
||
|
{
|
||
|
m_pCutSceneTask = NULL;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case CutSceneCustomEvents::CUTSCENE_CUSTOM_CLOTH_EVENT:
|
||
|
{
|
||
|
//cutsceneModelEntityDebugf("CCutsceneAnimatedModelEntity::DispatchEvent: CUTSCENE_CUSTOM_CLOTH_EVENT");
|
||
|
const CutSceneCustomEvents::ICutsceneCustomCustomEventArgs* pObjectVar = static_cast<const CutSceneCustomEvents::ICutsceneCustomCustomEventArgs*>(pEventArgs);
|
||
|
CEntity* pEntity = GetGameEntity();
|
||
|
if ( pEntity && pObjectVar
|
||
|
&& pObjectVar->GetEventType() == CCEVENT_TYPE_CUSTOM_0
|
||
|
)
|
||
|
{
|
||
|
crSkeleton* pSkel = pEntity->GetSkeleton();
|
||
|
if( pSkel )
|
||
|
{
|
||
|
Mat34V rootBoneMat;
|
||
|
pSkel->GetGlobalMtx(0, rootBoneMat);
|
||
|
|
||
|
atHashString ModelNameHash("cs_mrs_thornhill");
|
||
|
CCutsceneAnimatedModelEntity* pAnimatedModel = ((CutSceneManager*)pManager)->GetAnimatedModelEntityFromModelHash(ModelNameHash);
|
||
|
CEntity* pEntity = pAnimatedModel->GetGameEntity();
|
||
|
if( pEntity && pEntity->GetIsTypePed() )
|
||
|
{
|
||
|
CPed* pPed = static_cast<CPed*>(pEntity);
|
||
|
if( pPed )
|
||
|
{
|
||
|
for( int i = 0; i < PV_MAX_COMP; ++i )
|
||
|
{
|
||
|
if( pPed->m_CClothController[i] )
|
||
|
{
|
||
|
phVerletCloth* pVerletCloth = pPed->m_CClothController[i]->GetCloth(0);
|
||
|
Assert( pVerletCloth );
|
||
|
if( !pVerletCloth->m_VirtualBound )
|
||
|
{
|
||
|
float fCapsuleLen = pObjectVar->GetCapsuleLength();
|
||
|
float fCapsuleRad = pObjectVar->GetCapsuleRadius();
|
||
|
|
||
|
pVerletCloth->SetFlag(phVerletCloth::FLAG_COLLIDE_EDGES, true);
|
||
|
pVerletCloth->SetFlag(phVerletCloth::FLAG_IGNORE_OFFSET, true);
|
||
|
|
||
|
pVerletCloth->CreateVirtualBound( 1, &identityMat );
|
||
|
pVerletCloth->AttachVirtualBoundCapsule( fCapsuleRad, fCapsuleLen, rootBoneMat, 0 );
|
||
|
|
||
|
m_CollisionBound = (phBoundComposite*)pVerletCloth->m_VirtualBound.ptr;
|
||
|
|
||
|
#if USE_CAPSULE_EXTRA_EXTENTS
|
||
|
Assert( m_CollisionBound );
|
||
|
phBound* pColBound = m_CollisionBound->GetBound(0);
|
||
|
Assert( pColBound );
|
||
|
static float fCapsuleHalfHeight = 0.15f;
|
||
|
((phBoundCapsule*)pColBound)->SetHalfHeight( fCapsuleHalfHeight );
|
||
|
#endif
|
||
|
m_bUpdateCollisionBound = true;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
} // if( pPed )
|
||
|
}
|
||
|
} // if( pSkel )
|
||
|
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
|
||
|
case CUTSCENE_SET_ANIMATION_EVENT:
|
||
|
case CUTSCENE_PLAY_EVENT:
|
||
|
case CUTSCENE_PAUSE_EVENT:
|
||
|
case CUTSCENE_UPDATE_LOADING_EVENT:
|
||
|
case CUTSCENE_STEP_FORWARD_EVENT:
|
||
|
case CUTSCENE_STEP_BACKWARD_EVENT:
|
||
|
case CUTSCENE_FAST_FORWARD_EVENT:
|
||
|
case CUTSCENE_REWIND_EVENT:
|
||
|
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
//this is here to dispatch debug draw event for this entity.
|
||
|
#if __BANK
|
||
|
cutsEntity::DispatchEvent(pManager, pObject, iEventId, pEventArgs);
|
||
|
#endif
|
||
|
|
||
|
}
|
||
|
|
||
|
#if !__NO_OUTPUT
|
||
|
XPARAM(cutscenecallstacklogging);
|
||
|
#endif //!__NO_OUTPUT
|
||
|
|
||
|
#if !__NO_OUTPUT
|
||
|
void CCutsceneAnimatedModelEntity::SetUpEntityForCallStackLogging()
|
||
|
{
|
||
|
if(GetGameEntity() && GetGameEntity()->GetIsPhysical())
|
||
|
{
|
||
|
if(PARAM_cutscenecallstacklogging.Get() BANK_ONLY (&& (CutSceneManager::GetInstance() && CutSceneManager::GetInstance()->IsCallStackLogging())) )
|
||
|
{
|
||
|
CPhysical* phys = static_cast<CPhysical*>(GetGameEntity());
|
||
|
|
||
|
phys->m_LogSetMatrixCalls = true;
|
||
|
phys->m_LogVisibiltyCalls = true;
|
||
|
phys->m_LogDeletions = true;
|
||
|
phys->m_LogVariationCalls = true;
|
||
|
m_bIsloggingEntityCalls = true;
|
||
|
}
|
||
|
}
|
||
|
};
|
||
|
#endif //!__NO_OUTPUT
|
||
|
|
||
|
#if !__NO_OUTPUT
|
||
|
void CCutsceneAnimatedModelEntity::ResetEntityForCallStackLogging()
|
||
|
{
|
||
|
if(GetGameEntity() && GetGameEntity()->GetIsPhysical())
|
||
|
{
|
||
|
if(PARAM_cutscenecallstacklogging.Get() BANK_ONLY (&& (CutSceneManager::GetInstance() && CutSceneManager::GetInstance()->IsCallStackLogging())) )
|
||
|
{
|
||
|
CPhysical* phys = static_cast<CPhysical*>(GetGameEntity());
|
||
|
phys->m_LogSetMatrixCalls = false;
|
||
|
phys->m_LogVisibiltyCalls = false;
|
||
|
phys->m_LogDeletions = false;
|
||
|
phys->m_LogVariationCalls = false;
|
||
|
m_bIsloggingEntityCalls = false;
|
||
|
}
|
||
|
}
|
||
|
};
|
||
|
#endif //!__NO_OUTPUT
|
||
|
|
||
|
bool CCutsceneAnimatedModelEntity::HasScriptVisibleTagPassed(s32 TagHash)
|
||
|
{
|
||
|
for(int i=0; i < SIZE_OF_SCRIPT_VISIBLE_TAG_LIST; i++)
|
||
|
{
|
||
|
if(m_ScriptVisibleTags[i] != 0)
|
||
|
{
|
||
|
if(m_ScriptVisibleTags[i] == TagHash)
|
||
|
{
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
void CCutsceneAnimatedModelEntity::ResetScriptVisibleTags()
|
||
|
{
|
||
|
for(int i=0; i < SIZE_OF_SCRIPT_VISIBLE_TAG_LIST; i++)
|
||
|
{
|
||
|
m_ScriptVisibleTags[i] = 0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CCutsceneAnimatedModelEntity::FindScriptVisibleTags(const crClip* pClip, float startPhase, float endPhase)
|
||
|
{
|
||
|
if(m_FrameTagsAreProcessed != fwTimer::GetFrameCount())
|
||
|
{
|
||
|
ResetScriptVisibleTags();
|
||
|
m_FrameTagsAreProcessed = fwTimer::GetFrameCount();
|
||
|
}
|
||
|
|
||
|
startPhase = Clamp(startPhase, 0.0f, 1.0f);
|
||
|
endPhase = Clamp(endPhase, 0.0f, 1.0f);
|
||
|
|
||
|
crTagIterator it(*pClip->GetTags(), startPhase, endPhase, ms_VisibleToScriptKey);
|
||
|
int numOfTags =0;
|
||
|
while (*it)
|
||
|
{
|
||
|
const crTag* pTag = *it;
|
||
|
|
||
|
if(pTag)
|
||
|
{
|
||
|
const crPropertyAttribute* pAttr = pTag->GetAttribute(ms_EventKey );
|
||
|
|
||
|
if(pAttr && pAttr->GetType() == crPropertyAttribute::kTypeHashString)
|
||
|
{
|
||
|
const crPropertyAttributeHashString *pAttrHashString = static_cast< const crPropertyAttributeHashString * >(pAttr);
|
||
|
|
||
|
for(int i=0; i < SIZE_OF_SCRIPT_VISIBLE_TAG_LIST; i++)
|
||
|
{
|
||
|
if(m_ScriptVisibleTags[i] == 0)
|
||
|
{
|
||
|
m_ScriptVisibleTags[i] = pAttrHashString->GetHashString().GetHash();
|
||
|
cutsceneModelEntityDebugf3("Found Script Visible Tag: %s (%d) in Clip: %s between phases: (s:%f , e:%f)",
|
||
|
pAttrHashString->GetHashString().TryGetCStr(), pAttrHashString->GetHashString().GetHash(), m_pClip->GetName(), startPhase, endPhase);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
++it;
|
||
|
numOfTags++;
|
||
|
}
|
||
|
cutsceneAssertf(numOfTags < SIZE_OF_SCRIPT_VISIBLE_TAG_LIST, "Found more than %d script visible tags between phases: %f, %f for clip: %s ", SIZE_OF_SCRIPT_VISIBLE_TAG_LIST, startPhase, endPhase, pClip->GetName());
|
||
|
}
|
||
|
|
||
|
void CCutsceneAnimatedModelEntity::ComputeScriptVisibleTagsOnAnimClear(CutSceneManager* pCutSceneManager)
|
||
|
{
|
||
|
if (m_pClip && m_bShouldProcessTags)
|
||
|
{
|
||
|
if(!pCutSceneManager->IsConcatted())
|
||
|
{
|
||
|
float startPhase = (pCutSceneManager->GetCutScenePreviousTime() - m_fStartTime) / m_pClip->GetDuration();
|
||
|
if(startPhase != 1.0f)
|
||
|
{
|
||
|
FindScriptVisibleTags(m_pClip, startPhase, 1.0f);
|
||
|
cutsceneModelEntityDebugf3("Non Concat - ComputeScriptVisibleTagsOnAnimClear: %s (s:%f , e:%f)", m_pClip->GetName(), startPhase, 1.0f);
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
//compute anim phases based on concat boundaries
|
||
|
s32 currentConcatSection = pCutSceneManager->GetConcatSectionForTime(pCutSceneManager->GetCutSceneCurrentTime());
|
||
|
s32 previousConcatSection = pCutSceneManager->GetConcatSectionForTime(pCutSceneManager->GetCutScenePreviousTime());
|
||
|
|
||
|
if(currentConcatSection != previousConcatSection && ((currentConcatSection-previousConcatSection) > 1))
|
||
|
{
|
||
|
//compute the anim end time based concat boundary of the next concat section
|
||
|
float animEndEndTime = pCutSceneManager->GetConcatSectionStartTime(previousConcatSection + 1);
|
||
|
|
||
|
float endPhase = (animEndEndTime - m_fStartTime) / m_pClip->GetDuration();
|
||
|
|
||
|
float startPhase = (pCutSceneManager->GetCutScenePreviousTime() - m_fStartTime) / m_pClip->GetDuration();
|
||
|
|
||
|
if(endPhase != startPhase)
|
||
|
{
|
||
|
FindScriptVisibleTags(m_pClip, startPhase, endPhase);
|
||
|
cutsceneModelEntityDebugf3("Concat Boundary - ComputeScriptVisibleTagsOnAnimClear: %s (s:%f , e:%f)", m_pClip->GetName(), startPhase, endPhase);
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
//search for tags to the end of the anim, still in the same concat section
|
||
|
float startPhase = (pCutSceneManager->GetCutScenePreviousTime() - m_fStartTime) / m_pClip->GetDuration();
|
||
|
float endPhase = (pCutSceneManager->GetCutSceneCurrentTime() - m_fStartTime) / m_pClip->GetDuration();
|
||
|
endPhase = Clamp(endPhase, startPhase, 1.0f);
|
||
|
|
||
|
if(startPhase != endPhase)
|
||
|
{
|
||
|
FindScriptVisibleTags(m_pClip, startPhase, endPhase);
|
||
|
cutsceneModelEntityDebugf3("Concat Non-Boundary - ComputeScriptVisibleTagsOnAnimClear: %s (s:%f , e:%f)", m_pClip->GetName(), startPhase, endPhase);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
m_bClearedOrSetAnimThisFrame = true;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CCutsceneAnimatedModelEntity::ComputeScriptVisibleTagsOnUpdate(CutSceneManager* pCutSceneManager)
|
||
|
{
|
||
|
if (m_pClip && !m_bClearedOrSetAnimThisFrame && m_bShouldProcessTags)
|
||
|
{
|
||
|
float startPhase = (pCutSceneManager->GetCutScenePreviousTime() - m_fStartTime) / m_pClip->GetDuration();
|
||
|
|
||
|
float endPhase = (pCutSceneManager->GetCutSceneCurrentTime() - m_fStartTime) / m_pClip->GetDuration();
|
||
|
|
||
|
if(endPhase != startPhase)
|
||
|
{
|
||
|
FindScriptVisibleTags(m_pClip, startPhase, endPhase);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CCutsceneAnimatedModelEntity::ComputeScriptVisibleTagsOnAnimSet(CutSceneManager* pCutSceneManager)
|
||
|
{
|
||
|
if (m_pClip)
|
||
|
{
|
||
|
m_bShouldProcessTags = false;
|
||
|
|
||
|
const crTag* pTag = CClipEventTags::FindFirstEventTag(m_pClip, ms_VisibleToScriptKey);
|
||
|
|
||
|
if(pTag)
|
||
|
{
|
||
|
m_bShouldProcessTags = true;
|
||
|
}
|
||
|
|
||
|
if(m_bShouldProcessTags)
|
||
|
{
|
||
|
if(!pCutSceneManager->IsConcatted())
|
||
|
{
|
||
|
//get the last anim phase
|
||
|
//set end phase = 1.0f we are about to get a new anim
|
||
|
float endPhase = (pCutSceneManager->GetCutSceneCurrentTime() - m_fStartTime) / m_pClip->GetDuration();
|
||
|
if(endPhase != 0.0f)
|
||
|
{
|
||
|
FindScriptVisibleTags(m_pClip, 0.0f, endPhase);
|
||
|
cutsceneModelEntityDebugf3("Non Concat - ComputeScriptVisibleTagsOnAnimSet: %s (s:%f , e:%f)", m_pClip->GetName(), 0.0f, endPhase );
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
float previousTime = pCutSceneManager->GetCutScenePreviousTime();
|
||
|
|
||
|
if(pCutSceneManager->GetInternalTime() == pCutSceneManager->GetStartTime())
|
||
|
{
|
||
|
if(!pCutSceneManager->IsConcatSectionValidForPlayBack(0))
|
||
|
{
|
||
|
previousTime = -1.0f;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//Crossed a concat boundary compute the tag from the start of concat boundary to the current time
|
||
|
s32 currentConcatSection = pCutSceneManager->GetConcatSectionForTime(pCutSceneManager->GetCutSceneCurrentTime());
|
||
|
s32 previousConcatSection = pCutSceneManager->GetConcatSectionForTime(previousTime);
|
||
|
|
||
|
if(currentConcatSection != previousConcatSection && ((currentConcatSection-previousConcatSection) > 1))
|
||
|
{
|
||
|
//we compute the phase from this point into the anim
|
||
|
float concatStartTime = pCutSceneManager->GetConcatSectionStartTime(currentConcatSection);
|
||
|
|
||
|
s32 currentAnimSection = pCutSceneManager->GetSectionForTime( pCutSceneManager->GetCutSceneCurrentTime() );
|
||
|
float animSectionStartTime = pCutSceneManager->GetSectionStartTime(currentAnimSection);
|
||
|
float startPhase = 0.0f;
|
||
|
float endPhase = 0.0f;
|
||
|
|
||
|
//The start of the concat section is further on in time so need to calculate the phase of the anim relative to the concat section
|
||
|
//because it's the concat section that defines what to play not the anim section. Other wise the anim time is in a valid part of the
|
||
|
//concat so just use a start phase of zero and whatever has progressed.
|
||
|
//Showing how anim and cocnat sections can vary.
|
||
|
//e.g anim section: Start:0 | A1 end: 10 | A2 end:20| A3 end:30|
|
||
|
// concat section start:0 | end 12| end:18| end:30|
|
||
|
|
||
|
if(concatStartTime >= animSectionStartTime)
|
||
|
{
|
||
|
startPhase = (concatStartTime - animSectionStartTime) / m_pClip->GetDuration();
|
||
|
}
|
||
|
|
||
|
endPhase = (pCutSceneManager->GetCutSceneCurrentTime() - animSectionStartTime) / m_pClip->GetDuration();
|
||
|
|
||
|
if(endPhase != startPhase)
|
||
|
{
|
||
|
FindScriptVisibleTags(m_pClip, startPhase, endPhase);
|
||
|
cutsceneModelEntityDebugf3("Concat Boundary - ComputeScriptVisibleTagsOnAnimSet: %s (s:%f , e:%f)", m_pClip->GetName(), startPhase, endPhase );
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
float startPhase = (pCutSceneManager->GetCutScenePreviousTime() - m_fStartTime) / m_pClip->GetDuration();
|
||
|
float endPhase = (pCutSceneManager->GetCutSceneCurrentTime() - m_fStartTime) / m_pClip->GetDuration();
|
||
|
|
||
|
startPhase = Clamp(startPhase, 0.0f, endPhase);
|
||
|
|
||
|
if(endPhase != startPhase)
|
||
|
{
|
||
|
FindScriptVisibleTags(m_pClip, startPhase, endPhase);
|
||
|
}
|
||
|
cutsceneModelEntityDebugf3("Concat Non Boundary - ComputeScriptVisibleTagsOnAnimSet: %s (s:%f , e:%f)", m_pClip->GetName(), startPhase, endPhase );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
m_bClearedOrSetAnimThisFrame = true;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////
|
||
|
void CCutsceneAnimatedModelEntity::RequestRepositionOnlyEntityModelWhenNeeded(CutSceneManager* pManager, const cutfObject* pObject)
|
||
|
{
|
||
|
// check if we want to request a reposition only entity
|
||
|
if (!IsScriptRegisteredGameEntity() // check that script have not registered this as a game entity
|
||
|
&& IsScriptRegisteredRepositionOnlyEntity() // check that script have registered this as a reposition only entity
|
||
|
&& !m_RegisteredEntityFromScript.pEnt // check the entity has not been assigned to script already
|
||
|
&& m_pEntityForRepositionOnly == NULL // reposition entity has not been made yet
|
||
|
&& m_RegisteredEntityFromScript.bCreatedForScript // entity is to be created by the cutscene for the script
|
||
|
&& !m_bRequestRepositionOnlyEntity // request has not been made yet
|
||
|
)
|
||
|
{
|
||
|
cutsceneModelEntityDebugf2("RequestRepositionOnlyEntityModel ------------------------------------------- ");
|
||
|
|
||
|
// add the streaming request
|
||
|
pManager->GetAssetManager()->SetModelStreamingRequest(m_RegisteredEntityFromScript.ModelNameHash, pObject->GetObjectId(), MODEL_TYPE);
|
||
|
m_bRequestRepositionOnlyEntity = true;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
void CCutsceneAnimatedModelEntity::SetAnimPlayBackEventTime(float fEventTime)
|
||
|
{
|
||
|
m_fStartTime = fEventTime;
|
||
|
}
|
||
|
|
||
|
void CCutsceneAnimatedModelEntity::GetMoverTrackVelocity(const crClip* pClip, float fCurrentPhase, float fLastPhase, float fTimeStep)
|
||
|
{
|
||
|
if(m_pEntity)
|
||
|
{
|
||
|
if(fTimeStep > 0.0f)
|
||
|
{
|
||
|
if(pClip)
|
||
|
{
|
||
|
const float time = pClip->ConvertPhaseToTime(fCurrentPhase);
|
||
|
const float timeOnPreviousUpdate = pClip->ConvertPhaseToTime(fLastPhase);
|
||
|
bool bIsWarpFrame = pClip->CalcBlockPassed(timeOnPreviousUpdate, time);
|
||
|
|
||
|
if (bIsWarpFrame)
|
||
|
{
|
||
|
m_vVelocity.Zero();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
m_vVelocity = fwAnimHelpers::GetMoverTrackDisplacement(*pClip, fLastPhase, fCurrentPhase);
|
||
|
m_vVelocity /= fTimeStep;
|
||
|
}
|
||
|
//printf("CCutsceneAnimatedModelEntity::GetMoverTrackVelocity: %s, m_vVelocity: %.2f, %.2f, %.2f, Phases: %.2f - %.2f\n", pClip->GetName(), m_vVelocity.x, m_vVelocity.y, m_vVelocity.z, fLastPhase, fCurrentPhase);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
m_vVelocity.Zero();
|
||
|
}
|
||
|
|
||
|
cutsceneAssertf(rage::FPIsFinite(m_vVelocity.x), "Exit x velocity from cutscene is not finite" );
|
||
|
cutsceneAssertf(rage::FPIsFinite(m_vVelocity.y), "Exit y velocity from cutscene is not finite" );
|
||
|
cutsceneAssertf(rage::FPIsFinite(m_vVelocity.z), "Exit z velocity from cutscene is not finite" );
|
||
|
|
||
|
Matrix34 mEntityMat = MAT34V_TO_MATRIX34(m_pEntity->GetMatrix());
|
||
|
mEntityMat.Transform3x3(m_vVelocity);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CCutsceneAnimatedModelEntity::UpdateCutSceneTaskPhase(CTask* pTask, cutsManager* pManager)
|
||
|
{
|
||
|
CutSceneManager* pCutsManager = static_cast<CutSceneManager*>(pManager);
|
||
|
|
||
|
if(ShouldUpdateCutSceneTask(pTask, pManager))
|
||
|
{
|
||
|
if(pTask && pTask->GetTaskType() == CTaskTypes::TASK_CUTSCENE)
|
||
|
{
|
||
|
CTaskCutScene* pCutSceneTask = static_cast<CTaskCutScene*>(pTask);
|
||
|
|
||
|
const crClip* pClip = pCutSceneTask->GetClip();
|
||
|
|
||
|
if (pClip)
|
||
|
{
|
||
|
float fPhase = pCutsManager->GetPhaseUpdateAmount(pClip, GetAnimEventStartTime());
|
||
|
|
||
|
pCutSceneTask->SetPhase(fPhase);
|
||
|
|
||
|
if(pCutSceneTask->WillFinishThisPhase(fPhase))
|
||
|
{
|
||
|
cutsceneModelEntityDebugf1("CUTSCENE_BLEND_OUT_TAG");
|
||
|
m_bStoppedCalled = true;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
bool CCutsceneAnimatedModelEntity::ShouldUpdateCutSceneTask(CTask* pTask, cutsManager* pManager)
|
||
|
{
|
||
|
CutSceneManager* pCutsManager = static_cast<CutSceneManager*>(pManager);
|
||
|
|
||
|
if(m_SectionAnimWasRecieved != pCutsManager->GetCurrentSection())
|
||
|
{
|
||
|
if(pTask && pTask->GetTaskType() == CTaskTypes::TASK_CUTSCENE)
|
||
|
{
|
||
|
CTaskCutScene* pCutSceneTask = static_cast<CTaskCutScene*>(pTask);
|
||
|
|
||
|
pCutSceneTask->SetPhase(1.0f);
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
bool CCutsceneAnimatedModelEntity::RemoveEntityFromTheWorld(CEntity* pEntity, bool bDeleteScriptRegistered)
|
||
|
{
|
||
|
bool ShouldRemove = false;
|
||
|
if (pEntity)
|
||
|
{
|
||
|
bool CanDelete = m_RegisteredEntityFromScript.pEnt != pEntity || bDeleteScriptRegistered;
|
||
|
|
||
|
if(CanDelete|| m_RegisteredEntityFromScript.bDeleteBeforeEnd)
|
||
|
{
|
||
|
cutsceneModelEntityDebugf2("RemoveEntityFromWorld");
|
||
|
if(pEntity->GetIsPhysical())
|
||
|
{
|
||
|
//about to delete a script registered object
|
||
|
CTheScripts::UnregisterEntity((CPhysical*)pEntity, true);
|
||
|
}
|
||
|
#if !__NO_OUTPUT
|
||
|
if(pEntity->GetIsPhysical() && m_bIsloggingEntityCalls)
|
||
|
{
|
||
|
((CPhysical*)pEntity)->m_LogDeletions = false;
|
||
|
}
|
||
|
#endif //!__NO_OUTPUT
|
||
|
pEntity->FlagToDestroyWhenNextProcessed();
|
||
|
pEntity->DisableCollision();
|
||
|
SetVisibility(pEntity, false);
|
||
|
cutsceneModelEntityDebugf2("CCutsceneAnimatedModelEntity::RemoveEntityFromTheWorld: Hide entity (%s)", pEntity->GetModelName());
|
||
|
ShouldRemove = true;
|
||
|
}
|
||
|
}
|
||
|
return ShouldRemove;
|
||
|
}
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
#if __DEV
|
||
|
void CCutsceneAnimatedModelEntity::DebugDraw() const
|
||
|
{
|
||
|
Vector3 vGameEntityPosition;
|
||
|
Vector3 vPos;
|
||
|
Color32 Colour (Color_blue);
|
||
|
const CEntity* pEnt = NULL;
|
||
|
|
||
|
if(GetGameEntity())
|
||
|
{
|
||
|
pEnt = GetGameEntity();
|
||
|
}
|
||
|
|
||
|
if(!pEnt)
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if(pEnt)
|
||
|
{
|
||
|
if(CutSceneManager::GetInstance()->GetDebugManager().m_bDisplayAllSkeletons)
|
||
|
{
|
||
|
const crSkeleton* pSkeleton = pEnt->GetSkeleton();
|
||
|
CAnimViewer::RenderSkeleton(*pSkeleton, Color_red, Color_blue, 0.01f);
|
||
|
Matrix34 m = MAT34V_TO_MATRIX34(pEnt->GetMatrix());
|
||
|
grcDebugDraw::Axis(m, 0.5f, true);
|
||
|
}
|
||
|
|
||
|
vGameEntityPosition = VEC3V_TO_VECTOR3(pEnt->GetTransform().GetPosition());
|
||
|
}
|
||
|
|
||
|
|
||
|
//draw the scene handles
|
||
|
vPos = vGameEntityPosition;
|
||
|
vPos.z += 1.0f;
|
||
|
grcDebugDraw::Line(vGameEntityPosition,vPos,Colour);
|
||
|
char text [128];
|
||
|
const cutfModelObject* pModel = NULL;
|
||
|
|
||
|
if(GetCutfObject()->GetType() == CUTSCENE_MODEL_OBJECT_TYPE)
|
||
|
{
|
||
|
pModel = static_cast<const cutfModelObject*>(GetCutfObject());
|
||
|
}
|
||
|
|
||
|
if(pModel)
|
||
|
{
|
||
|
grcDebugDraw::Text(vPos, Colour, formatf(text, "Display Name: %s Scene Handle: %s", GetCutfObject()->GetDisplayName().c_str(), pModel->GetHandle().GetCStr()));
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
grcDebugDraw::Text(vPos, Colour, formatf(text, "Display Name: %s", GetCutfObject()->GetDisplayName().c_str()));
|
||
|
}
|
||
|
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
// Animated Prop Entity
|
||
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
CCutSceneAnimatedPropEntity::CCutSceneAnimatedPropEntity(const cutfObject* pObject)
|
||
|
:CCutsceneAnimatedModelEntity(pObject)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
CCutSceneAnimatedPropEntity::~CCutSceneAnimatedPropEntity()
|
||
|
{
|
||
|
//check that the script registered entity is being picked up by the script
|
||
|
if(m_RegisteredEntityFromScript.SceneNameHash > 0 && m_RegisteredEntityFromScript.bCreatedForScript)
|
||
|
{
|
||
|
if(m_RegisteredEntityFromScript.pEnt != NULL)
|
||
|
{
|
||
|
const CScriptEntityExtension* pExtension = m_RegisteredEntityFromScript.pEnt->GetExtension<CScriptEntityExtension>();
|
||
|
|
||
|
if(!CutSceneManager::GetInstance()->ShouldDeleteAllRegisteredEntites())
|
||
|
{
|
||
|
if(!IsRegisteredGameEntityUnderScriptControl())
|
||
|
{
|
||
|
cutsceneAssertf(pExtension, "Deleting a cutscene entity (\"%s\" %u) scene handle (\"%s\" %u) that was registered with CU_CREATE_AND_ANIMATE_NEW_SCRIPT_ENTITY use GET_ENTITY_INDEX_OF_REGISTERED_ENTITY to make sure it is pickup up by the script",
|
||
|
m_RegisteredEntityFromScript.ModelNameHash.TryGetCStr(),
|
||
|
m_RegisteredEntityFromScript.ModelNameHash.GetHash(),
|
||
|
m_RegisteredEntityFromScript.SceneNameHash.TryGetCStr(),
|
||
|
m_RegisteredEntityFromScript.SceneNameHash.GetHash());
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if(!pExtension)
|
||
|
{
|
||
|
m_RegisteredEntityFromScript.bDeleteBeforeEnd = true;
|
||
|
|
||
|
if(m_bCreatedByCutscene)
|
||
|
{
|
||
|
if(GetGameEntity())
|
||
|
{
|
||
|
GetGameEntity()->SetOwnedBy(ENTITY_OWNEDBY_TEMP);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
//need to implement a game version of this
|
||
|
void CCutSceneAnimatedPropEntity::CreateGameEntity(strLocalIndex iModelIndex, bool CreateRepositionEntity, bool UNUSED_PARAM(bRequestVariations), bool UNUSED_PARAM(bApplyVariations))
|
||
|
{
|
||
|
if(GetGameEntity() == NULL)
|
||
|
{
|
||
|
cutsceneModelEntityDebugf2("CreateGameEntity - Prop");
|
||
|
|
||
|
fwModelId modelId((strLocalIndex(iModelIndex)));
|
||
|
CBaseModelInfo* pModelInfo = CModelInfo::GetBaseModelInfo(modelId);
|
||
|
|
||
|
if(pModelInfo)
|
||
|
{
|
||
|
cutsceneAssertf(pModelInfo->GetIsTypeObject(), "CUTSCENE ASSET (Assign to *Default Anim Cutscene*): Exported incorrectly, %s is not a PropModel type", pModelInfo->GetModelName());
|
||
|
if(pModelInfo->GetIsTypeObject())
|
||
|
{
|
||
|
// By default objects are created at the origin and their drawables are created automatically this flag allows objects to be created without
|
||
|
// their drawable they are then moved to the scene origin and then their drawable is created
|
||
|
// this matters if the drawable contains lights as these lights will only be updated to be relative to the object when the lights bounding box
|
||
|
// is on screen and not when the object is moved (FTR I think this is the real bug)
|
||
|
// We don't want to make this the default behavior at this stage for fear of "fixing" things and causing double lighting etc
|
||
|
bool bCreateObjectsAtSceneOrigin = CutSceneManager::GetInstance()->GetOptionFlags().IsFlagSet(CUTSCENE_CREATE_OBJECTS_AT_SCENE_ORIGIN);
|
||
|
CObject* pObject = CObjectPopulation::CreateObject(modelId, ENTITY_OWNEDBY_CUTSCENE, bCreateObjectsAtSceneOrigin? false : true, true, false);
|
||
|
|
||
|
if (pObject)
|
||
|
{
|
||
|
#if GTA_REPLAY
|
||
|
CReplayMgr::RecordObject(pObject);
|
||
|
#endif //GTA_REPLAY
|
||
|
|
||
|
Matrix34 TempMat;
|
||
|
|
||
|
TempMat.Identity();
|
||
|
TempMat.d = m_vCreatePos;
|
||
|
|
||
|
//cant create objects on top of each other, the game complains about it.
|
||
|
TempMat.d.z += 0.001f * m_pCutfObject->GetObjectId();
|
||
|
|
||
|
pObject->SetMatrix(TempMat);
|
||
|
|
||
|
if (bCreateObjectsAtSceneOrigin)
|
||
|
{
|
||
|
pObject->CreateDrawable();
|
||
|
}
|
||
|
|
||
|
// Add Object to world after its position has been set
|
||
|
|
||
|
CGameWorld::Add(pObject, CGameWorld::OUTSIDE );
|
||
|
|
||
|
pObject->GetPortalTracker()->ScanUntilProbeTrue();
|
||
|
pObject->GetPortalTracker()->Update(VEC3V_TO_VECTOR3(pObject->GetTransform().GetPosition()));
|
||
|
pObject->GetPortalTracker()->SetIsCutsceneControlled(true);
|
||
|
|
||
|
if(CreateRepositionEntity)
|
||
|
{
|
||
|
SetRepositionOnlyEntity(pObject);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
SetGameEntity(pObject);
|
||
|
}
|
||
|
m_bCreatedByCutscene = true;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CCutSceneAnimatedPropEntity::ForceUpdateAi(cutsManager* pManager)
|
||
|
{
|
||
|
if(pManager)
|
||
|
{
|
||
|
CutSceneManager* pCutSceneManager = static_cast<CutSceneManager*> (pManager);
|
||
|
|
||
|
if(pCutSceneManager->GetShutDownMode() != SHUTDOWN_SESSION)
|
||
|
{
|
||
|
CObject* pObj = GetGameEntity();
|
||
|
if (pObj && pObj->GetObjectIntelligence())
|
||
|
{
|
||
|
pObj->GetObjectIntelligence()->Process();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
};
|
||
|
|
||
|
|
||
|
void CCutSceneAnimatedPropEntity::SetRepositionOnlyEntityReadyForCutscene()
|
||
|
{
|
||
|
if(GetGameRepositionOnlyEntity())
|
||
|
{
|
||
|
GetGameRepositionOnlyEntity()->m_nPhysicalFlags.bNotDamagedByAnything = true;
|
||
|
GetGameRepositionOnlyEntity()->SetIsVisibleForModule(SETISVISIBLE_MODULE_CUTSCENE, false);
|
||
|
cutsceneModelEntityDebugf2("CCutSceneAnimatedPropEntity::SetRepositionOnlyEntityReadyForCutscene: Hiding GetGameRepositionOnlyEntity (%s)", GetGameRepositionOnlyEntity()->GetModelName());
|
||
|
|
||
|
NetworkInterface::CutsceneStartedOnEntity(*GetGameRepositionOnlyEntity());
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CCutSceneAnimatedPropEntity::SetGameEntityReadyForCutscene()
|
||
|
{
|
||
|
if(GetGameEntity())
|
||
|
{
|
||
|
|
||
|
#if !__NO_OUTPUT
|
||
|
SetUpEntityForCallStackLogging();
|
||
|
#endif
|
||
|
|
||
|
GetGameEntity()->SetFixedPhysics(true);
|
||
|
GetGameEntity()->m_nPhysicalFlags.bNotDamagedByAnything = true;
|
||
|
GetGameEntity()->m_nDEflags.bForcePrePhysicsAnimUpdate = true;
|
||
|
GetGameEntity()->DisableCollision();
|
||
|
|
||
|
NetworkInterface::CutsceneStartedOnEntity(*GetGameEntity());
|
||
|
|
||
|
if(!m_RegisteredEntityFromScript.bCreatedForScript)
|
||
|
{
|
||
|
if(GetGameEntity()->IsADoor() && m_OptionFlags.IsFlagSet(CEO_UPDATE_AS_REAL_DOOR))
|
||
|
{
|
||
|
CDoor* door = static_cast<CDoor*>(GetGameEntity());
|
||
|
door->SetRegisteredWithCutscene(true);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CCutSceneAnimatedPropEntity::SetGameEntityReadyForGame(cutsManager* UNUSED_PARAM(pManager))
|
||
|
{
|
||
|
if(!m_bIsReadyForGame)
|
||
|
{
|
||
|
if(GetGameEntity())
|
||
|
{
|
||
|
NetworkInterface::CutsceneFinishedOnEntity(*GetGameEntity());
|
||
|
|
||
|
if(!m_RegisteredEntityFromScript.bCreatedForScript)
|
||
|
{
|
||
|
if(GetGameEntity()->IsADoor() && m_OptionFlags.IsFlagSet(CEO_UPDATE_AS_REAL_DOOR))
|
||
|
{
|
||
|
CDoor* door = static_cast<CDoor*>(GetGameEntity());
|
||
|
door->SetRegisteredWithCutscene(false);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#if !__NO_OUTPUT
|
||
|
ResetEntityForCallStackLogging();
|
||
|
#endif
|
||
|
if(m_RegisteredEntityFromScript.bCreatedForScript || !m_RegisteredEntityFromScript.bDeleteBeforeEnd)
|
||
|
{
|
||
|
cutsceneModelEntityDebugf2("SetGameEntityReadyForGame - Prop");
|
||
|
GetGameEntity()->m_nPhysicalFlags.bNotDamagedByAnything = m_bWasInvincible;
|
||
|
GetGameEntity()->m_nDEflags.bForcePrePhysicsAnimUpdate = false;
|
||
|
GetGameEntity()->EnableCollision();
|
||
|
GetGameEntity()->SetFixedPhysics(false);
|
||
|
}
|
||
|
bool CanDelete = m_RegisteredEntityFromScript.pEnt != GetGameEntity();
|
||
|
if(CanDelete|| m_RegisteredEntityFromScript.bDeleteBeforeEnd)
|
||
|
{
|
||
|
GetGameEntity()->SetOwnedBy(ENTITY_OWNEDBY_TEMP);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
GetGameEntity()->SetOwnedBy(ENTITY_OWNEDBY_SCRIPT);
|
||
|
SetVisibility(GetGameEntity(), true);
|
||
|
cutsceneModelEntityDebugf2("CCutSceneAnimatedPropEntity::SetGameEntityReadyForGame: Showing GetGameEntity (%s)", GetGameEntity()->GetModelName());
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if(GetGameRepositionOnlyEntity())
|
||
|
{
|
||
|
cutsceneModelEntityDebugf2("SetGameEntityReadyForGame - Prop (reposition only)");
|
||
|
GetGameRepositionOnlyEntity()->SetPosition(m_CurrentPosition);
|
||
|
GetGameRepositionOnlyEntity()->SetHeading(m_CurrentHeading);
|
||
|
GetGameRepositionOnlyEntity()->m_nPhysicalFlags.bNotDamagedByAnything = m_bWasInvincible;
|
||
|
GetGameRepositionOnlyEntity()->SetIsVisibleForModule(SETISVISIBLE_MODULE_CUTSCENE, true);
|
||
|
cutsceneModelEntityDebugf2("CCutSceneAnimatedPropEntity::SetGameEntityReadyForGame: Showing GetGameRepositionOnlyEntity (%s)", GetGameRepositionOnlyEntity()->GetModelName());
|
||
|
|
||
|
if(m_bCreatedByCutscene)
|
||
|
{
|
||
|
GetGameRepositionOnlyEntity()->SetOwnedBy(ENTITY_OWNEDBY_SCRIPT);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (m_pCutSceneTask)
|
||
|
{
|
||
|
m_pCutSceneTask->SetExitNextUpdate();
|
||
|
}
|
||
|
|
||
|
m_bIsReadyForGame = true;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
void CCutSceneAnimatedPropEntity::PlayClip (CutSceneManager* pCutManager, const crClip* pClip, float fEventTime, const strStreamingObjectName UNUSED_PARAM(pAnimDict))
|
||
|
{
|
||
|
if(GetGameEntity())
|
||
|
{
|
||
|
if(!m_pCutSceneTask)
|
||
|
{
|
||
|
m_pCutSceneTask = CreateCutsceneTask(pCutManager, pClip, fEventTime);
|
||
|
GetGameEntity()->SetTask(m_pCutSceneTask);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if(cutsceneVerifyf(m_pCutSceneTask->GetTaskType() == CTaskTypes::TASK_CUTSCENE, "Trying to set the clip on a CTaskCutscene, but entity %s is not running a cutscene task", m_pCutfObject->GetDisplayName().c_str()))
|
||
|
{
|
||
|
Matrix34 SceneMat;
|
||
|
pCutManager->GetSceneOrientationMatrix(SceneMat);
|
||
|
m_pCutSceneTask->SetClip(pClip,SceneMat, fEventTime);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//store info about the which section the anim started at.
|
||
|
SetAnimPlayBackEventTime(fEventTime);
|
||
|
}
|
||
|
|
||
|
|
||
|
void CCutSceneAnimatedPropEntity::UpdateCutSceneTask(cutsManager* pManager)
|
||
|
{
|
||
|
if(GetGameEntity())
|
||
|
{
|
||
|
const CObject* pObject = GetGameEntity();
|
||
|
if(pObject && pObject->GetObjectIntelligence())
|
||
|
{
|
||
|
CTask* pTask = pObject->GetObjectIntelligence()->FindTaskByType(CTaskTypes::TASK_CUTSCENE);
|
||
|
UpdateCutSceneTaskPhase(pTask, pManager);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
CTaskCutScene* CCutsceneAnimatedModelEntity::CreateCutsceneTask(CutSceneManager* pManager, const crClip* pClip, float fEventTime)
|
||
|
{
|
||
|
Matrix34 SceneMat(M34_IDENTITY);
|
||
|
|
||
|
pManager->GetSceneOrientationMatrix(SceneMat);
|
||
|
|
||
|
float fPhase = pManager->GetPhaseUpdateAmount(pClip,fEventTime);
|
||
|
|
||
|
CTaskCutScene* pTask = rage_new CTaskCutScene(pClip, SceneMat, fPhase, fEventTime);
|
||
|
|
||
|
return pTask;
|
||
|
}
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
void CCutSceneAnimatedPropEntity::DispatchEvent( cutsManager* pManager, const cutfObject* pObject, s32 iEventId, const cutfEventArgs* pEventArgs, const float UNUSED_PARAM(fTime), const u32 UNUSED_PARAM(StickyId) )
|
||
|
{
|
||
|
switch ( iEventId )
|
||
|
{
|
||
|
case CUTSCENE_PAUSE_EVENT:
|
||
|
case CUTSCENE_UPDATE_EVENT:
|
||
|
{
|
||
|
if (iEventId==CUTSCENE_UPDATE_EVENT && m_bStoppedCalled)
|
||
|
{
|
||
|
CreateRepositionOnlyGameEntityWhenModelLoaded(pManager, pObject, true, true );
|
||
|
SetGameEntityReadyForGame(pManager);
|
||
|
}
|
||
|
UpdateCutSceneTask(pManager);
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
CCutsceneAnimatedModelEntity::DispatchEvent( pManager,pObject, iEventId,pEventArgs);
|
||
|
}
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
// Animated Weapon Entity
|
||
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
CCutSceneAnimatedWeaponEntity::CCutSceneAnimatedWeaponEntity(const cutfObject* pObject)
|
||
|
:CCutSceneAnimatedPropEntity(pObject)
|
||
|
{
|
||
|
m_RegisteredGenericWeaponType = 0;
|
||
|
}
|
||
|
|
||
|
CCutSceneAnimatedWeaponEntity::~CCutSceneAnimatedWeaponEntity()
|
||
|
{
|
||
|
|
||
|
}
|
||
|
|
||
|
u32 CCutSceneAnimatedWeaponEntity::GetCutObjectGenericWeaponType () const
|
||
|
{
|
||
|
u32 GenericWeaponType = 0;
|
||
|
|
||
|
if(m_pCutfObject && m_pCutfObject->GetType() == CUTSCENE_MODEL_OBJECT_TYPE)
|
||
|
{
|
||
|
const cutfModelObject* pModelObject = static_cast<const cutfModelObject*>(m_pCutfObject);
|
||
|
|
||
|
if(pModelObject && pModelObject->GetModelType() == CUTSCENE_WEAPON_MODEL_TYPE)
|
||
|
{
|
||
|
const cutfWeaponModelObject* pWeapon = static_cast<const cutfWeaponModelObject*>(pModelObject);
|
||
|
|
||
|
if(pWeapon)
|
||
|
{
|
||
|
GenericWeaponType = pWeapon->GetGenericWeaponType();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return GenericWeaponType;
|
||
|
}
|
||
|
|
||
|
bool CCutSceneAnimatedWeaponEntity::IsScriptRegisteredGameEntity()
|
||
|
{
|
||
|
if(m_RegisteredGenericWeaponType == 0)
|
||
|
{
|
||
|
return CCutsceneAnimatedModelEntity::IsScriptRegisteredGameEntity();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if(m_pCutfObject)
|
||
|
{
|
||
|
const cutfWeaponModelObject* pWeapon = static_cast<const cutfWeaponModelObject*>(m_pCutfObject);
|
||
|
if(pWeapon)
|
||
|
{
|
||
|
return ((m_RegisteredEntityFromScript.SceneNameHash.GetHash()>0 && (m_RegisteredEntityFromScript.SceneNameHash.GetHash() == GetSceneHandleHash().GetHash())) && pWeapon->GetGenericWeaponType() == m_RegisteredGenericWeaponType);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
void CCutSceneAnimatedWeaponEntity::SetGameEntityReadyForCutscene()
|
||
|
{
|
||
|
// Base
|
||
|
CCutSceneAnimatedPropEntity::SetGameEntityReadyForCutscene();
|
||
|
|
||
|
CObject* pGameObject = GetGameEntity();
|
||
|
if (pGameObject && !pGameObject->m_pWeapon && pGameObject->GetBaseModelInfo() && pGameObject->GetBaseModelInfo()->GetModelType() == MI_TYPE_WEAPON)
|
||
|
{
|
||
|
CWeaponModelInfo* pWeaponModelInfo = static_cast<CWeaponModelInfo*>(pGameObject->GetBaseModelInfo());
|
||
|
|
||
|
// Get the weapon info from the model hash
|
||
|
const u32 uWeaponModelHash = pWeaponModelInfo->GetModelNameHash();
|
||
|
const CWeaponInfo* pWeaponInfo = CWeaponInfoManager::GetInfoFromModelNameHash<CWeaponInfo>(uWeaponModelHash ASSERT_ONLY(, true));
|
||
|
if(pWeaponInfo)
|
||
|
{
|
||
|
CPedEquippedWeapon::SetupAsWeapon(pGameObject, pWeaponInfo, 0);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
// Animated Actor Entity
|
||
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
#if __DEV
|
||
|
//THIS CURRENTLY DOES NOTHING TO FILTER ANY ANIMS BECAUSE THERE IS NO FILTER TO REMOVE ALL ANIM EXCEPT FACIAL
|
||
|
void CCutsceneAnimatedActorEntity::UpdateWithFaceViewer(CutSceneManager* pManager, CTaskCutScene* pCutSceneTask)
|
||
|
{
|
||
|
if(!pCutSceneTask || !pManager)
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
const CCutSceneCameraEntity* pCam = pManager->GetCamEntity();
|
||
|
//camera is pointing at ped
|
||
|
if(pCam && pCam->IsCameraPointingAtThisObject(this))
|
||
|
{
|
||
|
pCutSceneTask->SetCanApplyMoverTrackUpdate(false);
|
||
|
Matrix34 mSceneMat(M34_IDENTITY);
|
||
|
pManager->GetSceneOrientationMatrix(mSceneMat);
|
||
|
|
||
|
//pCutSceneTask->SetFilter(BONEMASK_HEADONLY); //removed because facial anims are applied by extra dofs that arent bones
|
||
|
|
||
|
//apply the new ped pos
|
||
|
mSceneMat.d.z+=1000.0f;
|
||
|
GetGameEntity()->SetMatrix(mSceneMat);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
//if(pCutSceneTask->GetFilter().GetHash() != BONEMASK_ALL)
|
||
|
//{
|
||
|
//removed because facial anims are applied by extra dofs that arent bones this filter will remove facial anims
|
||
|
// pCutSceneTask->SetFilter(BONEMASK_ALL);
|
||
|
pCutSceneTask->SetCanApplyMoverTrackUpdate(true);
|
||
|
//}
|
||
|
}
|
||
|
};
|
||
|
#endif
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
void CCutsceneAnimatedActorEntity::InitActor(CPed* pPed)
|
||
|
{
|
||
|
if (pPed)
|
||
|
{
|
||
|
pPed->PopTypeSet(POPTYPE_MISSION);
|
||
|
pPed->SetDefaultDecisionMaker();
|
||
|
pPed->SetBlockingOfNonTemporaryEvents(true);
|
||
|
pPed->SetPedConfigFlag( CPED_CONFIG_FLAG_DrownsInWater, false );
|
||
|
pPed->GetPedIntelligence()->SetDefaultRelationshipGroup();
|
||
|
pPed->m_nPhysicalFlags.bNotDamagedByAnything = true;
|
||
|
//possibly add the rag doll and low lod physics commands here
|
||
|
pPed->SetCharParamsBasedOnManagerType();
|
||
|
|
||
|
CGameWorld::Add(pPed, CGameWorld::OUTSIDE);
|
||
|
pPed->SetFixedPhysics(true);
|
||
|
}
|
||
|
};
|
||
|
/////////////////////////////////////////////////////////////////////////
|
||
|
// store the ped variation for when a ped has to be recreated
|
||
|
|
||
|
void CCutsceneAnimatedActorEntity::StoreActorVariationData(u32 iComponent, s32 iDrawable, s32 iTexture, sActorVariationData& ActorData )
|
||
|
{
|
||
|
cutsceneAssertf((iDrawable>-1 && iTexture>-1) || (iComponent>=PV_MAX_COMP && iDrawable>-2), "Component, Drawable or Texture is invalid (Component: %d (%s), Drawable: %d, Texture: %d)", iComponent, CPedVariationData::GetVarOrPropSlotName(iComponent), iDrawable, iTexture);
|
||
|
|
||
|
for (int i =0; i < ActorData.iPedVarData.GetCount(); i++)
|
||
|
{
|
||
|
if(iComponent == ActorData.iPedVarData[i].iComponent)
|
||
|
{
|
||
|
ActorData.iPedVarData[i].iDrawable = iDrawable;
|
||
|
ActorData.iPedVarData[i].iTexture = iTexture;
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
sPedComponentVar& NewPedComponent = ActorData.iPedVarData.Grow();
|
||
|
|
||
|
NewPedComponent.iComponent = iComponent;
|
||
|
NewPedComponent.iDrawable = iDrawable;
|
||
|
NewPedComponent.iTexture = iTexture;
|
||
|
}
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////
|
||
|
// Pass the latest setup to a newly streamed ped
|
||
|
|
||
|
void CCutsceneAnimatedActorEntity::RestoreEntityProperties(CEntity * pEnt)
|
||
|
{
|
||
|
if(pEnt && pEnt->GetIsTypePed())
|
||
|
{
|
||
|
CPed* pPed = static_cast<CPed*>(pEnt);
|
||
|
for(int i =0; i < m_sCurrentActorVariationData.iPedVarData.GetCount(); i ++)
|
||
|
{
|
||
|
SetCurrentActorVariation(pPed, m_sCurrentActorVariationData.iPedVarData[i].iComponent, m_sCurrentActorVariationData.iPedVarData[i].iDrawable, m_sCurrentActorVariationData.iPedVarData[i].iTexture);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
bool CCutsceneAnimatedActorEntity::RemoveEntityFromTheWorld(CEntity * pEnt, bool bDeleteRegistered)
|
||
|
{
|
||
|
if(pEnt && pEnt->GetIsTypePed())
|
||
|
{
|
||
|
CPed* pPed = static_cast<CPed*>(pEnt);
|
||
|
{
|
||
|
pPed->CleanUpPreloadData();
|
||
|
}
|
||
|
}
|
||
|
return CCutsceneAnimatedModelEntity::RemoveEntityFromTheWorld(pEnt, bDeleteRegistered);
|
||
|
}
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
CCutsceneAnimatedActorEntity::CCutsceneAnimatedActorEntity(const cutfObject* pObject)
|
||
|
:CCutsceneAnimatedModelEntity(pObject)
|
||
|
{
|
||
|
GetEntityVariationEvents();
|
||
|
m_VariationStreamingIndex = 0;
|
||
|
|
||
|
m_fVehicleLightingScalar = 0.0f;
|
||
|
m_fVehicleLightingScalarTargetValue = 0.0f;
|
||
|
m_fVehicleLightingScalarBlendRate = 1000.0f;
|
||
|
}
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////
|
||
|
//create our ingame ped
|
||
|
|
||
|
void CCutsceneAnimatedActorEntity::CreateGamePed(u32 iModelIndex, bool CreateRepositionEntity)
|
||
|
{
|
||
|
fwModelId modelId((strLocalIndex(iModelIndex)));
|
||
|
CBaseModelInfo* pModelInfo = CModelInfo::GetBaseModelInfo(modelId);
|
||
|
|
||
|
cutsceneModelEntityDebugf2("CreateGamePed - Actor");
|
||
|
|
||
|
if(pModelInfo)
|
||
|
{
|
||
|
cutsceneAssertf(pModelInfo->GetModelType() == MI_TYPE_PED, "CUTSCENE ASSET (Assign to *Default Anim Cutscene*): Exported incorrectly, %s is not a PedModel type", pModelInfo->GetModelName());
|
||
|
if(pModelInfo->GetModelType() == MI_TYPE_PED)
|
||
|
{
|
||
|
Matrix34 TempMat;
|
||
|
|
||
|
TempMat.Identity();
|
||
|
TempMat.d = m_vCreatePos;
|
||
|
|
||
|
if(iModelIndex != strLocalIndex::INVALID_INDEX)
|
||
|
{
|
||
|
const CControlledByInfo localAiControl(false, false);
|
||
|
|
||
|
CPedModelInfo* pPedModelInfo = static_cast<CPedModelInfo*>(pModelInfo);
|
||
|
|
||
|
CPed* pPed = NULL;
|
||
|
|
||
|
if (CreateRepositionEntity)
|
||
|
{
|
||
|
pPed = CPedFactory::GetFactory()->CreatePedFromSource(localAiControl, modelId, &TempMat, GetGameEntity(), true, false, false);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if(m_sScriptActorVariationData.iPedVarData.GetCount() > 0)
|
||
|
{
|
||
|
// Previously we called CreatePed with bApplyDefaultVariation = true but this still generated random
|
||
|
// peds if the ped was non streamed. Now we use bApplyDefaultVariation = false in order minimise streaming
|
||
|
// bandwidth on streamed peds. Either way we need to manually set non streamed peds to default after creation
|
||
|
pPed = CPedFactory::GetFactory()->CreatePed(localAiControl, modelId, &TempMat, false, false, false);
|
||
|
if (!pPedModelInfo->GetIsStreamedGfx())
|
||
|
{
|
||
|
pPed->SetVarDefault();
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
pPed = CPedFactory::GetFactory()->CreatePedFromSource(localAiControl, modelId, &TempMat, GetGameRepositionOnlyEntity(), true, false, false);
|
||
|
}
|
||
|
}
|
||
|
CPedInventoryLoadOutManager::SetDefaultLoadOut(pPed);
|
||
|
|
||
|
|
||
|
|
||
|
if (Verifyf(pPed, "trying to store a null ped pointer something has gone wrong with the registration"))
|
||
|
{
|
||
|
if(CreateRepositionEntity)
|
||
|
{
|
||
|
SetRepositionOnlyEntity(pPed);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
SetGameEntity(pPed);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CCutsceneAnimatedActorEntity::GetEntityVariationEvents()
|
||
|
{
|
||
|
m_pVariationEvents.Reset();
|
||
|
|
||
|
atArray<cutfEvent *> AllEventList;
|
||
|
const cutfCutsceneFile2* pCutfile = const_cast<const CutSceneManager*>(CutSceneManager::GetInstance())->GetCutfFile();
|
||
|
pCutfile->FindEventsForObjectIdOnly( m_pCutfObject->GetObjectId(), pCutfile->GetEventList(), AllEventList );
|
||
|
|
||
|
for ( int i = 0; i < AllEventList.GetCount(); ++i )
|
||
|
{
|
||
|
if (AllEventList[i]->GetEventId() == CUTSCENE_SET_VARIATION_EVENT)
|
||
|
{
|
||
|
cutfEventArgs *pEventArgs = const_cast<cutfEventArgs *>( AllEventList[i]->GetEventArgs());
|
||
|
|
||
|
if(pEventArgs && pEventArgs->GetType() == CUTSCENE_ACTOR_VARIATION_EVENT_ARGS_TYPE)
|
||
|
{
|
||
|
if(CutSceneManager::GetInstance()->IsConcatted())
|
||
|
{
|
||
|
// Are the events in a concat section that is going to be played
|
||
|
#if !__NO_OUTPUT
|
||
|
const cutfObjectVariationEventArgs* pVariationEventFlag = static_cast<const cutfObjectVariationEventArgs *>( pEventArgs );
|
||
|
int Component = pVariationEventFlag->GetComponent();
|
||
|
int Drawable = pVariationEventFlag->GetDrawable();
|
||
|
int Texture = pVariationEventFlag->GetTexture();
|
||
|
s32 section = CutSceneManager::GetInstance()->GetConcatSectionForTime(AllEventList[i]->GetTime());
|
||
|
#endif
|
||
|
bool bValidEventTime = CutSceneManager::GetInstance()->ValidateEventTime(AllEventList[i]->GetTime());
|
||
|
if (bValidEventTime)
|
||
|
{
|
||
|
|
||
|
cutsceneModelEntityDebugf3("GetEntityVariationEvents:: Variation event has valid section/time (%d/%f) : (Component: %d (%s), Drawable: %d, Texture: %d)", section, AllEventList[i]->GetTime(), Component, CPedVariationData::GetVarOrPropSlotName(Component), Drawable, Texture);
|
||
|
m_pVariationEvents.PushAndGrow(AllEventList[i]);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
cutsceneModelEntityDebugf3("GetEntityVariationEvents:: Variation event has invalid section/time (%d/%f) : (Component: %d (%s), Drawable: %d, Texture: %d)", section, AllEventList[i]->GetTime(), Component, CPedVariationData::GetVarOrPropSlotName(Component), Drawable, Texture );
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
m_pVariationEvents.PushAndGrow(AllEventList[i]);
|
||
|
}
|
||
|
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CCutsceneAnimatedActorEntity::PreStreamVariations(CutSceneManager* pManager, float CurrentTime, float LookAhead)
|
||
|
{
|
||
|
float StreamingOffsetBuffer = pManager->CalculateStreamingOffset(LookAhead, CurrentTime);
|
||
|
float LookAheadTime = pManager->GetTime() + StreamingOffsetBuffer;
|
||
|
|
||
|
//cutsceneModelEntityDebugf("PreStreamVariations - Current Time (%6.4f) -> Streaming time(%6.4f)", pManager->GetTime(), pManager->GetTime() + StreamingOffsetBuffer);
|
||
|
|
||
|
for ( int i = m_VariationStreamingIndex; i < m_pVariationEvents.GetCount(); ++i )
|
||
|
{
|
||
|
if(m_pVariationEvents[i]->GetTime() <= LookAheadTime)
|
||
|
{
|
||
|
bool bIsValidEventTime = true;
|
||
|
if (pManager->IsConcatted())
|
||
|
{
|
||
|
bIsValidEventTime = pManager->ValidateEventTime(m_pVariationEvents[i]->GetTime());
|
||
|
}
|
||
|
|
||
|
if ( bIsValidEventTime)
|
||
|
{
|
||
|
const cutfObjectVariationEventArgs *pEventArgs = static_cast<const cutfObjectVariationEventArgs *>( m_pVariationEvents[i]->GetEventArgs() );
|
||
|
if(pEventArgs)
|
||
|
{
|
||
|
s32 Component = pEventArgs->GetComponent();
|
||
|
s32 Drawable = pEventArgs->GetDrawable();
|
||
|
s32 Texture = pEventArgs->GetTexture();
|
||
|
|
||
|
if((Component>-1 && Drawable>-1 && Texture>-1) || (Component>=PV_MAX_COMP && Drawable>-1))
|
||
|
{
|
||
|
pManager->GetAssetManager()->SetActorVariationStreamingRequest(Component, Drawable, Texture, m_ModelNameHash, m_pCutfObject->GetObjectId());
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (Component<PV_MAX_COMP)
|
||
|
cutsceneModelEntityDebugf3( "PreStreamVariations: Ignoring invalid cutscene variation event (Component: %d (%s), Drawable: %d, Texture: %d)", Component, CPedVariationData::GetVarOrPropSlotName(Component), Drawable, Texture);
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
cutsceneModelEntityDebugf3( "PreStreamVariations: Ignoring invalid cutscene variation args");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Increment m_VariationStreamingIndex so we don't consider this variation again
|
||
|
m_VariationStreamingIndex++;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CCutsceneAnimatedActorEntity::ComputeInitialVariations(atHashString& UNUSED_PARAM(modelHashString))
|
||
|
{
|
||
|
//bool bRepositionOnlyEntity = (modelHashString == m_RegisteredEntityFromScript.ModelNameHash);
|
||
|
if ( /*!bRepositionOnlyEntity &&*/ !m_bComputeInitialVariationsForGameEntity)
|
||
|
{
|
||
|
m_bComputeInitialVariationsForGameEntity = true;
|
||
|
|
||
|
cutsceneModelEntityDebugf3( "ComputeInitialVariations (%s) ---------------------------------------------", m_ModelNameHash.TryGetCStr());
|
||
|
|
||
|
|
||
|
// Copy all the variations set by script from the initial variations array into the current variations array
|
||
|
for(int i = 0; i < m_sScriptActorVariationData.iPedVarData.GetCount(); i++ )
|
||
|
{
|
||
|
s32 Component = m_sScriptActorVariationData.iPedVarData[i].iComponent;
|
||
|
s32 Drawable = m_sScriptActorVariationData.iPedVarData[i].iDrawable;
|
||
|
s32 Texture = m_sScriptActorVariationData.iPedVarData[i].iTexture;
|
||
|
|
||
|
if((Component>-1 && Drawable>-1 && Texture>-1) || (Component>=PV_MAX_COMP && Drawable>-2))
|
||
|
{
|
||
|
cutsceneModelEntityDebugf3("ComputeInitialVariations - Script variation (Component: %d (%s), Drawable: %d, Texture: %d)",
|
||
|
Component,
|
||
|
CPedVariationData::GetVarOrPropSlotName(Component),
|
||
|
Drawable,
|
||
|
Texture);
|
||
|
|
||
|
StoreActorVariationData(Component, Drawable, Texture, m_sCurrentActorVariationData);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// For each cutscene variation event that happened on the start frame (may or may not be 0.0 depending on if the cutscene in branched)
|
||
|
for ( int i = m_VariationStreamingIndex; i < m_pVariationEvents.GetCount(); ++i )
|
||
|
{
|
||
|
float fEventTime = m_pVariationEvents[i]->GetTime();
|
||
|
float fStartTime = CutSceneManager::GetInstance()->GetStartTime();
|
||
|
if(fEventTime <= fStartTime)
|
||
|
{
|
||
|
bool bIsValidEventTime = true;
|
||
|
if (CutSceneManager::GetInstance()->IsConcatted())
|
||
|
{
|
||
|
bIsValidEventTime = CutSceneManager::GetInstance()->ValidateEventTime(fEventTime);
|
||
|
}
|
||
|
|
||
|
if (bIsValidEventTime)
|
||
|
{
|
||
|
bool bUseVariationFromCutsceneStartFrame = true;
|
||
|
const cutfObjectVariationEventArgs *pEventArgs = static_cast<const cutfObjectVariationEventArgs *>( m_pVariationEvents[i]->GetEventArgs() );
|
||
|
if(pEventArgs)
|
||
|
{
|
||
|
s32 Component = pEventArgs->GetComponent();
|
||
|
s32 Drawable = pEventArgs->GetDrawable();
|
||
|
s32 Texture = pEventArgs->GetTexture();
|
||
|
|
||
|
if((Component>-1 && Drawable>-1 && Texture>-1) || (Component>=PV_MAX_COMP && Drawable>-2))
|
||
|
{
|
||
|
// Favour script variation events over cutscene variation events on the first frame
|
||
|
for(int j = 0; j < m_sScriptActorVariationData.iPedVarData.GetCount(); j++ )
|
||
|
{
|
||
|
if((u32)Component == m_sScriptActorVariationData.iPedVarData[j].iComponent)
|
||
|
{
|
||
|
cutsceneModelEntityDebugf3("ComputeInitialVariations - Script variation (Component: %d (%s), Drawable: %d, Texture: %d) used rather than cutscene start frame variation (Component: %d (%s), Drawable: %d, Texture: %d)",
|
||
|
m_sScriptActorVariationData.iPedVarData[j].iComponent,
|
||
|
CPedVariationData::GetVarOrPropSlotName(m_sScriptActorVariationData.iPedVarData[j].iComponent),
|
||
|
m_sScriptActorVariationData.iPedVarData[j].iDrawable,
|
||
|
m_sScriptActorVariationData.iPedVarData[j].iTexture,
|
||
|
Component,
|
||
|
CPedVariationData::GetVarOrPropSlotName(Component),
|
||
|
Drawable,
|
||
|
Texture);
|
||
|
|
||
|
bUseVariationFromCutsceneStartFrame = false;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if(bUseVariationFromCutsceneStartFrame)
|
||
|
{
|
||
|
cutsceneModelEntityDebugf3("ComputeInitialVariations - Cutscene start frame variation (Component: %d (%s), Drawable: %d, Texture: %d)",
|
||
|
Component,
|
||
|
CPedVariationData::GetVarOrPropSlotName(Component),
|
||
|
Drawable,
|
||
|
Texture);
|
||
|
|
||
|
StoreActorVariationData(Component, Drawable, Texture, m_sCurrentActorVariationData);
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
cutsceneModelEntityDebugf3( "ComputeInitialVariations: Ignoring invalid cutscene variation event (Component: %d (%s), Drawable: %d, Texture: %d)", Component, CPedVariationData::GetVarOrPropSlotName(Component), Drawable, Texture);
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
cutsceneModelEntityDebugf3( "ComputeInitialVariations: Ignoring invalid cutscene variation args");
|
||
|
}
|
||
|
}
|
||
|
// Cutscene variations events are so increment m_VariationStreamingIndex so we don't consider this variation again
|
||
|
m_VariationStreamingIndex++;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Make sure all variation kinds have at least a default entry
|
||
|
//
|
||
|
|
||
|
// For each kind of variation component
|
||
|
for(u32 i = 0; i < PV_MAX_COMP; i++)
|
||
|
{
|
||
|
// Search for a valid entry
|
||
|
bool bFoundValidVariationEntry = false;
|
||
|
for(u32 j=0; j<m_sCurrentActorVariationData.iPedVarData.GetCount(); j++)
|
||
|
{
|
||
|
if(m_sCurrentActorVariationData.iPedVarData[j].iComponent == i)
|
||
|
{
|
||
|
bFoundValidVariationEntry = true;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// If there is no matching entry make a new "default" entry for that kind of variation in the initial variations array
|
||
|
if(!bFoundValidVariationEntry)
|
||
|
{
|
||
|
cutsceneModelEntityDebugf3("ComputeInitialVariations - Fallback variation (Component: %d (%s), Drawable: %d, Texture: %d)",
|
||
|
i,
|
||
|
CPedVariationData::GetVarOrPropSlotName(i),
|
||
|
0,
|
||
|
0);
|
||
|
|
||
|
StoreActorVariationData(i, 0, 0, m_sCurrentActorVariationData);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
cutsceneModelEntityDebugf( "ComputeInitialVariations: m_sCurrentActorVariationData[%d] (Component: %d (%s), Drawable: %d, Texture: %d)",
|
||
|
i,
|
||
|
m_sCurrentActorVariationData.iPedVarData[i].iComponent,
|
||
|
CPedVariationData::GetVarOrPropSlotName(m_sCurrentActorVariationData.iPedVarData[i].iComponent),
|
||
|
m_sCurrentActorVariationData.iPedVarData[i].iDrawable,
|
||
|
m_sCurrentActorVariationData.iPedVarData[i].iTexture);
|
||
|
*/
|
||
|
}
|
||
|
|
||
|
for(int i=0; i < m_sCurrentActorVariationData.iPedVarData.GetCount(); i++)
|
||
|
{
|
||
|
s32 Component = m_sCurrentActorVariationData.iPedVarData[i].iComponent;
|
||
|
s32 Drawable = m_sCurrentActorVariationData.iPedVarData[i].iDrawable;
|
||
|
s32 Texture = m_sCurrentActorVariationData.iPedVarData[i].iTexture;
|
||
|
|
||
|
if((Component>-1 && Drawable>-1 && Texture>-1) || (Component>=PV_MAX_COMP && Drawable>-1))
|
||
|
{
|
||
|
eStreamingRequestReturnValue streamingRequestReturnValue = CutSceneManager::GetInstance()->GetAssetManager()->SetActorVariationStreamingRequest((u32)Component, (u32)Drawable, (u32)Texture, m_ModelNameHash, m_pCutfObject->GetObjectId());
|
||
|
if(Component < PV_MAX_COMP)
|
||
|
{
|
||
|
if ((streamingRequestReturnValue == ESRRV_INVALID_VARIATION) && (Drawable > 0 || Texture > 0))
|
||
|
{
|
||
|
cutsceneModelEntityDebugf3( "ComputeInitialVariations: Ignoring invalid cutscene variation request (Component: %d (%s), Drawable: %d, Texture: %d) (requesting default instead)", Component, CPedVariationData::GetVarOrPropSlotName(Component), Drawable, Texture);
|
||
|
CutSceneManager::GetInstance()->GetAssetManager()->SetActorVariationStreamingRequest((u32)Component, 0, 0, m_ModelNameHash, m_pCutfObject->GetObjectId());
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (Component<PV_MAX_COMP)
|
||
|
cutsceneModelEntityDebugf3( "ComputeInitialVariations: Ignoring invalid cutscene variation event (Component: %d (%s), Drawable: %d, Texture: %d)", Component, CPedVariationData::GetVarOrPropSlotName(Component), Drawable, Texture);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CCutsceneAnimatedActorEntity::ComputeVariationsForSkip(atHashString& modelHashString)
|
||
|
{
|
||
|
/*cutsceneModelEntityDebugf("ComputeVariationsForSkip %s ---------------------------------------------", modelHashString.TryGetCStr());
|
||
|
cutsceneModelEntityDebugf("(iSceneId(%d),SceneNameHash(%s),ModelNameHash(%s),bDeleteBeforeEnd(%d),bCreatedForScript(%d),iEnterStatePhase(%6.4f),iExitStatePhase(%6.4f),bAppearInScene(%d)",
|
||
|
m_RegisteredEntityFromScript.iSceneId,
|
||
|
m_RegisteredEntityFromScript.SceneNameHash.TryGetCStr(),
|
||
|
m_RegisteredEntityFromScript.ModelNameHash.TryGetCStr(),
|
||
|
m_RegisteredEntityFromScript.bDeleteBeforeEnd,
|
||
|
m_RegisteredEntityFromScript.bCreatedForScript,
|
||
|
m_RegisteredEntityFromScript.iEnterStatePhase,
|
||
|
m_RegisteredEntityFromScript.iExitStatePhase,
|
||
|
m_RegisteredEntityFromScript.bAppearInScene );
|
||
|
|
||
|
bool bNeedsVariations = false;
|
||
|
|
||
|
static bool bMethodA = true;
|
||
|
if (bMethodA)
|
||
|
{
|
||
|
if (!IsScriptRegisteredGameEntity()
|
||
|
&& IsScriptRegisteredRepositionOnlyEntity()
|
||
|
&& !m_RegisteredEntityFromScript.pEnt
|
||
|
&& m_RegisteredEntityFromScript.bCreatedForScript )
|
||
|
{
|
||
|
bNeedsVariations = true;
|
||
|
}
|
||
|
|
||
|
// Only run when the repositionOnlyEntities model is loaded
|
||
|
bNeedsVariations = bNeedsVariations || ((modelHashString.GetHash() == m_RegisteredEntityFromScript.ModelNameHash) && !m_bComputeVariationsForSkipForRepositionOnlyEntity);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
atHashString modelNameHash(m_ModelNameHash);
|
||
|
if (!IsScriptRegisteredGameEntity()
|
||
|
&& IsScriptRegisteredRepositionOnlyEntity()
|
||
|
&& !m_RegisteredEntityFromScript.pEnt // no script entity being animated by the scene
|
||
|
&& m_RegisteredEntityFromScript.bCreatedForScript ) // reposition entity is to be created by the cutscene for the script
|
||
|
{
|
||
|
cutsceneModelEntityDebugf("ComputeVariationsForSkip - repositiononly = true = m_RegisteredEntityFromScript.ModelNameHash");
|
||
|
bNeedsVariations = true;
|
||
|
modelNameHash = m_RegisteredEntityFromScript.ModelNameHash;
|
||
|
|
||
|
}
|
||
|
|
||
|
if (!m_RegisteredEntityFromScript.bDeleteBeforeEnd)
|
||
|
{
|
||
|
bNeedsVariations = true;
|
||
|
cutsceneModelEntityDebugf("ComputeVariationsForSkip - repositiononly = true = ModelNameHash");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ( bNeedsVariations && !m_bComputeVariationsForSkipForRepositionOnlyEntity )
|
||
|
{
|
||
|
*/
|
||
|
|
||
|
atHashString modelNameHash(m_ModelNameHash);
|
||
|
|
||
|
if (!IsScriptRegisteredGameEntity()
|
||
|
&& IsScriptRegisteredRepositionOnlyEntity()
|
||
|
&& !m_RegisteredEntityFromScript.pEnt // no script entity being animated by the scene
|
||
|
&& m_RegisteredEntityFromScript.bCreatedForScript ) // reposition entity is to be created by script for the cutscene
|
||
|
|
||
|
{
|
||
|
modelNameHash = m_RegisteredEntityFromScript.ModelNameHash;
|
||
|
cutsceneModelEntityDebugf3("ComputeVariationsForSkip - repositiononly = true");
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
cutsceneModelEntityDebugf3("ComputeVariationsForSkip - repositiononly = false");
|
||
|
}
|
||
|
|
||
|
bool bAppropriateEntity = (modelHashString.GetHash() == modelNameHash.GetHash());
|
||
|
if ( bAppropriateEntity && !m_bComputeVariationsForSkipForRepositionOnlyEntity )
|
||
|
{
|
||
|
m_bComputeVariationsForSkipForRepositionOnlyEntity = true;
|
||
|
|
||
|
cutsceneModelEntityDebugf3("ComputeVariationsForSkip ---------------------------------------------");
|
||
|
|
||
|
//
|
||
|
// Any variations we have set thus far are collected in the current variations array
|
||
|
//
|
||
|
|
||
|
for(int i=0; i<m_sCurrentActorVariationData.iPedVarData.GetCount(); i++)
|
||
|
{
|
||
|
cutsceneModelEntityDebugf3("ComputeVariationsForSkip - PreExisting variations (Component: %d (%s), Drawable: %d, Texture: %d)",
|
||
|
m_sCurrentActorVariationData.iPedVarData[i].iComponent,
|
||
|
CPedVariationData::GetVarOrPropSlotName(m_sCurrentActorVariationData.iPedVarData[i].iComponent),
|
||
|
m_sCurrentActorVariationData.iPedVarData[i].iDrawable,
|
||
|
m_sCurrentActorVariationData.iPedVarData[i].iTexture);
|
||
|
}
|
||
|
|
||
|
float fEndTime = CutSceneManager::GetInstance()->GetEndTime();
|
||
|
float fStartTime = CutSceneManager::GetInstance()->GetStartTime();
|
||
|
|
||
|
// Search through all the variation events for this ped from the current time to the end time
|
||
|
for ( int i = 0; i < m_pVariationEvents.GetCount(); ++i )
|
||
|
{
|
||
|
float fEventTime = m_pVariationEvents[i]->GetTime();
|
||
|
if((fEventTime > fStartTime) && (fEventTime <= fEndTime))
|
||
|
{
|
||
|
bool bIsValidEventTime = true;
|
||
|
if (CutSceneManager::GetInstance()->IsConcatted())
|
||
|
{
|
||
|
bIsValidEventTime = CutSceneManager::GetInstance()->ValidateEventTime(fEventTime);
|
||
|
}
|
||
|
|
||
|
if (bIsValidEventTime)
|
||
|
{
|
||
|
const cutfObjectVariationEventArgs *pEventArgs = static_cast<const cutfObjectVariationEventArgs *>( m_pVariationEvents[i]->GetEventArgs() );
|
||
|
if(pEventArgs)
|
||
|
{
|
||
|
s32 Component = pEventArgs->GetComponent();
|
||
|
s32 Drawable = pEventArgs->GetDrawable();
|
||
|
s32 Texture = pEventArgs->GetTexture();
|
||
|
|
||
|
if((Component>-1 && Drawable>-1 && Texture>-1) || (Component>=PV_MAX_COMP))
|
||
|
{
|
||
|
cutsceneModelEntityDebugf3("ComputeVariationsForSkip - Cutscene variation (not start frame) (Component: %d (%s), Drawable: %d, Texture: %d)",
|
||
|
Component,
|
||
|
CPedVariationData::GetVarOrPropSlotName(Component),
|
||
|
Drawable,
|
||
|
Texture);
|
||
|
|
||
|
StoreActorVariationData(Component, Drawable, Texture, m_sCurrentActorVariationData);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
cutsceneModelEntityDebugf3( "ComputeVariationsForSkip: Ignoring invalid cutscene variation event (Component: %d (%s), Drawable: %d, Texture: %d)", Component, CPedVariationData::GetVarOrPropSlotName(Component), Drawable, Texture);
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
cutsceneModelEntityDebugf3( "ComputeVariationsForSkip: Ignoring invalid cutscene variation args");
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
//
|
||
|
// Make sure all variation kinds have at least a default entry
|
||
|
//
|
||
|
|
||
|
// For each kind of variation
|
||
|
for(u32 i = 0; i < PV_MAX_COMP; i++)
|
||
|
{
|
||
|
// Search for a matching entry
|
||
|
bool bFoundComponent = false;
|
||
|
for(int j=0; j<m_sCurrentActorVariationData.iPedVarData.GetCount(); j++)
|
||
|
{
|
||
|
if(m_sCurrentActorVariationData.iPedVarData[j].iComponent == i)
|
||
|
{
|
||
|
bFoundComponent = true;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// If there is no matching entry make a new "default" entry for that kind of variation in the initial variations array
|
||
|
if(!bFoundComponent)
|
||
|
{
|
||
|
cutsceneModelEntityDebugf3("ComputeVariationsForSkip - Fallback variation (Component: %d (%s), Drawable: %d, Texture: %d)",
|
||
|
i,
|
||
|
CPedVariationData::GetVarOrPropSlotName(i),
|
||
|
0,
|
||
|
0);
|
||
|
|
||
|
StoreActorVariationData(i, 0, 0, m_sCurrentActorVariationData);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Request each variation in the current variation array
|
||
|
//
|
||
|
for(int i=0; i < m_sCurrentActorVariationData.iPedVarData.GetCount(); i++)
|
||
|
{
|
||
|
s32 Component = m_sCurrentActorVariationData.iPedVarData[i].iComponent;
|
||
|
s32 Drawable = m_sCurrentActorVariationData.iPedVarData[i].iDrawable;
|
||
|
s32 Texture = m_sCurrentActorVariationData.iPedVarData[i].iTexture;
|
||
|
|
||
|
if((Component>-1 && Drawable>-1 && Texture>-1) || (Component>=PV_MAX_COMP && Drawable>-1))
|
||
|
{
|
||
|
eStreamingRequestReturnValue streamingRequestReturnValue = CutSceneManager::GetInstance()->GetAssetManager()->SetActorVariationStreamingRequest((u32)Component, (u32)Drawable, (u32)Texture, modelNameHash, m_pCutfObject->GetObjectId());
|
||
|
if(Component < PV_MAX_COMP)
|
||
|
{
|
||
|
if ((streamingRequestReturnValue == ESRRV_INVALID_VARIATION) && (Drawable > 0 || Texture > 0))
|
||
|
{
|
||
|
cutsceneModelEntityDebugf3( "ComputeVariationsForSkip: Ignoring invalid cutscene variation request (Component: %d (%s), Drawable: %d, Texture: %d) (requesting default instead)", Component, CPedVariationData::GetVarOrPropSlotName(Component), Drawable, Texture);
|
||
|
CutSceneManager::GetInstance()->GetAssetManager()->SetActorVariationStreamingRequest((u32)Component, 0, 0, modelNameHash, m_pCutfObject->GetObjectId());
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (Component<PV_MAX_COMP)
|
||
|
cutsceneModelEntityDebugf3( "ComputeVariationsForSkip: Ignoring invalid cutscene variation event (Component: %d (%s), Drawable: %d, Texture: %d)", Component, CPedVariationData::GetVarOrPropSlotName(Component), Drawable, Texture);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CCutsceneAnimatedActorEntity::AddActorToWorld(CPed* pPed)
|
||
|
{
|
||
|
if(pPed)
|
||
|
{
|
||
|
InitActor(pPed);
|
||
|
pPed->GetPortalTracker()->SetIsCutsceneControlled(true);
|
||
|
|
||
|
if (IsScriptRegisteredGameEntity())
|
||
|
{
|
||
|
m_RegisteredEntityFromScript.pEnt = pPed;
|
||
|
}
|
||
|
|
||
|
m_bCreatedByCutscene = true;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CCutsceneAnimatedActorEntity::CreateGameEntity(strLocalIndex iModelIndex, bool CreateRepositionEntity, bool bRequestVariations, bool bApplyVariations)
|
||
|
{
|
||
|
CPed* pPed = NULL;
|
||
|
|
||
|
if(CreateRepositionEntity)
|
||
|
{
|
||
|
pPed = GetGameRepositionOnlyEntity();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
pPed = GetGameEntity();
|
||
|
}
|
||
|
|
||
|
if(pPed == NULL)
|
||
|
{
|
||
|
cutsceneModelEntityDebugf2("CreateGameEntity - Actor - bRequestVariations(%s), bApplyVariations(%s)", bRequestVariations ? "T" : "F", bApplyVariations ? "T" : "F");
|
||
|
|
||
|
CreateGamePed(iModelIndex.Get(), CreateRepositionEntity);
|
||
|
|
||
|
if(CreateRepositionEntity)
|
||
|
{
|
||
|
pPed = GetGameRepositionOnlyEntity();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
pPed = GetGameEntity();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if(pPed && !pPed->GetIsAddedToWorld())
|
||
|
{
|
||
|
AddActorToWorld(pPed);
|
||
|
}
|
||
|
|
||
|
if (pPed)
|
||
|
{
|
||
|
if (bRequestVariations && !IsBlockingVariationStreamingAndApplication())
|
||
|
{
|
||
|
//
|
||
|
// Make sure all variation kinds have at least a default entry
|
||
|
//
|
||
|
|
||
|
// For each kind of variation component
|
||
|
for(u32 i = 0; i < PV_MAX_COMP; i++)
|
||
|
{
|
||
|
// Search for a valid entry
|
||
|
bool bFoundValidVariationEntry = false;
|
||
|
for(u32 j=0; j<m_sCurrentActorVariationData.iPedVarData.GetCount(); j++)
|
||
|
{
|
||
|
if(m_sCurrentActorVariationData.iPedVarData[j].iComponent == i)
|
||
|
{
|
||
|
bFoundValidVariationEntry = true;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// If there is no matching entry make a new "default" entry for that kind of variation in the initial variations array
|
||
|
if(!bFoundValidVariationEntry)
|
||
|
{
|
||
|
cutsceneModelEntityDebugf2("CreateGameEntity - Actor - - Fallback variation (Component: %d (%s), Drawable: %d, Texture: %d)",
|
||
|
i,
|
||
|
CPedVariationData::GetVarOrPropSlotName(i),
|
||
|
0,
|
||
|
0);
|
||
|
|
||
|
StoreActorVariationData(i, 0, 0, m_sCurrentActorVariationData);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
cutsceneModelEntityDebugf( "CreateGameEntity - Actor -: m_sCurrentActorVariationData[%d] (Component: %d (%s), Drawable: %d, Texture: %d)",
|
||
|
i,
|
||
|
m_sCurrentActorVariationData.iPedVarData[i].iComponent,
|
||
|
CPedVariationData::GetVarOrPropSlotName(m_sCurrentActorVariationData.iPedVarData[i].iComponent),
|
||
|
m_sCurrentActorVariationData.iPedVarData[i].iDrawable,
|
||
|
m_sCurrentActorVariationData.iPedVarData[i].iTexture);
|
||
|
*/
|
||
|
}
|
||
|
|
||
|
|
||
|
// Request the current variations
|
||
|
for(int i=0; i < m_sCurrentActorVariationData.iPedVarData.GetCount(); i++)
|
||
|
{
|
||
|
s32 Component = m_sCurrentActorVariationData.iPedVarData[i].iComponent;
|
||
|
s32 Drawable = m_sCurrentActorVariationData.iPedVarData[i].iDrawable;
|
||
|
s32 Texture = m_sCurrentActorVariationData.iPedVarData[i].iTexture;
|
||
|
|
||
|
if((Component>-1 && Drawable>-1 && Texture>-1) || (Component>=PV_MAX_COMP && Drawable>-1))
|
||
|
{
|
||
|
if (pPed && pPed->GetPedModelInfo() && pPed->GetPedModelInfo()->GetIsStreamedGfx())
|
||
|
{
|
||
|
atHashString modelNameHash(m_ModelNameHash);
|
||
|
if (CreateRepositionEntity && m_RegisteredEntityFromScript.ModelNameHash.GetHash()>0)
|
||
|
{
|
||
|
modelNameHash = m_RegisteredEntityFromScript.ModelNameHash.GetHash();
|
||
|
}
|
||
|
|
||
|
// Now we have a ped pointer we can check the variation requested by the cutscene or script is valid
|
||
|
if (pPed->IsVariationInRange(static_cast<ePedVarComp>(Component), Drawable, Texture))
|
||
|
{
|
||
|
CutSceneManager::GetInstance()->GetAssetManager()->SetActorVariationStreamingRequest((u32)Component, (u32)Drawable, (u32)Texture, modelNameHash, m_pCutfObject->GetObjectId());
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (Drawable > 0 || Texture > 0)
|
||
|
{
|
||
|
cutsceneModelEntityDebugf2( "CreateGameEntity: Ignoring out of range cutscene variation request (Component: %d (%s), Drawable: %d, Texture: %d) (requesting default instead)", Component, CPedVariationData::GetVarOrPropSlotName(Component), Drawable, Texture);
|
||
|
CutSceneManager::GetInstance()->GetAssetManager()->SetActorVariationStreamingRequest((u32)Component, 0, 0, modelNameHash, m_pCutfObject->GetObjectId());
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
cutsceneModelEntityDebugf2( "CreateGameEntity: Ignoring out of range cutscene variation request (Component: %d (%s), Drawable: %d, Texture: %d) (no valid default)", Component, CPedVariationData::GetVarOrPropSlotName(Component), Drawable, Texture);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
//cutsceneModelEntityDebugf( "CCutsceneAnimatedActorEntity: Ignoring invalid cutscene variation event (Component: %d (%s), Drawable: %d, Texture: %d)", Component, CPedVariationData::GetVarOrPropSlotName(Component), Drawable, Texture);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (bApplyVariations && !IsBlockingVariationStreamingAndApplication())
|
||
|
{
|
||
|
// Apply the current variations
|
||
|
RestoreEntityProperties(pPed);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
void CCutsceneAnimatedActorEntity::UpdateCutSceneTask(cutsManager* pManager)
|
||
|
{
|
||
|
CutSceneManager* pCutsManager = static_cast<CutSceneManager*>(pManager);
|
||
|
|
||
|
if(GetGameEntity())
|
||
|
{
|
||
|
CTask* pTask = GetGameEntity()->GetPedIntelligence()->FindTaskByType(CTaskTypes::TASK_CUTSCENE);
|
||
|
|
||
|
if(pTask && pTask->GetTaskType() == CTaskTypes::TASK_CUTSCENE)
|
||
|
{
|
||
|
CTaskCutScene* pCutSceneTask = static_cast<CTaskCutScene*>(pTask);
|
||
|
|
||
|
const crClip* pClip = pCutSceneTask->GetClip();
|
||
|
|
||
|
if (pClip)
|
||
|
{
|
||
|
float fPhase = pCutsManager->GetPhaseUpdateAmount(pClip, GetAnimEventStartTime());
|
||
|
|
||
|
float fLastPhase = pCutsManager->GetAnimPhaseForSection(pClip->GetDuration(),GetAnimEventStartTime(),pCutsManager->GetCutScenePreviousTime());
|
||
|
GetMoverTrackVelocity(pClip,fPhase,fLastPhase, pCutsManager->GetCurrentCutSceneTimeStep());
|
||
|
//Vector3 localEuler = pCutSceneTask->GetAnimOrigin().GetEulers();
|
||
|
//printf("Rotation for %s: %7.4f, %7.4f, %7.4f \n", pClip->GetName(), localEuler.x*RtoD, localEuler.y*RtoD, localEuler.z*RtoD);
|
||
|
|
||
|
//UpdateActorMotionState();
|
||
|
GetGameEntity()->SetDesiredHeading(GetGameEntity()->GetTransform().GetHeading());
|
||
|
|
||
|
UpdateCutSceneTaskPhase(pTask, pManager);
|
||
|
#if __DEV
|
||
|
//THIS CURRENTLY DOES NOTHING TO FILTER ANY ANIMS BECAUSE THERE IS NO FILTER TO REMOVE ALL ANIM EXCEPT FACIAL
|
||
|
UpdateWithFaceViewer(pCutsManager, pCutSceneTask);
|
||
|
#endif
|
||
|
// Vehicle lighting - Have we crossed any CutsceneBlendToVehicleLighting tags?
|
||
|
const crTags* pTags = pClip->GetTags();
|
||
|
if (pTags)
|
||
|
{
|
||
|
for (int i=0; i < pTags->GetNumTags(); i++)
|
||
|
{
|
||
|
const crTag* pTag = pTags->GetTag(i);
|
||
|
if (pTag)
|
||
|
{
|
||
|
//static CClipEventTags::Key cutsceneBlendToVehicleLightingKey("CutsceneBlendToVehicleLighting",0xB8336AF5);
|
||
|
if (pTag->GetKey() == CClipEventTags::CutsceneBlendToVehicleLighting.GetHash())
|
||
|
{
|
||
|
// Tag phase
|
||
|
const float fTagPhase = pTag->GetStart();
|
||
|
|
||
|
// Process this tag?
|
||
|
if (fTagPhase >= fLastPhase && fTagPhase <= fPhase)
|
||
|
{
|
||
|
const crProperty& rProperty = pTag->GetProperty();
|
||
|
const crPropertyAttribute* pAttribTarget = rProperty.GetAttribute(CClipEventTags::TargetValue.GetHash());
|
||
|
const crPropertyAttribute* pAttribTime = rProperty.GetAttribute(CClipEventTags::BlendTime.GetHash());
|
||
|
|
||
|
// Target value
|
||
|
if (pAttribTarget && pAttribTarget->GetType() == crPropertyAttribute::kTypeFloat)
|
||
|
{
|
||
|
const crPropertyAttributeFloat* pTagTargetValueFloat = static_cast<const crPropertyAttributeFloat*>(pAttribTarget);
|
||
|
{
|
||
|
m_fVehicleLightingScalarTargetValue = pTagTargetValueFloat->GetFloat();
|
||
|
m_fVehicleLightingScalarTargetValue = Clamp(m_fVehicleLightingScalarTargetValue, 0.0f, 1.0f);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Blend time - converted to rate
|
||
|
if (pAttribTime && pAttribTime->GetType() == crPropertyAttribute::kTypeFloat)
|
||
|
{
|
||
|
const crPropertyAttributeFloat* pTagBlendTimeFloat = static_cast<const crPropertyAttributeFloat*>(pAttribTime);
|
||
|
{
|
||
|
const float fBlendTime = pTagBlendTimeFloat->GetFloat();
|
||
|
|
||
|
if (fBlendTime > VERY_SMALL_FLOAT)
|
||
|
{
|
||
|
// Blend up or down?
|
||
|
if (m_fVehicleLightingScalarTargetValue < m_fVehicleLightingScalar)
|
||
|
{
|
||
|
m_fVehicleLightingScalarBlendRate = -(1.0f / fBlendTime);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
m_fVehicleLightingScalarBlendRate = 1.0f / fBlendTime;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
m_fVehicleLightingScalarBlendRate = 1000.0f;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Vehicle lighting - Update vehicle lighting scalar.
|
||
|
if (m_fVehicleLightingScalar != m_fVehicleLightingScalarTargetValue)
|
||
|
{
|
||
|
Assert(m_fVehicleLightingScalarTargetValue >= 0.0f && m_fVehicleLightingScalarTargetValue <= 1.0f);
|
||
|
|
||
|
if (m_fVehicleLightingScalarBlendRate == 1000.0f || m_fVehicleLightingScalarBlendRate == -1000.0f)
|
||
|
{
|
||
|
// Instant
|
||
|
m_fVehicleLightingScalar = m_fVehicleLightingScalarTargetValue;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// Blend
|
||
|
const float fDelta = pCutsManager->GetCutSceneCurrentTime() - pCutsManager->GetCutScenePreviousTime();
|
||
|
m_fVehicleLightingScalar += (fDelta * m_fVehicleLightingScalarBlendRate);
|
||
|
|
||
|
// Clamp
|
||
|
if (m_fVehicleLightingScalarBlendRate < 0.0f && m_fVehicleLightingScalar < m_fVehicleLightingScalarTargetValue)
|
||
|
{
|
||
|
m_fVehicleLightingScalar = m_fVehicleLightingScalarTargetValue;
|
||
|
}
|
||
|
else if (m_fVehicleLightingScalarBlendRate > 0.0f && m_fVehicleLightingScalar > m_fVehicleLightingScalarTargetValue)
|
||
|
{
|
||
|
m_fVehicleLightingScalar = m_fVehicleLightingScalarTargetValue;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Set the vehicle lighting scalar on the cutscene task
|
||
|
Assert(m_fVehicleLightingScalar >= 0.0f && m_fVehicleLightingScalar <= 1.0f);
|
||
|
pCutSceneTask->SetVehicleLightingScalar(m_fVehicleLightingScalar);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CCutsceneAnimatedActorEntity:: ForceUpdateAi(cutsManager* pManager)
|
||
|
{
|
||
|
if(pManager)
|
||
|
{
|
||
|
CutSceneManager* pCutSceneManager = static_cast<CutSceneManager*> (pManager);
|
||
|
|
||
|
if(pCutSceneManager->GetShutDownMode() != SHUTDOWN_SESSION)
|
||
|
{
|
||
|
CPed* pPed = GetGameEntity();
|
||
|
if (pPed)
|
||
|
{
|
||
|
pPed->InstantAIUpdate();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
};
|
||
|
/////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
void CCutsceneAnimatedActorEntity::SetGameEntityReadyForGame(cutsManager* pManager)
|
||
|
{
|
||
|
if(!m_bIsReadyForGame)
|
||
|
{
|
||
|
cutsceneModelEntityDebugf2("SetGameEntityReadyForGame - Actor");
|
||
|
|
||
|
if (GetGameEntity())
|
||
|
{
|
||
|
NetworkInterface::CutsceneFinishedOnEntity(*GetGameEntity());
|
||
|
}
|
||
|
|
||
|
if (GetGameRepositionOnlyEntity())
|
||
|
{
|
||
|
NetworkInterface::CutsceneFinishedOnEntity(*GetGameRepositionOnlyEntity());
|
||
|
}
|
||
|
|
||
|
if (GetGameEntity() && !GetGameRepositionOnlyEntity())
|
||
|
{
|
||
|
#if !__NO_OUTPUT
|
||
|
ResetEntityForCallStackLogging();
|
||
|
#endif
|
||
|
|
||
|
//only set entities needed for the game ready for the game
|
||
|
if(m_RegisteredEntityFromScript.bCreatedForScript || !m_RegisteredEntityFromScript.bDeleteBeforeEnd)
|
||
|
{
|
||
|
cutsceneModelEntityDebugf2("SetGameEntityReadyForGame: Setting cutscene ped (%s) ready for game", GetGameEntity()->GetModelName());
|
||
|
SetVisibility(GetGameEntity(), true);
|
||
|
cutsceneModelEntityDebugf2("CCutsceneAnimatedActorEntity::SetGameEntityReadyForGame1 : Showing GetGameEntity (%s)", GetGameEntity()->GetModelName());
|
||
|
|
||
|
GetGameEntity()->SetDesiredHeading(GetGameEntity()->GetTransform().GetHeading());
|
||
|
GetGameEntity()->SetFixedPhysics(false);
|
||
|
GetGameEntity()->EnableCollision();
|
||
|
GetGameEntity()->SetUseExtractedZ(false);
|
||
|
GetGameEntity()->m_nPhysicalFlags.bNotDamagedByAnything = m_bWasInvincible;
|
||
|
GetGameEntity()->SetVelocity(GetAnimatedVelocity());
|
||
|
|
||
|
if (m_OptionFlags.IsFlagSet(CEO_RESET_CAPSULE_AT_END))
|
||
|
{
|
||
|
GetGameEntity()->ClearBound();
|
||
|
GetGameEntity()->SetBoundPitch(0.0f);
|
||
|
GetGameEntity()->SetBoundHeading(0.0f);
|
||
|
GetGameEntity()->SetBoundOffset(VEC3_ZERO);
|
||
|
}
|
||
|
|
||
|
if(m_pCutfObject && !GetGameEntity()->GetPedAiLod().IsSafeToSwitchToFullPhysics())
|
||
|
{
|
||
|
cutsceneModelEntityWarningf("Scene %s has left %s where it's unsafe to turn physics on. Check that the anim is leaving the player out of collision with objects or map", pManager->GetCutsceneName(), m_pCutfObject->GetDisplayName().c_str());
|
||
|
}
|
||
|
GetGameEntity()->GetPedAiLod().ClearLowLodPhysicsFlag();
|
||
|
|
||
|
//if the entity is created by the scene lets reset these variables
|
||
|
if(m_bCreatedByCutscene)
|
||
|
{
|
||
|
GetGameEntity()->SetBlockingOfNonTemporaryEvents(false);
|
||
|
GetGameEntity()->SetPedConfigFlag( CPED_CONFIG_FLAG_DrownsInWater, true );
|
||
|
}
|
||
|
|
||
|
CutSceneManager* pCutSceneManager = static_cast<CutSceneManager*>(pManager);
|
||
|
|
||
|
//Set the matrices to be the same for the ragdoll if the scene has been skipped
|
||
|
if(pCutSceneManager->WasSkipped())
|
||
|
{
|
||
|
if(GetGameEntity()->GetRagdollInst() && GetGameEntity()->GetRagdollInst()->IsInLevel()
|
||
|
&& GetGameEntity()->GetRagdollState()!=RAGDOLL_STATE_PHYS
|
||
|
&& GetGameEntity()->GetRagdollState()!=RAGDOLL_STATE_ANIM_DRIVEN)
|
||
|
{
|
||
|
GetGameEntity()->GetRagdollInst()->SetMatrix(GetGameEntity()->GetMatrix());
|
||
|
PHSIM->SetLastInstanceMatrix(GetGameEntity()->GetRagdollInst(), GetGameEntity()->GetMatrix());
|
||
|
GetGameEntity()->GetRagdollInst()->PoseBoundsFromSkeleton(true, true);
|
||
|
GetGameEntity()->GetRagdollInst()->PoseBoundsFromSkeleton(true, true);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
CPed* pPed = GetGameEntity();
|
||
|
if (pPed->GetFacialData())
|
||
|
{
|
||
|
pPed->GetFacialData()->ResetFacialIdleAnimation(pPed);
|
||
|
}
|
||
|
|
||
|
if (!m_OptionFlags.IsFlagSet(CEO_PRESERVE_FACE_BLOOD_DAMAGE))
|
||
|
{
|
||
|
pPed->HideBloodDamage(kDamageZoneHead, false);
|
||
|
}
|
||
|
|
||
|
if (!m_OptionFlags.IsFlagSet(CEO_PRESERVE_BODY_BLOOD_DAMAGE))
|
||
|
{
|
||
|
if (m_OptionFlags.IsFlagSet(CEO_REMOVE_BODY_BLOOD_DAMAGE))
|
||
|
{
|
||
|
pPed->HideBloodDamage(kDamageZoneTorso, false);
|
||
|
pPed->HideBloodDamage(kDamageZoneLeftArm, false);
|
||
|
pPed->HideBloodDamage(kDamageZoneRightArm, false);
|
||
|
pPed->HideBloodDamage(kDamageZoneLeftLeg, false);
|
||
|
pPed->HideBloodDamage(kDamageZoneRightLeg, false);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
pPed->LimitBloodDamage(kDamageZoneTorso, -1);
|
||
|
pPed->LimitBloodDamage(kDamageZoneLeftArm, -1);
|
||
|
pPed->LimitBloodDamage(kDamageZoneRightArm, -1);
|
||
|
pPed->LimitBloodDamage(kDamageZoneLeftLeg, -1);
|
||
|
pPed->LimitBloodDamage(kDamageZoneRightLeg, -1);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
cutsceneModelEntityDebugf2("SetGameEntityReadyForGame: Disabling collision on cutscene ped (%s) as it is to be deleted", GetGameEntity()->GetModelName());
|
||
|
//Switch off the collision flags as this entity is to be deleted
|
||
|
if(GetGameEntity()->GetCurrentPhysicsInst()->IsInLevel())
|
||
|
{
|
||
|
CPhysics::GetLevel()->SetInstanceIncludeFlags(GetGameEntity()->GetCurrentPhysicsInst()->GetLevelIndex(), 0);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
//Switch off the collision flags as this entity is to be deleted
|
||
|
if(GetGameEntity() && GetGameEntity()->GetCurrentPhysicsInst()->IsInLevel())
|
||
|
{
|
||
|
cutsceneModelEntityDebugf2("SetGameEntityReadyForGame: Disabling collision on cutscene ped (%s) as it is to be deleted", GetGameEntity()->GetModelName());
|
||
|
CPhysics::GetLevel()->SetInstanceIncludeFlags(GetGameEntity()->GetCurrentPhysicsInst()->GetLevelIndex(), 0);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (GetGameRepositionOnlyEntity() && !m_RegisteredEntityFromScript.bDeleteBeforeEnd)
|
||
|
{
|
||
|
cutsceneModelEntityDebugf2("SetGameEntityReadyForGame: Setting reposition ped (%s) ready for game", GetGameRepositionOnlyEntity()->GetModelName());
|
||
|
GetGameRepositionOnlyEntity()->SetFixedPhysics(false);
|
||
|
GetGameRepositionOnlyEntity()->SetPosition(m_CurrentPosition);
|
||
|
GetGameRepositionOnlyEntity()->SetHeading(m_CurrentHeading);
|
||
|
GetGameRepositionOnlyEntity()->SetDesiredHeading(m_CurrentHeading);
|
||
|
GetGameRepositionOnlyEntity()->GetPortalTracker()->RequestRescanNextUpdate();
|
||
|
GetGameRepositionOnlyEntity()->EnableCollision();
|
||
|
GetGameRepositionOnlyEntity()->SetVelocity(GetAnimatedVelocity());
|
||
|
|
||
|
if (m_OptionFlags.IsFlagSet(CEO_RESET_CAPSULE_AT_END))
|
||
|
{
|
||
|
GetGameRepositionOnlyEntity()->ClearBound();
|
||
|
GetGameRepositionOnlyEntity()->SetBoundPitch(0.0f);
|
||
|
GetGameRepositionOnlyEntity()->SetBoundHeading(0.0f);
|
||
|
GetGameRepositionOnlyEntity()->SetBoundOffset(VEC3_ZERO);
|
||
|
}
|
||
|
|
||
|
GetGameRepositionOnlyEntity()->m_nPhysicalFlags.bNotDamagedByAnything = m_bWasInvincible;
|
||
|
GetGameRepositionOnlyEntity()->SetIsVisibleForModule(SETISVISIBLE_MODULE_CUTSCENE, true);
|
||
|
cutsceneModelEntityDebugf2("CCutsceneAnimatedActorEntity::SetGameEntityReadyForGame2: Showing GetGameRepositionOnlyEntity (%s)", GetGameRepositionOnlyEntity()->GetModelName());
|
||
|
|
||
|
CPed* pPed = GetGameRepositionOnlyEntity();
|
||
|
if (pPed->GetFacialData())
|
||
|
{
|
||
|
pPed->GetFacialData()->ResetFacialIdleAnimation(pPed);
|
||
|
}
|
||
|
|
||
|
if (GetGameEntity())
|
||
|
{
|
||
|
SetVisibility(GetGameEntity(), false);
|
||
|
cutsceneModelEntityDebugf2("CCutsceneAnimatedActorEntity::SetGameEntityReadyForGame3: Hiding GetGameEntity (%s)", GetGameEntity()->GetModelName());
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (m_pCutSceneTask)
|
||
|
{
|
||
|
m_pCutSceneTask->SetExitNextUpdate();
|
||
|
}
|
||
|
|
||
|
m_bIsReadyForGame = true;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
void CCutsceneAnimatedActorEntity::SetGameEntityReadyForCutscene()
|
||
|
{
|
||
|
if (GetGameEntity())
|
||
|
{
|
||
|
#if !__NO_OUTPUT
|
||
|
SetUpEntityForCallStackLogging();
|
||
|
#endif
|
||
|
|
||
|
cutsceneModelEntityDebugf2("SetGameEntityReadyForCutscene - Actor");
|
||
|
|
||
|
m_fOriginalLODMultiplier = GetGameEntity()->GetLodMultiplier();
|
||
|
GetGameEntity()->SetLodMultiplier(4.0f);
|
||
|
|
||
|
//remove any tasks or motion on the peds before scene starts
|
||
|
|
||
|
// PedIntelligence->FlushImmediately should be done before EquipWeapon to ensure correct prop cleanup [12/21/2012 mdawe]
|
||
|
GetGameEntity()->GetPedIntelligence()->FlushImmediately(true);
|
||
|
|
||
|
// Set the ped's hands to be empty [12/21/2012 mdawe]
|
||
|
if(GetGameEntity()->GetWeaponManager())
|
||
|
{
|
||
|
GetGameEntity()->GetWeaponManager()->EquipWeapon(GetGameEntity()->GetDefaultUnarmedWeaponHash(), -1, true);
|
||
|
}
|
||
|
|
||
|
// Kill off any non-facial idle animations
|
||
|
if (GetGameEntity()->GetAnimDirector())
|
||
|
{
|
||
|
fwAnimDirectorComponentFacialRig* pFacialRigComp = GetGameEntity()->GetAnimDirector()->GetComponentByPhase<fwAnimDirectorComponentFacialRig>(fwAnimDirectorComponent::kPhaseAll);
|
||
|
if (pFacialRigComp)
|
||
|
{
|
||
|
pFacialRigComp->RemoveAllNonIdleFacialAnims();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (GetGameEntity()->GetIsAttachedToGround())
|
||
|
{
|
||
|
GetGameEntity()->DetachFromGround();
|
||
|
}
|
||
|
GetGameEntity()->SetPedResetFlag(CPED_RESET_FLAG_DisableGroundAttachment, true);
|
||
|
|
||
|
GetGameEntity()->SetIsCrouching(false);
|
||
|
GetGameEntity()->RemoveMovementAnims();
|
||
|
GetGameEntity()->BlendOutAnyNonMovementAnims(INSTANT_BLEND_OUT_DELTA);
|
||
|
GetGameEntity()->StopAllMotion(true);
|
||
|
|
||
|
if(!m_OptionFlags.IsFlagSet(CEO_DONT_RESET_PED_CAPSULE))
|
||
|
{
|
||
|
GetGameEntity()->InstantResetDesiredMainMoverCapsuleDataForCutscene();
|
||
|
}
|
||
|
|
||
|
GetGameEntity()->SetFixedPhysics(true);
|
||
|
GetGameEntity()->DisableCollision();
|
||
|
GetGameEntity()->m_nPhysicalFlags.bNotDamagedByAnything = true;
|
||
|
|
||
|
// Clone damage from reposition only entity?
|
||
|
if(GetGameRepositionOnlyEntity() && m_OptionFlags.IsFlagSet(CEO_CLONE_DAMAGE_TO_CS_MODEL))
|
||
|
{
|
||
|
GetGameEntity()->CloneDamage(GetGameRepositionOnlyEntity(), true);
|
||
|
}
|
||
|
|
||
|
if (m_OptionFlags.IsFlagSet(CEO_PRESERVE_HAIR_SCALE))
|
||
|
{
|
||
|
m_fOriginalHairScale = GetGameEntity()->GetTargetHairScale();
|
||
|
}
|
||
|
|
||
|
if (!m_OptionFlags.IsFlagSet(CEO_PRESERVE_FACE_BLOOD_DAMAGE))
|
||
|
{
|
||
|
GetGameEntity()->HideBloodDamage(kDamageZoneHead, true);
|
||
|
PEDDAMAGEMANAGER.ClearDamageDecals( GetGameEntity()->GetDamageSetID(), kDamageZoneHead, ATSTRINGHASH("bruise",0xe838afb1));
|
||
|
}
|
||
|
|
||
|
if (!m_OptionFlags.IsFlagSet(CEO_PRESERVE_BODY_BLOOD_DAMAGE))
|
||
|
{
|
||
|
if (m_OptionFlags.IsFlagSet(CEO_REMOVE_BODY_BLOOD_DAMAGE))
|
||
|
{
|
||
|
GetGameEntity()->HideBloodDamage(kDamageZoneTorso, true);
|
||
|
GetGameEntity()->HideBloodDamage(kDamageZoneLeftArm, true);
|
||
|
GetGameEntity()->HideBloodDamage(kDamageZoneRightArm, true);
|
||
|
GetGameEntity()->HideBloodDamage(kDamageZoneLeftLeg, true);
|
||
|
GetGameEntity()->HideBloodDamage(kDamageZoneRightLeg, true);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
static s32 s_maxBloodDamageForCutscene = 2;
|
||
|
GetGameEntity()->LimitBloodDamage(kDamageZoneTorso, s_maxBloodDamageForCutscene);
|
||
|
GetGameEntity()->LimitBloodDamage(kDamageZoneLeftArm, s_maxBloodDamageForCutscene);
|
||
|
GetGameEntity()->LimitBloodDamage(kDamageZoneRightArm, s_maxBloodDamageForCutscene);
|
||
|
GetGameEntity()->LimitBloodDamage(kDamageZoneLeftLeg, s_maxBloodDamageForCutscene);
|
||
|
GetGameEntity()->LimitBloodDamage(kDamageZoneRightLeg, s_maxBloodDamageForCutscene);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (m_OptionFlags.IsFlagSet(CEO_IS_CASCADE_SHADOW_FOCUS_ENTITY_DURING_EXIT) && CutSceneManager::GetInstance() && CutSceneManager::GetInstance()->GetCamEntity())
|
||
|
{
|
||
|
// Register this with the camera
|
||
|
CCutSceneCameraEntity* pCam = const_cast<CCutSceneCameraEntity*>(CutSceneManager::GetInstance()->GetCamEntity());
|
||
|
if (pCam)
|
||
|
{
|
||
|
if (GetGameRepositionOnlyEntity())
|
||
|
{
|
||
|
pCam->SetCascadeShadowFocusEntityForSeamlessExit(GetGameRepositionOnlyEntity());
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
pCam->SetCascadeShadowFocusEntityForSeamlessExit(GetGameEntity());
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
NetworkInterface::CutsceneStartedOnEntity(*GetGameEntity());
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CCutsceneAnimatedActorEntity::SetRepositionOnlyEntityReadyForCutscene()
|
||
|
{
|
||
|
if(GetGameRepositionOnlyEntity())
|
||
|
{
|
||
|
m_fOriginalLODMultiplier = GetGameRepositionOnlyEntity()->GetLodMultiplier();
|
||
|
GetGameRepositionOnlyEntity()->SetLodMultiplier(4.0f);
|
||
|
|
||
|
if(GetGameRepositionOnlyEntity()->GetWeaponManager())
|
||
|
{
|
||
|
GetGameRepositionOnlyEntity()->GetWeaponManager()->EquipWeapon(GetGameRepositionOnlyEntity()->GetDefaultUnarmedWeaponHash(), -1, true);
|
||
|
}
|
||
|
|
||
|
if(GetGameRepositionOnlyEntity()->IsNetworkClone())
|
||
|
{
|
||
|
GetGameRepositionOnlyEntity()->GetPedIntelligence()->FlushImmediately(false);
|
||
|
GetGameRepositionOnlyEntity()->GetPedIntelligence()->AddTaskDefault(rage_new CTaskNetworkClone());
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
GetGameRepositionOnlyEntity()->GetPedIntelligence()->FlushImmediately(true);
|
||
|
}
|
||
|
|
||
|
GetGameRepositionOnlyEntity()->SetIsCrouching(false);
|
||
|
GetGameRepositionOnlyEntity()->RemoveMovementAnims();
|
||
|
GetGameRepositionOnlyEntity()->BlendOutAnyNonMovementAnims(INSTANT_BLEND_OUT_DELTA);
|
||
|
GetGameRepositionOnlyEntity()->StopAllMotion(true);
|
||
|
GetGameRepositionOnlyEntity()->DisableCollision();
|
||
|
GetGameRepositionOnlyEntity()->SetFixedPhysics(true);
|
||
|
GetGameRepositionOnlyEntity()->m_nPhysicalFlags.bNotDamagedByAnything = true;
|
||
|
GetGameRepositionOnlyEntity()->SetIsVisibleForModule(SETISVISIBLE_MODULE_CUTSCENE, false);
|
||
|
cutsceneModelEntityDebugf2("CCutsceneAnimatedActorEntity::SetRepositionOnlyEntityReadyForCutscene: Hiding GetGameRepositionOnlyEntity (%s)", GetGameRepositionOnlyEntity()->GetModelName());
|
||
|
|
||
|
NetworkInterface::CutsceneStartedOnEntity(*GetGameRepositionOnlyEntity());
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
void CCutsceneAnimatedActorEntity::UpdateActorMotionState()
|
||
|
{
|
||
|
if(GetGameEntity())
|
||
|
{
|
||
|
GetGameEntity()->ForceMotionStateThisFrame(CPedMotionStates::MotionState_DoNothing);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////
|
||
|
namespace
|
||
|
{
|
||
|
void* g_pCharClothController = NULL;
|
||
|
int g_capsuleLeftT = 0;
|
||
|
int g_capsuleRightT = 1;
|
||
|
float g_customLength = -1.0f;
|
||
|
float g_customRadius = -1.0f;
|
||
|
}
|
||
|
|
||
|
void CCutsceneAnimatedActorEntity::DispatchEvent(cutsManager* pManager, const cutfObject* pObject, s32 iEventId, const cutfEventArgs* pEventArgs,const float fEventTime, const u32 UNUSED_PARAM(StickyId))
|
||
|
{
|
||
|
switch ( iEventId )
|
||
|
{
|
||
|
case CUTSCENE_UPDATE_EVENT:
|
||
|
case CUTSCENE_PAUSE_EVENT:
|
||
|
{
|
||
|
if (m_bIsReadyForGame)
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
/*if ( iEventId == CUTSCENE_UPDATE_EVENT)
|
||
|
{
|
||
|
cutsceneModelEntityDebugf("CCutsceneAnimatedActorEntity::DispatchEvent: CUTSCENE_UPDATE_EVENT");
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
cutsceneModelEntityDebugf("CCutsceneAnimatedActorEntity::DispatchEvent: CUTSCENE_PAUSE_EVENT");
|
||
|
}*/
|
||
|
|
||
|
CutSceneManager* pCutSceneManager = static_cast<CutSceneManager*>(pManager);
|
||
|
|
||
|
if (GetGameEntity())
|
||
|
GetGameEntity()->SetPedResetFlag(CPED_RESET_FLAG_OverridePhysics, true);
|
||
|
|
||
|
if(GetGameEntity() && m_pCutSceneTask == NULL)
|
||
|
{
|
||
|
GetGameEntity()->SetPedResetFlag(CPED_RESET_FLAG_DisablePotentialBlastReactions, true);
|
||
|
}
|
||
|
|
||
|
if(!IsBlockingVariationStreamingAndApplication())
|
||
|
{
|
||
|
PreStreamVariations(pCutSceneManager, pManager->GetTime(), PED_VARIATION_STREAMING_OFFSET);
|
||
|
}
|
||
|
|
||
|
if (iEventId==CUTSCENE_UPDATE_EVENT && m_bStoppedCalled)
|
||
|
{
|
||
|
CreateRepositionOnlyGameEntityWhenModelLoaded(pManager, pObject, true, true );
|
||
|
SetGameEntityReadyForGame(pManager);
|
||
|
}
|
||
|
|
||
|
UpdateCutSceneTask(pManager);
|
||
|
|
||
|
//Need to prevent time slicing if being updated by the cut scene system, cant just rely on the task blocking it
|
||
|
if (GetGameEntity())
|
||
|
{
|
||
|
GetGameEntity()->GetPedAiLod().SetForceNoTimesliceIntelligenceUpdate(true);
|
||
|
GetGameEntity()->GetPedAiLod().SetBlockedLodFlag(CPedAILod::AL_LodTimesliceIntelligenceUpdate | CPedAILod::AL_LodTimesliceAnimUpdate);
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case CUTSCENE_SET_VARIATION_EVENT:
|
||
|
{
|
||
|
if(IsBlockingVariationStreamingAndApplication())
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (m_bIsReadyForGame)
|
||
|
{
|
||
|
//cutsceneModelEntityDebugf("CCutsceneAnimatedActorEntity::DispatchEvent: Ignoring CUTSCENE_SET_VARIATION_EVENT m_bIsReadyForGame = false");
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
CutSceneManager* pCutSceneManager = static_cast<CutSceneManager*>(pManager);
|
||
|
|
||
|
//dont set the variations from the first frame, it has already been done.
|
||
|
if((pCutSceneManager->GetCutSceneCurrentTime() > pCutSceneManager->GetStartTime()) && (fEventTime > pCutSceneManager->GetStartTime()) && !m_bIsReadyForGame )
|
||
|
{
|
||
|
if(!GetGameEntity())
|
||
|
{
|
||
|
cutsceneModelEntityWarningf("No ped entity to set a variation on %s", pObject->GetDisplayName().c_str());
|
||
|
}
|
||
|
|
||
|
//cutsceneModelEntityDebugf("CCutsceneAnimatedActorEntity::DispatchEvent - CUTSCENE_SET_VARIATION_EVENT");
|
||
|
cutsceneAssertf(pEventArgs, "Cutscene content bug! CUTSCENE_SET_VARIATION_EVENT (object name=%s type=%s)(event id=%i) is corrupted and needs to be recreated, variation will not be applied!", pObject->GetDisplayName().c_str(), pObject->GetTypeName(), iEventId);
|
||
|
if (pEventArgs && pEventArgs->GetType() == CUTSCENE_ACTOR_VARIATION_EVENT_ARGS_TYPE)
|
||
|
{
|
||
|
CutSceneManager* pCutSceneManager = static_cast<CutSceneManager*>(pManager);
|
||
|
CCutSceneAssetMgrEntity* pAssetManager = pCutSceneManager->GetAssetManager();
|
||
|
|
||
|
const cutfObjectVariationEventArgs* pVariationEventFlag = static_cast<const cutfObjectVariationEventArgs *>( pEventArgs );
|
||
|
|
||
|
int Component = pVariationEventFlag->GetComponent();
|
||
|
int Drawable = pVariationEventFlag->GetDrawable();
|
||
|
int Texture = pVariationEventFlag->GetTexture();
|
||
|
|
||
|
if ((Component>-1 && Drawable>-1 && Texture>-1) || (Component>=PV_MAX_COMP && Drawable>-2))
|
||
|
{
|
||
|
cutsceneModelEntityDebugf3("CCutsceneAnimatedActorEntity::DispatchEvent: CUTSCENE_SET_VARIATION_EVENT: (Component: %d (%s), Drawable: %d, Texture: %d)", Component, CPedVariationData::GetVarOrPropSlotName(Component), Drawable, Texture);
|
||
|
SetCurrentActorVariation(GetGameEntity(), Component, Drawable, Texture);
|
||
|
if (Component<PV_MAX_COMP)
|
||
|
pAssetManager->RemoveVariationStreamRequest(Component, Drawable, Texture, m_ModelNameHash, pObject->GetObjectId());
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
cutsceneModelEntityDebugf3("CCutsceneAnimatedActorEntity::DispatchEvent: Ignoring CUTSCENE_SET_VARIATION_EVENT with invalid data: (Component: %d (%s), Drawable: %d, Texture: %d)", Component, CPedVariationData::GetVarOrPropSlotName(Component), Drawable, Texture);
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
cutsceneModelEntityDebugf3("CCutsceneAnimatedActorEntity::DispatchEvent: Ignoring CUTSCENE_SET_VARIATION_EVENT with invalid or null event arguments");
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
//cutsceneModelEntityDebugf("CCutsceneAnimatedActorEntity::DispatchEvent: Ignoring CUTSCENE_SET_VARIATION_EVENT pCutSceneManager->GetCutSceneCurrentTime() != pCutSceneManager->GetStartTimeFromStartFrame() && !m_bIsReadyForGame");
|
||
|
}
|
||
|
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case CUTSCENE_SET_DUAL_CLIP_EVENT:
|
||
|
{
|
||
|
if (pEventArgs && pEventArgs->GetType() == CUTSCENE_DUAL_CLIP_EVENT_ARGS_TYPE)
|
||
|
{
|
||
|
if (pObject)
|
||
|
{
|
||
|
cutsceneAssertf (0,"Not supported : CUTSCENE_SET_DUAL_CLIP_EVENT %s ",pObject->GetDisplayName().c_str());
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
|
||
|
case CUTSCENE_END_OF_SCENE_EVENT:
|
||
|
{
|
||
|
cutsceneModelEntityDebugf3("CCutsceneAnimatedActorEntity::DispatchEvent - CUTSCENE_END_OF_SCENE_EVENT");
|
||
|
|
||
|
#if RECORDING_VERTS
|
||
|
if( PFD_DebugRecords.WillDraw() )
|
||
|
{
|
||
|
g_DbgRecordCustomClothEvents.Reset();
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
if( GetGameEntity() && GetGameEntity()->GetIsTypePed() )
|
||
|
{
|
||
|
CPed* pPed = static_cast<CPed*>(GetGameEntity());
|
||
|
if( pPed )
|
||
|
{
|
||
|
for( int i = 0; i < PV_MAX_COMP; ++i )
|
||
|
{
|
||
|
characterClothController* pCharClothController = pPed->m_CClothController[i];
|
||
|
if( pCharClothController )
|
||
|
{
|
||
|
pCharClothController->CheckQueuedPinning();
|
||
|
pCharClothController->SetPinRadiusSetThreshold( PIN_RADIUSSETS_PACKAGE_THRESHOLD );
|
||
|
pCharClothController->SetFlag( characterClothController::enIsForceSkin, false);
|
||
|
pCharClothController->SetFlag( characterClothController::enIsProne, false );
|
||
|
pCharClothController->SetFlag( characterClothController::enIsProneFlipped, false );
|
||
|
pCharClothController->SetFlag( characterClothController::enIsEndCutscene, true );
|
||
|
pCharClothController->SetPackageIndex(0);
|
||
|
|
||
|
if( (i == PV_COMP_UPPR) && (g_pCharClothController == pCharClothController) )
|
||
|
{
|
||
|
characterCloth* pCharCloth = (characterCloth*)pCharClothController->GetOwner();
|
||
|
Assert( pCharCloth );
|
||
|
const phBoundComposite* pCustomBound = pCharCloth->GetBoundComposite();
|
||
|
Assert( pCustomBound );
|
||
|
if( pCustomBound )
|
||
|
{
|
||
|
Assert( g_customLength > 0.0f );
|
||
|
Assert( g_customRadius > 0.0f );
|
||
|
|
||
|
phBound* pBoundPart = pCustomBound->GetBound(g_capsuleLeftT);
|
||
|
Assert( pBoundPart );
|
||
|
Assert( pBoundPart->GetType() == phBound::CAPSULE );
|
||
|
|
||
|
phBoundCapsule* pBoundCapsule = (phBoundCapsule*)pBoundPart;
|
||
|
Assert( pBoundCapsule );
|
||
|
pBoundCapsule->SetCapsuleSize( g_customRadius, g_customLength );
|
||
|
|
||
|
pBoundPart = pCustomBound->GetBound(g_capsuleRightT);
|
||
|
Assert( pBoundPart );
|
||
|
Assert( pBoundPart->GetType() == phBound::CAPSULE );
|
||
|
|
||
|
pBoundCapsule = (phBoundCapsule*)pBoundPart;
|
||
|
Assert( pBoundCapsule );
|
||
|
pBoundCapsule->SetCapsuleSize( g_customRadius, g_customLength );
|
||
|
|
||
|
g_pCharClothController = NULL;
|
||
|
g_customLength = -1.0f;
|
||
|
g_customRadius = -1.0f;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
phVerletCloth* verletCloth = pCharClothController->GetCloth(0);
|
||
|
Assert( verletCloth );
|
||
|
|
||
|
verletCloth->DetachVirtualBound();
|
||
|
|
||
|
verletCloth->SetFlag(phVerletCloth::FLAG_COLLIDE_EDGES, false);
|
||
|
verletCloth->SetFlag(phVerletCloth::FLAG_IGNORE_OFFSET, false);
|
||
|
} // if( pPed->m_CClothController[i] )
|
||
|
} // for( int i = 0; i < PV_MAX_COMP; ++i )
|
||
|
|
||
|
pPed->SetPedConfigFlag( CPED_CONFIG_FLAG_ForceSkinCharacterCloth, false );
|
||
|
pPed->SetPedConfigFlag( CPED_CONFIG_FLAG_ForcePoseCharacterCloth, false );
|
||
|
pPed->SetPedConfigFlag( CPED_CONFIG_FLAG_ForcePackageCharacterCloth, false );
|
||
|
|
||
|
} // CPed* pPed = static_cast<CPed*>(GetGameEntity());
|
||
|
} // if( GetGameEntity() && GetGameEntity()->GetIsTypePed() )
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case CutSceneCustomEvents::CUTSCENE_CUSTOM_CLOTH_EVENT:
|
||
|
{
|
||
|
//cutsceneModelEntityDebugf("CCutsceneAnimatedActorEntity::DispatchEvent: CUTSCENE_CUSTOM_CLOTH_EVENT");
|
||
|
const CutSceneCustomEvents::ICutsceneCustomCustomEventArgs* pObjectVar = static_cast<const CutSceneCustomEvents::ICutsceneCustomCustomEventArgs*>(pEventArgs);
|
||
|
if( GetGameEntity() && GetGameEntity()->GetIsTypePed() && pObjectVar )
|
||
|
{
|
||
|
clothDebugf1("CUTSCENE_CUSTOM_CLOTH_EVENT: eventType = %d", pObjectVar->GetEventType() );
|
||
|
|
||
|
CPed* pPed = static_cast<CPed*>(GetGameEntity());
|
||
|
if( pPed )
|
||
|
{
|
||
|
const int eventType = pObjectVar->GetEventType();
|
||
|
AssertMsg( (eventType > 0 && eventType < CCEVENT_TYPE_MAX), "The event type value is not correct" );
|
||
|
|
||
|
if( eventType == CCEVENT_TYPE_SET_SKIN_ON_ONCREATE )
|
||
|
{
|
||
|
pPed->SetPedConfigFlag( CPED_CONFIG_FLAG_ForceSkinCharacterCloth, true );
|
||
|
}
|
||
|
else if( eventType == CCEVENT_TYPE_SET_SKIN_OFF_ONCREATE )
|
||
|
{
|
||
|
pPed->SetPedConfigFlag( CPED_CONFIG_FLAG_ForceSkinCharacterCloth, false );
|
||
|
}
|
||
|
else if( eventType == CCEVENT_TYPE_QUEUE_POSE_ON || eventType == CCEVENT_TYPE_SET_POSE )
|
||
|
{
|
||
|
pPed->SetPedConfigFlag( CPED_CONFIG_FLAG_ForcePoseCharacterCloth, true );
|
||
|
pPed->QueueClothPoseIndex( (u8)pObjectVar->GetCapsuleLength() );
|
||
|
}
|
||
|
else if( eventType == CCEVENT_TYPE_QUEUE_POSE_OFF )
|
||
|
{
|
||
|
pPed->SetPedConfigFlag( CPED_CONFIG_FLAG_ForcePoseCharacterCloth, false );
|
||
|
}
|
||
|
else if( eventType == CCEVENT_TYPE_SET_PACKAGE_INDEX )
|
||
|
{
|
||
|
pPed->SetPedConfigFlag( CPED_CONFIG_FLAG_ForcePackageCharacterCloth, true );
|
||
|
pPed->QueueClothPackageIndex( (u8)pObjectVar->GetCapsuleLength() );
|
||
|
}
|
||
|
else if( eventType == CCEVENT_TYPE_SET_PRONE_ON )
|
||
|
{
|
||
|
pPed->SetPedConfigFlag( CPED_CONFIG_FLAG_ForceProneCharacterCloth, true );
|
||
|
}
|
||
|
|
||
|
for( int i = 0; i < PV_MAX_COMP; ++i )
|
||
|
{
|
||
|
characterClothController* pCharClothController = pPed->m_CClothController[i];
|
||
|
if( pCharClothController )
|
||
|
{
|
||
|
phVerletCloth* verletCloth = pCharClothController->GetCloth(0);
|
||
|
Assert( verletCloth );
|
||
|
|
||
|
#if RECORDING_VERTS
|
||
|
if( PFD_DebugRecords.WillDraw()
|
||
|
&& eventType != CCEVENT_TYPE_ATTACH_COLLISION
|
||
|
&& eventType != CCEVENT_TYPE_SET_PACKAGE_INDEX
|
||
|
&& eventType != CCEVENT_TYPE_SET_POSE
|
||
|
)
|
||
|
{
|
||
|
recordCustomClothEvent rec;
|
||
|
rec.m_Text = "CUTSCENE_CUSTOM_CLOTH_EVENT";
|
||
|
rec.m_ClothControllerName = pPed->m_CClothController[i]->GetName();
|
||
|
rec.m_EventType = eventType;
|
||
|
//rec.m_Frames = 60;
|
||
|
g_DbgRecordCustomClothEvents.Push( rec );
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
|
||
|
// TODO: add debug text showing warning on the screen if bound exists already ?
|
||
|
if( eventType == CCEVENT_TYPE_ATTACH_COLLISION && !verletCloth->m_VirtualBound )
|
||
|
{
|
||
|
Vector3 vPos = VEC3_ZERO;
|
||
|
vPos.x = pObjectVar->GetPositionX();
|
||
|
vPos.y = pObjectVar->GetPositionY();
|
||
|
vPos.z = pObjectVar->GetPositionZ();
|
||
|
|
||
|
Vector3 vRot = VEC3_ZERO;
|
||
|
vRot.x = pObjectVar->GetRotationX();
|
||
|
vRot.y = pObjectVar->GetRotationY();
|
||
|
vRot.z = pObjectVar->GetRotationZ();
|
||
|
|
||
|
Mat34V boundMat;
|
||
|
Mat34VFromEulersXYZ( boundMat, VECTOR3_TO_VEC3V(vRot) );
|
||
|
boundMat.SetCol3( VECTOR3_TO_VEC3V(vPos) );
|
||
|
|
||
|
float fCapsuleLen = pObjectVar->GetCapsuleLength();
|
||
|
float fCapsuleRad = pObjectVar->GetCapsuleRadius();
|
||
|
|
||
|
verletCloth->SetFlag(phVerletCloth::FLAG_COLLIDE_EDGES, true);
|
||
|
verletCloth->SetFlag(phVerletCloth::FLAG_IGNORE_OFFSET, true);
|
||
|
|
||
|
verletCloth->CreateVirtualBound( 1, &identityMat );
|
||
|
verletCloth->AttachVirtualBoundCapsule( fCapsuleRad, fCapsuleLen, boundMat, 0 );
|
||
|
|
||
|
#if RECORDING_VERTS
|
||
|
if( PFD_DebugRecords.WillDraw() )
|
||
|
{
|
||
|
recordCustomClothEvent rec;
|
||
|
rec.m_Text = "CUTSCENE_CUSTOM_CLOTH_EVENT";
|
||
|
rec.m_ClothControllerName = pPed->m_CClothController[i]->GetName();
|
||
|
rec.m_EventType = eventType;
|
||
|
rec.m_Position = VECTOR3_TO_VEC3V(vPos);
|
||
|
rec.m_Rotation = VECTOR3_TO_VEC3V(vRot);
|
||
|
rec.m_CapsuleLength = fCapsuleLen;
|
||
|
rec.m_CapsuleRadius = fCapsuleRad;
|
||
|
//rec.m_Frames = 60;
|
||
|
g_DbgRecordCustomClothEvents.Push( rec );
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
}
|
||
|
else if( eventType == CCEVENT_TYPE_DETACH_COLLISION )
|
||
|
{
|
||
|
verletCloth->DetachVirtualBound();
|
||
|
|
||
|
verletCloth->SetFlag(phVerletCloth::FLAG_COLLIDE_EDGES, false);
|
||
|
verletCloth->SetFlag(phVerletCloth::FLAG_IGNORE_OFFSET, false);
|
||
|
}
|
||
|
else if( eventType == CCEVENT_TYPE_SET_SKIN_ON )
|
||
|
{
|
||
|
pCharClothController->SetFlag( characterClothController::enIsForceSkin, true);
|
||
|
}
|
||
|
else if( eventType == CCEVENT_TYPE_SET_SKIN_OFF )
|
||
|
{
|
||
|
pCharClothController->SetFlag( characterClothController::enIsForceSkin, false);
|
||
|
}
|
||
|
else if( eventType == CCEVENT_TYPE_FORCE_PIN )
|
||
|
{
|
||
|
pCharClothController->SetForcePin(1);
|
||
|
}
|
||
|
else if( eventType == CCEVENT_TYPE_SET_PACKAGE_INDEX )
|
||
|
{
|
||
|
pCharClothController->SetPackageIndex( (u8)pObjectVar->GetCapsuleLength() );
|
||
|
|
||
|
pPed->SetPedConfigFlag( CPED_CONFIG_FLAG_ForcePackageCharacterCloth, false );
|
||
|
#if RECORDING_VERTS
|
||
|
if( PFD_DebugRecords.WillDraw() )
|
||
|
{
|
||
|
recordCustomClothEvent rec;
|
||
|
rec.m_Text = "CUTSCENE_CUSTOM_CLOTH_EVENT";
|
||
|
rec.m_ClothControllerName = pPed->m_CClothController[i]->GetName();
|
||
|
rec.m_EventType = eventType;
|
||
|
rec.m_CapsuleLength = pObjectVar->GetCapsuleLength();
|
||
|
//rec.m_Frames = 60;
|
||
|
g_DbgRecordCustomClothEvents.Push( rec );
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
}
|
||
|
else if( eventType == CCEVENT_TYPE_SET_PRONE_ON )
|
||
|
{
|
||
|
pCharClothController->SetFlag( characterClothController::enIsProneFlipped, true );
|
||
|
pPed->SetPedConfigFlag( CPED_CONFIG_FLAG_ForceProneCharacterCloth, false );
|
||
|
}
|
||
|
else if( eventType == CCEVENT_TYPE_SET_PRONE_OFF )
|
||
|
{
|
||
|
pCharClothController->SetFlag( characterClothController::enIsProne, false );
|
||
|
pCharClothController->SetFlag( characterClothController::enIsProneFlipped, false );
|
||
|
}
|
||
|
else if( eventType == CCEVENT_TYPE_SET_PIN_RADIUS_THRESHOLD )
|
||
|
{
|
||
|
pCharClothController->SetPinRadiusSetThreshold( pObjectVar->GetCapsuleLength() );
|
||
|
}
|
||
|
else if( eventType == CCEVENT_TYPE_SET_POSE )
|
||
|
{
|
||
|
// NOTE: if we set a pose then don't skin
|
||
|
pCharClothController->SetFlag( characterClothController::enIsForceSkin, false );
|
||
|
pCharClothController->SetForcePin( 0 );
|
||
|
|
||
|
characterCloth* pCharCloth = (characterCloth*)pCharClothController->GetOwner();
|
||
|
Assert( pCharCloth );
|
||
|
pCharCloth->SetPose( (u8)pObjectVar->GetCapsuleLength() );
|
||
|
|
||
|
pPed->SetPedConfigFlag( CPED_CONFIG_FLAG_ForcePoseCharacterCloth, false );
|
||
|
|
||
|
#if RECORDING_VERTS
|
||
|
if( PFD_DebugRecords.WillDraw() )
|
||
|
{
|
||
|
recordCustomClothEvent rec;
|
||
|
rec.m_Text = "CUTSCENE_CUSTOM_CLOTH_EVENT";
|
||
|
rec.m_ClothControllerName = pPed->m_CClothController[i]->GetName();
|
||
|
rec.m_EventType = eventType;
|
||
|
rec.m_CapsuleLength = pObjectVar->GetCapsuleLength();
|
||
|
g_DbgRecordCustomClothEvents.Push( rec );
|
||
|
}
|
||
|
#endif
|
||
|
}
|
||
|
else if( eventType == CCEVENT_TYPE_CUSTOM_1 && i == PV_COMP_UPPR )
|
||
|
{
|
||
|
// TODO: hacky way to increase the raduis on the collision bounds from cutscene
|
||
|
characterCloth* pCharCloth = (characterCloth*)pCharClothController->GetOwner();
|
||
|
Assert( pCharCloth );
|
||
|
const phBoundComposite* pCustomBound = pCharCloth->GetBoundComposite();
|
||
|
Assert( pCustomBound );
|
||
|
if( pCustomBound )
|
||
|
{
|
||
|
phBound* pBoundPart = pCustomBound->GetBound(g_capsuleLeftT);
|
||
|
Assert( pBoundPart );
|
||
|
Assert( pBoundPart->GetType() == phBound::CAPSULE );
|
||
|
|
||
|
phBoundCapsule* pBoundCapsule = (phBoundCapsule*)pBoundPart;
|
||
|
Assert( pBoundCapsule );
|
||
|
pBoundCapsule->SetCapsuleSize( pObjectVar->GetCapsuleRadius(), pObjectVar->GetCapsuleLength() );
|
||
|
|
||
|
pBoundPart = pCustomBound->GetBound(g_capsuleRightT);
|
||
|
Assert( pBoundPart );
|
||
|
Assert( pBoundPart->GetType() == phBound::CAPSULE );
|
||
|
|
||
|
pBoundCapsule = (phBoundCapsule*)pBoundPart;
|
||
|
Assert( pBoundCapsule );
|
||
|
pBoundCapsule->SetCapsuleSize( pObjectVar->GetCapsuleRadius(), pObjectVar->GetCapsuleLength() );
|
||
|
|
||
|
Assert( !g_pCharClothController );
|
||
|
g_pCharClothController = pCharClothController;
|
||
|
g_customLength = pObjectVar->GetCapsuleLength();
|
||
|
g_customRadius = pObjectVar->GetCapsuleRadius();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
} // for
|
||
|
|
||
|
} // if( pPed )
|
||
|
} // if ( GetGameEntity ...
|
||
|
}
|
||
|
break;
|
||
|
case CUTSCENE_STOP_EVENT:
|
||
|
{
|
||
|
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
}
|
||
|
|
||
|
//this is here to dispatch debug draw event for this entity.
|
||
|
#if __BANK
|
||
|
cutsEntity::DispatchEvent(pManager, pObject, iEventId, pEventArgs);
|
||
|
#endif
|
||
|
|
||
|
CCutsceneAnimatedModelEntity::DispatchEvent(pManager, pObject, iEventId, pEventArgs);
|
||
|
}
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
void CCutsceneAnimatedActorEntity::PlayClip (CutSceneManager* pCutManager, const crClip* pClip, float fEventTime, const strStreamingObjectName UNUSED_PARAM(pAnimDict))
|
||
|
{
|
||
|
//Assertf(CutSceneManager::GetInstance()->GetAssetManager()->HaveAllVariationsLoaded(PED_VARIATION_TYPE), "Variations not yet loaded");
|
||
|
//CutSceneManager::GetInstance()->GetAssetManager()->DumpAllVariationsLoaded(m_pCutfObject->GetObjectId());
|
||
|
|
||
|
if(GetGameEntity())
|
||
|
{
|
||
|
if(!m_pCutSceneTask)
|
||
|
{
|
||
|
GetGameEntity()->SetPedResetFlag( CPED_RESET_FLAG_AllowUpdateIfNoCollisionLoaded, true );
|
||
|
|
||
|
// Make sure we don't timeslice the ai / animation this frame.
|
||
|
GetGameEntity()->GetPedAiLod().SetForceNoTimesliceIntelligenceUpdate(true);
|
||
|
GetGameEntity()->GetPedAiLod().SetBlockedLodFlag(CPedAILod::AL_LodTimesliceIntelligenceUpdate | CPedAILod::AL_LodTimesliceAnimUpdate);
|
||
|
|
||
|
if(GetGameEntity()->IsProtectedBaseFlagSet(fwEntity::IS_FIXED_UNTIL_COLLISION))
|
||
|
{
|
||
|
GetGameEntity()->UpdateFixedWaitingForCollision(false);
|
||
|
}
|
||
|
|
||
|
if(GetGameEntity()->GetPedIntelligence()->GetTaskEventResponse())
|
||
|
{
|
||
|
GetGameEntity()->GetPedIntelligence()->FlushImmediately(true);
|
||
|
}
|
||
|
|
||
|
m_pCutSceneTask = CreateCutsceneTask(pCutManager, pClip, fEventTime);
|
||
|
|
||
|
m_pCutSceneTask->SetPreserveHairScale(m_OptionFlags.IsFlagSet(CEO_PRESERVE_HAIR_SCALE));
|
||
|
m_pCutSceneTask->SetInstantHairScaleUpdate(m_OptionFlags.IsFlagSet(CEO_INSTANT_HAIR_SCALE_SETUP));
|
||
|
m_pCutSceneTask->SetOriginalHairScale(m_fOriginalHairScale);
|
||
|
|
||
|
if(GetGameEntity()->IsNetworkClone())
|
||
|
{
|
||
|
GetGameEntity()->GetPedIntelligence()->AddLocalCloneTask(m_pCutSceneTask, PED_TASK_PRIORITY_PRIMARY);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
GetGameEntity()->GetPedIntelligence()->AddTaskAtPriority(m_pCutSceneTask, PED_TASK_PRIORITY_PRIMARY, TRUE);
|
||
|
}
|
||
|
|
||
|
GetGameEntity()->SetFixedPhysics(false);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if(cutsceneVerifyf(m_pCutSceneTask->GetTaskType() == CTaskTypes::TASK_CUTSCENE, "Trying to set the clip on a CTaskCutscene, but entity %s is not running a cutscene task", m_pCutfObject->GetDisplayName().c_str()))
|
||
|
{
|
||
|
Matrix34 SceneMat;
|
||
|
pCutManager->GetSceneOrientationMatrix(SceneMat);
|
||
|
m_pCutSceneTask->SetClip(pClip,SceneMat, fEventTime);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
#if __DEV
|
||
|
if(GetGameEntity() && m_pCutSceneTask && m_pCutSceneTask->GetTaskType() == CTaskTypes::TASK_CUTSCENE)
|
||
|
{
|
||
|
//THIS CURRENTLY DOES NOTHING TO FILTER ANY ANIMS BECAUSE THERE IS NO FILTER TO REMOVE ALL ANIM EXCEPT FACIAL
|
||
|
UpdateWithFaceViewer(pCutManager, m_pCutSceneTask);
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
SetAnimPlayBackEventTime(fEventTime);
|
||
|
}
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////
|
||
|
//Gets the position of an actors bone (used for face zoom but could use for hands etc
|
||
|
|
||
|
bool CCutsceneAnimatedActorEntity::GetActorBonePosition(eAnimBoneTag ePedBone, Matrix34 &mMat) const
|
||
|
{
|
||
|
const crSkeleton* pSkel = NULL;
|
||
|
|
||
|
s32 nBoneIndex = -1;
|
||
|
|
||
|
if (GetGameEntity())
|
||
|
{
|
||
|
pSkel = GetGameEntity()->GetSkeleton();
|
||
|
nBoneIndex = GetGameEntity()->GetBoneIndexFromBoneTag(ePedBone);
|
||
|
}
|
||
|
|
||
|
if (pSkel && nBoneIndex!= -1)
|
||
|
{
|
||
|
pSkel->GetGlobalMtx(nBoneIndex, RC_MAT34V(mMat));
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////
|
||
|
//set the variation on an actor
|
||
|
|
||
|
void CCutsceneAnimatedActorEntity::SetCurrentActorVariation(CPed* pPed, u32 iComponent, s32 iDrawable, s32 iTexture)
|
||
|
{
|
||
|
if(IsBlockingVariationStreamingAndApplication())
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
//setting the variation on a ped
|
||
|
if (pPed && pPed->GetPedModelInfo() && pPed->GetPedModelInfo()->GetVarInfo())
|
||
|
{
|
||
|
if(iComponent < PV_MAX_COMP)
|
||
|
{
|
||
|
if(pPed->IsVariationInRange(static_cast<ePedVarComp>(iComponent),iDrawable,iTexture))
|
||
|
{
|
||
|
//if(!pPed->HasVariation(static_cast<ePedVarComp>(iComponent), iDrawable, iTexture))
|
||
|
{
|
||
|
if (pPed->GetPedModelInfo()->GetIsStreamedGfx())
|
||
|
{
|
||
|
// Check the variation is loaded
|
||
|
eVariationStreamingStatus variationStreamingStatus = CutSceneManager::GetInstance()->GetAssetManager()->GetVariationLoadingState(iComponent, iDrawable, iTexture, m_ModelNameHash, m_pCutfObject->GetObjectId());
|
||
|
if( variationStreamingStatus == LOADING_VARIATION)
|
||
|
{
|
||
|
cutsceneModelEntityDebugf3("SetCurrentActorVariation (%s, %p) - Variation is still loading (Component: %d (%s), Drawable: %d, Texture: %d) ",
|
||
|
pPed->GetModelName(), pPed, iComponent, CPedVariationData::GetVarOrPropSlotName(iComponent), iDrawable, iTexture );
|
||
|
}
|
||
|
else if ( variationStreamingStatus == NO_REQUEST_FOR_VARIATION )
|
||
|
{
|
||
|
cutsceneModelEntityDebugf3("SetCurrentActorVariation (%s, %p) - Variation has no request (Component: %d (%s), Drawable: %d, Texture: %d) ",
|
||
|
pPed->GetModelName(), pPed, iComponent, CPedVariationData::GetVarOrPropSlotName(iComponent), iDrawable, iTexture );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#if !__NO_OUTPUT
|
||
|
bool ReactivateLogging = false;
|
||
|
if(pPed->m_LogVariationCalls)
|
||
|
{
|
||
|
pPed->m_LogVariationCalls = false;
|
||
|
ReactivateLogging = true;
|
||
|
}
|
||
|
#endif //!__NO_OUTPUT
|
||
|
pPed->SetVariation(static_cast<ePedVarComp>(iComponent), iDrawable, 0, iTexture, 0, 0, true);
|
||
|
#if !__NO_OUTPUT
|
||
|
if(ReactivateLogging)
|
||
|
{
|
||
|
pPed->m_LogVariationCalls = true;
|
||
|
}
|
||
|
#endif //!__NO_OUTPUT
|
||
|
|
||
|
cutsceneModelEntityDebugf3("SetCurrentActorVariation (%s, %p) - Actual SetVariation - (Component: %d (%s), Drawable: %d/%d, Texture: %d/%d)",
|
||
|
pPed->GetModelName(), pPed, iComponent, CPedVariationData::GetVarOrPropSlotName(iComponent),
|
||
|
iDrawable, pPed->GetPedModelInfo()->GetVarInfo()->GetMaxNumDrawbls(static_cast<ePedVarComp>(iComponent)),
|
||
|
iTexture, pPed->GetPedModelInfo()->GetVarInfo()->GetMaxNumTex(static_cast<ePedVarComp>(iComponent),iDrawable));
|
||
|
|
||
|
}
|
||
|
/*else
|
||
|
{
|
||
|
cutsceneModelEntityDebugf("SetCurrentActorVariation (%s, %p) - Already has variation - (Component: %d (%s), Drawable: %d/%d, Texture: %d/%d)",
|
||
|
pPed->GetModelName(), pPed, iComponent, CPedVariationData::GetVarOrPropSlotName(iComponent),
|
||
|
iDrawable, pPed->GetPedModelInfo()->GetVarInfo()->GetMaxNumDrawbls(static_cast<ePedVarComp>(iComponent)),
|
||
|
iTexture, pPed->GetPedModelInfo()->GetVarInfo()->GetMaxNumTex(static_cast<ePedVarComp>(iComponent),iDrawable));
|
||
|
}*/
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
cutsceneModelEntityDebugf3("SetCurrentActorVariation (%s, %p) - Variation not in range - (Component: %d (%s), Drawable: %d/%d, Texture: %d/%d) (using default instead) ",
|
||
|
pPed->GetModelName(), pPed, iComponent, CPedVariationData::GetVarOrPropSlotName(iComponent),
|
||
|
iDrawable, pPed->GetPedModelInfo()->GetVarInfo()->GetMaxNumDrawbls(static_cast<ePedVarComp>(iComponent)),
|
||
|
iTexture, pPed->GetPedModelInfo()->GetVarInfo()->GetMaxNumTex(static_cast<ePedVarComp>(iComponent),iDrawable));
|
||
|
|
||
|
// Check the default variation is loaded
|
||
|
eVariationStreamingStatus variationStreamingStatus = CutSceneManager::GetInstance()->GetAssetManager()->GetVariationLoadingState(iComponent, 0, 0, m_ModelNameHash, m_pCutfObject->GetObjectId());
|
||
|
if( variationStreamingStatus == LOADING_VARIATION)
|
||
|
{
|
||
|
cutsceneModelEntityDebugf3("SetCurrentActorVariation (%s, %p) - Variation is still loading (Component: %d (%s), Drawable: %d, Texture: %d) ",
|
||
|
pPed->GetModelName(), pPed, iComponent, CPedVariationData::GetVarOrPropSlotName(iComponent), 0, 0 );
|
||
|
}
|
||
|
else if ( variationStreamingStatus == NO_REQUEST_FOR_VARIATION )
|
||
|
{
|
||
|
cutsceneModelEntityDebugf3("SetCurrentActorVariation (%s, %p) - Variation has no request (Component: %d (%s), Drawable: %d, Texture: %d) ",
|
||
|
pPed->GetModelName(), pPed, iComponent, CPedVariationData::GetVarOrPropSlotName(iComponent), 0, 0 );
|
||
|
}
|
||
|
|
||
|
#if !__NO_OUTPUT
|
||
|
bool ReactivateLogging = false;
|
||
|
if(pPed->m_LogVariationCalls)
|
||
|
{
|
||
|
pPed->m_LogVariationCalls = false;
|
||
|
ReactivateLogging = true;
|
||
|
}
|
||
|
#endif //!__NO_OUTPUT
|
||
|
pPed->SetVariation(static_cast<ePedVarComp>(iComponent), 0, 0, 0, 0, 0, true);
|
||
|
#if !__NO_OUTPUT
|
||
|
if(ReactivateLogging)
|
||
|
{
|
||
|
pPed->m_LogVariationCalls = true;
|
||
|
}
|
||
|
#endif //!__NO_OUTPUT
|
||
|
|
||
|
cutsceneModelEntityDebugf3("SetCurrentActorVariation (%s, %p) - Actual SetVariation - (Component: %d (%s), Drawable: %d/%d, Texture: %d/%d)",
|
||
|
pPed->GetModelName(), pPed, iComponent, CPedVariationData::GetVarOrPropSlotName(0),
|
||
|
0, pPed->GetPedModelInfo()->GetVarInfo()->GetMaxNumDrawbls(static_cast<ePedVarComp>(0)),
|
||
|
0, pPed->GetPedModelInfo()->GetVarInfo()->GetMaxNumTex(static_cast<ePedVarComp>(0),0));
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
int iPropComponent = iComponent - PV_MAX_COMP;
|
||
|
if(iDrawable != -1)
|
||
|
{
|
||
|
CPedPropsMgr::SetPedProp(pPed, (eAnchorPoints)iPropComponent , iDrawable, iTexture, ANCHOR_NONE, NULL, NULL);
|
||
|
cutsceneModelEntityDebugf3("SetCurrentActorVariation (%s, %p) - Actual SetPedProp - (Component: %d (%s), Drawable: %d, Texture: %d)", pPed->GetModelName(), pPed, iComponent, CPedVariationData::GetVarOrPropSlotName(iComponent), iDrawable, iTexture);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
CPedPropsMgr::ClearPedProp(pPed, (eAnchorPoints)iPropComponent );
|
||
|
if(iComponent == PV_COMP_HEAD && pPed->GetHelmetComponent())
|
||
|
{
|
||
|
pPed->GetHelmetComponent()->DisableHelmet(false);
|
||
|
}
|
||
|
cutsceneModelEntityDebugf3("SetActorCurrentVariation (%s, %p) - Actual ClearPedProp - (Component: %d (%s))", pPed->GetModelName(), pPed, iComponent, CPedVariationData::GetVarOrPropSlotName(iComponent));
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
cutsceneModelEntityDebugf3("SetCurrentActorVariation - Ped not loaded (or malformed). Failed to set variation on ped but storing the variation to apply once the ped is loaded. - (Component: %d (%s), Drawable: %d, Texture: %d)",
|
||
|
iComponent, CPedVariationData::GetVarOrPropSlotName(iComponent),iDrawable, iTexture);
|
||
|
}
|
||
|
|
||
|
if ((iDrawable>-1 && iTexture>-1) || (iComponent>=PV_MAX_COMP && iDrawable>-2))
|
||
|
{
|
||
|
StoreActorVariationData( iComponent, iDrawable, iTexture, m_sCurrentActorVariationData);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CCutsceneAnimatedActorEntity::SetScriptActorVariationData( u32 iComponent, s32 iDrawable, s32 iTexture)
|
||
|
{
|
||
|
if((iDrawable>-1 && iTexture>-1) || (iComponent>=PV_MAX_COMP && iDrawable>-2))
|
||
|
{
|
||
|
// Store the variations set by script in their own array
|
||
|
// These will be used in favour of cutscene variations on the start frame
|
||
|
StoreActorVariationData(iComponent, iDrawable, iTexture, m_sScriptActorVariationData);
|
||
|
|
||
|
// Also copy the variations into the current array
|
||
|
// Peds not loaded before the scene dotn get ComputeInitialVariations called on them
|
||
|
StoreActorVariationData(iComponent, iDrawable, iTexture, m_sCurrentActorVariationData);
|
||
|
}
|
||
|
}
|
||
|
/////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
CCutsceneAnimatedActorEntity::~CCutsceneAnimatedActorEntity()
|
||
|
{
|
||
|
//check that the script registered entity is being picked up by the script
|
||
|
if(m_RegisteredEntityFromScript.pEnt != NULL)
|
||
|
{
|
||
|
if(m_RegisteredEntityFromScript.pEnt->GetIsTypePed())
|
||
|
{
|
||
|
CPed* pPed = (CPed*)m_RegisteredEntityFromScript.pEnt.Get();
|
||
|
|
||
|
if(!pPed->IsLocalPlayer())
|
||
|
{
|
||
|
if(m_RegisteredEntityFromScript.SceneNameHash > 0 && m_RegisteredEntityFromScript.bCreatedForScript)
|
||
|
{
|
||
|
const CScriptEntityExtension* pExtension = m_RegisteredEntityFromScript.pEnt->GetExtension<CScriptEntityExtension>();
|
||
|
|
||
|
if(!CutSceneManager::GetInstance()->ShouldDeleteAllRegisteredEntites())
|
||
|
{
|
||
|
if(!IsRegisteredGameEntityUnderScriptControl())
|
||
|
{
|
||
|
cutsceneAssertf(pExtension, "Deleting a cutscene entity (\"%s\" %u) scene handle (\"%s\" %u) that was registered with CU_CREATE_AND_ANIMATE_NEW_SCRIPT_ENTITY use GET_ENTITY_INDEX_OF_REGISTERED_ENTITY to make sure it is pickup up by the script",
|
||
|
m_RegisteredEntityFromScript.ModelNameHash.TryGetCStr(),
|
||
|
m_RegisteredEntityFromScript.ModelNameHash.GetHash(),
|
||
|
m_RegisteredEntityFromScript.SceneNameHash.TryGetCStr(),
|
||
|
m_RegisteredEntityFromScript.SceneNameHash.GetHash());
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if(!pExtension)
|
||
|
{
|
||
|
m_RegisteredEntityFromScript.bDeleteBeforeEnd = true;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (GetGameEntity())
|
||
|
{
|
||
|
bool CanDelete = m_RegisteredEntityFromScript.pEnt != GetGameEntity();
|
||
|
|
||
|
if(CanDelete|| m_RegisteredEntityFromScript.bDeleteBeforeEnd)
|
||
|
{
|
||
|
GetGameEntity()->PopTypeSet(POPTYPE_RANDOM_AMBIENT);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
// Vehicle
|
||
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
CCutsceneAnimatedVehicleEntity::CCutsceneAnimatedVehicleEntity(const cutfObject* pObject)
|
||
|
:CCutsceneAnimatedModelEntity(pObject)
|
||
|
{
|
||
|
m_iAnimDict = -1;
|
||
|
|
||
|
#if __BANK
|
||
|
InitaliseVehicleExtraList();
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
CCutsceneAnimatedVehicleEntity::~CCutsceneAnimatedVehicleEntity()
|
||
|
{
|
||
|
//check that the script registered entity is being picked up by the script
|
||
|
if(m_RegisteredEntityFromScript.SceneNameHash > 0 && m_RegisteredEntityFromScript.bCreatedForScript)
|
||
|
{
|
||
|
if(m_RegisteredEntityFromScript.pEnt != NULL)
|
||
|
{
|
||
|
const CScriptEntityExtension* pExtension = m_RegisteredEntityFromScript.pEnt->GetExtension<CScriptEntityExtension>();
|
||
|
|
||
|
if(!CutSceneManager::GetInstance()->ShouldDeleteAllRegisteredEntites())
|
||
|
{
|
||
|
if(!IsRegisteredGameEntityUnderScriptControl())
|
||
|
{
|
||
|
cutsceneAssertf(pExtension, "Deleting a cutscene entity (\"%s\" %u) scene handle (\"%s\" %u) that was registered with CU_CREATE_AND_ANIMATE_NEW_SCRIPT_ENTITY use GET_ENTITY_INDEX_OF_REGISTERED_ENTITY to make sure it is pickup up by the script",
|
||
|
m_RegisteredEntityFromScript.ModelNameHash.TryGetCStr(),
|
||
|
m_RegisteredEntityFromScript.ModelNameHash.GetHash(),
|
||
|
m_RegisteredEntityFromScript.SceneNameHash.TryGetCStr(),
|
||
|
m_RegisteredEntityFromScript.SceneNameHash.GetHash());
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if(!pExtension)
|
||
|
{
|
||
|
m_RegisteredEntityFromScript.bDeleteBeforeEnd = true;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
void CCutsceneAnimatedVehicleEntity::DispatchEvent(cutsManager* pManager, const cutfObject* pObject, s32 iEventId, const cutfEventArgs* pEventArgs, const float UNUSED_PARAM(fTime), const u32 UNUSED_PARAM(StickyId))
|
||
|
{
|
||
|
switch ( iEventId )
|
||
|
{
|
||
|
case CUTSCENE_UPDATE_EVENT:
|
||
|
case CUTSCENE_PAUSE_EVENT:
|
||
|
{
|
||
|
if (iEventId==CUTSCENE_UPDATE_EVENT && m_bStoppedCalled)
|
||
|
{
|
||
|
CreateRepositionOnlyGameEntityWhenModelLoaded(pManager, pObject, true, true );
|
||
|
SetGameEntityReadyForGame(pManager);
|
||
|
}
|
||
|
|
||
|
UpdateCutSceneTask(pManager);
|
||
|
|
||
|
if (GetGameEntity() && !m_bIsReadyForGame)
|
||
|
{
|
||
|
CVehicleAILodManager::DisableTimeslicingImmediately(*GetGameEntity());
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case CUTSCENE_SET_VARIATION_EVENT:
|
||
|
{
|
||
|
if (m_bIsReadyForGame)
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
cutsceneModelEntityDebugf3("CCutsceneAnimatedVehicleEntity:CUTSCENE_SET_VARIATION_EVENT");
|
||
|
|
||
|
cutsceneAssertf(pEventArgs, "Cutscene content bug! CUTSCENE_SET_VARIATION_EVENT (object name=%s type=%s)(event id=%i) is corrupted and needs to be recreated, variation will not be applied!", pObject->GetDisplayName().c_str(), pObject->GetTypeName(), iEventId);
|
||
|
if (pEventArgs && pEventArgs->GetType() == CUTSCENE_VEHICLE_VARIATION_EVENT_ARGS_TYPE)
|
||
|
{
|
||
|
const cutfVehicleVariationEventArgs* pVariationEventFlag = static_cast<const cutfVehicleVariationEventArgs *>( pEventArgs );
|
||
|
|
||
|
SetVariation(pVariationEventFlag->GetBodyColour() ,
|
||
|
pVariationEventFlag->GetSecondaryBodyColour(),
|
||
|
pVariationEventFlag->GetSpecularBodyColour(),
|
||
|
pVariationEventFlag->GetWheelTrimColour(),
|
||
|
pVariationEventFlag->GetBodyColour5(),
|
||
|
pVariationEventFlag->GetBodyColour6(),
|
||
|
pVariationEventFlag->GetLiveryId(),
|
||
|
pVariationEventFlag->GetLivery2Id(),
|
||
|
pVariationEventFlag->GetDirtLevel() );
|
||
|
|
||
|
cutsceneDebugf1("%s CCutsceneAnimatedVehicleEntity:CUTSCENE_SET_VARIATION_EVENT BodyColor: %d, Second BodyColor: %d, SpecBody: %d, Wheel Trim Col: %d, BodyColor5: %d, BodyColor6: %d, Livery id: %d, Livery2 id: %d, Dirt Lev: %f "
|
||
|
, pObject->GetDisplayName().c_str(), pVariationEventFlag->GetBodyColour(),
|
||
|
pVariationEventFlag->GetSecondaryBodyColour(),
|
||
|
pVariationEventFlag->GetSpecularBodyColour(),
|
||
|
pVariationEventFlag->GetWheelTrimColour(),
|
||
|
pVariationEventFlag->GetBodyColour5(),
|
||
|
pVariationEventFlag->GetBodyColour6(),
|
||
|
pVariationEventFlag->GetLiveryId(),
|
||
|
pVariationEventFlag->GetLivery2Id(),
|
||
|
pVariationEventFlag->GetDirtLevel());
|
||
|
}
|
||
|
|
||
|
if (pEventArgs && pEventArgs->GetType() == CUTSCENE_VEHICLE_EXTRA_EVENT_ARGS_TYPE)
|
||
|
{
|
||
|
const cutfVehicleExtraEventArgs* pExtraEventFlag = static_cast<const cutfVehicleExtraEventArgs *>( pEventArgs );
|
||
|
|
||
|
if(GetGameEntity())
|
||
|
{
|
||
|
SetGameVehicleExtra(pExtraEventFlag->GetBoneIdList());
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case CutSceneCustomEvents::CUTSCENE_SET_VEHICLE_DAMAGE_EVENT:
|
||
|
{
|
||
|
if (m_bIsReadyForGame)
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
cutsceneDebugf1("%s CCutsceneAnimatedVehicleEntity:CUTSCENE_SET_VEHICLE_DAMAGE_EVENT", pObject->GetDisplayName().c_str());
|
||
|
if (pEventArgs && pEventArgs->GetType() == CUTSCENE_NAME_EVENT_ARGS_TYPE)
|
||
|
{
|
||
|
const cutfNameEventArgs* pObjectVar = static_cast<const cutfNameEventArgs*>(pEventArgs);
|
||
|
|
||
|
Vector3 vDamage = VEC3_ZERO;
|
||
|
float fDamage = 0.0f;
|
||
|
float fDeform = 0.0f;
|
||
|
|
||
|
if(pObjectVar->GetAttributeList().FindAttributeAnyCase("vPos.x"))
|
||
|
{
|
||
|
vDamage.x = pObjectVar->GetAttributeList().FindAttributeAnyCase("vPos.x")->FindFloatValue();
|
||
|
}
|
||
|
if(pObjectVar->GetAttributeList().FindAttributeAnyCase("vPos.y"))
|
||
|
{
|
||
|
vDamage.y = pObjectVar->GetAttributeList().FindAttributeAnyCase("vPos.y")->FindFloatValue();
|
||
|
}
|
||
|
|
||
|
if(pObjectVar->GetAttributeList().FindAttributeAnyCase("vPos.z"))
|
||
|
{
|
||
|
vDamage.z = pObjectVar->GetAttributeList().FindAttributeAnyCase("vPos.z")->FindFloatValue();
|
||
|
}
|
||
|
|
||
|
if(pObjectVar->GetAttributeList().FindAttributeAnyCase("fDamage"))
|
||
|
{
|
||
|
fDamage = pObjectVar->GetAttributeList().FindAttributeAnyCase("fDamage")->FindFloatValue();
|
||
|
}
|
||
|
|
||
|
if(pObjectVar->GetAttributeList().FindAttributeAnyCase("fDeform"))
|
||
|
{
|
||
|
fDeform = pObjectVar->GetAttributeList().FindAttributeAnyCase("fDeform")->FindFloatValue();
|
||
|
}
|
||
|
|
||
|
//cutsceneDebugf1("%s CCutsceneAnimatedVehicleEntity:CUTSCENE_SET_VEHICLE_DAMAGE_EVENT pos: x:%f, y:%f, z:%f, ", pObject->GetDisplayName(), )
|
||
|
SetVehicleDamage(vDamage,fDamage,fDeform, true);
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
CCutsceneAnimatedModelEntity::DispatchEvent(pManager, pObject, iEventId, pEventArgs);
|
||
|
}
|
||
|
|
||
|
void CCutsceneAnimatedVehicleEntity::ForceUpdateAi(cutsManager* pManager)
|
||
|
{
|
||
|
if(pManager)
|
||
|
{
|
||
|
CutSceneManager* pCutSceneManager = static_cast<CutSceneManager*> (pManager);
|
||
|
|
||
|
if(pCutSceneManager->GetShutDownMode() != SHUTDOWN_SESSION)
|
||
|
{
|
||
|
CVehicle* pVeh = GetGameEntity();
|
||
|
if (pVeh && pVeh->GetIntelligence() && pVeh->GetIntelligence()->GetTaskManager() && GetCutsceneTaskForEntity())
|
||
|
{
|
||
|
// TODO - Update the vehicle a.i. properly if we find we need to cross blend between vehicle anims, etc
|
||
|
// For now lets just get rid of the cutscene task.
|
||
|
pVeh->GetIntelligence()->GetTaskManager()->ClearTask(VEHICLE_TASK_TREE_SECONDARY, VEHICLE_TASK_SECONDARY_ANIM);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
};
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
void CCutsceneAnimatedVehicleEntity::PlayClip (CutSceneManager* pCutManager, const crClip* pClip, float fEventTime, const strStreamingObjectName UNUSED_PARAM(pAnimDict))
|
||
|
{
|
||
|
if (GetGameEntity())
|
||
|
{
|
||
|
if(!m_pCutSceneTask)
|
||
|
{
|
||
|
// Ready the vehicle for animation
|
||
|
GetGameEntity()->SetFixedPhysics(true);
|
||
|
GetGameEntity()->m_nVehicleFlags.bAnimateWheels = true;
|
||
|
GetGameEntity()->m_nVehicleFlags.bAnimatePropellers = true;
|
||
|
GetGameEntity()->m_nVehicleFlags.bAnimateJoints = true;
|
||
|
CVehicleAILodManager::DisableTimeslicingImmediately(*GetGameEntity());
|
||
|
GetGameEntity()->InitAnimLazy();
|
||
|
|
||
|
GetGameEntity()->SetDriveMusclesToAnimation(true);
|
||
|
m_pCutSceneTask = CreateCutsceneTask(pCutManager, pClip, fEventTime);
|
||
|
GetGameEntity()->GetIntelligence()->GetTaskManager()->GetTree(VEHICLE_TASK_TREE_SECONDARY)->SetTask(m_pCutSceneTask, VEHICLE_TASK_SECONDARY_ANIM);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if(cutsceneVerifyf(m_pCutSceneTask->GetTaskType() == CTaskTypes::TASK_CUTSCENE, "Trying to set the clip on a CTaskCutscene, but entity %s is not running a cutscene task", m_pCutfObject->GetDisplayName().c_str()))
|
||
|
{
|
||
|
Matrix34 SceneMat;
|
||
|
pCutManager->GetSceneOrientationMatrix(SceneMat);
|
||
|
m_pCutSceneTask->SetClip(pClip,SceneMat, fEventTime);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
SetAnimPlayBackEventTime(fEventTime);
|
||
|
}
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////
|
||
|
//Restore a vehicle to a previous setting
|
||
|
|
||
|
void CCutsceneAnimatedVehicleEntity::RestoreEntityProperties(CEntity* UNUSED_PARAM(pEnt))
|
||
|
{
|
||
|
SetVariation(m_sVehicleData.iBodyColour, m_sVehicleData.iSecondColour, m_sVehicleData.iSpecColour, m_sVehicleData.iWheelColour, m_sVehicleData.iBodyColour5, m_sVehicleData.iBodyColour6,
|
||
|
m_sVehicleData.iLiveryId, m_sVehicleData.iLivery2Id, m_sVehicleData.fDirt);
|
||
|
|
||
|
if(m_sVehicleData.HiddenBones.GetCount() > 0 )
|
||
|
{
|
||
|
if(GetGameEntity())
|
||
|
{
|
||
|
SetGameVehicleExtra(m_sVehicleData.HiddenBones);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
void CCutsceneAnimatedVehicleEntity::SetVariation(int iBodyColour, int iSecondColour, int iSpecColour, int iWheelColour, int iBodyColour5, int iBodyColour6, int LiveryId, int Livery2Id, float fDirt)
|
||
|
{
|
||
|
//store the variation for later use if we delete and need to recreate the vehicle
|
||
|
m_sVehicleData.iBodyColour = iBodyColour;
|
||
|
m_sVehicleData.iSecondColour = iSecondColour;
|
||
|
m_sVehicleData.iSpecColour = iSpecColour;
|
||
|
m_sVehicleData.iWheelColour = iWheelColour;
|
||
|
m_sVehicleData.iBodyColour5 = iBodyColour5;
|
||
|
m_sVehicleData.iBodyColour6 = iBodyColour6;
|
||
|
m_sVehicleData.iLiveryId = LiveryId;
|
||
|
m_sVehicleData.iLivery2Id = Livery2Id;
|
||
|
m_sVehicleData.fDirt = fDirt;
|
||
|
|
||
|
if(GetGameEntity())
|
||
|
{
|
||
|
GetGameEntity()->SetBodyColour1( static_cast<u8>(iBodyColour) );
|
||
|
GetGameEntity()->SetBodyColour2( static_cast<u8>(iSecondColour) );
|
||
|
GetGameEntity()->SetBodyColour3( static_cast<u8>(iSpecColour));
|
||
|
GetGameEntity()->SetBodyColour4( static_cast<u8>(iWheelColour) );
|
||
|
GetGameEntity()->SetBodyColour5( static_cast<u8>(iBodyColour5) );
|
||
|
GetGameEntity()->SetBodyColour6( static_cast<u8>(iBodyColour6) );
|
||
|
GetGameEntity()->SetLiveryId(LiveryId);
|
||
|
GetGameEntity()->SetLivery2Id(Livery2Id);
|
||
|
GetGameEntity()->SetBodyDirtLevel(fDirt);
|
||
|
GetGameEntity()->UpdateBodyColourRemapping();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////
|
||
|
//Game side vehicles have a hierarchy that describes various components, need to map our bone ids to its hierachy
|
||
|
|
||
|
void CCutsceneAnimatedVehicleEntity::SetGameVehicleExtra(const atArray<s32>& Bones)
|
||
|
{
|
||
|
//store the variation for later use if we delete and need to recreate the vehicle for streaming.
|
||
|
m_sVehicleData.HiddenBones.Reset();
|
||
|
for (int i =0; i < Bones.GetCount(); i++)
|
||
|
{
|
||
|
m_sVehicleData.HiddenBones.PushAndGrow(Bones[i]);
|
||
|
}
|
||
|
|
||
|
//m_sVehicleData.HiddenBones.CopyFrom(Bones, Bones.GetCount());
|
||
|
|
||
|
//have reserved the first array to be 0 if extras have been reactivated
|
||
|
if(Bones.GetCount()> 0 && Bones[0] != 0)
|
||
|
{
|
||
|
//Reactivate any previous turned off bones
|
||
|
for(int i=0; i < 10; i ++)
|
||
|
{
|
||
|
int VehicleHeirachy = i + VEH_EXTRA_1;
|
||
|
bool bReactivateExtra = true;
|
||
|
|
||
|
if (!GetGameEntity()->GetIsExtraOn(((eHierarchyId)VehicleHeirachy))) //extra is off do we need ot turn it off or is it on the list.
|
||
|
{
|
||
|
//look through our list of bones
|
||
|
for(int i = 0; i < Bones.GetCount(); i++ )
|
||
|
{
|
||
|
s32 iMappedNewBoneId = (Bones[i] - VEHICLE_HEIRACHY_MODIFIER) + (VEH_EXTRA_1 - 1);
|
||
|
//if its on our list already, leave it.
|
||
|
if(VehicleHeirachy == iMappedNewBoneId )
|
||
|
{
|
||
|
bReactivateExtra = false;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (bReactivateExtra)
|
||
|
{
|
||
|
GetGameEntity()->TurnOffExtra(((eHierarchyId)VehicleHeirachy), false );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//Turn off any bones on our list
|
||
|
for(int i = 0; i < Bones.GetCount(); i++ )
|
||
|
{
|
||
|
s32 iBoneId = Bones[i]; //store the bone id
|
||
|
|
||
|
//remap to the heirchy- iboneids are u16hash of the bone name, starting at extra_1
|
||
|
//VEHICLE_HEIRACHY_MODIFIER is the hash of extra_0 so we subtract to get 1, 2, 3 etc
|
||
|
//and add to a zeroed VEH_EXTRA_X
|
||
|
int iMappedNewBoneId = (iBoneId - VEHICLE_HEIRACHY_MODIFIER) + (VEH_EXTRA_1 - 1);
|
||
|
if (GetGameEntity()->GetIsExtraOn(((eHierarchyId)iMappedNewBoneId)))
|
||
|
{
|
||
|
GetGameEntity()->TurnOffExtra(((eHierarchyId)iMappedNewBoneId), true );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
//Careful: reactivating vehicle extras actually repairs the whole vehicle
|
||
|
for(int i=0; i < 10; i ++)
|
||
|
{
|
||
|
int VehicleHeirachy = i + VEH_EXTRA_1;
|
||
|
if (!GetGameEntity()->GetIsExtraOn(((eHierarchyId)VehicleHeirachy)))
|
||
|
{
|
||
|
GetGameEntity()->TurnOffExtra(((eHierarchyId)VehicleHeirachy), false);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
};
|
||
|
|
||
|
void CCutsceneAnimatedVehicleEntity::SetVehicleDamage(const Vector3& scrVecDamage, float damageAmount, float deformationScale, bool localDamage)
|
||
|
{
|
||
|
CVehicle *pVehicle = GetGameEntity();
|
||
|
|
||
|
if (pVehicle)
|
||
|
{
|
||
|
const Vector3 passedPos(scrVecDamage);
|
||
|
Vector3 impactPos = passedPos;
|
||
|
if( localDamage )
|
||
|
{
|
||
|
impactPos = pVehicle->TransformIntoWorldSpace(impactPos);
|
||
|
}
|
||
|
|
||
|
Vector3 impactImpulse = -passedPos;
|
||
|
impactImpulse.Normalize();
|
||
|
|
||
|
Vector3 normalizedImpulse = impactImpulse;
|
||
|
|
||
|
impactImpulse *= damageAmount;
|
||
|
if( localDamage )
|
||
|
{
|
||
|
impactImpulse = VEC3V_TO_VECTOR3(pVehicle->GetTransform().Transform3x3(VECTOR3_TO_VEC3V(impactImpulse)));
|
||
|
}
|
||
|
|
||
|
// Deformation
|
||
|
pVehicle->GetVehicleDamage()->GetDeformation()->ApplyCollisionImpact(impactImpulse*deformationScale, impactPos, NULL);
|
||
|
|
||
|
// Damage
|
||
|
pVehicle->GetVehicleDamage()->ApplyDamage(NULL,DAMAGE_TYPE_UNKNOWN, 0, damageAmount, impactPos, normalizedImpulse, -normalizedImpulse, 0);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
void CCutsceneAnimatedVehicleEntity::CreateGameEntity(strLocalIndex iModelIndex, bool CreateRepositionEntity, bool UNUSED_PARAM(bRequestVariations), bool UNUSED_PARAM(bApplyVariations))
|
||
|
{
|
||
|
if(GetGameEntity() == NULL)
|
||
|
{
|
||
|
cutsceneModelEntityDebugf2("CreateGameEntity - Vehicle");
|
||
|
|
||
|
CBaseModelInfo* pModelInfo = CModelInfo::GetBaseModelInfo(fwModelId(iModelIndex));
|
||
|
if(pModelInfo)
|
||
|
{
|
||
|
cutsceneAssertf(pModelInfo->GetModelType() == MI_TYPE_VEHICLE, "CUTSCENE ASSET (Assign to *Default Anim Cutscene*): Exported incorrectly, %s is not a VehicleModel type", pModelInfo->GetModelName());
|
||
|
if(pModelInfo->GetModelType() == MI_TYPE_VEHICLE)
|
||
|
{
|
||
|
Matrix34 TempMat;
|
||
|
|
||
|
TempMat.Identity();
|
||
|
TempMat.d = m_vCreatePos;
|
||
|
|
||
|
const CControlledByInfo localAiControl(false, false);
|
||
|
fwModelId modelId(iModelIndex);
|
||
|
CVehicle* pVehicle = CVehicleFactory::GetFactory()->Create(modelId, ENTITY_OWNEDBY_CUTSCENE, POPTYPE_MISSION, &TempMat, false);
|
||
|
|
||
|
if (Verifyf(pVehicle, "trying to store a null ped pointer something has gone wrong with the registration"))
|
||
|
{
|
||
|
//store the vehicle pointer
|
||
|
if(CreateRepositionEntity)
|
||
|
{
|
||
|
SetRepositionOnlyEntity(pVehicle);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
SetGameEntity(pVehicle);
|
||
|
}
|
||
|
|
||
|
if(pVehicle)
|
||
|
{
|
||
|
pVehicle->SetIsAbandoned();
|
||
|
pVehicle->m_nPhysicalFlags.bNotDamagedByAnything = true;
|
||
|
|
||
|
CGameWorld::Add(pVehicle, CGameWorld::OUTSIDE);
|
||
|
pVehicle->SetFixedPhysics(true);
|
||
|
pVehicle->GetPortalTracker()->RequestRescanNextUpdate();
|
||
|
|
||
|
pVehicle->GetPortalTracker()->SetIsCutsceneControlled(true);
|
||
|
|
||
|
pVehicle->m_nDEflags.bForcePrePhysicsAnimUpdate = true;
|
||
|
|
||
|
if (pVehicle->GetVehicleType() == VEHICLE_TYPE_TRAIN)
|
||
|
{
|
||
|
((CTrain*)pVehicle)->m_nTrainFlags.bIsCutsceneControlled = true;
|
||
|
}
|
||
|
m_bCreatedByCutscene = true;
|
||
|
|
||
|
//if (bApplyVariations)
|
||
|
//{
|
||
|
// Apply the current variations
|
||
|
//RestoreEntityProperties(pVehicle);
|
||
|
//}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CCutsceneAnimatedVehicleEntity::HideVehicleFragmentComponent()
|
||
|
{
|
||
|
if(GetCutfObject() && GetGameEntity())
|
||
|
{
|
||
|
if(m_pCutfObject->GetType() == CUTSCENE_MODEL_OBJECT_TYPE)
|
||
|
{
|
||
|
const cutfModelObject* pModel = static_cast<const cutfModelObject*>(m_pCutfObject);
|
||
|
|
||
|
if(pModel->GetModelType() == CUTSCENE_VEHICLE_MODEL_TYPE)
|
||
|
{
|
||
|
const cutfVehicleModelObject* pModelObject = static_cast<const cutfVehicleModelObject*>(m_pCutfObject);
|
||
|
|
||
|
if(pModelObject->GetRemoveBoneNameList().GetCount() > 0)
|
||
|
{
|
||
|
for (int i = 0; i < pModelObject->GetRemoveBoneNameList().GetCount(); i++)
|
||
|
{
|
||
|
const crBoneData* pBoneData = GetGameEntity()->GetSkeletonData().FindBoneData(pModelObject->GetRemoveBoneNameList()[i].c_str());
|
||
|
|
||
|
if(pBoneData)
|
||
|
{
|
||
|
int BoneIndex = pBoneData->GetIndex();
|
||
|
|
||
|
CVehicleModelInfo* pModel = GetGameEntity()->GetVehicleModelInfo();
|
||
|
|
||
|
if(pModel)
|
||
|
{
|
||
|
CVehicleStructure* pVehicleStruct = pModel->GetStructure();
|
||
|
|
||
|
if(pVehicleStruct)
|
||
|
{
|
||
|
for(int j=0; j < VEH_NUM_NODES; j++)
|
||
|
{
|
||
|
if (pVehicleStruct->m_nBoneIndices[j] == BoneIndex)
|
||
|
{
|
||
|
eHierarchyId HeirarchyId = (eHierarchyId)j;
|
||
|
|
||
|
if(GetGameEntity()->HasFragmentComponent(HeirarchyId))
|
||
|
{
|
||
|
GetGameEntity()->RemoveFragmentComponent(HeirarchyId);
|
||
|
cutsceneModelEntityDebugf2("HideVehicleFragmentComponent: Removing component %s from vehicle", pModelObject->GetRemoveBoneNameList()[i].c_str());
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
cutsceneModelEntityDebugf2("HideVehicleFragmentComponent: Couldn't remove component %s, it may have already been removed", pModelObject->GetRemoveBoneNameList()[i].c_str());
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
void CCutsceneAnimatedVehicleEntity::SetGameEntityReadyForCutscene()
|
||
|
{
|
||
|
if(GetGameEntity())
|
||
|
{
|
||
|
#if !__NO_OUTPUT
|
||
|
SetUpEntityForCallStackLogging();
|
||
|
#endif
|
||
|
|
||
|
GetGameEntity()->SetOwnedBy(ENTITY_OWNEDBY_CUTSCENE);
|
||
|
GetGameEntity()->SetFixedPhysics(true);
|
||
|
GetGameEntity()->m_nPhysicalFlags.bNotDamagedByAnything = true;
|
||
|
GetGameEntity()->m_nDEflags.bForcePrePhysicsAnimUpdate = true;
|
||
|
GetGameEntity()->DisableCollision();
|
||
|
GetGameEntity()->ResetSuspension();
|
||
|
GetGameEntity()->SetForceHd(true);
|
||
|
CVehicleRecordingMgr::StopPlaybackRecordedCar(GetGameEntity());
|
||
|
HideVehicleFragmentComponent();
|
||
|
|
||
|
if (m_OptionFlags.IsFlagSet(CEO_IS_CASCADE_SHADOW_FOCUS_ENTITY_DURING_EXIT) && CutSceneManager::GetInstance() && CutSceneManager::GetInstance()->GetCamEntity())
|
||
|
{
|
||
|
// Register this with the camera
|
||
|
CCutSceneCameraEntity* pCam = const_cast<CCutSceneCameraEntity*>(CutSceneManager::GetInstance()->GetCamEntity());
|
||
|
if (pCam)
|
||
|
{
|
||
|
pCam->SetCascadeShadowFocusEntityForSeamlessExit(GetGameEntity());
|
||
|
}
|
||
|
}
|
||
|
|
||
|
NetworkInterface::CutsceneStartedOnEntity(*GetGameEntity());
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CCutsceneAnimatedVehicleEntity::SetRepositionOnlyEntityReadyForCutscene()
|
||
|
{
|
||
|
if(GetGameRepositionOnlyEntity())
|
||
|
{
|
||
|
cutsceneModelEntityDebugf2("SetRepositionOnlyEntityReadyForCutscene - Vehicle");
|
||
|
GetGameRepositionOnlyEntity()->m_nPhysicalFlags.bNotDamagedByAnything = true;
|
||
|
GetGameRepositionOnlyEntity()->SetIsVisibleForModule(SETISVISIBLE_MODULE_CUTSCENE, false);
|
||
|
cutsceneModelEntityDebugf2("CCutsceneAnimatedVehicleEntity::SetRepositionOnlyEntityReadyForCutscene: Hiding GetGameRepositionOnlyEntity (%s)", GetGameRepositionOnlyEntity()->GetModelName());
|
||
|
|
||
|
NetworkInterface::CutsceneStartedOnEntity(*GetGameRepositionOnlyEntity());
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CCutsceneAnimatedVehicleEntity::SetGameEntityReadyForGame(cutsManager* UNUSED_PARAM(pManager))
|
||
|
{
|
||
|
if(!m_bIsReadyForGame)
|
||
|
{
|
||
|
if(GetGameEntity())
|
||
|
{
|
||
|
NetworkInterface::CutsceneFinishedOnEntity(*GetGameEntity());
|
||
|
|
||
|
#if !__NO_OUTPUT
|
||
|
ResetEntityForCallStackLogging();
|
||
|
#endif
|
||
|
|
||
|
GetGameEntity()->SetLodMultiplier(m_fOriginalLODMultiplier);
|
||
|
|
||
|
cutsceneModelEntityDebugf2("CCutsceneAnimatedVehicleEntity::SetGameEntityReadyForGame - Vehicle");
|
||
|
if (GetGameEntity()->GetVehicleType() == VEHICLE_TYPE_TRAIN)
|
||
|
{
|
||
|
((CTrain*)GetGameEntity())->m_nTrainFlags.bIsCutsceneControlled = false;
|
||
|
}
|
||
|
|
||
|
bool canEnableCollision = true;
|
||
|
if(NetworkInterface::IsGameInProgress() && GetGameEntity()->GetNetworkObject())
|
||
|
{
|
||
|
canEnableCollision = !SafeCast(CNetObjPhysical, GetGameEntity()->GetNetworkObject())->GetKeepCollisionDisabledAfterAnimScene();
|
||
|
}
|
||
|
|
||
|
if(canEnableCollision)
|
||
|
{
|
||
|
GetGameEntity()->EnableCollision();
|
||
|
}
|
||
|
|
||
|
GetGameEntity()->SetForceHd(false);
|
||
|
GetGameEntity()->SetFixedPhysics(false);
|
||
|
GetGameEntity()->m_nVehicleFlags.bAnimateWheels = false;
|
||
|
GetGameEntity()->m_nVehicleFlags.bAnimatePropellers = false;
|
||
|
GetGameEntity()->m_nVehicleFlags.bAnimateJoints = false;
|
||
|
GetGameEntity()->m_nPhysicalFlags.bNotDamagedByAnything = m_bWasInvincible;
|
||
|
GetGameEntity()->m_nDEflags.bForcePrePhysicsAnimUpdate = false;
|
||
|
GetGameEntity()->SetDriveMusclesToAnimation(false);
|
||
|
|
||
|
if(!GetGameEntity()->m_nVehicleFlags.bUseCutsceneWheelCompression)
|
||
|
{
|
||
|
GetGameEntity()->PlaceOnRoadAdjust();
|
||
|
}
|
||
|
|
||
|
if(GetGameEntity()->InheritsFromTrailer())
|
||
|
{
|
||
|
//Need to enforce constraint limits on trailers to avoid pops
|
||
|
GetGameEntity()->ActivatePhysics();
|
||
|
}
|
||
|
|
||
|
bool CanDelete = m_RegisteredEntityFromScript.pEnt != GetGameEntity();
|
||
|
|
||
|
if(CanDelete|| m_RegisteredEntityFromScript.bDeleteBeforeEnd)
|
||
|
{
|
||
|
GetGameEntity()->SetOwnedBy(ENTITY_OWNEDBY_TEMP);
|
||
|
GetGameEntity()->PopTypeSet(POPTYPE_RANDOM_AMBIENT);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
GetGameEntity()->SetOwnedBy(ENTITY_OWNEDBY_SCRIPT);
|
||
|
SetVisibility(GetGameEntity(), true);
|
||
|
cutsceneModelEntityDebugf3("CCutsceneAnimatedVehicleEntity::SetGameEntityReadyForGame1: Showing GetGameEntity (%s)", GetGameEntity()->GetModelName());
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if(GetGameRepositionOnlyEntity())
|
||
|
{
|
||
|
cutsceneModelEntityDebugf2("SetGameEntityReadyForGame - Vehicle (reposition only");
|
||
|
GetGameRepositionOnlyEntity()->SetLodMultiplier(m_fOriginalLODMultiplier);
|
||
|
GetGameRepositionOnlyEntity()->SetHeading(m_CurrentHeading);
|
||
|
GetGameRepositionOnlyEntity()->SetPosition(m_CurrentPosition);
|
||
|
GetGameRepositionOnlyEntity()->SetFixedPhysics(false);
|
||
|
GetGameRepositionOnlyEntity()->m_nPhysicalFlags.bNotDamagedByAnything = m_bWasInvincible;
|
||
|
GetGameRepositionOnlyEntity()->SetIsVisibleForModule(SETISVISIBLE_MODULE_CUTSCENE, true);
|
||
|
cutsceneModelEntityDebugf2("CCutsceneAnimatedVehicleEntity::SetGameEntityReadyForGame2: Showing GetGameRepositionOnlyEntity (%s)", GetGameRepositionOnlyEntity()->GetModelName());
|
||
|
GetGameRepositionOnlyEntity()->m_nDEflags.bForcePrePhysicsAnimUpdate = false;
|
||
|
}
|
||
|
|
||
|
if (m_pCutSceneTask)
|
||
|
{
|
||
|
m_pCutSceneTask->SetExitNextUpdate();
|
||
|
}
|
||
|
|
||
|
m_bIsReadyForGame = true;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
void CCutsceneAnimatedVehicleEntity::SetupSuspension()
|
||
|
{
|
||
|
for(int i = 0; i < GetGameEntity()->GetNumWheels(); i++)
|
||
|
{
|
||
|
CWheel *pWheel = GetGameEntity()->GetWheel(i);
|
||
|
pWheel->UpdateSuspension(NULL, false);
|
||
|
}
|
||
|
|
||
|
if(GetGameEntity()->GetCurrentPhysicsInst() && CPhysics::GetLevel()->IsInactive(GetGameEntity()->GetCurrentPhysicsInst()->GetLevelIndex()))
|
||
|
{
|
||
|
fragInstGta * pVehicleFragInst = GetGameEntity()->GetVehicleFragInst();
|
||
|
if(pVehicleFragInst && pVehicleFragInst->GetCacheEntry() && pVehicleFragInst->GetCacheEntry()->GetHierInst() &&
|
||
|
pVehicleFragInst->GetCacheEntry()->GetHierInst()->articulatedCollider)
|
||
|
{
|
||
|
GetGameEntity()->GetVehicleFragInst()->GetCacheEntry()->GetHierInst()->articulatedCollider->SetColliderMatrixFromInstance();
|
||
|
}
|
||
|
}
|
||
|
GetGameEntity()->GetVehicleFragInst()->SyncSkeletonToArticulatedBody(true);
|
||
|
}
|
||
|
|
||
|
void CCutsceneAnimatedVehicleEntity::UpdateCutSceneTask(cutsManager* pManager)
|
||
|
{
|
||
|
if(GetGameEntity() && GetGameEntity()->GetIntelligence())
|
||
|
{
|
||
|
aiTask* CurrentVehicleTask = GetGameEntity()->GetIntelligence()->GetTaskManager()->GetTree(VEHICLE_TASK_TREE_SECONDARY)->GetTask(VEHICLE_TASK_SECONDARY_ANIM);
|
||
|
|
||
|
if(CurrentVehicleTask && CurrentVehicleTask->GetTaskType() == CTaskTypes::TASK_CUTSCENE)
|
||
|
{
|
||
|
CTask* pTask = static_cast<CTask*>(CurrentVehicleTask);
|
||
|
UpdateCutSceneTaskPhase(pTask, pManager);
|
||
|
|
||
|
// Update vehicle velocity
|
||
|
if (!m_bStoppedCalled)
|
||
|
{
|
||
|
CTaskCutScene* pCutSceneTask = static_cast<CTaskCutScene*>(pTask);
|
||
|
const crClip* pClip = pCutSceneTask->GetClip();
|
||
|
|
||
|
if (pClip)
|
||
|
{
|
||
|
CutSceneManager* pCutsManager = static_cast<CutSceneManager*>(pManager);
|
||
|
|
||
|
float fPhase = pCutsManager->GetPhaseUpdateAmount(pClip, GetAnimEventStartTime());
|
||
|
float fLastPhase = pCutsManager->GetAnimPhaseForSection(pClip->GetDuration(),GetAnimEventStartTime(), pCutsManager->GetCutScenePreviousTime());
|
||
|
|
||
|
const float time = pClip->ConvertPhaseToTime(fPhase);
|
||
|
const float timeOnPreviousUpdate = pClip->ConvertPhaseToTime(fLastPhase);
|
||
|
bool bIsWarpFrame = pClip->CalcBlockPassed(timeOnPreviousUpdate, time);
|
||
|
|
||
|
const float fCurrentTimeStep = pCutsManager->GetCurrentCutSceneTimeStep();
|
||
|
|
||
|
if (bIsWarpFrame || fCurrentTimeStep <= 0.0001f)
|
||
|
{
|
||
|
GetGameEntity()->SetVelocity(VEC3_ZERO);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
Vector3 vehVelocity(VEC3_ZERO);
|
||
|
Vector3 vehDistance = fwAnimHelpers::GetMoverTrackTranslationDiff(*pClip, fLastPhase, fPhase);
|
||
|
vehVelocity = vehDistance/fCurrentTimeStep;
|
||
|
|
||
|
pCutSceneTask->GetAnimOrigin().Transform3x3(vehVelocity);
|
||
|
|
||
|
#if __ASSERT
|
||
|
if (vehVelocity.Mag2() > 62500.0f)
|
||
|
{
|
||
|
cutsceneAssertf(0, "Cutscene vehicle (%s) velocity is > 250 ms-1. Moved distance (%.2f, %.2f, %.2f) meters in %6.4f seconds\n", GetGameEntity()->GetModelName(), vehDistance.x, vehDistance.y, vehDistance.z, fCurrentTimeStep);
|
||
|
}
|
||
|
#endif //__ASSERT
|
||
|
|
||
|
GetGameEntity()->SetVelocity( vehVelocity );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////
|
||
|
//Allow for manual adding and subtraction of bones
|
||
|
|
||
|
#if __BANK
|
||
|
void CCutsceneAnimatedVehicleEntity::SetBoneToHide(s32 Boneid, bool bHide)
|
||
|
{
|
||
|
for(int i=0; i < m_HiddenBones.GetCount(); i++)
|
||
|
{
|
||
|
if(m_HiddenBones[i] == Boneid )
|
||
|
{
|
||
|
if(!bHide)
|
||
|
{
|
||
|
m_HiddenBones.Delete(i);
|
||
|
}
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
m_HiddenBones.PushAndGrow(Boneid);
|
||
|
}
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////
|
||
|
//When debugging a real vehicle find the extras that are already switched off.
|
||
|
|
||
|
void CCutsceneAnimatedVehicleEntity::InitaliseVehicleExtraList()
|
||
|
{
|
||
|
if(GetGameEntity())
|
||
|
{
|
||
|
for(int i=0; i < 10; i ++)
|
||
|
{
|
||
|
int VehicleHeirachy = i + VEH_EXTRA_1;
|
||
|
if (!GetGameEntity()->GetIsExtraOn(((eHierarchyId)VehicleHeirachy)))
|
||
|
{
|
||
|
m_HiddenBones.PushAndGrow((VEHICLE_HEIRACHY_MODIFIER+1) + i );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
// Rayfire
|
||
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
CCutSceneRayFireEntity::CCutSceneRayFireEntity(const cutfObject* pObject)
|
||
|
: cutsUniqueEntity(pObject)
|
||
|
{
|
||
|
m_fEventTime = 0.0f;
|
||
|
m_iRayFireId = -1;
|
||
|
}
|
||
|
|
||
|
CCutSceneRayFireEntity::~CCutSceneRayFireEntity()
|
||
|
{
|
||
|
if (m_iRayFireId>-1)
|
||
|
{
|
||
|
CCompEntity* pCompEntity = CCompEntity::GetPool()->GetAt(m_iRayFireId);
|
||
|
|
||
|
if (pCompEntity)
|
||
|
{
|
||
|
pCompEntity->SetIsCutsceneDriven(false);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
m_iRayFireId = -1;
|
||
|
}
|
||
|
|
||
|
void CCutSceneRayFireEntity::DispatchEvent(cutsManager* pManager, const cutfObject* pObject, s32 iEventId, const cutfEventArgs* UNUSED_PARAM(pEventArgs), const float fTime, const u32 UNUSED_PARAM(StickyId))
|
||
|
{
|
||
|
switch ( iEventId )
|
||
|
{
|
||
|
case CUTSCENE_START_OF_SCENE_EVENT:
|
||
|
{
|
||
|
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case CUTSCENE_PAUSE_EVENT:
|
||
|
case CUTSCENE_UPDATE_EVENT:
|
||
|
{
|
||
|
if(m_iRayFireId > -1 )
|
||
|
{
|
||
|
CCompEntity* pCompEntity = CCompEntity::GetPool()->GetAt(m_iRayFireId);
|
||
|
|
||
|
if(pCompEntity && pCompEntity->GetPrimaryAnimatedObject())
|
||
|
{
|
||
|
if(object_commands::CommandGetCompositeEntityState(m_iRayFireId) == CE_STATE_ANIMATING)
|
||
|
{
|
||
|
CObject* pObj = pCompEntity->GetPrimaryAnimatedObject();
|
||
|
|
||
|
if(cutsceneVerifyf(pObj, "CUTSCENE_UPDATE_EVENT: Component entity failed to create the animated rayfire object: %s", pObj->GetModelName()))
|
||
|
{
|
||
|
if(cutsceneVerifyf(pObj->GetAnimDirector(), "CUTSCENE_UPDATE_EVENT: Rayfire object %s has failed to create an anim director", pObj->GetModelName()))
|
||
|
{
|
||
|
CMoveObject& move = pObj->GetMoveObject();
|
||
|
|
||
|
const crClip* pClip = move.GetClipHelper().GetClip();
|
||
|
|
||
|
CutSceneManager* pCutSceneManager = static_cast<CutSceneManager*>(pManager);
|
||
|
|
||
|
if(pClip)
|
||
|
{
|
||
|
float fPhase = pCutSceneManager->GetAnimPhaseForSection(pClip->GetDuration(), m_fEventTime, pCutSceneManager->GetCutSceneCurrentTime() );
|
||
|
pCompEntity->SetIsCutsceneDriven(true);
|
||
|
move.GetClipHelper().SetRate(0.0f);
|
||
|
move.GetClipHelper().SetPhase(fPhase);
|
||
|
for(u32 i=1; i<pCompEntity->GetChildObjects().GetCount(); i++){
|
||
|
if (pCompEntity->GetChild(i)){
|
||
|
CMoveObject& move = pCompEntity->GetChild(i)->GetMoveObject();
|
||
|
move.GetClipHelper().SetRate(0.0f);
|
||
|
move.GetClipHelper().SetPhase(fPhase);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
case CUTSCENE_SET_ANIM_EVENT:
|
||
|
{
|
||
|
CutSceneManager* pCutSceneManager = static_cast<CutSceneManager*>(pManager);
|
||
|
|
||
|
CCutSceneAssetMgrEntity* pAssetManager = pCutSceneManager->GetAssetManager();
|
||
|
|
||
|
s32 iIndex = pAssetManager->GetGameIndex(pObject->GetObjectId());
|
||
|
|
||
|
if(iIndex > -1)
|
||
|
{
|
||
|
if(object_commands::CommandGetCompositeEntityState(iIndex) != 0 )
|
||
|
{
|
||
|
if(object_commands::CommandGetCompositeEntityState(iIndex) == CE_STATE_PRIMED)
|
||
|
{
|
||
|
object_commands::CommandSetCompositeEntityState(iIndex, CE_STATE_START_ANIM);
|
||
|
|
||
|
CCompEntity* pCompEntity = CCompEntity::GetPool()->GetAt(iIndex);
|
||
|
|
||
|
//calling update to make sure we create the anim director
|
||
|
pCompEntity->Update();
|
||
|
|
||
|
if(pCompEntity && pCompEntity->GetPrimaryAnimatedObject())
|
||
|
{
|
||
|
CObject* pObj = pCompEntity->GetPrimaryAnimatedObject();
|
||
|
if(cutsceneVerifyf(pObj, "CUTSCENE_SET_ANIM_EVENT: Component entity failed to create the animated rayfire object: %s", pObj->GetModelName()))
|
||
|
{
|
||
|
if(cutsceneVerifyf(pObj->GetAnimDirector(), "CUTSCENE_SET_ANIM_EVENT: Rayfire object %s has failed to create an anim director", pObj->GetModelName()))
|
||
|
{
|
||
|
CMoveObject& move = pObj->GetMoveObject();
|
||
|
|
||
|
const crClip* pClip = move.GetClipHelper().GetClip();
|
||
|
|
||
|
CutSceneManager* pCutSceneManager = static_cast<CutSceneManager*>(pManager);
|
||
|
m_fEventTime = fTime;
|
||
|
|
||
|
if(pClip)
|
||
|
{
|
||
|
//m_HaveAnimToUpdate = true;
|
||
|
float fPhase = pCutSceneManager->GetAnimPhaseForSection(pClip->GetDuration(), m_fEventTime, pCutSceneManager->GetCutSceneCurrentTime() );
|
||
|
move.GetClipHelper().SetRate(0.0f);
|
||
|
move.GetClipHelper().SetPhase(fPhase);
|
||
|
pCompEntity->SetIsCutsceneDriven(true);
|
||
|
|
||
|
for(u32 i=1; i<pCompEntity->GetChildObjects().GetCount(); i++){
|
||
|
if (pCompEntity->GetChild(i)){
|
||
|
CMoveObject& move = pCompEntity->GetChild(i)->GetMoveObject();
|
||
|
move.GetClipHelper().SetRate(0.0f);
|
||
|
move.GetClipHelper().SetPhase(fPhase);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
m_iRayFireId = pAssetManager->GetGameIndex(pObject->GetObjectId());
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
}
|