TAttachedEffectId CEffectsController::AttachLight(const int targetSlot, const char *helperName, const SLightAttachParams &attachParams) { CRY_ASSERT(m_pOwnerEntity); CDLight light; light.SetLightColor(ColorF(attachParams.color.x * attachParams.diffuseMultiplier, attachParams.color.y * attachParams.diffuseMultiplier, attachParams.color.z * attachParams.diffuseMultiplier, 1.0f)); light.SetSpecularMult( (float)__fsel( -attachParams.diffuseMultiplier, attachParams.specularMultiplier, (attachParams.specularMultiplier / (attachParams.diffuseMultiplier + FLT_EPSILON)) ) ); light.m_nLightStyle = attachParams.style; light.SetAnimSpeed(attachParams.animSpeed); light.m_fLightFrustumAngle = 45.0f; light.m_fRadius = attachParams.radius; light.m_fLightFrustumAngle = attachParams.projectFov * 0.5f; light.m_fHDRDynamic = attachParams.hdrDynamic; light.m_Flags |= attachParams.deferred ? DLF_DEFERRED_LIGHT : 0; light.m_Flags |= attachParams.castShadows ? DLF_CASTSHADOW_MAPS : 0; light.m_nEntityId = m_pOwnerEntity->GetId(); if (attachParams.projectTexture && attachParams.projectTexture[0]) { light.m_pLightImage = gEnv->pRenderer->EF_LoadTexture(attachParams.projectTexture); if (!light.m_pLightImage || !light.m_pLightImage->IsTextureLoaded()) { GameWarning("[EntityEffects] Entity '%s' failed to load projecting light texture '%s'!", m_pOwnerEntity->GetName(), attachParams.projectTexture); return 0; } } if ((light.m_pLightImage != NULL) && light.m_pLightImage->IsTextureLoaded()) { light.m_Flags |= DLF_PROJECT; } else { if (light.m_pLightImage) { light.m_pLightImage->Release(); } light.m_pLightImage = NULL; light.m_Flags |= DLF_POINT; } IMaterial* pMaterial = NULL; if (attachParams.material && attachParams.material[0]) { pMaterial = gEnv->p3DEngine->GetMaterialManager()->LoadMaterial(attachParams.material); } SEntitySlotInfo slotInfo; SEffectInfo effectInfo; const bool validSlot = m_pOwnerEntity->GetSlotInfo(targetSlot, slotInfo); if (!validSlot || slotInfo.pStatObj) { //Get helper position on static object (if any) Vec3 helperPos(ZERO); Vec3 localHelperPosition = attachParams.offset; if (validSlot) { helperPos = slotInfo.pStatObj->GetHelperPos(helperName); if (helperPos.IsZero()) { const int childCount = m_pOwnerEntity->GetChildCount(); for (int i=0;i<childCount;++i) { if (IEntity* pChild = m_pOwnerEntity->GetChild(i)) { if (IStatObj* statObj = pChild->GetStatObj(targetSlot)) { helperPos = statObj->GetHelperPos(helperName); if (!helperPos.IsZero()) { helperPos += pChild->GetPos(); break; } } } } } localHelperPosition = helperPos + attachParams.offset; localHelperPosition = m_pOwnerEntity->GetSlotLocalTM(targetSlot, false).TransformPoint(localHelperPosition); } int attachSlot = FindSafeSlot(attachParams.firstSafeSlot); ++m_effectGeneratorId; effectInfo.id = m_effectGeneratorId; effectInfo.entityEffectSlot = m_pOwnerEntity->LoadLight(attachSlot, &light); if ((effectInfo.entityEffectSlot >= 0) && pMaterial) { m_pOwnerEntity->SetSlotMaterial(effectInfo.entityEffectSlot, pMaterial); } Matrix34 localEffectMtx = Matrix34(Matrix33::CreateRotationVDir(attachParams.direction)); localEffectMtx.SetTranslation(localHelperPosition); m_pOwnerEntity->SetSlotLocalTM(effectInfo.entityEffectSlot, localEffectMtx); m_attachedEffects.push_back(effectInfo); return m_effectGeneratorId; } else if (slotInfo.pCharacter) { IAttachmentManager *pAttachmentManager = slotInfo.pCharacter->GetIAttachmentManager(); IAttachment *pAttachment = pAttachmentManager->GetInterfaceByName(helperName); if (pAttachment) { CLightAttachment *pLightAttachment = new CLightAttachment(); pLightAttachment->LoadLight(light); ILightSource* pLightSource = pLightAttachment->GetLightSource(); if (pLightSource) { pLightSource->SetMaterial(pMaterial); pLightSource->SetCastingException(attachParams.pCasterException); } pAttachment->AddBinding(pLightAttachment); const bool customOffset = (attachParams.offset != Vec3Constants<float>::fVec3_Zero) || (attachParams.direction != Vec3Constants<float>::fVec3_OneY); if (customOffset) { pAttachment->SetAttRelativeDefault(QuatT(Quat::CreateRotationVDir(attachParams.direction), attachParams.offset)); } } else { GameWarning("[EntityEffects] Entity '%s' trying to attach light to attachment '%s' which does not exist!", m_pOwnerEntity->GetName(), helperName); return 0; } ++m_effectGeneratorId; effectInfo.id = m_effectGeneratorId; effectInfo.helperName = helperName; effectInfo.characterEffectSlot = targetSlot; m_attachedEffects.push_back(effectInfo); return m_effectGeneratorId; } return 0; }
int CScriptBind_GameToken::SetToken( IFunctionHandler *pH) { SCRIPT_CHECK_PARAMETERS(2); const char* tokenName = 0; if (pH->GetParams(tokenName) == false) { GameWarning("[GameToken.SetToken] Usage: GameToken.SetToken TokenName TokenValue]"); return pH->EndFunction(); } ScriptAnyValue val; TFlowInputData data; if (pH->GetParamAny( 2, val) == false) { GameWarning("[GameToken.SetToken(%s)] Usage: GameToken.SetToken TokenName TokenValue]", tokenName); return pH->EndFunction(); } switch (val.type) { case ANY_TBOOLEAN: { bool v; val.CopyTo(v); data.Set(v); } break; case ANY_TNUMBER: { float v; val.CopyTo(v); data.Set(v); } break; case ANY_TSTRING: { const char* v; val.CopyTo(v); data.Set(string(v)); } break; case ANY_TVECTOR: { Vec3 v; val.CopyTo(v); data.Set(v); } case ANY_TTABLE: { float x,y,z; IScriptTable * pTable = val.table; assert (pTable != 0); if (pTable->GetValue( "x", x ) && pTable->GetValue( "y", y ) && pTable->GetValue( "z", z )) { data.Set(Vec3(x,y,z)); } else { GameWarning("[GameToken.SetToken(%s)] Cannot convert parameter type '%s' to Vec3", tokenName, ScriptAnyTypeToString(val.type)); return pH->EndFunction(); } } break; case ANY_THANDLE: { ScriptHandle handle; val.CopyTo(handle); data.Set((EntityId)handle.n); } break; default: GameWarning("[GameToken.SetToken(%s)] Cannot convert parameter type '%s'", tokenName, ScriptAnyTypeToString(val.type)); return pH->EndFunction(); break; // dummy ;-) } #ifdef SCRIPT_GAMETOKEN_ALWAYS_CREATE m_pTokenSystem->SetOrCreateToken(tokenName, data); #else IGameToken *pToken = m_pTokenSystem->FindToken(tokenName); if (!pToken) GameWarning("[GameToken.SetToken] Cannot find token '%s'", tokenName); else { pToken->SetValue(data); } #endif return pH->EndFunction(); }
//------------------------------------------------------------------------ void CWeaponSystem::Scan(const char *folderName) { stack_string folder = folderName; stack_string search = folder; stack_string subName; stack_string xmlFile; search += "/*.*"; ICryPak *pPak = gEnv->pCryPak; _finddata_t fd; intptr_t handle = pPak->FindFirst(search.c_str(), &fd); if(!m_recursing) CryLog("Loading ammo XML definitions from '%s'!", folderName); if(handle > -1) { do { if(!strcmp(fd.name, ".") || !strcmp(fd.name, "..")) continue; if(fd.attrib & _A_SUBDIR) { subName = folder+"/"+fd.name; if(m_recursing) Scan(subName.c_str()); else { m_recursing=true; Scan(subName.c_str()); m_recursing=false; } continue; } if(stricmp(PathUtil::GetExt(fd.name), "xml")) continue; xmlFile = folder + "/" + fd.name; XmlNodeRef rootNode = m_pSystem->LoadXmlFromFile(xmlFile.c_str()); if(!rootNode) { GameWarning("Invalid XML file '%s'! Skipping...", xmlFile.c_str()); continue; } if(!ScanXML(rootNode, xmlFile.c_str())) continue; } while(pPak->FindNext(handle, &fd) >= 0); } if(!m_recursing) CryLog("Finished loading ammo XML definitions from '%s'!", folderName); if(!m_reloading && !m_recursing) m_folders.push_back(folderName); }
void CAutoAimManager::UpdateTargetInfo(SAutoaimTarget& aaTarget, float fFrameTime) { IEntity * pTargetEntity = gEnv->pEntitySystem->GetEntity(aaTarget.entityId); if(pTargetEntity) { CActorPtr pTargetActor = aaTarget.pActorWeak.lock(); if (pTargetActor) { Vec3 characterPos; Quat characterRot; //Need this because of decouple catch-up movement if (IAnimatedCharacter* pAnimatedCharacter = pTargetActor->GetAnimatedCharacter()) { const QuatT& animationLocation = pAnimatedCharacter->GetAnimLocation(); characterPos = animationLocation.t; characterRot = animationLocation.q; } else { const Matrix34& targetWorldTM = pTargetEntity->GetWorldTM(); //Fallback to entity position characterPos = targetWorldTM.GetTranslation(); characterRot = Quat(targetWorldTM); } Vec3 primaryOffset(0.0f, 0.0f, aaTarget.fallbackOffset); Vec3 secondaryOffset(0.0f, 0.0f, aaTarget.fallbackOffset); if (aaTarget.primaryBoneId >= 0) { if (pTargetActor->HasBoneID(aaTarget.primaryBoneId)) { primaryOffset = pTargetActor->GetBoneTransform(aaTarget.primaryBoneId).t; } else { GameWarning("CAutoAimManager: Character %s missing primary boneID: %s", pTargetEntity->GetName(), s_BONE_ID_NAME[aaTarget.primaryBoneId]); aaTarget.primaryBoneId = -1; } } if (aaTarget.secondaryBoneId >= 0) { if (pTargetActor->HasBoneID(aaTarget.secondaryBoneId)) { secondaryOffset = pTargetActor->GetBoneTransform(aaTarget.secondaryBoneId).t; } else { GameWarning("CAutoAimManager: Character %s missing secondary boneID: %s", pTargetEntity->GetName(), s_BONE_ID_NAME[aaTarget.secondaryBoneId]); aaTarget.secondaryBoneId = -1; } } aaTarget.primaryAimPosition = characterPos + (characterRot * primaryOffset); aaTarget.secondaryAimPosition = characterPos + (characterRot * secondaryOffset); //Update hostility (changes during gameplay) if (!gEnv->bMultiplayer) { uint8 targetFaction = (aaTarget.aiFaction != IFactionMap::InvalidFactionID) ? aaTarget.aiFaction : GetTargetFaction(*pTargetEntity); if (gEnv->pAISystem->GetFactionMap().GetReaction(GetLocalPlayerFaction(), aaTarget.aiFaction) == IFactionMap::Hostile) { aaTarget.SetFlag(eAATF_AIHostile); } else { aaTarget.RemoveFlag(eAATF_AIHostile); } aaTarget.aiFaction = targetFaction; } } else if(aaTarget.hasSkeleton) { //Not an actor but has a skeleton (and so can use bone offsets) ISkeletonPose* pSkeletonPose = pTargetEntity->GetCharacter(0)->GetISkeletonPose(); const Matrix34& characterMat = pTargetEntity->GetWorldTM(); const Vec3 characterPos = characterMat.GetTranslation(); const Quat characterRot(characterMat); Vec3 primaryOffset(0.0f, 0.0f, aaTarget.fallbackOffset); Vec3 secondaryOffset(0.0f, 0.0f, aaTarget.fallbackOffset); if (aaTarget.primaryBoneId >= 0) { primaryOffset = pSkeletonPose->GetAbsJointByID(aaTarget.primaryBoneId).t; } if (aaTarget.secondaryBoneId >= 0) { secondaryOffset = pSkeletonPose->GetAbsJointByID(aaTarget.secondaryBoneId).t; } aaTarget.primaryAimPosition = characterPos + (characterRot * primaryOffset); aaTarget.secondaryAimPosition = characterPos + (characterRot * secondaryOffset); } else { //Must be an object const Matrix34& entityWorldTM = pTargetEntity->GetWorldTM(); Vec3 primaryPosition = entityWorldTM.GetTranslation(); Vec3 secondaryPosition = entityWorldTM.TransformPoint(Vec3(0.0f, 0.0f, 0.5f)); AABB entityLocalBBox; pTargetEntity->GetLocalBounds(entityLocalBBox); if (!entityLocalBBox.IsEmpty()) { const Vec3 offset (0.0f, 0.0f, entityLocalBBox.GetRadius() * 0.2f); const Vec3 objectCenter = entityLocalBBox.GetCenter(); primaryPosition = entityWorldTM.TransformPoint((objectCenter - offset)); secondaryPosition = entityWorldTM.TransformPoint((objectCenter + offset)); } aaTarget.primaryAimPosition = primaryPosition; aaTarget.secondaryAimPosition = secondaryPosition; } //The physics drags the render proxy and entity behind it. If we auto aim at the render position, // we will handicap the console players by failing to let them aim ahead of the target. if(IPhysicalEntity * pPhysicalEntity = pTargetEntity->GetPhysics()) { pe_status_dynamics dyn; if(pPhysicalEntity->GetStatus(&dyn)) { Vec3 lookAhead = (dyn.v * fFrameTime); aaTarget.primaryAimPosition = aaTarget.primaryAimPosition + lookAhead; aaTarget.secondaryAimPosition = aaTarget.secondaryAimPosition + lookAhead; } } } }
void CDownloadMgr::Init( const char *pInResourceDescriptionsFile) { m_resources.clear(); XmlNodeRef node=GetISystem()->LoadXmlFromFile(pInResourceDescriptionsFile); if (!node || strcmp("downloadmgr_config",node->getTag())) { GameWarning("Failed to load download mgr config file %s", pInResourceDescriptionsFile); return; } CDownloadableResource defaultResource; XmlNodeRef defaultXML(0); #ifdef GAME_IS_CRYSIS2 for (int i=0, n=node->getChildCount(); i<n; i++) { XmlNodeRef x=node->getChild(i); if (x && strcmp(x->getTag(),"default_resource")==0) { const char *config=NULL; if (x->getAttr("config",&config) && strcmp(config,g_pGameCVars->g_dataCentreConfig)==0) { defaultXML=x; break; } } } #endif if (defaultXML) { defaultResource.LoadConfig(defaultXML); } XmlNodeRef resources=node->findChild("resources"); if (resources) { int numResources=resources->getChildCount(); m_resources.reserve(numResources+k_localizedResourceSlop); for (int i=0; i<numResources; ++i) { bool ok=false; CDownloadableResourcePtr pParse=new CDownloadableResource(defaultResource); if (pParse) { pParse->LoadConfig(resources->getChild(i)); ok=pParse->Validate(); } if (!ok) { GameWarning("Error loading resource description %d %s from %s",i,pParse->m_descName.c_str(),pInResourceDescriptionsFile); } else { m_resources.push_back(pParse); } } } }
// implementation of Net.Expose() - exposes a class int CScriptRMI::ExposeClass( IFunctionHandler * pFH ) { SmartScriptTable params, cls, clientMethods, serverMethods; SmartScriptTable clientTable, serverTable; SmartScriptTable serverProperties; IScriptSystem * pSS = pFH->GetIScriptSystem(); if (pFH->GetParamCount() != 1) { pSS->RaiseError( "Net.Expose takes only one parameter - a table" ); return pFH->EndFunction(false); } if (!pFH->GetParam( 1, params )) { pSS->RaiseError( "Net.Expose takes only one parameter - a table" ); return pFH->EndFunction(false); } if (!params->GetValue( "Class", cls )) { pSS->RaiseError( "No 'Class' parameter to Net.Expose" ); return pFH->EndFunction(false); } if (!params->GetValue( "ClientMethods", clientMethods )) { GameWarning( "No 'ClientMethods' parameter to Net.Expose" ); } else if (!cls->GetValue("Client", clientTable)) { pSS->RaiseError( "'ClientMethods' exposed, but no 'Client' table in class" ); return pFH->EndFunction(false); } if (!params->GetValue( "ServerMethods", serverMethods )) { GameWarning( "No 'ServerMethods' parameter to Net.Expose" ); } else if (!cls->GetValue("Server", serverTable)) { pSS->RaiseError( "'ServerMethods' exposed, but no 'Server' table in class" ); return pFH->EndFunction(false); } params->GetValue( "ServerProperties", serverProperties ); if (clientMethods.GetPtr()) { CRY_ASSERT( clientTable.GetPtr() ); if (!BuildDispatchTable( clientMethods, clientTable, cls, CLIENT_DISPATCH_FIELD )) return pFH->EndFunction(false); } if (serverMethods.GetPtr()) { CRY_ASSERT( serverTable.GetPtr() ); if (!BuildDispatchTable( serverMethods, serverTable, cls, SERVER_DISPATCH_FIELD )) return pFH->EndFunction(false); } if (serverProperties.GetPtr()) { if (!BuildSynchTable(serverProperties, cls, SERVER_SYNCHED_FIELD)) return pFH->EndFunction(false); } return pFH->EndFunction(true); }
// initialize an entity for networked methods void CScriptRMI::SetupEntity( EntityId eid, IEntity * pEntity, bool client, bool server ) { if (!m_pParent) { GameWarning( "Trying to setup an entity for network with no game started... failing" ); return; } IEntityClass * pClass = pEntity->GetClass(); stack_string className = pClass->GetName(); IScriptTable * pEntityTable = pEntity->GetScriptTable(); IScriptSystem * pSS = pEntityTable->GetScriptSystem(); SmartScriptTable clientDispatchTable, serverDispatchTable, serverSynchedTable; pEntityTable->GetValue( CLIENT_DISPATCH_FIELD, clientDispatchTable ); pEntityTable->GetValue( SERVER_DISPATCH_FIELD, serverDispatchTable ); pEntityTable->GetValue( SERVER_SYNCHED_FIELD, serverSynchedTable ); bool validated; if (clientDispatchTable.GetPtr()) { if (!clientDispatchTable->GetValue(VALIDATED_FIELD, validated)) return; if (!validated) { SmartScriptTable methods; if (!pEntityTable->GetValue( "Client", methods )) { GameWarning( "No Client table, but has a client dispatch on class %s", pEntity->GetClass()->GetName() ); return; } if (!ValidateDispatchTable( pEntity->GetClass()->GetName(), clientDispatchTable, methods, false )) return; } } if (serverDispatchTable.GetPtr()) { if (!serverDispatchTable->GetValue(VALIDATED_FIELD, validated)) return; if (!validated) { SmartScriptTable methods; if (!pEntityTable->GetValue( "Server", methods )) { GameWarning( "No Server table, but has a server dispatch on class %s", pEntity->GetClass()->GetName() ); return; } if (!ValidateDispatchTable( pEntity->GetClass()->GetName(), serverDispatchTable, methods, true )) return; } } ScriptHandle id; id.n = eid; ScriptHandle flags; if (client && serverDispatchTable.GetPtr()) { flags.n = eDF_ToServer; AddProxyTable( pEntityTable, id, flags, "server", serverDispatchTable ); } if (server && clientDispatchTable.GetPtr()) { // only expose ownClient, otherClients for actors with a channelId flags.n = eDF_ToClientOnChannel; AddProxyTable( pEntityTable, id, flags, "onClient", clientDispatchTable ); flags.n = eDF_ToClientOnOtherChannels; AddProxyTable( pEntityTable, id, flags, "otherClients", clientDispatchTable ); flags.n = eDF_ToClientOnChannel | eDF_ToClientOnOtherChannels; AddProxyTable( pEntityTable, id, flags, "allClients", clientDispatchTable ); } if (serverSynchedTable.GetPtr()) { AddSynchedTable( pEntityTable, id, "synched", serverSynchedTable ); } CryAutoCriticalSection lkDispatch(m_dispatchMutex); std::map<string, size_t>::iterator iter = m_entityClassToEntityTypeID.find(CONST_TEMP_STRING(pEntity->GetClass()->GetName())); if (iter == m_entityClassToEntityTypeID.end()) { //[Timur] commented out as spam. //GameWarning("[scriptrmi] unable to find class %s", pEntity->GetClass()->GetName()); } else m_entities[eid] = iter->second; }
void CHUDMissionObjectiveSystem::LoadObjectiveAnalysisData(const char* levelpath) { CryFixedStringT<128> filename; if(levelpath==NULL) { filename = "Libs/UI/ObjectivesAnalysis.xml"; } else { filename.Format("%s/leveldata/ObjectivesAnalysis.xml", levelpath); } XmlNodeRef root = GetISystem()->LoadXmlFromFile(filename.c_str()); if (root == 0) return; XmlNodeRef analysisDataContainerNode = root->findChild("AnalysisData"); SObjectiveAnalysisData analysisData; SSingleObjectiveAnalysisData singleAnalysisData; if (analysisDataContainerNode != 0) { for(int i = 0; i < analysisDataContainerNode->getChildCount(); ++i) { XmlNodeRef analysisDataNode = analysisDataContainerNode->getChild(i); const char* szOuterId = analysisDataNode->getAttr("Id"); if (szOuterId == NULL || szOuterId[0] == '\0') { GameWarning("CHUDMissionObjectiveSystem::LoadObjectiveAnalysisData: Failed to load analysisdata, invalid id"); continue; } analysisData.m_singleObjectiveData.clear(); const int iNumSingleAnalysis = analysisDataNode->getChildCount(); bool bFailedAddedSingleAnalysis = false; for (int j = 0; j < iNumSingleAnalysis; j++) { XmlNodeRef singleAnalysisDataNode = analysisDataNode->getChild(j); const char* szSingleId; int iUseOuterId; // UseOuterId saves needing to duplicate text to the outer Id bool bResult = singleAnalysisDataNode->getAttr("UseOuterId", iUseOuterId); if (bResult && (iUseOuterId == 1)) { szSingleId = szOuterId; } else { szSingleId = analysisDataNode->getAttr("Id"); } if (szSingleId == NULL || szSingleId[0] == '\0') { GameWarning("CHUDMissionObjectiveSystem::LoadObjectiveAnalysisData: Failed to load single analysisdata section for analysis: %s, invalid id", szOuterId); bFailedAddedSingleAnalysis = true; break; } singleAnalysisData.m_id = szSingleId; singleAnalysisDataNode->getAttr("Percent", singleAnalysisData.m_fPercent); analysisData.m_singleObjectiveData.push_back(singleAnalysisData); } if (bFailedAddedSingleAnalysis || analysisData.m_singleObjectiveData.size() < 1) { GameWarning("CHUDMissionObjectiveSystem::LoadObjectiveAnalysisData: Failed to load analysisdata: %s, problem with section data", szOuterId); continue; } analysisDataNode->getAttr("OverrideSectionID",analysisData.m_iOverrideIndex); analysisDataNode->getAttr("AttachInWorld", analysisData.m_bAttachInWorld); m_objectiveAnalysisData[szOuterId] = analysisData; } } }
void SAmmoParams::LoadPhysics() { const IItemParamsNode *physics = pItemParams->GetChild("physics"); if (!physics) { return; } const char *typ = physics->GetAttribute("type"); if (typ) { if (!strcmpi(typ, "particle")) { physicalizationType = ePT_Particle; } else if (!strcmpi(typ, "rigid")) { physicalizationType = ePT_Rigid; } else if(!strcmpi(typ, "static")) { physicalizationType = ePT_Static; } else { GameWarning("Unknow physicalization type '%s' for projectile '%s'!", typ, pEntityClass->GetName()); } } CItemParamReader reader(physics); if(physicalizationType != ePT_Static) { reader.Read("mass", mass); reader.Read("speed", speed); reader.Read("max_logged_collisions", maxLoggedCollisions); reader.Read("traceable", traceable); reader.Read("spin", spin); reader.Read("spin_random", spinRandom); } // material const char *material = 0; reader.Read("material", material); if (material) { pSurfaceType = gEnv->p3DEngine->GetMaterialManager()->GetSurfaceTypeByName(material); } if (physicalizationType == ePT_Particle) { pParticleParams = new pe_params_particle(); float radius = 0.005f; reader.Read("radius", radius); pParticleParams->thickness = radius * 2.0f; pParticleParams->size = radius * 2.0f; reader.Read("air_resistance", pParticleParams->kAirResistance); reader.Read("water_resistance", pParticleParams->kWaterResistance); reader.Read("gravity", pParticleParams->gravity); reader.Read("water_gravity", pParticleParams->waterGravity); reader.Read("thrust", pParticleParams->accThrust); reader.Read("lift", pParticleParams->accLift); reader.Read("min_bounce_speed", pParticleParams->minBounceVel); reader.Read("pierceability", pParticleParams->iPierceability); if (pSurfaceType) { pParticleParams->surface_idx = pSurfaceType->GetId(); } int flag = 0; reader.Read("single_contact", flag); pParticleParams->flags = flag ? particle_single_contact : 0; flag = 0; reader.Read("no_roll", flag); pParticleParams->flags |= flag ? particle_no_roll : 0; flag = 0; reader.Read("no_spin", flag); pParticleParams->flags |= flag ? particle_no_spin : 0; flag = 0; reader.Read("no_path_alignment", flag); pParticleParams->flags |= flag ? particle_no_path_alignment : 0; flag = 0; pParticleParams->mass = mass; } }
bool CDialogActorContext::Update(float dt) { if (IsAborted()) return true; // FIXME: this should never happen, as we should get a notification before. // temp leave in for tracking down a bug [AlexL: 23/11/2006] IEntity* pEntity = gEnv->pEntitySystem->GetEntity(m_entityID); if (pEntity == 0) { m_pIActor = 0; GameWarning("[DIALOG] CDialogActorContext::Update: %s Actor=%d (EntityId=%d) no longer existent.", m_pSession->GetDebugName(), m_actorID, m_entityID); AbortContext(true, CDialogSession::eAR_EntityDestroyed); return true; } CDialogSession::AlertnessInterruptMode alertnessInterruptMode = m_pSession->GetAlertnessInterruptMode(); if(alertnessInterruptMode != CDialogSession::None) { if(IAIObject* aiObject = pEntity->GetAI()) { if(IAIActorProxy* aiActorProxy = aiObject->GetProxy()) { if(aiActorProxy->GetAlertnessState() >= alertnessInterruptMode) { AbortContext(true, CDialogSession::eAR_AIAborted); return true; } } } } float now = m_pSession->GetCurTime(); if (!CheckActorFlags(CDialogSession::eDACF_NoActorDeadAbort) && m_pIActor && m_pIActor->IsDead()) { if (!IsAborted()) { DiaLOG::Log(DiaLOG::eAlways, "[DIALOG] CDialogActorContext::Update: %s Actor=%d (EntityId=%d) has died. Aborting.", m_pSession->GetDebugName(), m_actorID, m_entityID); AbortContext(true, CDialogSession::eAR_ActorDead); return true; } } if (m_bIsLocalPlayer) { // when the local player is involved in the conversation do some special checks if (DoLocalPlayerChecks(dt) == false) { DiaLOG::Log(DiaLOG::eAlways, "[DIALOG] CDialogActorContext::Update: %s Abort from LocalPlayer.", m_pSession->GetDebugName()); AbortContext(true, m_bIsAwareInRange == false ? CDialogSession::eAR_PlayerOutOfRange : CDialogSession::eAR_PlayerOutOfView); return true; } } if (m_bAbortFromAI) { m_bAbortFromAI = false; if (!IsAborted()) { DiaLOG::Log(DiaLOG::eAlways, "[DIALOG] CDialogActorContext::Update: %s Abort from AI.", m_pSession->GetDebugName()); AbortContext(true, CDialogSession::eAR_AIAborted); return true; } } if (SessionAllowsLookAt()) { DoStickyLookAt(); } int loop = 0; do { // DiaLOG::Log("[DIALOG] DiaLOG::eAlways"CDialogActorContext::Update: %s now=%f actorId=%d loop=%d", m_pSession->GetDebugName(), now, m_actorID, loop); bool bAdvance = false; switch (m_phase) { case eDAC_Idle: break; case eDAC_NewLine: { m_bHasScheduled = false; m_lookAtTimeOut = LOOKAT_TIMEOUT; m_animTimeOut = ANIM_TIMEOUT; m_soundTimeOut = SOUND_TIMEOUT; // wait one second until sound is timed out m_bAnimScheduled = false; m_bAnimStarted = false; m_bSoundScheduled = false; m_bSoundStarted = false; m_soundLength = 0.0f; if (m_pCurLine->m_flagResetLookAt) { m_stickyLookAtActorID = CDialogScript::NO_ACTOR_ID; m_lookAtActorID = CDialogScript::NO_ACTOR_ID; } // check if look-at sticky is set else if (m_pCurLine->m_lookatActor != CDialogScript::NO_ACTOR_ID) { if (m_pCurLine->m_flagLookAtSticky == false) { m_lookAtActorID = m_pCurLine->m_lookatActor; m_stickyLookAtActorID = CDialogScript::NO_ACTOR_ID; } else { m_stickyLookAtActorID = m_pCurLine->m_lookatActor; m_lookAtActorID = CDialogScript::NO_ACTOR_ID; } } bAdvance = true; // handle the first sticky look-at here if (SessionAllowsLookAt()) { DoStickyLookAt(); } #if 0 // test for immediate scheduling of next line while the current line is still playing // maybe we're going to use some special delay TAGS like FORCE_NEXT, WAIT if (m_pCurLine->m_delay <= -999.0f) { m_bHasScheduled = true; m_pSession->ScheduleNextLine(0.0f); } #endif } break; case eDAC_LookAt: { bool bWaitForLookAtFinish = true; bAdvance = true; if (SessionAllowsLookAt() == false) { break; } // Question: maybe do this although EP is requested if (bWaitForLookAtFinish && m_lookAtActorID != CDialogScript::NO_ACTOR_ID && m_pCurLine->m_flagAGEP == false) { IEntity* pActorEntity = m_pSession->GetActorEntity(m_actorID); IEntity* pLookAtEntity = m_pSession->GetActorEntity(m_lookAtActorID); if (pActorEntity != 0) { m_lookAtTimeOut -= dt; bool bTargetReached; //bool bSuccess = DoLookAt(pActorEntity, pLookAtEntity, bTargetReached); DoLookAt(pActorEntity, pLookAtEntity, bTargetReached); //DiaLOG::Log(DiaLOG::eDebugA, "[DIALOG] CDialogActorContext::Update: %s now=%f actorID=%d phase=eDAC_LookAt %d", // m_pSession->GetDebugName(), now, m_actorID, bTargetReached); if (/* bSuccess == false || */ bTargetReached || m_lookAtTimeOut<=0.0f) { DiaLOG::Log(DiaLOG::eAlways, "[DIALOG] CDialogActorContext::Update: %s now=%f actorID=%d phase=eDAC_LookAt %s", m_pSession->GetDebugName(), now, m_actorID, bTargetReached ? "Target Reached" : "Timed Out"); m_lookAtActorID = CDialogScript::NO_ACTOR_ID; } else bAdvance = false; } } } break; case eDAC_Anim: { bAdvance = true; if (SessionAllowsLookAt() && m_lookAtActorID != CDialogScript::NO_ACTOR_ID) // maybe: don't do this when EP is requested [&& m_pCurLine->m_flagAGEP == false] { IEntity* pActorEntity = m_pSession->GetActorEntity(m_actorID); IEntity* pLookAtEntity = m_pSession->GetActorEntity(m_lookAtActorID); if (pActorEntity != 0) { m_lookAtTimeOut -= dt; bool bTargetReached; //bool bSuccess = DoLookAt(pActorEntity, pLookAtEntity, bTargetReached); DoLookAt(pActorEntity, pLookAtEntity, bTargetReached); if (/* bSuccess == false || */ bTargetReached || m_lookAtTimeOut<=0.0f) { DiaLOG::Log(DiaLOG::eAlways, "[DIALOG] CDialogActorContext::Update: %s now=%f actorID=%d phase=eDAC_Anim %s", m_pSession->GetDebugName(), now, m_actorID, bTargetReached ? "Target Reached" : "Timed Out"); m_lookAtActorID = CDialogScript::NO_ACTOR_ID; } else bAdvance = false; } } const bool bHasAnim = !m_pCurLine->m_anim.empty(); if (SessionAllowsAnim() && bHasAnim) { bAdvance = false; if (!m_bAnimScheduled) { m_bSoundStopsAnim = false; // whenever there is a new animation, no need for the still playing sound // to stop the animation m_bAnimStarted = false; m_bAnimScheduled = true; // schedule animation IEntity* pActorEntity = m_pSession->GetActorEntity(m_actorID); if (pActorEntity) DoAnimAction(pActorEntity, m_pCurLine->m_anim, m_pCurLine->m_flagAGSignal, m_pCurLine->m_flagAGEP); else bAdvance = true; } else { // we scheduled it already // wait until it starts or timeout m_animTimeOut-=dt; bAdvance = m_animTimeOut <= 0.0f || m_bAnimStarted; if (bAdvance) { DiaLOG::Log(DiaLOG::eAlways, "[DIALOG] CDialogActorContext::Update: %s Now=%f actorID=%d phase=eDAC_Anim %s", m_pSession->GetDebugName(), now, m_actorID, m_bAnimStarted ? "Anim Started" : "Anim Timed Out"); } } } } break; case eDAC_ScheduleSoundPlay: { bAdvance = true; const bool bHasSound = m_pCurLine->m_audioID != INVALID_AUDIO_CONTROL_ID; if (bHasSound) { if (m_bSoundScheduled == false) { IEntity* pActorEntity = m_pSession->GetActorEntity(m_actorID); if (pActorEntity == 0) break; IEntityAudioProxy* pActorAudioProxy = m_pSession->GetEntityAudioProxy(pActorEntity); if (pActorAudioProxy == 0) break; if(m_SpeechAuxProxy == INVALID_AUDIO_PROXY_ID) { m_SpeechAuxProxy = pActorAudioProxy->CreateAuxAudioProxy(); pActorAudioProxy->AddAsListenerToAuxAudioProxy(m_SpeechAuxProxy, &CDialogActorContext::OnAudioTriggerFinished, eART_AUDIO_CALLBACK_MANAGER_REQUEST, eACMRT_REPORT_FINISHED_TRIGGER_INSTANCE); } UpdateAuxProxyPosition(); SAudioCallBackInfos callbackInfos(0, (void*)CDialogActorContext::GetClassIdentifier(), reinterpret_cast<void*>(static_cast<intptr_t>(m_ContextID)), eARF_PRIORITY_NORMAL | eARF_SYNC_FINISHED_CALLBACK); if(!pActorAudioProxy->ExecuteTrigger(m_pCurLine->m_audioID, eLSM_None, m_SpeechAuxProxy, callbackInfos)) { m_bSoundStarted = false; m_bHasScheduled = false; m_pSession->ScheduleNextLine(2.0f); } else { m_bSoundStarted = true; m_bHasScheduled = true; //todo: get the length of the sound to schedule the next line (set m_soundLength). Currently we schedule the next line as soon as the current one is finished, ignoring the specified "delay" parameter. its done in: DialogTriggerFinishedCallback const char* triggerName = gEnv->pAudioSystem->GetAudioControlName(eACT_TRIGGER, m_pCurLine->m_audioID); if (triggerName == NULL) triggerName = "dialog trigger"; DiaLOG::Log(DiaLOG::eDebugA, "[DIALOG] CDialogActorContex::Update: %s Now=%f actorID=%d phase=eDAC_ScheduleSoundPlay: Starting '%s'", m_pSession->GetDebugName(), now, m_actorID, triggerName); } } else { // sound has been scheduled // wait for sound start or timeout m_soundTimeOut-=dt; const bool bTimedOut = m_soundTimeOut <= 0.0f; bAdvance = bTimedOut || m_bSoundStarted; if (bAdvance) { if (bTimedOut) StopSound(true); // unregister from sound as listener and free resource DiaLOG::Log(DiaLOG::eAlways, "[DIALOG] CDialogActorContext::Update: %s Now=%f actorID=%d phase=eDAC_ScheduleSoundPlay %s", m_pSession->GetDebugName(), now, m_actorID, m_bSoundStarted ? "Sound Started" : "Sound Timed Out"); } } } } break; case eDAC_SoundFacial: { bAdvance = true; const bool bHasSound = m_pCurLine->m_audioID != INVALID_AUDIO_CONTROL_ID; const bool bHasFacial = !m_pCurLine->m_facial.empty() || m_pCurLine->m_flagResetFacial; if (bHasFacial) { IEntity* pActorEntity = m_pSession->GetActorEntity(m_actorID); if (pActorEntity) DoFacialExpression(pActorEntity, m_pCurLine->m_facial, m_pCurLine->m_facialWeight, m_pCurLine->m_facialFadeTime); } //hd-todo: re-add me, when we have a way to query the length of the audio-lines //float delay = m_pCurLine->m_delay; //if (bHasSound && m_bSoundStarted) //{ // if (m_soundLength <= 0.0f) // { // m_soundLength = cry_random(2.0f, 6.0f); // DiaLOG::Log(DiaLOG::eAlways, "[DIALOG] CDialogActorContext::Update: %s Now=%f actorID=%d phase=eDAC_SoundFacial Faking SoundTime to %f", // m_pSession->GetDebugName(), now, m_actorID, m_soundLength); // } // DiaLOG::Log(DiaLOG::eAlways, "[DIALOG] CDialogActorContext::Update: %s Now=%f actorID=%d phase=eDAC_SoundFacial Delay=%f SoundTime=%f", // m_pSession->GetDebugName(), now , m_actorID, delay, m_soundLength); // delay += m_soundLength; //} //// schedule END //if (delay < 0.0f) // delay = 0.0f; //m_pSession->ScheduleNextLine(delay+0.05f); // ~1 frame at 20 fps. we now stop the current line sound before going for next line. Sometimes, this stop call is right before the // // sound has actually stopped in engine side. When that happens, the engine is adding ~2 seconds extra to the sound duration (because fade problems related to NAX header) // // and that looks bad if subtitles are enabled. So we add this small delay here to try to minimize that situation. // // this is part of the workaround for some dialogs apparently never finishing in the engine side (rare). //m_bHasScheduled = true; } break; case eDAC_EndLine: bAdvance = true; if (m_bHasScheduled == false) { m_bHasScheduled = true; m_pSession->ScheduleNextLine(m_pCurLine->m_delay); } break; } if (bAdvance) { AdvancePhase(); dt = 0.0f; ++loop; assert (loop <= eDAC_EndLine+1); if (loop > eDAC_EndLine+1) { DiaLOG::Log(DiaLOG::eAlways, "[DIALOG] CDialogActorContext::Update: %s Actor=%d InternalLoopCount=%d. Final Exit!", m_pSession->GetDebugName(), m_actorID, loop); } } else { if (IsStillPlaying()) { UpdateAuxProxyPosition(); } break; } } while (true); return true; }
void CHUDMissionObjectiveSystem::LoadLevelObjectivesInternal(const char* levelpath) { CryFixedStringT<128> filename; if (levelpath==NULL) { // there is no Objectives_global.xml, but there is a file with the previous standard naming // load the file with old name for backwards compatibility if (!gEnv->pCryPak->IsFileExist("Libs/UI/Objectives_global.xml") && gEnv->pCryPak->IsFileExist("Libs/UI/Objectives_new.xml")) { CryWarning(VALIDATOR_MODULE_GAME, VALIDATOR_WARNING, "File 'Objectives_new.xml' is deprecated and should be renamed to 'Objectives_global.xml'"); filename = "Libs/UI/Objectives_new.xml"; } else { filename = "Libs/UI/Objectives_global.xml"; } } else { filename.Format("%s/leveldata/Objectives.xml", levelpath); } /*if(gEnv->bMultiplayer) { CGameRules *pGameRules = g_pGame->GetGameRules(); if(stricmp (pGameRules->GetEntity()->GetClass()->GetName(), "Coop")) filename = "Libs/UI/MP_Objectives.xml"; }*/ XmlNodeRef missionObjectives = GetISystem()->LoadXmlFromFile(filename.c_str()); if (missionObjectives == 0) return; for(int tag = 0; tag < missionObjectives->getChildCount(); ++tag) { XmlNodeRef mission = missionObjectives->getChild(tag); const char* attrib; const char* objective; const char* text; const char* optional; const char* levelName; if (!mission->getAttr("name", &levelName)) { levelName = mission->getTag(); } for(int obj = 0; obj < mission->getChildCount(); ++obj) { XmlNodeRef objectiveNode = mission->getChild(obj); string id(levelName); id.append("."); id.append(objectiveNode->getTag()); if(objectiveNode->getAttributeByIndex(0, &attrib, &objective) && objectiveNode->getAttributeByIndex(1, &attrib, &text)) { bool secondaryObjective = false; int attribs = objectiveNode->getNumAttributes(); for(int attribIndex = 2; attribIndex < attribs; ++attribIndex) { if(objectiveNode->getAttributeByIndex(attribIndex, &attrib, &optional)) { if(attrib) { if(!stricmp(attrib, "Secondary")) { if(!stricmp(optional, "true")) secondaryObjective = true; } } } } m_currentMissionObjectives.push_back(CHUDMissionObjective(this, id.c_str(), objective, text, secondaryObjective)); } else GameWarning("Error reading mission objectives."); } } }
void CLaserBeam::UpdateLaser(const CLaserBeam::SLaserUpdateDesc& laserUpdateDesc) { if(m_pLaserParams && m_laserOn) { IEntity* pLaserEntity = CreateLaserEntity(); if (pLaserEntity) { m_lastLaserUpdatePosition = laserUpdateDesc.m_laserPos; m_lastLaserUpdateDirection = laserUpdateDesc.m_laserDir; m_laserUpdateTimer += laserUpdateDesc.m_frameTime; UpdateLaserGeometry(*pLaserEntity); if(m_laserUpdateTimer < LASER_UPDATE_TIME) return; m_laserUpdateTimer = Random(0.0f, LASER_UPDATE_TIME * 0.4f); if ((laserUpdateDesc.m_ownerCloaked && !laserUpdateDesc.m_weaponZoomed) || laserUpdateDesc.m_bOwnerHidden) { pLaserEntity->Hide(true); return; } pLaserEntity->Hide(false); const float range = m_pLaserParams->laser_range[GetIndexFromGeometrySlot()]; // Use the same flags as the AI system uses for visbility. const int objects = ent_terrain|ent_static|ent_rigid|ent_sleeping_rigid|ent_independent; //ent_living; const int flags = (geom_colltype_ray << rwi_colltype_bit) | rwi_colltype_any | (10 & rwi_pierceability_mask) | (geom_colltype14 << rwi_colltype_bit); //If we did not get a result, just cancel it, we will queue a new one again RayCastRequest::Priority requestPriority = RayCastRequest::MediumPriority; if (m_queuedRayId != 0) { g_pGame->GetRayCaster().Cancel(m_queuedRayId); m_queuedRayId = 0; requestPriority = RayCastRequest::HighPriority; } IItemSystem* pItemSystem = g_pGame->GetIGameFramework()->GetIItemSystem(); IPhysicalEntity* pSkipEntity = NULL; uint8 numSkips = 0; CItem* pItem = static_cast<CItem*>(pItemSystem->GetItem(m_ownerEntityId)); if(pItem) { if(pItem->IsAccessory()) { CItem* pParentItem = static_cast<CItem*>(pItemSystem->GetItem(pItem->GetParentId())); if(pParentItem) { pItem = pParentItem; } } IEntity* pOwnerEnt = 0; CWeapon* pWeapon = static_cast<CWeapon*>(pItem->GetIWeapon()); if (pWeapon && pWeapon->GetHostId() != 0) { pOwnerEnt = gEnv->pEntitySystem->GetEntity(pWeapon->GetHostId()); } else { pOwnerEnt = pItem->GetOwner(); } if(pOwnerEnt) { IPhysicalEntity* pOwnerPhysics = pOwnerEnt->GetPhysics(); if(pOwnerPhysics) { pSkipEntity = pOwnerPhysics; numSkips++; } } } m_queuedRayId = g_pGame->GetRayCaster().Queue( requestPriority, RayCastRequest(laserUpdateDesc.m_laserPos, laserUpdateDesc.m_laserDir*range, objects, flags, &pSkipEntity, numSkips), functor(*this, &CLaserBeam::OnRayCastDataReceived)); } } else if (!m_pLaserParams) { GameWarning("LASER PARAMS: Item of type CLaser is missing it's laser params!"); } }
void CUILobbyMP::RegisterLeaderboardCB(CryLobbyTaskID TaskID, ECryLobbyError Error, void *Arg) { if (Error > eCLE_SuccessContinue) GameWarning("CUILobbyMP::RegisterLeaderboardCB: Failed to register, code: %i", Error); }
void CLedgeManager::Serialize( TSerialize ser ) { if (ser.IsReading()) { ser.BeginGroup( "LevelLedges" ); { uint32 objectsToSerialize = 0; ser.Value( "serializedLedgeCount", objectsToSerialize ); for (uint32 idx = 0; idx < objectsToSerialize; ++idx) { ser.BeginGroup( "Ledge" ); { uint32 objectIdx = 0; ser.Value( "ledgeIndex", objectIdx ); if( objectIdx < m_levelLedges.m_ledgeCount ) { SLedgeObject& ledgeObject = m_levelLedges.m_pLedgeObjects[objectIdx]; ser.Value( "flagsIn", ledgeObject.m_ledgeFlags[LedgeSide_In] ); ser.Value( "flagsOut", ledgeObject.m_ledgeFlags[LedgeSide_Out] ); uint32 markerCount = 0; ser.Value( "markersCount", markerCount ); if( markerCount == ledgeObject.m_markersCount ) { const uint32 markerEnd = ledgeObject.m_markersStartIdx + ledgeObject.m_markersCount; CRY_ASSERT( markerEnd <= m_levelLedges.m_markerCount ); for( uint32 markerIdx = ledgeObject.m_markersStartIdx; markerIdx < markerEnd; ++markerIdx ) { SLedgeMarker& marker = m_levelLedges.m_pMarkers[markerIdx]; ser.BeginGroup( "Marker" ); { ser.Value( "pos", marker.m_worldPosition ); ser.Value( "dir", marker.m_facingDirection ); } ser.EndGroup(); // "Marker" } } else { //Save game not in synch with level data GameWarning( "LedgeManager - Trying to update markers for ledge %d, but there is a mismatch in the markers count. %d-%d", objectIdx, markerCount, ledgeObject.m_markersCount ); } } else { //Save game not in synch with level data GameWarning( "LedgeManager - Trying to load saved data for ledge %d, when there is only %d registered", objectIdx, m_levelLedges.m_ledgeCount ); } } ser.EndGroup(); // "Ledge" } } ser.EndGroup(); // "LevelLedges" } else { ser.BeginGroup( "LevelLedges" ); { uint32 objectsToSerialize = 0; for (uint32 objectIdx = 0; objectIdx < m_levelLedges.m_ledgeCount; ++objectIdx) { objectsToSerialize += (m_levelLedges.m_pLedgeObjects[objectIdx].NeedsToBeSerialized()); } ser.Value( "serializedLedgeCount", objectsToSerialize ); for (uint32 objectIdx = 0; objectIdx < m_levelLedges.m_ledgeCount; ++objectIdx) { SLedgeObject& ledgeObject = m_levelLedges.m_pLedgeObjects[objectIdx]; if ( ledgeObject.NeedsToBeSerialized() == false ) continue; ser.BeginGroup( "Ledge" ); { ser.Value( "ledgeIndex", objectIdx ); ser.Value( "flagsIn", ledgeObject.m_ledgeFlags[LedgeSide_In] ); ser.Value( "flagsOut", ledgeObject.m_ledgeFlags[LedgeSide_Out] ); ser.Value( "markersCount", ledgeObject.m_markersCount ); const uint32 markerEnd = ledgeObject.m_markersStartIdx + ledgeObject.m_markersCount; CRY_ASSERT( markerEnd <= m_levelLedges.m_markerCount ); for( uint32 markerIdx = ledgeObject.m_markersStartIdx; markerIdx < markerEnd; ++markerIdx ) { SLedgeMarker& marker = m_levelLedges.m_pMarkers[markerIdx]; ser.BeginGroup( "Marker" ); { ser.Value( "pos", marker.m_worldPosition ); ser.Value( "dir", marker.m_facingDirection ); } ser.EndGroup(); // "Marker" } } ser.EndGroup(); // "Ledge" } } ser.EndGroup(); // "LevelLedges" } }
void CGameStateRecorder::OnRecordedGameplayEvent(IEntity *pEntity, const GameplayEvent &event, int currentFrame, bool bRecording) { EntityId id; m_currentFrame = currentFrame; int demo_forceGameState = 0; if(!bRecording) { ICVar *pVar = gEnv->pConsole->GetCVar("demo_force_game_state"); if(pVar) demo_forceGameState = pVar->GetIVal(); } if(!pEntity || !(id = pEntity->GetId())) return; if(m_IgnoredEvents.size()) if(event.event == m_IgnoredEvents[0]) { m_IgnoredEvents.erase(m_IgnoredEvents.begin()); return; } TGameStates::iterator itActor = m_GameStates.find(id); if(itActor == m_GameStates.end()) { m_GameStates.insert(std::make_pair(id,SActorGameState())); itActor = m_GameStates.find(id); } if(itActor == m_GameStates.end()) { GameWarning("TimeDemo:GameState: actor %s not found in records",pEntity->GetName()); return; } SActorGameState &gstate = itActor->second; switch(event.event) { case eGE_HealthChanged: { gstate.health = event.value; if(!m_bRecording) { CActor *pActor = (CActor *)(gEnv->pGame->GetIGameFramework()->GetIActorSystem()->GetActor(id)); if(pActor) { if(m_bLogWarning) { if(CHECK_MISMATCH(pActor->GetHealth(), gstate.health,10)) { if(!gstate.bHealthDifferent) { GameWarning("TimeDemo:GameState: Frame %d - Actor %s - HEALTH mismatch (%d, %d)",m_currentFrame,pEntity->GetName(), static_cast<int>(pActor->GetHealth()), static_cast<int>(gstate.health)); gstate.bHealthDifferent = true; } } else gstate.bHealthDifferent = false; } if(demo_forceGameState) pActor->SetHealth(gstate.health); } } } break; case eGE_WeaponFireModeChanged: { TItemName sel = (event.description); if(sel) { TItemContainer &Items = gstate.Items; TItemContainer::iterator iti = Items.find(sel); uint8 recFireModeIdx = uint8(event.value); if(iti != Items.end()) iti->second.fireMode = recFireModeIdx; CActor *pActor = (CActor *)(gEnv->pGame->GetIGameFramework()->GetIActorSystem()->GetActor(id)); if(pActor && pActor->GetInventory()) { IItem *pItem = pActor->GetInventory()->GetItemByName(sel); CWeapon *pWeapon; if(pItem && (pWeapon = (CWeapon *)(pItem->GetIWeapon()))) { int fireModeIdx = pWeapon->GetCurrentFireMode(); if(m_bLogWarning) { CheckDifference(recFireModeIdx,fireModeIdx,"TimeDemo:GameState: Frame %d - Actor %s - FIRE MODE mismatch for weapon %s (rec:%d, cur:%d)",pEntity,pItem->GetEntity() ? pItem->GetEntity()->GetName() : "(null)"); } if(demo_forceGameState==2 && fireModeIdx!= recFireModeIdx) pWeapon->SetCurrentFireMode(recFireModeIdx); } } } } break; case eGE_WeaponReload: { const char *ammoType = event.description; TAmmoContainer &ammoMags = gstate.AmmoMags; TAmmoContainer::iterator it = ammoMags.find(ammoType); if(it!=ammoMags.end()) { it->second -= (uint16)event.value; CActor *pActor = (CActor *)(gEnv->pGame->GetIGameFramework()->GetIActorSystem()->GetActor(id)); if(pActor) { CInventory *pInventory = (CInventory *)(pActor->GetInventory()); if(pInventory) { { IEntityClass *pAmmoClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass(ammoType); if(pAmmoClass) { if(m_bLogWarning) CheckDifference(it->second,pInventory->GetAmmoCount(pAmmoClass),"TimeDemo:GameState: Frame %d - Actor %s - WEAPON RELOAD, ammo count mismatch for ammo class %s (rec:%d, cur:%d)",pEntity,ammoType); if(demo_forceGameState == 2) pInventory->SetAmmoCount(pAmmoClass,it->second); } } } } } } break; case eGE_ItemSelected: { TItemName itemName = event.description; gstate.itemSelected = itemName; if(itemName) { if(!bRecording && (event.value > 0 || demo_forceGameState==2)) // EVENT.VALUE > 0 means initialization { CActor *pActor = (CActor *)(gEnv->pGame->GetIGameFramework()->GetIActorSystem()->GetActor(id)); if(pActor && pActor->GetInventory()) { IItem *pItem = pActor->GetInventory()->GetItemByName(itemName); if(pItem) pActor->SelectItem(pItem->GetEntityId(),false); } } } if(m_bLogWarning) { CActor *pActor = (CActor *)(gEnv->pGame->GetIGameFramework()->GetIActorSystem()->GetActor(id)); if(pActor) { IItem *pItem = pActor->GetCurrentItem(); const char *curItemName= pItem && pItem->GetEntity() ? pItem->GetEntity()->GetName(): NULL; CheckDifferenceString(itemName,curItemName,"TimeDemo:GameState: Frame %d - Actor %s - SELECTED ITEM mismatch (rec:%s, cur:%s)",pEntity); } } break; } break; case eGE_ItemExchanged: { // prevent unwanted record/play mismatch error with current item during item exchanging // two unneeded game events are sent (selecting fists) m_IgnoredEvents.push_back(eGE_ItemSelected); m_IgnoredEvents.push_back(eGE_ItemSelected); } break; case eGE_ItemPickedUp: { TItemName sel = (TItemName)event.description; // gstate.itemSelected = sel; TItemContainer &Items = gstate.Items; TItemContainer::iterator it = Items.find(sel); if(it == Items.end()) { Items.insert(std::make_pair(sel,SItemProperties())); it = Items.find(sel); } if(it != Items.end()) { it->second.count++; CActor *pActor = (CActor *)(gEnv->pGame->GetIGameFramework()->GetIActorSystem()->GetActor(id)); if(pActor && !m_bRecording) { CInventory *pInventory = (CInventory *)(pActor->GetInventory()); if(pInventory) { // just check if the item is the inventory if(m_bLogWarning && !pInventory->GetItemByName(sel)) GameWarning("TimeDemo:GameState: Frame %d - Actor %s - Recorded PICKED UP ITEM class '%s' not found in current inventory",m_currentFrame,pEntity->GetName(),sel); if(demo_forceGameState == 2) { IEntity *pItemEntity = gEnv->pEntitySystem->FindEntityByName(sel); if(pItemEntity) pInventory->AddItem(pItemEntity->GetId()); else GameWarning("TimeDemo:GameState: Frame %d - Actor %s - PICKED UP ITEM entity %s not found in level",m_currentFrame,pEntity->GetName(),sel); } } } } else if(m_bLogWarning) { if(!sel) sel = "(null)"; GameWarning("TimeDemo:GameState: Frame %d - Actor %s - PICKED UP ITEM %s not found in recorded inventory",m_currentFrame,pEntity->GetName(),sel); } } break; case eGE_AmmoPickedUp: { uint16 ammoCount = (uint16)(event.value); TItemName sel = (TItemName)event.description; TAmmoContainer &Ammo = gstate.AmmoMags; TAmmoContainer::iterator it = Ammo.find(sel); if(it == Ammo.end()) Ammo.insert(std::make_pair(sel,ammoCount)); else it->second = ammoCount; if(!m_bRecording) { CActor *pActor = (CActor *)(gEnv->pGame->GetIGameFramework()->GetIActorSystem()->GetActor(id)); if(pActor) { CInventory *pInventory = (CInventory *)(pActor->GetInventory()); if(pInventory) { IEntityClass *pClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass(sel); if(m_bLogWarning) CheckDifference(ammoCount,pInventory->GetAmmoCount(pClass),"TimeDemo:GameState: Frame %d - Actor %s - AMMO PICKEDUP: count mismatch for ammo class %s (rec:%d, cur:%d)", pEntity,sel); if(demo_forceGameState == 2) pInventory->SetAmmoCount(pClass,ammoCount); } } } } break; case eGE_AccessoryPickedUp: { TItemName sel = (TItemName)event.description; // gstate.itemSelected = sel; TAccessoryContainer &Accessories = gstate.Accessories; TAccessoryContainer::iterator it = Accessories.find(sel); if(it == Accessories.end()) { Accessories.insert(std::make_pair(sel,1)); } else it->second++; CActor *pActor = (CActor *)(gEnv->pGame->GetIGameFramework()->GetIActorSystem()->GetActor(id)); if(pActor) { CInventory *pInventory = (CInventory *)(pActor->GetInventory()); if(pInventory) { IEntityClass *pClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass(sel); if(m_bLogWarning && !pInventory->HasAccessory(pClass)) GameWarning("TimeDemo:GameState: Frame %d - Actor %s - ACCESSORY PICKEDUP %s not found in current inventory", m_currentFrame, pEntity->GetName(),sel ? sel:"(null)"); if(demo_forceGameState == 2 && pClass) pInventory->AddAccessory(pClass);// doesn't actually add it if it's there already } } } break; case eGE_ItemDropped: { TItemName sel = (TItemName)event.description; //gstate.itemSelected = sel; TItemContainer &Items = gstate.Items; TItemContainer::iterator it = Items.find(sel); if(it != Items.end()) { it->second.count--; if(it->second.count<=0) Items.erase(it); if(demo_forceGameState == 2) { CActor *pActor = (CActor *)(gEnv->pGame->GetIGameFramework()->GetIActorSystem()->GetActor(id)); if(pActor) { CInventory *pInventory = (CInventory *)(pActor->GetInventory()); if(pInventory) { IEntityClass *pClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass(sel); if(pClass) { EntityId itemId = pInventory->GetItemByClass(pClass); if(itemId) pInventory->RemoveItem(itemId); } } } } } else GameWarning("TimeDemo:GameState: Frame %d - Actor %s - ITEM DROPPED, wrong item selected (%s)",m_currentFrame,pEntity->GetName(),sel); } break; case eGE_AmmoCount: { TItemContainer &Items = gstate.Items; TItemName itemClassDesc = event.description; TItemContainer::iterator it = Items.find(itemClassDesc); if(it != Items.end()) { SItemProperties &item = it->second; const char *ammoClassDesc = (const char *)(event.extra); if(ammoClassDesc) { string szAmmoClassDesc(ammoClassDesc); bool bAmmoMag = IsAmmoGrenade(ammoClassDesc); TAmmoContainer &itemAmmo = bAmmoMag ? gstate.AmmoMags : item.Ammo; if(itemAmmo.find(szAmmoClassDesc)==itemAmmo.end()) itemAmmo.insert(std::make_pair(szAmmoClassDesc,int(event.value))); else itemAmmo[szAmmoClassDesc] = (uint16)event.value; if(!bRecording && (m_bLogWarning || demo_forceGameState==2)) { CActor *pActor = (CActor *)(gEnv->pGame->GetIGameFramework()->GetIActorSystem()->GetActor(id)); if(pActor) { CInventory *pInventory = (CInventory *)(pActor->GetInventory()); if(pInventory) { IItem *pItem = pInventory->GetItemByName(itemClassDesc); if(pItem) { CWeapon *pWeapon = (CWeapon *)(pItem->GetIWeapon()); if(pWeapon) { IEntityClass *pAmmoClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass(ammoClassDesc); if(pAmmoClass) { if(m_bLogWarning) { int curAmmoCount = (bAmmoMag ? pInventory->GetAmmoCount(pAmmoClass) : pWeapon->GetAmmoCount(pAmmoClass)); CheckDifference(int(event.value),curAmmoCount,"TimeDemo:GameState: Frame %d - Actor %s - AMMO COUNT mismatch for ammo class %s (rec:%d, cur:%d)",pEntity,ammoClassDesc); } if(demo_forceGameState==2) pWeapon->SetAmmoCount(pAmmoClass,int(event.value)); } } } } } } } else GameWarning("TimeDemo:GameState: Frame %d - Actor %s - AMMO COUNT null ammoClass descriptor",m_currentFrame,pEntity->GetName()); } else GameWarning("TimeDemo:GameState: Frame %d - Actor %s - AMMO COUNT wrong item selected (%s)",m_currentFrame,pEntity->GetName(),itemClassDesc); } break; case eGE_AttachedAccessory: { // always force attachment of accessory to the current weapon // kind of a workaround, the HUD weapon modifier menu is spawned during timedemo playback // but it doesn't use recorded input events if(!bRecording) { CActor *pActor = (CActor *)(gEnv->pGame->GetIGameFramework()->GetIActorSystem()->GetActor(id)); if(pActor) { CInventory *pInventory = (CInventory *)(pActor->GetInventory()); if(pInventory) { const char *sel = event.description; IEntityClass *pClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass(sel); if(!sel) sel = "(null)"; if(!pInventory->HasAccessory(pClass)) { if(m_bLogWarning) GameWarning("TimeDemo:GameState: Frame %d - Actor %s - ATTACHED ACCESSORY %s not found in current inventory", m_currentFrame,pEntity->GetName(),sel); } else { CItem *pCurrentItem = (CItem *)(pActor->GetCurrentItem()); if(pCurrentItem) pCurrentItem->SwitchAccessory(sel); } } } } } break; case eGE_EntityGrabbed: { if(demo_forceGameState==2) { TItemName itemName = event.description; if(itemName) { IEntity *pGrabbedEntity = gEnv->pEntitySystem->FindEntityByName(itemName); if(pGrabbedEntity) { CActor *pActor = (CActor *)(gEnv->pGame->GetIGameFramework()->GetIActorSystem()->GetActor(id)); if(pActor) { IItem *pItem = GetItemOfName(pActor,itemName); if(!pItem) { // it's a pickable entity, won't end up in the inventory //(otherwise it would be managed by eGE_ItemPickedUp) COffHand *pOffHand = static_cast<COffHand *>(pActor->GetWeaponByClass(CItem::sOffHandClass)); if(pOffHand && !pOffHand->GetPreHeldEntityId()) pOffHand->ForcePickUp(pGrabbedEntity->GetId()); } } } } } } break; default: break; } }
//------------------------------------------------------------------------ bool CItem::ReadGeometry(const IItemParamsNode *geometry) { FUNCTION_PROFILER(GetISystem(), PROFILE_GAME); if (!m_sharedparams->Valid()) { // read teh helpers m_sharedparams->helpers.resize(0); const IItemParamsNode *attachments = geometry->GetChild("boneattachments"); if (attachments) { int n = attachments->GetChildCount(); SAttachmentHelper helper; for (int i=0; i<n; i++) { const IItemParamsNode *attachment = attachments->GetChild(i); const char *slot = attachment->GetAttribute("target"); const char *name = attachment->GetAttribute("name"); const char *bone = attachment->GetAttribute("bone"); int islot = TargetToSlot(slot); if (islot == eIGS_Last) { GameWarning("Invalid attachment helper target for item '%s'! Skipping...", GetEntity()->GetName()); continue; } if (!name || !bone) { GameWarning("Invalid attachment helper specification for item '%s'! Skipping...", GetEntity()->GetName()); continue; } helper.name = name; helper.bone = bone; helper.slot = islot; m_sharedparams->helpers.push_back(helper); } } } bool result = true; int n = geometry->GetChildCount(); for (int i=0; i<n; i++) { const IItemParamsNode *child = geometry->GetChild(i); int islot=TargetToSlot(geometry->GetChildName(i)); if (islot!=eIGS_Last) { result = result && SetGeometryFromParams(islot, child); if (result) PlayAction(m_idleAnimation[islot], 0, true, (eIPAF_Default|eIPAF_NoBlend)&~eIPAF_Owner); } } ForceSkinning(true); return result; }
void CGameStateRecorder::OnGameplayEvent(IEntity *pEntity, const GameplayEvent &event) { EntityId id; if(!pEntity || !(id = pEntity->GetId())) { GameWarning("TimeDemo:GameState::OnGamePlayEvent: Entity not found"); return; } CActor *pActor = (CActor *)(gEnv->pGame->GetIGameFramework()->GetIActorSystem()->GetActor(id)); if(!pActor) { GameWarning("TimeDemo:GameState::OnGamePlayEvent: Entity %s has no actor", pEntity->GetName()); return; } GameplayEvent event2 = event; event2.extra = 0;// event2 is the forwarded event, extra either will be not used by the listener or re-set as a string uint8 eType = event.event; bool bPlayer = (pActor->IsPlayer() && m_mode); if(bPlayer || m_mode==GPM_AllActors) { //items switch(eType) { case eGE_ItemPickedUp: { CheckInventory(pActor,0);//,*m_pRecordGameEventFtor); } break; case eGE_ItemDropped: { TItemName itemName = GetItemName(EntityId(event.extra)); if(!itemName) //if(itemIdx < 0) break; event2.description = itemName; SendGamePlayEvent(pEntity,event2); IEntity *pItemEntity = gEnv->pEntitySystem->FindEntityByName(itemName); if(!pItemEntity) break; IItem *pItem = g_pGame->GetIGameFramework()->GetIItemSystem()->GetItem(pItemEntity->GetId()); if(!pItem) break; IEntityClass *pItemClass = pItem->GetEntity()->GetClass(); if(pItemClass && !strcmpi(pItemClass->GetName(),"SOCOM")) { IItem *pCurrentItem = pActor->GetCurrentItem(); if(pCurrentItem) { IEntityClass *pCurrentItemClass = pCurrentItem->GetEntity()->GetClass(); if(pCurrentItemClass && !strcmpi(pCurrentItemClass->GetName(),"SOCOM")) { GameplayEvent event3; event3.event = eGE_ItemSelected; TItemName currItemName = GetItemName(pCurrentItem->GetEntity()->GetId()); if(!currItemName) break; event3.value = 0; event3.description = (const char *)currItemName; SendGamePlayEvent(pEntity,event3); } } } } break; case eGE_WeaponFireModeChanged: { TItemName itemIdx = GetItemName(EntityId(event.extra)); if(!itemIdx)//if(itemIdx < 0) break; event2.description = (const char *)itemIdx; SendGamePlayEvent(pEntity,event2); } break; case eGE_ItemSelected: { EntityId itemId = EntityId(event.extra); TItemName itemIdx = GetItemName(itemId); if(itemId && !itemIdx) break; event2.value = 0; event2.description = (const char *)itemIdx; SendGamePlayEvent(pEntity,event2); } break; case eGE_AttachedAccessory: { if(!IsGrenade(event.description)) // NOT OffHandGrenade SendGamePlayEvent(pEntity,event2); } break; case eGE_AmmoCount: { const char *itemIdx = event.description; if(!itemIdx) break; TGameStates::iterator itGS; /*if(pActor->IsPlayer()) itGS = m_itSingleActorGameState; else */ if(pActor->GetEntity()) itGS = m_GameStates.find(pActor->GetEntity()->GetId()); else break; if(itGS == m_GameStates.end()) break; SActorGameState &gstate = itGS->second; IEntity *pItemEntity = gEnv->pEntitySystem->FindEntityByName(itemIdx); if(!pItemEntity) break; IItem *pItem = g_pGame->GetIGameFramework()->GetIItemSystem()->GetItem(pItemEntity->GetId()); if(!pItem) break; CWeapon *pWeapon = (CWeapon *)(pItem->GetIWeapon()); if(pWeapon && pWeapon->GetEntity()) { TItemContainer::iterator it = gstate.Items.find(itemIdx); if(it==gstate.Items.end()) break; SItemProperties &recItem = it->second; SWeaponAmmo weaponAmmo = pWeapon->GetFirstAmmo(); bool bGrenade = false; if(!weaponAmmo.pAmmoClass) { // special case for grenades if(IsAmmoGrenade((const char *)(event.extra))) { weaponAmmo.pAmmoClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass((const char *)event.extra); weaponAmmo.count = (int)event.value; bGrenade = true; } } for(; weaponAmmo.pAmmoClass ; weaponAmmo = pWeapon->GetNextAmmo()) { int ammoCount = weaponAmmo.count; const char *ammoClass; if(weaponAmmo.pAmmoClass && (ammoClass = weaponAmmo.pAmmoClass->GetName())) { TAmmoContainer &recAmmo = bGrenade? gstate.AmmoMags : recItem.Ammo; if(recAmmo.find(ammoClass) == recAmmo.end()) recAmmo.insert(std::make_pair(ammoClass,0)); if(ammoCount != recAmmo[ammoClass]) { event2.event = eGE_AmmoCount; event2.value = (float)ammoCount; if(event2.value < 0) event2.value = 0; event2.extra = (void *)ammoClass; event2.description = (const char *)itemIdx; SendGamePlayEvent(pEntity,event2); } } } } } break; case eGE_EntityGrabbed: { EntityId entityId = EntityId(event.extra); IEntity *pGrabbedEntity = gEnv->pEntitySystem->GetEntity(entityId); if(pGrabbedEntity) { event2.description = pGrabbedEntity->GetName(); SendGamePlayEvent(pEntity,event2); } } break; case eGE_WeaponReload: case eGE_ZoomedIn: case eGE_ZoomedOut: case eGE_HealthChanged: case eGE_ItemExchanged: SendGamePlayEvent(pEntity,event2); break; default: break; } } }
//------------------------------------------------------------------------ bool CItem::ReadAction(const IItemParamsNode *actionparams, SAction *pAction) { const char *actionName = actionparams->GetAttribute("name"); if (!actionName) { GameWarning("Missing action name for item '%s'! Skipping...", GetEntity()->GetName()); return false; } int children=0; actionparams->GetAttribute("children", children); pAction->children=children!=0; int n = actionparams->GetChildCount(); for (int i=0; i<n; i++) { const IItemParamsNode *child = actionparams->GetChild(i); const char *childName = actionparams->GetChildName(i); if (!stricmp(childName, "sound")) { const char *name = child->GetAttribute("name"); if (!name) { GameWarning("Missing name of sound for action '%s' in item '%s'! Skipping...", actionName, GetEntity()->GetName()); return false; } const char *slot = child->GetAttribute("target"); int islot = TargetToSlot(slot); if ((islot != eIGS_FirstPerson) && (islot != eIGS_ThirdPerson)) { GameWarning("Invalid sound target '%s' for action '%s' in item '%s'! Skipping...", slot, actionName, GetEntity()->GetName()); return false; } if (!pAction->sound[islot].name.empty()) { GameWarning("Sound target '%s' for action '%s' in item '%s' already specified! Skipping...", slot, actionName, GetEntity()->GetName()); return false; } float radius = 1.0f; child->GetAttribute("radius", radius); float sphere = 0.0f; child->GetAttribute("sphere", sphere); int isstatic = 0; child->GetAttribute("static", isstatic); int issynched =0; child->GetAttribute("synched", issynched); pAction->sound[islot].name = name; pAction->sound[islot].airadius = radius; pAction->sound[islot].sphere = sphere; pAction->sound[islot].isstatic = isstatic!=0; pAction->sound[islot].issynched = issynched!=0; } else if (!stricmp(childName, "animation")) { const char *name = child->GetAttribute("name"); if (!name) { GameWarning("Missing name of animation for action '%s' in item '%s'! Skipping...", actionName, GetEntity()->GetName()); return false; } const char *slot = child->GetAttribute("target"); int islot = TargetToSlot(slot); if (islot == eIGS_Last) { GameWarning("Invalid animation target '%s' for action '%s' in item '%s'! Skipping...", slot, actionName, GetEntity()->GetName()); return false; } float speed = 1.0f; child->GetAttribute("speed", speed); float blend = 0.125f; child->GetAttribute("blendTime", blend); SAnimation animation; const char *camera_helper = child->GetAttribute("camera_helper"); if (camera_helper && camera_helper[0]) { int pos=1; child->GetAttribute("camera_position", pos); int rot=1; child->GetAttribute("camera_rotation", rot); int follow=0; child->GetAttribute("camera_follow", follow); int reorient=0; child->GetAttribute("camera_reorient", reorient); animation.camera_helper = camera_helper; animation.camera_pos=pos!=0; animation.camera_rot=rot!=0; animation.camera_follow=follow!=0; animation.camera_reorient=reorient!=0; } animation.name = name; animation.speed = speed; animation.blend = blend; pAction->animation[islot].push_back(animation); } else if (!stricmp(childName, "effect")) { const char *name = child->GetAttribute("name"); if (!name) { GameWarning("Missing name of effect for action '%s' in item '%s'! Skipping...", actionName, GetEntity()->GetName()); return false; } const char *slot = child->GetAttribute("target"); int islot = TargetToSlot(slot); if ((islot != eIGS_FirstPerson) && (islot != eIGS_ThirdPerson)) { GameWarning("Invalid effect target '%s' for action '%s' in item '%s'! Skipping...", slot, actionName, GetEntity()->GetName()); return false; } if (!pAction->effect[islot].name.empty()) { GameWarning("Effect target '%s' for action '%s' in item '%s' already specified! Skipping...", slot, actionName, GetEntity()->GetName()); return false; } pAction->effect[islot].name = name; const char *helper = child->GetAttribute("helper"); if (helper && helper[0]) pAction->effect[islot].helper = helper; } else { GameWarning("Unknown param '%s' for action '%s' in item '%s'! Skipping...", childName, actionName, GetEntity()->GetName()); return false; } } return true; }
// build a script dispatch table - this table is the metatable for all // dispatch proxy tables used (onClient, allClients, otherClients) bool CScriptRMI::BuildDispatchTable( SmartScriptTable methods, SmartScriptTable classMethodTable, SmartScriptTable cls, const char * name ) { IScriptSystem * pSS = methods->GetScriptSystem(); SmartScriptTable dispatch( pSS ); uint8 funcID = 0; IScriptTable::SUserFunctionDesc fd; SFunctionInfo info; IScriptTable::Iterator iter = methods->BeginIteration(); while (methods->MoveNext(iter)) { if (iter.sKey) { const char * function = iter.sKey; if (strlen(function)>=2 && function[0] == '_' && function[1] == '_') { methods->EndIteration(iter); pSS->RaiseError( "In Net.Expose: can't expose functions beginning with '__' (function was %s)", function ); return false; } SmartScriptTable specTable; if (!methods->GetValue(function, specTable)) { methods->EndIteration(iter); pSS->RaiseError( "In Net.Expose: function %s entry is not a table (in %s)", function, name ); return false; } // fetch format int count = specTable->Count(); if (count < 1) { methods->EndIteration(iter); pSS->RaiseError( "In Net.Expose: function %s entry is an empty table (in %s)", function, name ); return false; } else if (count-1 > MaxRMIParameters) { methods->EndIteration(iter); pSS->RaiseError( "In Net.Expose: function %s has too many parameters (%d) (in %s)", function, count-1, name ); return false; } int tempReliability; if (!specTable->GetAt(1, tempReliability) || tempReliability < 0 || tempReliability >= eNRT_NumReliabilityTypes) { methods->EndIteration(iter); pSS->RaiseError( "In Net.Expose: function %s has invalid reliability type %d (in %s)", function, tempReliability, name ); return false; } ENetReliabilityType reliability = (ENetReliabilityType) tempReliability; if (!specTable->GetAt(2, tempReliability) || tempReliability < 0 || tempReliability >= eRAT_NumAttachmentTypes) { methods->EndIteration(iter); pSS->RaiseError( "In Net.Expose: function %s has invalid attachment type %d (in %s)", function, tempReliability, name ); } ERMIAttachmentType attachment = (ERMIAttachmentType) tempReliability; string format; format.reserve(count-1); for (int i=3; i<=count; i++) { int type = 666; if (!specTable->GetAt( i, type ) || type<-128 || type>127) { methods->EndIteration(iter); pSS->RaiseError( "In Net.Expose: function %s has invalid serialization policy %d at %d (in %s)", function, type, i, name ); return false; } format.push_back( (char) type ); } CRY_ASSERT( format.length() <= MaxRMIParameters ); strcpy( info.format, format.c_str() ); info.funcID = funcID; info.reliability = reliability; info.attachment = attachment; fd.pUserDataFunc = ProxyFunction; fd.sFunctionName = function; fd.nDataSize = sizeof(SFunctionInfo); fd.pDataBuffer = &info; fd.sGlobalName = "<net-dispatch>"; fd.sFunctionParams = "(...)"; dispatch->AddFunction( fd ); string lookupData = function; lookupData += ":"; lookupData += format; dispatch->SetAt( funcID+1, lookupData.c_str() ); funcID ++; if (funcID == 0) { funcID--; methods->EndIteration(iter); pSS->RaiseError( "Too many functions... max is %d", funcID ); return false; } } else { GameWarning( "In Net.Expose: non-string key ignored" ); } } methods->EndIteration(iter); dispatch->SetValue( VALIDATED_FIELD, false ); cls->SetValue( name, dispatch ); return true; }
//------------------------------------------------------------------------ bool CItem::ReadLayer(const IItemParamsNode *layer, SLayer *pLayer) { const char *layerName = layer->GetAttribute("name"); if (!layerName) { GameWarning("Missing layer name for item '%s'! Skipping...", GetEntity()->GetName()); return false; } pLayer->isstatic=false; int isstatic; if (layer->GetAttribute("static", isstatic)) pLayer->isstatic = isstatic!=0; int n = layer->GetChildCount(); for (int i=0; i<n; i++) { const IItemParamsNode *child = layer->GetChild(i); if (!stricmp(layer->GetChildName(i), "animation")) { const char *name = child->GetAttribute("name"); if (!name) { GameWarning("Missing name of animation for layer '%s' in item '%s'! Skipping...", layerName, GetEntity()->GetName()); return false; } const char *slot = child->GetAttribute("target"); int islot = TargetToSlot(slot); if (islot == eIGS_Last) { GameWarning("Invalid animation target '%s' of for layer '%s' in item '%s'! Skipping...", slot, layerName, GetEntity()->GetName()); return false; } pLayer->name[islot] = name; pLayer->id[islot] = 0; child->GetAttribute("layerId", pLayer->id[islot]); } else if (!stricmp(layer->GetChildName(i), "bones")) { int nb = child->GetChildCount(); for (int b=0; b<nb; b++) { const IItemParamsNode *bone = child->GetChild(b); if (!stricmp(child->GetChildName(b), "bone")) { const char *name = bone->GetAttribute("name"); if (!name) { GameWarning("Missing name of bone for layer '%s' in item '%s'! Skipping...", layerName, GetEntity()->GetName()); return false; } pLayer->bones.push_back(name); } } } else { GameWarning("Unknown param '%s' for layer '%s' in item '%s'! Skipping...", layer->GetChildName(i), layerName, GetEntity()->GetName()); return false; } } return true; }
// one-time validation of entity tables bool CScriptRMI::ValidateDispatchTable( const char * clazz, SmartScriptTable dispatch, SmartScriptTable methods, bool bServerTable ) { CryAutoCriticalSection lkDispatch(m_dispatchMutex); std::map<string,size_t>::iterator iterN = m_entityClassToEntityTypeID.lower_bound(clazz); if (iterN == m_entityClassToEntityTypeID.end() || iterN->first != clazz) { iterN = m_entityClassToEntityTypeID.insert( iterN, std::make_pair(clazz, m_entityClassToEntityTypeID.size()) ); CRY_ASSERT(iterN->second == m_dispatch.size()); m_dispatch.push_back(SDispatch()); } SDispatch& dispatchTblCont = m_dispatch[iterN->second]; SFunctionDispatchTable& dispatchTbl = bServerTable ? dispatchTblCont.server : dispatchTblCont.client; IScriptTable::Iterator iter = dispatch->BeginIteration(); while (dispatch->MoveNext(iter)) { if (iter.sKey) { if (iter.sKey[0] == '_' && iter.sKey[1] == '_') continue; ScriptVarType type = methods->GetValueType( iter.sKey ); if (type != svtFunction) { GameWarning( "In class %s: function %s is exposed but not defined", clazz, iter.sKey ); dispatch->EndIteration(iter); return false; } } else { int id = iter.nKey; CRY_ASSERT(id>0); id--; if (id >= dispatchTbl.size()) dispatchTbl.resize(id+1); SFunctionDispatch& dt = dispatchTbl[id]; if (iter.value.GetVarType() != svtString) { GameWarning("Expected a string in dispatch table, got type %d", iter.value.GetVarType()); dispatch->EndIteration(iter); return false; } const char * funcData = iter.value.str; const char * colon = strchr(funcData, ':'); if (colon == NULL) { dispatch->EndIteration(iter); return false; } if (colon - funcData > MaxSynchedPropertyNameLength) { dispatch->EndIteration(iter); return false; } memcpy( dt.name, funcData, colon-funcData ); dt.name[colon-funcData] = 0; strcpy(dt.format, colon + 1); } } dispatch->EndIteration(iter); dispatch->SetValue( VALIDATED_FIELD, true ); if (bServerTable) { dispatchTblCont.m_serverDispatchScriptTable = dispatch; } else { dispatchTblCont.m_clientDispatchScriptTable = dispatch; } return true; }
bool CDialogActorContext::Update(float dt) { if (IsAborted()) return true; // FIXME: this should never happen, as we should get a notification before. // temp leave in for tracking down a bug [AlexL: 23/11/2006] IEntity* pEntity = gEnv->pEntitySystem->GetEntity(m_entityID); if (pEntity == 0) { m_pIActor = 0; GameWarning("[DIALOG] CDialogActorContext::Update: %s Actor=%d (EntityId=%d) no longer existent.", m_pSession->GetDebugName(), m_actorID, m_entityID); AbortContext(true, CDialogSession::eAR_EntityDestroyed); return true; } CDialogSession::AlertnessInterruptMode alertnessInterruptMode = m_pSession->GetAlertnessInterruptMode(); if(alertnessInterruptMode != CDialogSession::None) { if(IAIObject* aiObject = pEntity->GetAI()) { if(IAIActorProxy* aiActorProxy = aiObject->GetProxy()) { if(aiActorProxy->GetAlertnessState() >= alertnessInterruptMode) { AbortContext(true, CDialogSession::eAR_AIAborted); return true; } } } } float now = m_pSession->GetCurTime(); if (!CheckActorFlags(CDialogSession::eDACF_NoActorDeadAbort) && m_pIActor && m_pIActor->IsDead()) { if (!IsAborted()) { DiaLOG::Log(DiaLOG::eAlways, "[DIALOG] CDialogActorContext::Update: %s Actor=%d (EntityId=%d) has died. Aborting.", m_pSession->GetDebugName(), m_actorID, m_entityID); AbortContext(true, CDialogSession::eAR_ActorDead); return true; } } if (m_bIsLocalPlayer) { // when the local player is involved in the conversation do some special checks if (DoLocalPlayerChecks(dt) == false) { DiaLOG::Log(DiaLOG::eAlways, "[DIALOG] CDialogActorContext::Update: %s Abort from LocalPlayer.", m_pSession->GetDebugName()); AbortContext(true, m_bIsAwareInRange == false ? CDialogSession::eAR_PlayerOutOfRange : CDialogSession::eAR_PlayerOutOfView); return true; } } if (m_bAbortFromAI) { m_bAbortFromAI = false; if (!IsAborted()) { DiaLOG::Log(DiaLOG::eAlways, "[DIALOG] CDialogActorContext::Update: %s Abort from AI.", m_pSession->GetDebugName()); AbortContext(true, CDialogSession::eAR_AIAborted); return true; } } if (SessionAllowsLookAt()) { DoStickyLookAt(); } int loop = 0; do { // DiaLOG::Log("[DIALOG] DiaLOG::eAlways"CDialogActorContext::Update: %s now=%f actorId=%d loop=%d", m_pSession->GetDebugName(), now, m_actorID, loop); bool bAdvance = false; switch (m_phase) { case eDAC_Idle: break; case eDAC_NewLine: { m_bHasScheduled = false; m_lookAtTimeOut = LOOKAT_TIMEOUT; m_animTimeOut = ANIM_TIMEOUT; m_soundTimeOut = SOUND_TIMEOUT; // wait one second until sound is timed out m_bAnimScheduled = false; m_bAnimStarted = false; m_bSoundScheduled = false; m_bSoundStarted = false; m_soundLength = 0.0f; if (m_pCurLine->m_flagResetLookAt) { m_stickyLookAtActorID = CDialogScript::NO_ACTOR_ID; m_lookAtActorID = CDialogScript::NO_ACTOR_ID; } // check if look-at sticky is set else if (m_pCurLine->m_lookatActor != CDialogScript::NO_ACTOR_ID) { if (m_pCurLine->m_flagLookAtSticky == false) { m_lookAtActorID = m_pCurLine->m_lookatActor; m_stickyLookAtActorID = CDialogScript::NO_ACTOR_ID; } else { m_stickyLookAtActorID = m_pCurLine->m_lookatActor; m_lookAtActorID = CDialogScript::NO_ACTOR_ID; } } bAdvance = true; // handle the first sticky look-at here if (SessionAllowsLookAt()) { DoStickyLookAt(); } } break; case eDAC_LookAt: { bool bWaitForLookAtFinish = true; bAdvance = true; if (SessionAllowsLookAt() == false) { break; } // Question: maybe do this although EP is requested if (bWaitForLookAtFinish && m_lookAtActorID != CDialogScript::NO_ACTOR_ID && m_pCurLine->m_flagAGEP == false) { IEntity* pActorEntity = m_pSession->GetActorEntity(m_actorID); IEntity* pLookAtEntity = m_pSession->GetActorEntity(m_lookAtActorID); if (pActorEntity != 0) { m_lookAtTimeOut -= dt; bool bTargetReached; //bool bSuccess = DoLookAt(pActorEntity, pLookAtEntity, bTargetReached); DoLookAt(pActorEntity, pLookAtEntity, bTargetReached); //DiaLOG::Log(DiaLOG::eDebugA, "[DIALOG] CDialogActorContext::Update: %s now=%f actorID=%d phase=eDAC_LookAt %d", // m_pSession->GetDebugName(), now, m_actorID, bTargetReached); if (/* bSuccess == false || */ bTargetReached || m_lookAtTimeOut<=0.0f) { DiaLOG::Log(DiaLOG::eAlways, "[DIALOG] CDialogActorContext::Update: %s now=%f actorID=%d phase=eDAC_LookAt %s", m_pSession->GetDebugName(), now, m_actorID, bTargetReached ? "Target Reached" : "Timed Out"); m_lookAtActorID = CDialogScript::NO_ACTOR_ID; } else bAdvance = false; } } } break; case eDAC_Anim: { bAdvance = true; if (SessionAllowsLookAt() && m_lookAtActorID != CDialogScript::NO_ACTOR_ID) // maybe: don't do this when EP is requested [&& m_pCurLine->m_flagAGEP == false] { IEntity* pActorEntity = m_pSession->GetActorEntity(m_actorID); IEntity* pLookAtEntity = m_pSession->GetActorEntity(m_lookAtActorID); if (pActorEntity != 0) { m_lookAtTimeOut -= dt; bool bTargetReached; //bool bSuccess = DoLookAt(pActorEntity, pLookAtEntity, bTargetReached); DoLookAt(pActorEntity, pLookAtEntity, bTargetReached); if (/* bSuccess == false || */ bTargetReached || m_lookAtTimeOut<=0.0f) { DiaLOG::Log(DiaLOG::eAlways, "[DIALOG] CDialogActorContext::Update: %s now=%f actorID=%d phase=eDAC_Anim %s", m_pSession->GetDebugName(), now, m_actorID, bTargetReached ? "Target Reached" : "Timed Out"); m_lookAtActorID = CDialogScript::NO_ACTOR_ID; } else bAdvance = false; } } const bool bHasAnim = !m_pCurLine->m_anim.empty(); if (SessionAllowsAnim() && bHasAnim) { bAdvance = false; if (!m_bAnimScheduled) { m_bSoundStopsAnim = false; // whenever there is a new animation, no need for the still playing sound // to stop the animation m_bAnimStarted = false; m_bAnimScheduled = true; // schedule animation IEntity* pActorEntity = m_pSession->GetActorEntity(m_actorID); if (pActorEntity) DoAnimAction(pActorEntity, m_pCurLine->m_anim, m_pCurLine->m_flagAGSignal, m_pCurLine->m_flagAGEP); else bAdvance = true; } else { // we scheduled it already // wait until it starts or timeout m_animTimeOut-=dt; bAdvance = m_animTimeOut <= 0.0f || m_bAnimStarted; if (bAdvance) { DiaLOG::Log(DiaLOG::eAlways, "[DIALOG] CDialogActorContext::Update: %s Now=%f actorID=%d phase=eDAC_Anim %s", m_pSession->GetDebugName(), now, m_actorID, m_bAnimStarted ? "Anim Started" : "Anim Timed Out"); } } } } break; case eDAC_ScheduleSoundPlay: { bAdvance = true; const bool bHasSound = !m_pCurLine->m_sound.empty(); if (bHasSound) { if (m_bSoundScheduled == false) { IEntity* pActorEntity = m_pSession->GetActorEntity(m_actorID); if (pActorEntity == 0) break; IEntityAudioProxy* pActorAudioProxy = m_pSession->GetEntityAudioProxy(pActorEntity); if (pActorAudioProxy == 0) break; REINST("play voice line"); // start a new sound //int sFlags = CDialogActorContext::SOUND_FLAGS; //if (CDialogSystem::sLoadSoundSynchronously != 0) // sFlags |= FLAG_SOUND_LOAD_SYNCHRONOUSLY; // //// if it's the local player make the sound relative to the entity //if (m_bIsLocalPlayer) // sFlags |= FLAG_SOUND_RELATIVE; //const char* soundKey = GetSoundKey(m_pCurLine->m_sound); //ISound* pSound = 0; //pSound = gEnv->pAudioSystem->CreateSound(soundKey, sFlags); //DiaLOG::Log(DiaLOG::eDebugA, "[DIALOG] CDialogActorContex::Update: %s Now=%f actorID=%d phase=eDAC_ScheduleSoundPlay: Starting '%s' [key=%s]", // m_pSession->GetDebugName(), now, m_actorID, m_pCurLine->m_sound.c_str(), soundKey); //if (!pSound) //{ // GameWarning("[DIALOG] CDialogActorContext::Update: %s ActorID=%d: Cannot play sound '%s'", // m_pSession->GetDebugName(), m_actorID, m_pCurLine->m_sound.c_str()); //} //if (pSound) //{ // if (m_bSoundStopsAnim) // { // m_bSoundStopsAnim = false; // if (m_pAGState != 0) // { // ResetAGState(); // DiaLOG::Log(DiaLOG::eDebugA, "[DIALOG] CDialogActorContext::Update: %s Now=%f actorID=%d phase=eDAC_ScheduleSoundPlay: Stopping old animation", // m_pSession->GetDebugName(), now, m_actorID); // } // } // StopSound(); // apparently, if we dont explicitely stop the sound, in rare cases it never stops. Im pretty sure that is an engine/fmod bug. // // stopping it this way may lead to some subtitles staying for an extra couple seconds on screen (this comes from another engine bug/problem related to an extra fade out time added to cover the dummy NAX soudns) // m_soundID = pSound->GetId(); // m_bSoundStarted = false; // m_bSoundScheduled = true; // // tell the animation whether to stop on sound stop // m_bSoundStopsAnim = m_pCurLine->m_flagSoundStopsAnim; // DiaLOG::Log(DiaLOG::eDebugA, "[DIALOG] CDialogActorContext::Update: %s Now=%f actorID=%d phase=eDAC_ScheduleSoundPlay: Reg as listener on 0x%p '%s'", // m_pSession->GetDebugName(), now, m_actorID, pSound, pSound->GetName()); // pSound->SetSemantic(eSoundSemantic_Dialog); // pSound->AddEventListener(this, "DialogActor"); // event listener will set m_soundLength // // sound proxy uses head pos on dialog sounds // const bool bResult = pActorAudioProxy->PlaySound(pSound, Vec3(ZERO), FORWARD_DIRECTION, 1.0f); // if (bResult) // { // // Fetch some localization info for the sound // ILocalizationManager* pLocMgr = gEnv->pSystem->GetLocalizationManager(); // if (pLocMgr && CDialogSystem::sWarnOnMissingLoc != 0) // { // SLocalizedInfoGame GameInfo; // const bool bFound = pLocMgr->GetLocalizedInfoByKey(soundKey, GameInfo); // if (!bFound) // { // GameWarning("[DIALOG] CDialogActorContext::Update: '%s' DialogScript '%s': Localized info for '%s' not found!", // m_pSession->GetDebugName(), m_pSession->GetScript()->GetID().c_str(), m_pCurLine->m_sound.c_str()); // } // } // bAdvance = false; // don't advance // } // else // { // GameWarning("[DIALOG] CDialogActorContext::Update: %s ActorID=%d: Cannot play sound '%s' [AudioProxy ignored playback]", // m_pSession->GetDebugName(), m_actorID, m_pCurLine->m_sound.c_str()); // pSound->Stop(ESoundStopMode_AtOnce); // m_soundID = INVALID_SOUNDID; // pSound->RemoveEventListener(this); // pSound = NULL; // } //} //else //{ // GameWarning("[DIALOG] CDialogActorContext::Update: %s ActorID=%d: Cannot play sound '%s' [AudioProxy returns invalid sound]", // m_pSession->GetDebugName(), m_actorID, m_pCurLine->m_sound.c_str()); //} } else { // sound has been scheduled // wait for sound start or timeout m_soundTimeOut-=dt; const bool bTimedOut = m_soundTimeOut <= 0.0f; bAdvance = bTimedOut || m_bSoundStarted; if (bAdvance) { if (bTimedOut) StopSound(true); // unregister from sound as listener and free resource DiaLOG::Log(DiaLOG::eAlways, "[DIALOG] CDialogActorContext::Update: %s Now=%f actorID=%d phase=eDAC_ScheduleSoundPlay %s", m_pSession->GetDebugName(), now, m_actorID, m_bSoundStarted ? "Sound Started" : "Sound Timed Out"); } } } } break; case eDAC_SoundFacial: { bAdvance = true; const bool bHasSound = !m_pCurLine->m_sound.empty(); const bool bHasFacial = !m_pCurLine->m_facial.empty() || m_pCurLine->m_flagResetFacial; if (bHasFacial) { IEntity* pActorEntity = m_pSession->GetActorEntity(m_actorID); if (pActorEntity) DoFacialExpression(pActorEntity, m_pCurLine->m_facial, m_pCurLine->m_facialWeight, m_pCurLine->m_facialFadeTime); } float delay = m_pCurLine->m_delay; if (bHasSound && m_bSoundStarted) { if (m_soundLength < 0.0f) { m_soundLength = Random(2.0f,6.0f); DiaLOG::Log(DiaLOG::eAlways, "[DIALOG] CDialogActorContext::Update: %s Now=%f actorID=%d phase=eDAC_SoundFacial Faking SoundTime to %f", m_pSession->GetDebugName(), now, m_actorID, m_soundLength); } DiaLOG::Log(DiaLOG::eAlways, "[DIALOG] CDialogActorContext::Update: %s Now=%f actorID=%d phase=eDAC_SoundFacial Delay=%f SoundTime=%f", m_pSession->GetDebugName(), now , m_actorID, delay, m_soundLength); delay += m_soundLength; } // schedule END if (delay < 0.0f) delay = 0.0f; m_pSession->ScheduleNextLine(delay+0.05f); // ~1 frame at 20 fps. we now stop the current line sound before going for next line. Sometimes, this stop call is right before the // sound has actually stopped in engine side. When that happens, the engine is adding ~2 seconds extra to the sound duration (because fade problems related to NAX header) // and that looks bad if subtitles are enabled. So we add this small delay here to try to minimize that situation. // this is part of the workaround for some dialogs apparently never finishing in the engine side (rare). m_bHasScheduled = true; } break; case eDAC_EndLine: bAdvance = true; if (m_bHasScheduled == false) { m_bHasScheduled = true; m_pSession->ScheduleNextLine(m_pCurLine->m_delay); } break; } if (bAdvance) { AdvancePhase(); dt = 0.0f; ++loop; assert (loop <= eDAC_EndLine+1); if (loop > eDAC_EndLine+1) { DiaLOG::Log(DiaLOG::eAlways, "[DIALOG] CDialogActorContext::Update: %s Actor=%d InternalLoopCount=%d. Final Exit!", m_pSession->GetDebugName(), m_actorID, loop); } } else break; } while (true); return true; }
int CScriptBind_Boids::CreateFlock( IFunctionHandler *pH, SmartScriptTable entity,int nType,SmartScriptTable paramTable ) { if(boids_enabled == 0) return 0; IEntity *pEntity = GetEntity(entity); if (!pEntity) { GameWarning( "Boids.CreateFlock called with an invalid entity" ); return pH->EndFunction(); } pEntity->SetFlags( pEntity->GetFlags() | ENTITY_FLAG_CLIENT_ONLY ); CFlock *pFlock = 0; switch (nType) { case EFLOCK_BIRDS: pFlock = new CBirdsFlock(pEntity); break; case EFLOCK_CHICKENS: pFlock = new CChickenFlock(pEntity); break; case EFLOCK_FISH: pFlock = new CFishFlock(pEntity); break; case EFLOCK_FROGS: pFlock = new CFrogFlock(pEntity); break; case EFLOCK_TURTLES: pFlock = new CTurtleFlock(pEntity); break; case EFLOCK_BUGS: pFlock = new CBugsFlock(pEntity); break; } if (pFlock==NULL) { GameWarning( "Boids.CreateFlock wrong flock type %d specified",nType ); return pH->EndFunction(); } ////////////////////////////////////////////////////////////////////////// // Creates a boids proxy for this entity, and attach flock to it. CBoidsProxyPtr pBoidsProxy = ComponentCreateAndRegister_DeleteWithRelease<CBoidsProxy>( IComponent::SComponentInitializer(pEntity), true ); pEntity->SetProxy( ENTITY_PROXY_BOIDS,pBoidsProxy ); SBoidContext bc; pFlock->GetBoidSettings( bc ); SBoidsCreateContext ctx; if (ReadParamsTable( paramTable,bc,ctx )) { bc.entity = pEntity; pFlock->SetBoidSettings( bc ); pFlock->CreateBoids( ctx ); } // Assign flock to boids proxy and update some settings. pBoidsProxy->SetFlock(pFlock); return pH->EndFunction(); }
void CAutoTester::Start(const char *stateSetup, const char *outputPath, bool quitWhenDone) { // If the string has any '#' characters in it (the "new" seperator) then we'll split the string up at those characters... // If not, we'll use '!' (the "old" seperator) char breakAtChar = strchr(stateSetup, '#') ? '#' : '!'; CryLogAlways("CAutoTester::Start() stateSetup=\"%s\" outputPath=\"%s\" seperator=\"%c\"", stateSetup, outputPath, breakAtChar); assert(!m_started); m_started=true; m_outputPath=outputPath; m_quitWhenDone = quitWhenDone; const char *str=stateSetup; // .dll hell stops simple access to memReplay functionality so can't look for running -memReplay // memReplay commands all early exit if they fail anyways gEnv->pConsole->ExecuteString("memReplayDumpSymbols"); #define MAX_TOKEN_LEN 128 char tokenName[MAX_TOKEN_LEN]; char valueName[MAX_TOKEN_LEN]; bool success; memset(&m_stateData, 0, sizeof(m_stateData)); success = GetParam(&str, tokenName, MAX_TOKEN_LEN, valueName, MAX_TOKEN_LEN, breakAtChar); assert (m_state == ATEST_STATE_NONE); if (success && stricmp(tokenName, "state") == 0) { m_state = FindStateFromStr(valueName); cry_strncpy(m_includeThisInFileName, valueName, sizeof(m_includeThisInFileName)); CryLogAlways("CAutoTester::Start initializing state (name='%s', id=%d, %s)", valueName, m_state, (m_state == ATEST_STATE_NONE) ? "invalid" : "valid"); DesignerWarning (m_state != ATEST_STATE_NONE, "'%s' is not the name of an auto-test state", valueName); // If anything needs to default to something non-zero, set it here... switch (m_state) { case ATEST_STATE_TEST_PERFORMANCE: m_stateData.testPerformance.m_subState = CAutoTester::k_testPerformance_substate_ingame; break; } // Read each parameter... while (GetParam(&str, tokenName, MAX_TOKEN_LEN, valueName, MAX_TOKEN_LEN, breakAtChar)) { bool paramUsed = false; if (stricmp(tokenName, "outputName") == 0) { cry_strncpy(m_includeThisInFileName, valueName, sizeof(m_includeThisInFileName)); CryLogAlways("CAutoTester::Start has set output name to '%s'", m_includeThisInFileName); m_createVerboseFilename=false; paramUsed = true; } else { switch (m_state) { case ATEST_STATE_TEST_NUM_CLIENTS: if (stricmp(tokenName, "timeToRun") == 0) { m_stateData.testNumClients.m_timeOut = (float)atof(valueName); paramUsed = true; } else if (stricmp(tokenName, "numClients") == 0) { m_stateData.testNumClients.m_numClientsExpected = atoi(valueName); paramUsed = true; } break; case ATEST_STATE_TEST_NUM_CLIENTS_LEVEL_ROTATE: if (stricmp(tokenName, "timeToRunEachLevel") == 0) { m_stateData.testNumClientsRotate.m_levelTimeOut = (float)atof(valueName); paramUsed = true; } else if (stricmp(tokenName, "numClients") == 0) { m_stateData.testNumClientsRotate.m_numClientsExpected = atoi(valueName); paramUsed = true; } else if (stricmp(tokenName, "timeToRunFirstLevel") == 0) { m_stateData.testNumClientsRotate.m_firstLevelTimeOut = (float)atof(valueName); paramUsed = true; } break; #if ENABLE_FEATURE_TESTER case ATEST_STATE_TEST_FEATURES: if (stricmp(tokenName, "rules") == 0) { CryLogAlways ("CAutoTester::Start executing 'sv_gamerules %s'", valueName); gEnv->pConsole->ExecuteString(string().Format("sv_gamerules %s", valueName)); paramUsed = true; } else if (stricmp(tokenName, "level") == 0) { IGameRulesSystem * gameRulesSystem = gEnv->pGame->GetIGameFramework()->GetIGameRulesSystem(); const char * sv_gamerules = gEnv->pConsole->GetCVar("sv_gamerules")->GetString(); const char * fullGameRulesName = gameRulesSystem->GetGameRulesName(sv_gamerules); bool isMultiPlayerMode = (fullGameRulesName && strcmp(fullGameRulesName, "SinglePlayer") != 0); const char * additionalParams = isMultiPlayerMode ? " s nb" : ""; if (gEnv->bMultiplayer != isMultiPlayerMode) { GameWarning("Auto-tester is loading '%s' in mode '%s' while environment is set up for %s", valueName, sv_gamerules, gEnv->bMultiplayer ? "multi-player" : "single-player"); } CryLogAlways ("CAutoTester::Start executing 'map %s%s' (mode is '%s' i.e. '%s' so isMultiPlayer=%d)", valueName, additionalParams, sv_gamerules, fullGameRulesName, isMultiPlayerMode); if (isMultiPlayerMode) { gEnv->pConsole->ExecuteString("net_setonlinemode lan"); } gEnv->pConsole->ExecuteString(string().Format("map %s%s", valueName, additionalParams)); paramUsed = true; } else if (stricmp(tokenName, "set") == 0) { cry_strncpy(m_stateData.testRunFeatureTests.m_setNames, valueName, sizeof(m_stateData.testRunFeatureTests.m_setNames)); paramUsed = true; } else if (stricmp(tokenName, "file") == 0) { cry_strncpy(m_stateData.testRunFeatureTests.m_loadFileName, valueName, sizeof(m_stateData.testRunFeatureTests.m_loadFileName)); paramUsed = true; } break; #endif case ATEST_STATE_TEST_PERFORMANCE: if (stricmp(tokenName, "configFile") == 0) { cry_strncpy(m_stateData.testPerformance.m_configFile, valueName, 256); //m_stateData.testPerformance.m_configFile = valueName; CryLogAlways ("CAutoTester::Start configFile set '%s'", valueName); paramUsed = true; } else if (stricmp(tokenName, "timeToRun") == 0) { m_stateData.testPerformance.m_timeOut = (float)atof(valueName); paramUsed = true; } else if (stricmp(tokenName, "delayToStart") == 0) { m_stateData.testPerformance.m_delayToStart = (float)atof(valueName); paramUsed = true; } break; } DesignerWarning(paramUsed, "Unexpected key/value pair '%s'='%s' in %s setup string!", tokenName, valueName, s_autoTesterStateNames[m_state]); } } // All parameters have been read... now finish initialization switch (m_state) { case ATEST_STATE_TEST_NUM_CLIENTS_LEVEL_ROTATE: { if (m_stateData.testNumClientsRotate.m_firstLevelTimeOut == 0) { CryLogAlways("no timeToRunFirstLevel set, setting to timeToRunEachLevel=%d", (int)m_stateData.testNumClientsRotate.m_levelTimeOut); m_stateData.testNumClientsRotate.m_firstLevelTimeOut = m_stateData.testNumClientsRotate.m_levelTimeOut; } float timeSeconds=gEnv->pTimer->GetFrameStartTime().GetSeconds(); m_stateData.testNumClientsRotate.m_nextTimeOut = timeSeconds + m_stateData.testNumClientsRotate.m_firstLevelTimeOut; // level rotation is setup with +sv_levelrotation levelrotation.xml and also -root to override looking in the profile dir gEnv->pConsole->ExecuteString("g_nextlevel"); // has to be a better way of doing this break; } case ATEST_STATE_TEST_FEATURES: #if ENABLE_FEATURE_TESTER m_writeResultsCompleteTestCasePass = true; if (m_stateData.testRunFeatureTests.m_loadFileName[0]) { gEnv->pConsole->ExecuteString(string().Format("ft_load %s", m_stateData.testRunFeatureTests.m_loadFileName)); } if (m_stateData.testRunFeatureTests.m_setNames[0]) { CFeatureTester::GetInstance()->InformAutoTesterOfResults(this); gEnv->pConsole->ExecuteString(string().Format("ft_runAll %s", m_stateData.testRunFeatureTests.m_setNames)); } #else DesignerWarning(false, "Feature tester is not included in this build!"); #endif break; } } else { CRY_ASSERT_MESSAGE(0, string().Format("CAutoTester::Start() failed to find state at start in %s", stateSetup)); } // TODO will maybe need to load in the existing file if we want all tests in the same file... junit/bamboo should cope with each test in a different file? }
void CDownloadableResource::StartDownloading() { if (m_state==k_notStarted) { if (m_port==0) { GameWarning("Error tried to start downloading on unconfigured CDownloadableResource"); m_state=k_failedInternalError; } else { STCPServiceDataPtr pTransaction(NULL); m_pService=gEnv->pNetwork->GetLobby()->GetLobbyService()->GetTCPService(m_server,m_port); if (m_pService) { static const int MAX_HEADER_SIZE=300; CryFixedStringT<MAX_HEADER_SIZE> httpHeader; // For HTTP 1.0. /*httpHeader.Format( "GET /%s%s HTTP/1.0\n" "\n", m_urlPrefix.c_str(), m_url.c_str());*/ // For HTTP 1.1. Needed to download data from servers that are "multi-homed" httpHeader.Format( "GET /%s%s HTTP/1.1\n" "Host: %s:%d\n" "\n", m_urlPrefix.c_str(), m_url.c_str(), m_server.c_str(), m_port); pTransaction=new STCPServiceData(); if (pTransaction) { int len=httpHeader.length(); pTransaction->length=len; pTransaction->pData=new char[len]; if (pTransaction->pData) { memcpy(pTransaction->pData,httpHeader.c_str(),len); pTransaction->tcpServReplyCb=ReceiveDataCallback; pTransaction->pUserArg=this; // do ref counting manually for callback data this->AddRef(); #if DOWNLOAD_MGR_DBG m_downloadStarted=gEnv->pTimer->GetAsyncCurTime(); #endif m_state=k_awaitingHTTPResponse; if (!m_pService->UploadData(pTransaction)) { this->Release(); pTransaction=NULL; } } else { pTransaction=NULL; } } } if (!pTransaction) { m_state=k_failedInternalError; } } } }
// //----------------------------------------------------------------------------------------------------------- // (MATT) Moved here from Scriptbind_AI when that was moved to the AI system {2008/02/15:15:23:16} int CScriptBind_Action::RegisterWithAI(IFunctionHandler *pH) { if (gEnv->bMultiplayer && !gEnv->bServer) return pH->EndFunction(); int type; ScriptHandle hdl; if (!pH->GetParams(hdl, type)) return pH->EndFunction(); EntityId entityID = (EntityId)hdl.n; IEntity *pEntity = gEnv->pEntitySystem->GetEntity(entityID); if(!pEntity) { GameWarning("RegisterWithAI: Tried to set register with AI nonExisting entity with id [%d]. ", entityID); return pH->EndFunction(); } // Apparently we can't assume that there is just one IGameObject to an entity, because we choose between (at least) Actor and Vehicle objects. // (MATT) Do we really need to check on the actor system here? {2008/02/15:18:38:34} IGameFramework *pGameFramework = gEnv->pGame->GetIGameFramework(); IVehicleSystem* pVSystem = pGameFramework->GetIVehicleSystem(); IActorSystem* pASystem = pGameFramework->GetIActorSystem(); if(!pASystem) { GameWarning("RegisterWithAI: no ActorSystem for %s.", pEntity->GetName()); return pH->EndFunction(); } AIObjectParams params(type, 0, entityID); bool autoDisable(true); // For most types, we need to parse the tables // For others we leave them blank switch (type) { case AIOBJECT_ACTOR: case AIOBJECT_2D_FLY: case AIOBJECT_BOAT: case AIOBJECT_CAR: case AIOBJECT_HELICOPTER: case AIOBJECT_INFECTED: case AIOBJECT_ALIENTICK: case AIOBJECT_HELICOPTERCRYSIS2: if(gEnv->pAISystem && ! gEnv->pAISystem->ParseTables(3, true, pH, params, autoDisable)) return pH->EndFunction(); default:; } // Most types check these, so just get them in advance IActor* pActor = pASystem->GetActor( pEntity->GetId() ); IVehicle* pVehicle = NULL; if( pVSystem ) pVehicle = pVSystem->GetVehicle( pEntity->GetId() ); // Set this if we've found something to create a proxy from IGameObject* pGameObject = NULL; switch(type) { case AIOBJECT_ACTOR: case AIOBJECT_2D_FLY: case AIOBJECT_INFECTED: case AIOBJECT_ALIENTICK: { // (MATT) The pActor/pVehicle test below - is it basically trying to distiguish between the two cases above? If so, separate them! {2008/02/15:19:38:08} if(!pActor) { GameWarning("RegisterWithAI: no Actor for %s.", pEntity->GetName()); return pH->EndFunction(); } pGameObject = pActor->GetGameObject(); } break; case AIOBJECT_BOAT: case AIOBJECT_CAR: { if(!pVehicle) { GameWarning("RegisterWithAI: no Vehicle for %s (Id %i).", pEntity->GetName(), pEntity->GetId()); return pH->EndFunction(); } pGameObject = pVehicle->GetGameObject(); } break; case AIOBJECT_HELICOPTER: case AIOBJECT_HELICOPTERCRYSIS2: { if(!pVehicle) { GameWarning("RegisterWithAI: no Vehicle for %s (Id %i).", pEntity->GetName(), pEntity->GetId()); return pH->EndFunction(); } pGameObject = pVehicle->GetGameObject(); params.m_moveAbility.b3DMove = true; } break; case AIOBJECT_PLAYER: { if(IsDemoPlayback()) return pH->EndFunction(); SmartScriptTable pTable; if (pH->GetParamCount() > 2) pH->GetParam(3,pTable); else return pH->EndFunction(); pGameObject = pActor->GetGameObject(); pTable->GetValue("groupid",params.m_sParamStruct.m_nGroup); const char* faction = 0; if (pTable->GetValue("esFaction", faction) && gEnv->pAISystem) { params.m_sParamStruct.factionID = gEnv->pAISystem->GetFactionMap().GetFactionID(faction); if (faction && *faction && (params.m_sParamStruct.factionID == IFactionMap::InvalidFactionID)) { GameWarning("Unknown faction '%s' being set...", faction); } } else { // Márcio: backwards compatibility int species = -1; if (!pTable->GetValue("eiSpecies", species)) pTable->GetValue("species", species); if (species > -1) params.m_sParamStruct.factionID = species; } pTable->GetValue("commrange",params.m_sParamStruct.m_fCommRange); //Luciano - added to use GROUPONLY signals SmartScriptTable pPerceptionTable; if(pTable->GetValue("Perception",pPerceptionTable)) { pPerceptionTable->GetValue( "sightrange", params.m_sParamStruct.m_PerceptionParams.sightRange); } } break; case AIOBJECT_SNDSUPRESSOR: { // (MATT) This doesn't need a proxy? {2008/02/15:19:45:58} SmartScriptTable pTable; // Properties table if (pH->GetParamCount() > 2) pH->GetParam(3,pTable); else return pH->EndFunction(); if (!pTable->GetValue("radius",params.m_moveAbility.pathRadius)) params.m_moveAbility.pathRadius = 10.f; break; } case AIOBJECT_WAYPOINT: break; /* // this block is commented out since params.m_sParamStruct is currently ignored in pEntity->RegisterInAISystem() // instead of setting the group id here, it will be set from the script right after registering default: // try to get groupid settings for anchors params.m_sParamStruct.m_nGroup = -1; params.m_sParamStruct.m_nSpecies = -1; { SmartScriptTable pTable; if ( pH->GetParamCount() > 2 ) pH->GetParam( 3, pTable ); if ( *pTable ) pTable->GetValue( "groupid", params.m_sParamStruct.m_nGroup ); } break; */ } // Remove any existing AI object pEntity->RegisterInAISystem(AIObjectParams(0)); // Register in AI to get a new AI object, deregistering the old one in the process pEntity->RegisterInAISystem(params); // (MATT) ? {2008/02/15:19:46:29} // AI object was not created (possibly AI System is disabled) if (IAIObject* aiObject = pEntity->GetAI()) { if(type==AIOBJECT_SNDSUPRESSOR) aiObject->SetRadius(params.m_moveAbility.pathRadius); else if(type>=AIANCHOR_FIRST) // if anchor - set radius { SmartScriptTable pTable; // Properties table if (pH->GetParamCount() > 2) pH->GetParam(3,pTable); else return pH->EndFunction(); float radius(0.f); pTable->GetValue("radius",radius); int groupId = -1; pTable->GetValue("groupid", groupId); aiObject->SetGroupId(groupId); aiObject->SetRadius(radius); } if (IAIActorProxy* proxy = aiObject->GetProxy()) proxy->UpdateMeAlways(!autoDisable); } return pH->EndFunction(); }
void CGameStats::SubmitPlayerStats(const SPlayerInfo& plr, bool server, bool client) { if(!m_statsTrack) return; SStatsTrackHelper hlp(this); //server stats const SPlayerStats& stats = *(plr.stats.back()); if(server) { hlp.PlayerValue(plr.id, "name", plr.name.c_str()); hlp.PlayerValue(plr.id, "rank", plr.rank); hlp.PlayerValue(plr.id, "kills", stats.m_kills); hlp.PlayerValue(plr.id, "deaths", stats.m_deaths); hlp.PlayerValue(plr.id, "shots", stats.m_shots); hlp.PlayerValue(plr.id, "hits", stats.m_hits); hlp.PlayerValue(plr.id, "melee", stats.m_melee); } //here are some client-only stats - mainly times if(client) { CTimeValue time = SGetTime(m_roundStart); plr.stats.back()->End(time); int played = int((time - plr.stats.back()->m_started).GetSeconds()+0.5f); int played_minutes = played/60; hlp.PlayerValue(plr.id,"played",played_minutes); static string keyName; keyName.Format("Played%s",m_gameMode.c_str()); hlp.PlayerCatValue(plr.id, "mode", keyName, played); keyName.Format("PlayedMap%s",m_mapName.c_str()); hlp.PlayerCatValue(plr.id, "map", keyName, played); for(int i=0; i<4; ++i) { int used = int(stats.m_suit.m_used[i].GetSeconds()+0.5f); if(!used) continue; keyName.Format("UsedSuit%d",i); hlp.PlayerCatValue(plr.id, "suit_mode", keyName, used); } for(int i=0; i<stats.m_vehicles.m_vehicles.size(); ++i) { const SPlayerStats::SVehicles::SVehicle& veh = stats.m_vehicles.m_vehicles[i]; int used = int(veh.m_used.GetSeconds() + 0.5f); keyName.Format("UsedVehicle%s",veh.m_name.c_str()); hlp.PlayerCatValue(plr.id, "vehicle", keyName, used); } for(int i=0; i<stats.m_weapons.m_weapons.size(); ++i) { const SPlayerStats::SWeapons::SWeapon& wep= stats.m_weapons.m_weapons[i]; if(!wep.m_kills) continue; keyName.Format("WeaponKills%s", wep.m_name.c_str()); hlp.PlayerCatValue(plr.id, "weapon", keyName, wep.m_kills); } } //Debugging stuff if(!hlp.m_errors.empty()) { GameWarning("Stats tracking : SubmitPlayerStats tried to use %d missing key(s)", (int)hlp.m_errors.size()); for(int i=0; i<hlp.m_errors.size(); ++i) { GameWarning(" Key %s not found",hlp.m_errors[i].c_str()); } } }
//------------------------------------------------------------------------ void CVehiclePartAnimated::FlagSkeleton(ISkeletonPose* pSkeletonPose,IDefaultSkeleton &rIDefaultSkeleton) { if (!pSkeletonPose) return; IPhysicalEntity* pPhysics = GetEntity()->GetPhysics(); if (!pPhysics) return; string name; int idWater = rIDefaultSkeleton.GetJointIDByName("proxy_water"); uint32 buoyancyParts = (idWater != -1) ? 1 : 0; uint32 jointCount = rIDefaultSkeleton.GetJointCount(); for (uint32 i = 0; i < jointCount; ++i) { int physId = pSkeletonPose->GetPhysIdOnJoint(i); if (physId >= 0) { CheckColltypeHeavy(physId); name = rIDefaultSkeleton.GetJointNameByID(i); // when water proxy available, remove float from all others // if no water proxy, we leave only "proxy" parts floating if (idWater != -1) { if (i == idWater) { SetFlags(physId, geom_collides, false); SetFlagsCollider(physId, 0); } else SetFlags(physId, geom_floats, false); } else { if (name.find("proxy") != string::npos) ++buoyancyParts; else SetFlags(physId, geom_floats, false); } // all objects which have a corresponding *_proxy on the skeleton // are set to ray collision only if (name.find("_proxy") == string::npos) { name.append("_proxy"); int proxyId = rIDefaultSkeleton.GetJointIDByName(name.c_str()); if (proxyId != -1) { // remove ray collision from hull proxy(s) SetFlags(pSkeletonPose->GetPhysIdOnJoint(proxyId), geom_colltype_ray | geom_colltype13, false); // get StatObj from main part, to connect proxies foreignData with it IStatObj* pStatObj = pSkeletonPose->GetStatObjOnJoint(i); if (pStatObj) { pe_params_part params; params.partid = proxyId; if (pPhysics->GetParams(¶ms)) { if (params.pPhysGeom && params.pPhysGeom->pGeom) params.pPhysGeom->pGeom->SetForeignData(pStatObj, 0); } } for (int p = 2; p < 6; ++p) { // check additional proxies, by naming convention _02, .. _05 char buf[64]; cry_sprintf(buf, "%s_%02i", name.c_str(), p); proxyId = rIDefaultSkeleton.GetJointIDByName(buf); if (proxyId == -1) break; int proxyPhysId = pSkeletonPose->GetPhysIdOnJoint(proxyId); if (proxyPhysId == -1) continue; SetFlags(proxyPhysId, geom_colltype_ray | geom_colltype13, false); // connect proxies to main StatObj (needed for bullet tests, decals) if (pStatObj) { pe_params_part params; params.partid = proxyPhysId; if (pPhysics->GetParams(¶ms)) { if (params.pPhysGeom && params.pPhysGeom->pGeom) params.pPhysGeom->pGeom->SetForeignData(pStatObj, 0); } } } // set ray-collision only on the part SetFlags(physId, geom_collides | geom_floats, false); SetFlags(physId, geom_colltype_ray | geom_colltype13, true); SetFlagsCollider(physId, 0); } } } } if (buoyancyParts == 0) { // as fallback, use part with largest volume for buoyancy int partId = -1; float maxV = 0.f; pe_status_nparts nparts; int numParts = pPhysics->GetStatus(&nparts); for (int i = 0; i < numParts; ++i) { pe_params_part params; params.ipart = i; if (pPhysics->GetParams(¶ms)) { float v = (params.pPhysGeomProxy) ? params.pPhysGeomProxy->V : params.pPhysGeom->V; if (v > maxV) { partId = params.partid; maxV = v; } } } if (partId != -1) SetFlags(partId, geom_floats, true); else GameWarning("[CVehiclePartAnimated]: <%s> has no buoyancy parts! (Check material for correct physicalization setup properties)",GetEntity()->GetName()); } int jointId, physId; if ((jointId = rIDefaultSkeleton.GetJointIDByName("proxy_skirt")) != -1) { if ((physId = pSkeletonPose->GetPhysIdOnJoint(jointId)) != -1) { SetFlags(physId, geom_collides | geom_floats, false); SetFlags(physId, geom_colltype_ray | geom_colltype13 | geom_colltype_player | geom_colltype_foliage, true); SetFlagsCollider(physId, 0); } } // remove collision flags from all _proxy geoms by debug cvar // useful for seeing through, testing ray proxies etc if (VehicleCVars().v_disable_hull > 0) { for (uint32 i = 0; i < rIDefaultSkeleton.GetJointCount(); ++i) { if (strstr(rIDefaultSkeleton.GetJointNameByID(i), "_proxy")) { SetFlags(pSkeletonPose->GetPhysIdOnJoint(i), geom_collides | geom_floats, false); SetFlagsCollider(pSkeletonPose->GetPhysIdOnJoint(i), 0); } } } }
//------------------------------------------------------------------------ bool CWeaponSystem::ScanXML(XmlNodeRef &root, const char *xmlFile) { MEMSTAT_CONTEXT_FMT(EMemStatContextTypes::MSC_Other, 0, "Weapon xml (%s)", xmlFile); if(strcmpi(root->getTag(), "ammo")) return false; const char *name = root->getAttr("name"); if(!name) { GameWarning("Missing ammo name in XML '%s'! Skipping...", xmlFile); return false; } const char *className = root->getAttr("class"); if(!className) { GameWarning("Missing ammo class in XML '%s'! Skipping...", xmlFile); return false; } TProjectileRegistry::iterator it = m_projectileregistry.find(CONST_TEMP_STRING(className)); if(it == m_projectileregistry.end()) { GameWarning("Unknown ammo class '%s' specified in XML '%s'! Skipping...", className, xmlFile); return false; } const char *scriptName = root->getAttr("script"); IEntityClassRegistry::SEntityClassDesc classDesc; classDesc.sName = name; classDesc.sScriptFile = scriptName?scriptName:""; //classDesc.pUserProxyData = (void *)it->second; //classDesc.pUserProxyCreateFunc = &CreateProxy<CProjectile>; classDesc.flags |= ECLF_INVISIBLE; IEntityClass *pClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass(name); if(!m_reloading && !pClass) { m_pGame->GetIGameFramework()->GetIGameObjectSystem()->RegisterExtension(name, it->second, &classDesc); pClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass(name); assert(pClass); } TAmmoTypeParams::iterator ait=m_ammoparams.find(pClass); if(ait==m_ammoparams.end()) { std::pair<TAmmoTypeParams::iterator, bool> result = m_ammoparams.insert(TAmmoTypeParams::value_type(pClass, SAmmoTypeDesc())); ait=result.first; } const char *configName = root->getAttr("configuration"); IItemParamsNode *params = m_pItemSystem->CreateParams(); params->ConvertFromXML(root); SAmmoParams *pAmmoParams=new SAmmoParams(params, pClass); SAmmoTypeDesc &desc=ait->second; if(!configName || !configName[0]) { if(desc.params) delete desc.params; desc.params=pAmmoParams; } else desc.configurations.insert(std::make_pair<string, const SAmmoParams *>(configName, pAmmoParams)); return true; }
TAttachedEffectId CEffectsController::AttachParticleEffect(IParticleEffect* pParticleEffect, const int targetSlot, const char *helperName, const SEffectAttachParams &attachParams) { CRY_ASSERT(m_pOwnerEntity); if (pParticleEffect) { SEntitySlotInfo slotInfo; SEffectInfo effectInfo; const bool validSlot = m_pOwnerEntity->GetSlotInfo(targetSlot, slotInfo); if (!validSlot || slotInfo.pStatObj) { //Get helper position on static object (if any) Vec3 localHelperPosition = attachParams.offset; if (validSlot) { const Matrix34& localSlotMtx = m_pOwnerEntity->GetSlotLocalTM(targetSlot, false); localHelperPosition = slotInfo.pStatObj->GetHelperPos(helperName) + attachParams.offset; localHelperPosition = localSlotMtx.TransformPoint(localHelperPosition); } int attachSlot = FindSafeSlot(attachParams.firstSafeSlot); //Offset particle to desired location effectInfo.entityEffectSlot = m_pOwnerEntity->LoadParticleEmitter(attachSlot, pParticleEffect, 0, attachParams.prime, false); Matrix34 localEffectMtx(IParticleEffect::ParticleLoc(localHelperPosition, attachParams.direction, attachParams.scale)); m_pOwnerEntity->SetSlotLocalTM(effectInfo.entityEffectSlot, localEffectMtx); ++m_effectGeneratorId; effectInfo.id = m_effectGeneratorId; m_attachedEffects.push_back(effectInfo); return m_effectGeneratorId; } else if (slotInfo.pCharacter) { IAttachmentManager *pAttachmentManager = slotInfo.pCharacter->GetIAttachmentManager(); IAttachment *pAttachment = pAttachmentManager->GetInterfaceByName(helperName); if (pAttachment) { CEffectAttachment *pEffectAttachment = new CEffectAttachment(pParticleEffect, attachParams.offset, attachParams.direction, attachParams.scale); if (attachParams.prime) { if (IParticleEmitter* pEmitter = pEffectAttachment->GetEmitter()) { pEmitter->Prime(); } } pAttachment->AddBinding(pEffectAttachment); pEffectAttachment->ProcessAttachment(pAttachment); } else { GameWarning("[EntityEffects] Can not attach '%s' to entity '%s', attachment point helper '%s' does not exist", pParticleEffect->GetName(), m_pOwnerEntity->GetName(), helperName); return 0; } ++m_effectGeneratorId; effectInfo.id = m_effectGeneratorId; effectInfo.characterEffectSlot = targetSlot; effectInfo.helperName = helperName; m_attachedEffects.push_back(effectInfo); return m_effectGeneratorId; } } return 0; }