void CMPTrackViewManager::Client_SynchAnimationTimes(const CGameRules::STrackViewParameters& params) { IMovieSystem *pMovieSystem = gEnv->pMovieSystem; int numTrackViews = params.m_NumberOfTrackViews + params.m_NumberOfFinishedTrackViews; CryLog("CMPTrackViewManager::Client_SynchAnimationTimes() numTrackViews=%d; numFinishedTrackViews=%d", params.m_NumberOfTrackViews, params.m_NumberOfFinishedTrackViews); for(int i = 0; i < numTrackViews; ++i) { int trackviewHashId = params.m_Ids[i]; if(trackviewHashId == 0) continue; for(int k = 0; k < pMovieSystem->GetNumSequences(); ++k) { IAnimSequence* pSequence = pMovieSystem->GetSequence(k); CryHashStringId id(pSequence->GetName()); if(id == trackviewHashId) { float timeValue = params.m_Times[i]; // even finished sequences include their time now, to handle aborted sequences float currentTimeValue = pMovieSystem->GetPlayingTime(pSequence); CryLog("CMPTrackViewManager::Client_SynchAnimationTimes() Sequence %d %s at time %f", i, pSequence->GetName(), timeValue); if(pMovieSystem->IsPlaying(pSequence)) { // always update finished anims if( i>=params.m_NumberOfTrackViews || fabs(currentTimeValue - timeValue) > s_TrackViewMinTimeDifferenceForSynch) //If we are close enough don't update - avoid unnecessary jerking { pMovieSystem->SetPlayingTime(pSequence, timeValue); } } else { pMovieSystem->PlaySequence(pSequence, NULL, true, false, timeValue); if(params.m_bInitialData && i>=params.m_NumberOfTrackViews && m_FinishedTrackViewCount < CGameRules::STrackViewParameters::sMaxTrackViews) { m_FinishedTrackViews[m_FinishedTrackViewCount++] = id.id; } } if (i>=params.m_NumberOfTrackViews) { // this is a finished trackview, so having setup the correct playtime above, lets actually stop it like it should be CryLog("CMPTrackViewManager::Client_SynchAnimationTimes() Sequence %d %s is a finished trackview, stopping it", i, pSequence->GetName()); pMovieSystem->StopSequence(pSequence); } } } } }
IAnimSequence* CMPTrackViewManager::FindTrackviewSequence(int trackviewId) { IMovieSystem *pMovieSystem = gEnv->pMovieSystem; for(int i = 0; i < pMovieSystem->GetNumSequences(); ++i) { IAnimSequence* pSequence = pMovieSystem->GetSequence(i); CryHashStringId id(pSequence->GetName()); if(id == trackviewId) { return pSequence; } } return NULL; }
void CMPTrackViewManager::Update() { #ifndef _RELEASE if (g_pGameCVars->g_mptrackview_debug) { IMovieSystem *pMovieSystem = gEnv->pMovieSystem; int numSequences=pMovieSystem->GetNumSequences(); CryWatch("num finished trackviews=%d", m_FinishedTrackViewCount); for (int i=0; i<m_FinishedTrackViewCount; i++) { const char *foundName="NOT FOUND"; // SLOW IAnimSequence *foundSequence = FindTrackviewSequence(m_FinishedTrackViews[i]); if (foundSequence) { foundName = foundSequence->GetName(); } CryWatch("finished[%d] hash=%x; time=%f; foundName=%s", i, m_FinishedTrackViews[i], m_FinishedTrackViewTimes[i], foundName); } int numPlaying=pMovieSystem->GetNumPlayingSequences(); for(int i = 0; i < numPlaying; ++i) { IAnimSequence* pSequence = pMovieSystem->GetPlayingSequence(i); if( pSequence ) { const char *name=pSequence->GetName(); if (!name) { name = "[NULL]"; } CryHashStringId hash_id(pSequence->GetName()); float timeValue = pMovieSystem->GetPlayingTime(pSequence); CryWatch("Seq[%d]: name=%s; time=%f; hash=%x", i, name, timeValue, hash_id.id); } } } #endif }
void CCinematicInput::OnAction( const EntityId actorId, const ActionId& actionId, int activationMode, float value) { const CGameActions& gameActions = g_pGame->Actions(); if (actionId == gameActions.attack1_cine) { CWeapon* pPrimaryWeapon = GetWeapon( eWeapon_Primary ); if (pPrimaryWeapon != NULL) { pPrimaryWeapon->OnAction( actorId, actionId, activationMode, value ); } } else if (actionId == gameActions.attack2_cine) { CWeapon* pSecondaryWeapon = GetWeapon( eWeapon_Secondary ); if (pSecondaryWeapon != NULL) { pSecondaryWeapon->OnAction( actorId, actionId, activationMode, value ); } } else if (actionId == gameActions.skip_cutscene) { const int playingSequences = gEnv->pMovieSystem->GetNumPlayingSequences(); for (int i = 0; i < playingSequences; ++i) { IAnimSequence* pSeq = gEnv->pMovieSystem->GetPlayingSequence(i); if (pSeq && pSeq->GetFlags() & IAnimSequence::eSeqFlags_CutScene) { if (!(pSeq->GetFlags() & IAnimSequence::eSeqFlags_NoAbort)) { gEnv->pMovieSystem->SetPlayingTime(pSeq, pSeq->GetTimeRange().end); } } } } }
bool CEditorGame::BuildEntitySerializationList(XmlNodeRef output) { if(!output) return false; typedef std::vector<IFlowGraph*> TFGVector; TSerializationData entityData; // all entities TFGVector flowGraphs; // all flowgraphs // build the all-entity list, and keep a record of those entities // which have a flowgraph attached IEntityIt* pIt = gEnv->pEntitySystem->GetEntityIterator(); while(IEntity* pEntity = pIt->Next()) { IEntityFlowGraphProxy* pFGProxy = static_cast<IEntityFlowGraphProxy*>(pEntity->GetProxy(ENTITY_PROXY_FLOWGRAPH)); if(pFGProxy) { flowGraphs.push_back(pFGProxy->GetFlowGraph()); MarkEntityForSerialize(entityData, pEntity, eST_FlowGraphContainer); } if (!stricmp(pEntity->GetClass()->GetName(), "Constraint")) { MarkEntityForSerialize(entityData, pEntity, eST_Class); float constraintRadius = -FLT_MAX; if (IScriptTable* entityTable = pEntity->GetScriptTable()) { SmartScriptTable props; if (entityTable->GetValue("Properties", props)) props->GetValue("radius", constraintRadius); } if (constraintRadius > 0.0f) { const Vec3 boxMin = pEntity->GetWorldPos() - Vec3(constraintRadius + 0.05f); const Vec3 boxMax = pEntity->GetWorldPos() + Vec3(constraintRadius + 0.05f); IPhysicalEntity** nearbyEntities = 0; if (size_t entityCount = gEnv->pPhysicalWorld->GetEntitiesInBox(boxMin, boxMax, nearbyEntities, ent_all)) { for (size_t i = 0; i < entityCount; ++i) { if (IEntity* nearbyEntity = gEnv->pEntitySystem->GetEntityFromPhysics(nearbyEntities[i])) MarkEntityForSerialize(entityData, nearbyEntity, eST_ConstraintNeighbour); } } } else { CryLogAlways("Failed to find a value radius property for constraint '%s'. " "Serialization for this constraint might not work.", pEntity->GetName()); } } else if(ShouldSaveEntityClass(pEntity)) // some classes should always be saved MarkEntityForSerialize(entityData, pEntity, eST_Class); } // for each FG, mark all entities referenced as needing saving for(TFGVector::const_iterator it = flowGraphs.begin(); it != flowGraphs.end(); ++it) { if(!*it) continue; IFlowNodeIteratorPtr nodeIt = (*it)->CreateNodeIterator(); TFlowNodeId nodeId = 0; while(IFlowNodeData* pNode = nodeIt->Next(nodeId)) { EntityId nodeEntity = (*it)->GetEntityId(nodeId); if(nodeEntity != 0) { IEntity* pEntity = gEnv->pEntitySystem->GetEntity(nodeEntity); MarkEntityForSerialize(entityData, pEntity, eST_FlowGraph); } } } // now do the same for entities moved by trackview for(int i=0; i<gEnv->pMovieSystem->GetNumSequences(); ++i) { IAnimSequence* pSeq = gEnv->pMovieSystem->GetSequence(i); int nodeCount = pSeq->GetNodeCount(); for(int j=0; j<nodeCount; ++j) { IAnimNode* pNode = pSeq->GetNode(j); if(pNode) { IEntity* pEntity = pNode->GetEntity(); if(pEntity && ShouldSaveTrackViewEntityClass(pEntity)) { MarkEntityForSerialize(entityData, pEntity, eST_TrackView); } if(EntityGUID* guid = pNode->GetEntityGuid()) { EntityId id = gEnv->pEntitySystem->FindEntityByGuid(*guid); if(id != 0) { IEntity* pEntity2 = gEnv->pEntitySystem->GetEntity(id); MarkEntityForSerialize(entityData, pEntity2, eST_TrackView); } } } } } // now check entity links: any entity linked to or from a serialized // entity must also be serialized for(TSerializationData::iterator it = entityData.begin(), end = entityData.end(); it != end; ++it) { IEntity* pEntity = gEnv->pEntitySystem->GetEntity(it->first); assert(pEntity); IEntityLink* pLink = pEntity->GetEntityLinks(); while(pLink) { IEntity* pLinkedEntity = gEnv->pEntitySystem->GetEntity(pLink->entityId); assert(pLinkedEntity); MarkEntityForSerialize(entityData, pLinkedEntity, eST_Linked); pLink = pLink->next; } } // output the final file, plus debug info #if SERIALIZATION_EXPORT_DEBUG int saveCount = 0; int totalCount = 0; int fgCount = 0; int fgRefCount = 0; int classCount = 0; int tvCount = 0; int childCount = 0; int parentCount = 0; int linkCount = 0; int fgUnique = 0; int fgRefUnique = 0; int classUnique = 0; int tvUnique = 0; int linkUnique = 0; typedef std::map<string, int> TClassSaveInfo; TClassSaveInfo classesNotSaved; TClassSaveInfo classesSaved; #endif output->setTag("EntitySerialization"); for(TSerializationData::const_iterator it = entityData.begin(); it != entityData.end(); ++it) { IEntity* pEntity = gEnv->pEntitySystem->GetEntity(it->first); #if SERIALIZATION_EXPORT_DEBUG ++totalCount; string reasons = "Saving: "; #endif if(it->second != eST_NotSerialized) { XmlNodeRef child = output->createNode("Entity"); child->setAttr("id", it->first); //child->setAttr("class", pEntity->GetClass()->GetName()); // debug check //child->setAttr("name", pEntity->GetName()); // debug check output->addChild(child); #if SERIALIZATION_EXPORT_DEBUG classesSaved[pEntity->GetClass()->GetName()]++; ++saveCount; if(it->second & eST_FlowGraphContainer) { reasons += "FG Container; "; ++fgCount; } if(it->second & eST_FlowGraph) { reasons += "FG reference; "; ++fgRefCount; } if(it->second & eST_Class) { reasons += "Class; "; ++classCount; } if(it->second & eST_TrackView) { reasons += "Trackview; "; ++tvCount; } if(it->second & eST_Child) { reasons += "Child; "; ++childCount; } if(it->second & eST_Parent) { reasons += "Parent; "; ++parentCount; } if(it->second & eST_Linked) { reasons += "Linked; "; ++linkCount; } // unique counts (things added as a result of only one condition) switch(it->second) { case eST_FlowGraph: ++fgRefUnique; break; case eST_FlowGraphContainer: ++fgUnique; break; case eST_Class: ++classUnique; break; case eST_TrackView: ++tvUnique; break; case eST_Linked: ++linkUnique; break; default: break; } } else { reasons = "Not saving"; classesNotSaved[pEntity->GetClass()->GetName()]++; } CryLogAlways("Entity %s (%d, class %s) : %s", pEntity->GetName(), it->first, pEntity->GetClass()->GetName(), reasons.c_str()); #endif } }
void CMPTrackViewManager::Server_SynchAnimationTimes(CGameRules::STrackViewParameters& params) { IMovieSystem *pMovieSystem = gEnv->pMovieSystem; int count = 0; IAnimSequence* pSequence = NULL; CryLog("CMPTrackViewManager::Server_SynchAnimationTimes()"); for(int i = 0; i < CGameRules::STrackViewParameters::sMaxTrackViews; ++i) { if(i < pMovieSystem->GetNumPlayingSequences()) pSequence = pMovieSystem->GetPlayingSequence(i); else pSequence = NULL; if( pSequence ) { if (pSequence->GetFlags() & IAnimSequence::NO_MP_SYNCING_NEEDED) { CryLog("CMPTrackViewManager::Server_SynchAnimationTimes() skipping syncing of playing anim sequence %s (%s) as it has NO_MP_SYNCING_NEEDED flag set", pSequence->GetName(), pSequence->GetFullName()); continue; } CryHashStringId id(pSequence->GetName()); params.m_Ids[i] = id.id; float timeValue = pMovieSystem->GetPlayingTime(pSequence); params.m_Times[i] = timeValue; CryLog("CMPTrackViewManager::Server_SynchAnimationTimes() adding playing sequence %d %s at time %f", i, pSequence->GetName(), timeValue); ++count; } else { #ifndef _RELEASE if(count + m_FinishedTrackViewCount > CGameRules::STrackViewParameters::sMaxTrackViews) { CryWarning(VALIDATOR_MODULE_NETWORK, VALIDATOR_WARNING, "Trying to synch %i animations but system set to %i in GameRules.h", count + m_FinishedTrackViewCount, CGameRules::STrackViewParameters::sMaxTrackViews); } #endif params.m_NumberOfFinishedTrackViews = m_FinishedTrackViewCount; for(int j = 0; j < m_FinishedTrackViewCount && i < CGameRules::STrackViewParameters::sMaxTrackViews; ++j, ++i) { params.m_Ids[i] = m_FinishedTrackViews[j]; params.m_Times[i] = m_FinishedTrackViewTimes[j]; #ifndef _RELEASE IAnimSequence *pTrackviewSequence = FindTrackviewSequence(m_FinishedTrackViews[j]); CryLog("CMPTrackViewManager::Server_SynchAnimationTimes() adding finished sequence %d %s at time %f", i, pTrackviewSequence ? pTrackviewSequence->GetName() : "NULL", m_FinishedTrackViewTimes[j]); #endif } break; } } params.m_NumberOfTrackViews = count; params.m_bInitialData = true; }