void CGameAchievements::OnEntityKilled(const HitInfo &hitInfo) { // target must be an AI IActor* pTarget = g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(hitInfo.targetId); if(!pTarget || pTarget->IsPlayer()) return; // shooter might be null, if this is a collision, but will be checked otherwise IActor* pShooter = g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(hitInfo.shooterId); switch(CategoriseHit(hitInfo.type)) { case eCHT_Bullet: { // ignore AI shots if(!pShooter || !pShooter->IsPlayer()) break; CProjectile* pProjectile = g_pGame->GetWeaponSystem()->GetProjectile(hitInfo.projectileId); assert(pProjectile); const CTimeValue& spawnTime = pProjectile ? pProjectile->GetSpawnTime() : 0.0f; if(spawnTime == 0.0f) break; if(hitInfo.projectileId == m_lastPlayerKillBulletId && spawnTime == m_lastPlayerKillBulletSpawnTime) { // same projectile as previously, trigger the 'two kills one bullet' objective GiveAchievement(eA_SPFeature_OneBulletTwoKills); } else { // save for later m_lastPlayerKillBulletId = hitInfo.projectileId; m_lastPlayerKillBulletSpawnTime = spawnTime; } } break; case eCHT_Grenade: { if(!pShooter || !pShooter->IsPlayer()) break; CProjectile* pGrenade = g_pGame->GetWeaponSystem()->GetProjectile(hitInfo.projectileId); const CTimeValue& spawnTime = pGrenade ? pGrenade->GetSpawnTime() : 0.0f; if(spawnTime == 0.0f) break; if(hitInfo.projectileId == m_lastPlayerKillGrenadeId && spawnTime == m_lastPlayerKillGrenadeSpawnTime) { if(++m_killsWithOneGrenade == 3) { GiveAchievement(eA_SPFeature_OneGrenadeThreeKills); } } else { // save for later m_lastPlayerKillGrenadeId = hitInfo.projectileId; m_lastPlayerKillGrenadeSpawnTime = spawnTime; m_killsWithOneGrenade = 1; } } break; case eCHT_Collision: { CTimeValue now = gEnv->pTimer->GetFrameStartTime(); if(hitInfo.weaponId != 0 && hitInfo.weaponId == m_lastPlayerThrownObject && (now-m_lastPlayerThrownTime) < THROW_TIME_THRESHOLD) { // AI was killed by an object the player threw in the last x seconds... g_pGame->GetPersistantStats()->IncrementClientStats(EIPS_ThrownObjectKill, 1); } } break; default: break; } }
//------------------------------------------------------------------------ void CVehicleMovementVTOL::Update(const float deltaTime) { FUNCTION_PROFILER(GetISystem(), PROFILE_GAME); CVehicleMovementHelicopter::Update(deltaTime); CryAutoCriticalSection lk(m_lock); if(m_pWingsAnimation) { m_pWingsAnimation->SetTime(m_wingsAnimTime); } IActorSystem *pActorSystem = g_pGame->GetIGameFramework()->GetIActorSystem(); assert(pActorSystem); IActor *pActor = pActorSystem->GetActor(m_actorId); if(pActor && pActor->IsClient()) { float turbulence = m_turbulence; if(m_pAltitudeLimitVar) { float altitudeLimit = m_pAltitudeLimitVar->GetFVal(); float currentHeight = m_pEntity->GetWorldPos().z; if(!iszero(altitudeLimit)) { float altitudeLowerOffset; if(m_pAltitudeLimitLowerOffsetVar) { float r = 1.0f - min(1.0f, max(0.0f, m_pAltitudeLimitLowerOffsetVar->GetFVal())); altitudeLowerOffset = r * altitudeLimit; if(currentHeight >= altitudeLowerOffset) { if(currentHeight > altitudeLowerOffset) { float zone = altitudeLimit - altitudeLowerOffset; turbulence += (currentHeight - altitudeLowerOffset) / (zone); } } } } } if(turbulence > 0.0f) { static_cast<CActor *>(pActor)->CameraShake(0.50f * turbulence, 0.0f, 0.05f, 0.04f, Vec3(0.0f, 0.0f, 0.0f), 10, "VTOL_Update_Turbulence"); } float enginePowerRatio = m_enginePower / m_enginePowerMax; if(enginePowerRatio > 0.0f) { float rpmScaleDesired = 0.2f; rpmScaleDesired += abs(m_forwardAction) * 0.8f; rpmScaleDesired += abs(m_strafeAction) * 0.4f; rpmScaleDesired += abs(m_turnAction) * 0.25f; rpmScaleDesired = min(1.0f, rpmScaleDesired); Interpolate(m_rpmScale, rpmScaleDesired, 1.0f, deltaTime); } float turnParamGoal = min(1.0f, abs(m_turnAction)) * 0.6f; turnParamGoal *= (min(1.0f, max(0.0f, m_speedRatio)) + 1.0f) * 0.50f; turnParamGoal += turnParamGoal * m_boost * 0.25f; Interpolate(m_soundParamTurn, turnParamGoal, 0.5f, deltaTime); SetSoundParam(eSID_Run, "turn", m_soundParamTurn); float damage = GetSoundDamage(); if(damage > 0.1f) { //if (ISound* pSound = GetOrPlaySound(eSID_Damage, 5.f, m_enginePos)) //SetSoundParam(pSound, "damage", damage); } } }
bool CDevMode::OnInputEvent( const SInputEvent& evt ) { FUNCTION_PROFILER(GetISystem(), PROFILE_ACTION); bool handled = false; bool canCheat = CCryAction::GetCryAction()->CanCheat(); IActor* pActor = CCryAction::GetCryAction()->GetClientActor(); if (!pActor) return false; IEntity* pEntity = pActor->GetEntity(); if (!pEntity) return false; // tag-point functionality is provided by the editor already, so we should ignore it // when running in the editor if (!gEnv->IsEditor()) { if ((evt.state == eIS_Pressed) && canCheat) { if ((evt.modifiers & eMM_Shift)!=0 && (evt.modifiers & eMM_Alt) == 0) // Shift ONLY { if (handled = (evt.keyId == eKI_F1)) GotoTagPoint(0); if (handled = (evt.keyId == eKI_F2)) GotoTagPoint(1); if (handled = (evt.keyId == eKI_F3)) GotoTagPoint(2); if (handled = (evt.keyId == eKI_F4)) GotoTagPoint(3); if (handled = (evt.keyId == eKI_F5)) GotoTagPoint(4); if (handled = (evt.keyId == eKI_F6)) GotoTagPoint(5); if (handled = (evt.keyId == eKI_F7)) GotoTagPoint(6); if (handled = (evt.keyId == eKI_F8)) GotoTagPoint(7); if (handled = (evt.keyId == eKI_F9)) GotoTagPoint(8); if (handled = (evt.keyId == eKI_F10)) GotoTagPoint(9); if (handled = (evt.keyId == eKI_F11)) GotoTagPoint(10); if (handled = (evt.keyId == eKI_F12)) GotoTagPoint(11); } else if ((evt.modifiers & eMM_Shift) == 0 && ((evt.modifiers & eMM_Alt)!=0 || (evt.modifiers & eMM_Ctrl)!=0)) // Alt or Ctrl and NO Shift { if (handled = (evt.keyId == eKI_F1)) SaveTagPoint(0); if (handled = (evt.keyId == eKI_F2)) SaveTagPoint(1); if (handled = (evt.keyId == eKI_F3)) SaveTagPoint(2); if (handled = (evt.keyId == eKI_F4)) SaveTagPoint(3); if (handled = (evt.keyId == eKI_F5)) SaveTagPoint(4); if (handled = (evt.keyId == eKI_F6)) SaveTagPoint(5); if (handled = (evt.keyId == eKI_F7)) SaveTagPoint(6); if (handled = (evt.keyId == eKI_F8)) SaveTagPoint(7); if (handled = (evt.keyId == eKI_F9)) SaveTagPoint(8); if (handled = (evt.keyId == eKI_F10)) SaveTagPoint(9); if (handled = (evt.keyId == eKI_F11)) SaveTagPoint(10); if (handled = (evt.keyId == eKI_F12)) SaveTagPoint(11); } } } else { // place commands which should only be dealt with in game mode here } // shared commands if (canCheat) { if (!handled && (evt.state == eIS_Pressed) && (evt.modifiers & eMM_Shift) != 0 && (evt.modifiers & eMM_Alt) != 0) { if (handled = (evt.keyId == eKI_NP_1)) GotoSpecialSpawnPoint(1); if (handled = (evt.keyId == eKI_NP_2)) GotoSpecialSpawnPoint(2); if (handled = (evt.keyId == eKI_NP_3)) GotoSpecialSpawnPoint(3); if (handled = (evt.keyId == eKI_NP_4)) GotoSpecialSpawnPoint(4); if (handled = (evt.keyId == eKI_NP_5)) GotoSpecialSpawnPoint(5); if (handled = (evt.keyId == eKI_NP_6)) GotoSpecialSpawnPoint(6); if (handled = (evt.keyId == eKI_NP_7)) GotoSpecialSpawnPoint(7); if (handled = (evt.keyId == eKI_NP_8)) GotoSpecialSpawnPoint(8); if (handled = (evt.keyId == eKI_NP_9)) GotoSpecialSpawnPoint(9); } else if (!handled && (evt.state == eIS_Pressed) && !(evt.modifiers & eMM_Modifiers)) { if (handled = (evt.keyId == eKI_NP_1) && !gEnv->bMultiplayer) // give all items { CCryAction::GetCryAction()->GetIItemSystem()->GetIEquipmentManager()->GiveEquipmentPack(pActor, "Player_Default", true, true); } else if (handled = (evt.keyId == eKI_F2)) // go to next spawnpoint { Vec3 oldPos = pEntity->GetWorldPos(); if (gEnv->pScriptSystem->BeginCall("BasicActor", "OnNextSpawnPoint")) { gEnv->pScriptSystem->PushFuncParam(pEntity->GetScriptTable()); gEnv->pScriptSystem->EndCall(); if (gEnv->pStatoscope) { char buffer[100]; Vec3 pos = pEntity->GetWorldPos(); sprintf(buffer, "Teleported from (%.2f, %.2f, %.2f) to (%.2f, %.2f, %.2f)", oldPos.x, oldPos.y, oldPos.z, pos.x, pos.y, pos.z); gEnv->pStatoscope->AddUserMarker("Player", buffer); } } } } } if (handled == false && evt.state == eIS_Pressed && (evt.modifiers & eMM_Alt)!=0) { if(evt.keyId == eKI_F7) SwitchSlowDownGameSpeed(); else if(evt.keyId==eKI_F8) SwitchHUD(); } // AlexL: don't mark commands as handled for now. Would stop processing/propagating to other // listeners. especially for non-modifier keys like f7,f8,f9 problematic return false; // handled; }
//------------------------------------------------------------------------ void CGameRules::OnHostMigrationStateChanged() { CGame::EHostMigrationState migrationState = g_pGame->GetHostMigrationState(); if (migrationState == CGame::eHMS_Resuming) { // Assume remaining players aren't going to make it const uint32 maxMigratingPlayers = m_migratingPlayerMaxCount; for (uint32 index = 0; index < maxMigratingPlayers; ++ index) { SMigratingPlayerInfo *pPlayerInfo = &m_pMigratingPlayerInfo[index]; if (pPlayerInfo->InUse()) { // Pretend the player has disconnected FakeDisconnectPlayer(pPlayerInfo->m_originalEntityId); pPlayerInfo->Reset(); } } if (gEnv->bServer) { GetGameObject()->InvokeRMI(ClHostMigrationFinished(), NoParams(), eRMI_ToRemoteClients); } } else if (migrationState == CGame::eHMS_NotMigrating) { if (gEnv->bServer) { TPlayers players; GetPlayers(players); const int numPlayers = players.size(); for (int i = 0; i < numPlayers; ++ i) { IActor *pActor = g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(players[i]); if (pActor) { pActor->SetMigrating(false); } } } else { CPlayer *pPlayer = static_cast<CPlayer *>(g_pGame->GetIGameFramework()->GetClientActor()); if (pPlayer) { pPlayer->SetMigrating(false); } } CallOnForbiddenAreas("OnHostMigrationFinished"); // Migration has finished, if we've still got client params then they won't be valid anymore SAFE_DELETE(m_pHostMigrationClientParams); } else if (migrationState == CGame::eHMS_WaitingForPlayers) { CallOnForbiddenAreas("OnHostMigrationStarted"); } }
//------------------------------------------------------------------------- void CLam::ActivateLaser(bool activate, bool aiRequest /* = false */) { if (m_laserActivated == activate) return; CItem *pParent = NULL; EntityId ownerId = 0; bool ok = false; if (IItem *pOwnerItem = m_pItemSystem->GetItem(GetParentId())) { pParent = (CItem *)pOwnerItem; IWeapon *pWeapon = pOwnerItem->GetIWeapon(); if(pWeapon) ownerId = pOwnerItem->GetOwnerId(); ok = true; } else { pParent = this; ownerId = GetOwnerId(); } IActor *pOwnerActor = gEnv->pGame->GetIGameFramework()->GetIActorSystem()->GetActor(ownerId); if(!pOwnerActor) return; if(activate && !aiRequest && !pOwnerActor->IsPlayer()) return; //Special FP stuff if(pOwnerActor->IsPlayer() && !m_lamparams.isLaser) return; m_laserActivated = activate; //Activate or deactivate effect?? if (!m_laserActivated) { AttachLAMLaser(false, eIGS_FirstPerson); AttachLAMLaser(false, eIGS_ThirdPerson); } else { bool tp = pOwnerActor->IsThirdPerson(); if(!tp && ok) { SAccessoryParams *params = pParent->GetAccessoryParams(GetEntity()->GetClass()->GetName()); if (!params) return; m_laserHelperFP.clear(); m_laserHelperFP = params->attach_helper.c_str(); m_laserHelperFP.replace("_LAM",""); } AttachLAMLaser(true, tp?eIGS_ThirdPerson:eIGS_FirstPerson); } if (m_laserActivated || m_lightActivated) GetGameObject()->EnablePostUpdates(this); if (!m_laserActivated && !m_lightActivated) GetGameObject()->DisablePostUpdates(this); }
void CHUDTagNames::Update() { CActor *pClientActor = static_cast<CActor *>(g_pGame->GetIGameFramework()->GetClientActor()); CGameRules *pGameRules = g_pGame->GetGameRules(); if(!pClientActor || !pGameRules || !gEnv->bMultiplayer) return; int iClientTeam = pGameRules->GetTeam(pClientActor->GetEntityId()); // Skip enemies, they need to be added only when shot // (except in spectator mode when we display everyone) for(int iTeam = 0; iTeam < pGameRules->GetTeamCount() + 1; ++iTeam) { if((iTeam == iClientTeam) || (pClientActor->GetSpectatorMode() != CActor::eASM_None)) { int iTeamPlayerCount = pGameRules->GetTeamPlayerCount(iTeam); for(int iPlayer=0; iPlayer<iTeamPlayerCount; iPlayer++) { IActor *pActor = g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(pGameRules->GetTeamPlayer(iTeam,iPlayer)); if(!pActor) continue; // Never display the local player if(pActor == pClientActor) continue; // never display other spectators if(static_cast<CActor*>(pActor)->GetSpectatorMode() != CActor::eASM_None) continue; // never display the name of the player we're spectating (it's shown separately with their current health) if(pClientActor->GetSpectatorMode() == CActor::eASM_Follow && pClientActor->GetSpectatorTarget() == pActor->GetEntityId()) continue; DrawTagName(pActor); } } } IVehicleSystem *pVehicleSystem = gEnv->pGame->GetIGameFramework()->GetIVehicleSystem(); if(!pVehicleSystem) return; IVehicleIteratorPtr pVehicleIter = pVehicleSystem->CreateVehicleIterator(); while(IVehicle *pVehicle=pVehicleIter->Next()) { SVehicleStatus rVehicleStatus = pVehicle->GetStatus(); if(0 == rVehicleStatus.passengerCount) continue; // Skip enemy vehicles, they need to be added only when shot (except in spectator mode...) bool bEnemyVehicle = true; for(int iSeatId=1; iSeatId<=pVehicle->GetLastSeatId(); iSeatId++) { IVehicleSeat *pVehicleSeat = pVehicle->GetSeatById(iSeatId); if(!pVehicleSeat) continue; EntityId uiEntityId = pVehicleSeat->GetPassenger(); if(0 == iClientTeam) { if(uiEntityId && IsFriendlyToClient(uiEntityId)) { bEnemyVehicle = false; } } else if(uiEntityId && pGameRules->GetTeam(uiEntityId) == iClientTeam) { bEnemyVehicle = false; } } if(bEnemyVehicle && (pClientActor->GetSpectatorMode() == CActor::eASM_None)) // again, draw enemies in spectator mode continue; DrawTagName(pVehicle); } // don't need to do any of this if we're in spectator mode - all player names will have been drawn above. if(pClientActor->GetSpectatorMode() == CActor::eASM_None) { for(TEnemyTagNamesList::iterator iter=m_enemyTagNamesList.begin(); iter!=m_enemyTagNamesList.end(); ++iter) { SEnemyTagName *pEnemyTagName = &(*iter); if(gEnv->pTimer->GetAsyncTime().GetSeconds() >= pEnemyTagName->fSpawnTime+((float) g_pGameCVars->hud_mpNamesDuration)) { // Note: iter=my_list.erase(iter) may not be standard/safe TEnemyTagNamesList::iterator iterNext = iter; ++iterNext; m_enemyTagNamesList.erase(iter); iter = iterNext; } else { IActor *pActor = g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(pEnemyTagName->uiEntityId); if(pActor) DrawTagName(pActor); IVehicle *pVehicle = gEnv->pGame->GetIGameFramework()->GetIVehicleSystem()->GetVehicle(pEnemyTagName->uiEntityId); if(pVehicle) DrawTagName(pVehicle); } } } }
void CHUDTagNames::DrawTagName(IVehicle *pVehicle) { CRY_ASSERT(pVehicle); if(!pVehicle) return; CActor *pClientActor = static_cast<CActor *>(g_pGame->GetIGameFramework()->GetClientActor()); CGameRules *pGameRules = g_pGame->GetGameRules(); int iClientTeam = pGameRules->GetTeam(pClientActor->GetEntityId()); bool bThirdPerson = pClientActor->IsThirdPerson(); bool bDrawSeatTagNames = false; if(pClientActor->GetSpectatorMode() == CActor::eASM_Follow) { IActor *pFollowedActor = g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(pClientActor->GetSpectatorTarget()); if(pFollowedActor) bDrawSeatTagNames = (pVehicle == pFollowedActor->GetLinkedVehicle()); } else bDrawSeatTagNames = (pVehicle == pClientActor->GetLinkedVehicle()); if(bDrawSeatTagNames) { // When this is local player vehicle, we always display all passengers name above their head so that he can identify them for(int iSeatId=1; iSeatId<=pVehicle->GetLastSeatId(); iSeatId++) { IVehicleSeat *pVehicleSeat = pVehicle->GetSeatById(iSeatId); if(!pVehicleSeat) continue; IActor *pActor = g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(pVehicleSeat->GetPassenger()); if(!pActor || (pActor == pClientActor && !bThirdPerson)) continue; DrawTagName(pActor,true); } return; } ColorF rgbTagName = COLOR_ENEMY; // Driver seat is always 1 IVehicleSeat *pVehicleSeat = pVehicle->GetSeatById(1); if(!pVehicleSeat) return; IVehicleHelper *pVehicleHelper = pVehicleSeat->GetSitHelper(); if(!pVehicleHelper) return; Vec3 vWorldPos = pVehicleHelper->GetWorldTM().GetTranslation(); // Add some offset to be above the driver/pilot vWorldPos.z += 1.2f; AABB box; pVehicle->GetEntity()->GetWorldBounds(box); bool bDrawOnTop = false; if(ProjectOnSphere(vWorldPos,box)) { bDrawOnTop = true; } m_tagNamesVector.resize(0); for(int iSeatId=1; iSeatId<=pVehicle->GetLastSeatId(); iSeatId++) { IVehicleSeat *pVehicleSeat = pVehicle->GetSeatById(iSeatId); if(!pVehicleSeat) continue; EntityId uiEntityId = pVehicleSeat->GetPassenger(); IActor *pActor = g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(uiEntityId); if(!pActor) continue; const char *szRank = GetPlayerRank(uiEntityId); IEntity *pEntity = pActor->GetEntity(); if(!pEntity) continue; char szText[HUD_MAX_STRING_SIZE]; if(szRank) { sprintf(szText,"%s %s",szRank,pEntity->GetName()); } else { sprintf(szText,"%s",pEntity->GetName()); } if(0 == iClientTeam) { if(uiEntityId && IsFriendlyToClient(uiEntityId)) { rgbTagName = COLOR_FRIEND; } } else if(uiEntityId && pGameRules->GetTeam(uiEntityId) == iClientTeam) { rgbTagName = COLOR_FRIEND; } if(pActor->GetHealth() <= 0) { rgbTagName = COLOR_DEAD; } m_tagNamesVector.resize(m_tagNamesVector.size()+1); STagName *pTagName = &m_tagNamesVector[m_tagNamesVector.size()-1]; pTagName->strName = szText; pTagName->vWorld = vWorldPos; pTagName->bDrawOnTop = bDrawOnTop; pTagName->rgb = rgbTagName; } DrawTagNames(); }
void CHUDTagNames::DrawTagName(IActor *pActor,bool bLocalVehicle) { CRY_ASSERT(pActor); if(!pActor) return; IActor *pClientActor = g_pGame->GetIGameFramework()->GetClientActor(); CGameRules *pGameRules = g_pGame->GetGameRules(); int iClientTeam = pGameRules->GetTeam(pClientActor->GetEntityId()); if(!bLocalVehicle && pActor->GetLinkedVehicle()) return; const char *szRank = GetPlayerRank(pActor->GetEntityId()); IEntity *pEntity = pActor->GetEntity(); if(!pEntity) return; char szText[HUD_MAX_STRING_SIZE]; if(szRank) { sprintf(szText,"%s %s",szRank,pEntity->GetName()); } else { sprintf(szText,"%s",pEntity->GetName()); } ICharacterInstance *pCharacterInstance = pEntity->GetCharacter(0); if(!pCharacterInstance) return; ISkeletonPose *pSkeletonPose = pCharacterInstance->GetISkeletonPose(); if(!pSkeletonPose) return; int16 sHeadID = pSkeletonPose->GetJointIDByName("Bip01 Head"); if(-1 == sHeadID) return; Matrix34 matWorld = pEntity->GetWorldTM() * Matrix34(pSkeletonPose->GetAbsJointByID(sHeadID)); Vec3 vWorldPos = matWorld.GetTranslation(); // Who has a bigger head? :) vWorldPos.z += 0.4f; AABB box; pEntity->GetWorldBounds(box); bool bDrawOnTop = bLocalVehicle; if(ProjectOnSphere(vWorldPos,box)) { bDrawOnTop = true; } ColorF rgbTagName = COLOR_ENEMY; if(0 == iClientTeam) { if(IsFriendlyToClient(pActor->GetEntityId())) { rgbTagName = COLOR_FRIEND; } } else if(pGameRules->GetTeam(pActor->GetEntityId()) == iClientTeam) { rgbTagName = COLOR_FRIEND; } if(pActor->GetHealth() <= 0) { rgbTagName = COLOR_DEAD; } m_tagNamesVector.resize(1); for(std::vector<EntityId>::iterator iter=SAFE_HUD_FUNC_RET(GetRadar()->GetSelectedTeamMates())->begin(); iter!=SAFE_HUD_FUNC_RET(GetRadar()->GetSelectedTeamMates())->end(); ++iter) { if(pActor->GetEntityId() == *iter) { // Teammate is selected in radar, force the visibility of that name bDrawOnTop = true; break; } } STagName *pTagName = &m_tagNamesVector[0]; pTagName->strName = szText; pTagName->vWorld = vWorldPos; pTagName->bDrawOnTop = bDrawOnTop; pTagName->rgb = rgbTagName; DrawTagNames(); }
//-------------------------------------------------------------------------------------------------- // Name: SpawnParticlesOnSkeleton // Desc: Spawn particles on Skeleton //-------------------------------------------------------------------------------------------------- void CGameEffect::SpawnParticlesOnSkeleton(IEntity* pEntity, IParticleEmitter* pParticleEmitter, uint32 numParticles,float maxHeightScale) const { if((pEntity) && (numParticles>0) && (pParticleEmitter) && (maxHeightScale>0.0f)) { ICharacterInstance* pCharacter = pEntity->GetCharacter(0); if(pCharacter) { IDefaultSkeleton& rIDefaultSkeleton = pCharacter->GetIDefaultSkeleton(); ISkeletonPose* pPose = pCharacter->GetISkeletonPose(); if(pPose) { Vec3 animPos; Quat animRot; IActor* pActor = gEnv->pGame->GetIGameFramework()->GetIActorSystem()->GetActor(pEntity->GetId()); if(pActor) // First try to get animation data { QuatT animLoc = pActor->GetAnimatedCharacter()->GetAnimLocation(); animPos = animLoc.t; animRot = animLoc.q; } else // If no actor, then use entity data { animPos = pEntity->GetWorldPos(); animRot = pEntity->GetWorldRotation(); } animRot.Invert(); AABB bbox; pEntity->GetLocalBounds(bbox); float bbHeight = bbox.max.z - bbox.min.z; // Avoid division by 0 if(bbHeight == 0) { bbHeight = 0.0001f; } const uint32 numJoints = rIDefaultSkeleton.GetJointCount(); for (uint32 i = 0; i < numParticles; ++i) { int id = cry_random(0U, numJoints - 1); int parentId = rIDefaultSkeleton.GetJointParentIDByID(id); if(parentId>0) { QuatT boneQuat = pPose->GetAbsJointByID(id); QuatT parentBoneQuat= pPose->GetAbsJointByID(parentId); float lerpScale = cry_random(0.0f, 1.0f); QuatTS loc(IDENTITY); loc.t = LERP(boneQuat.t,parentBoneQuat.t,lerpScale); float heightScale = ((loc.t.z - bbox.min.z) / bbHeight); if(heightScale < maxHeightScale) { loc.t = loc.t * animRot; loc.t = loc.t + animPos; pParticleEmitter->EmitParticle(NULL, NULL, &loc); } } } } } } }//-------------------------------------------------------------------------------------------------
void ProcessEvent( EFlowEvent event, SActivationInfo *pActInfo ) { switch (event) { case eFE_Initialize: { m_actInfo = *pActInfo; Reset(); } break; case eFE_Activate: { IItemSystem* pItemSys = CCryAction::GetCryAction()->GetIItemSystem(); // create listener if (IsPortActive(pActInfo, IN_DISABLE)) { Reset(); } if (IsPortActive(pActInfo, IN_ENABLE)) { Reset(); IItem* pItem = 0; EntityId weaponId = GetPortEntityId(pActInfo, IN_WEAPONID); if (weaponId != 0) { pItem = pItemSys->GetItem(weaponId); } else { IActor* pActor = CCryAction::GetCryAction()->GetClientActor(); if (!pActor) return; IInventory *pInventory = pActor->GetInventory(); if (!pInventory) return; const string& weaponClass = GetPortString(pActInfo, IN_WEAPONCLASS); if (!weaponClass.empty()) { // get actor weapon by class IEntityClass* pClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass(weaponClass); pItem = pItemSys->GetItem( pInventory->GetItemByClass(pClass) ); } else { // get current actor weapon pItem = pItemSys->GetItem(pInventory->GetCurrentItem()); } } if (!pItem || !pItem->GetIWeapon()) { GameWarning("[flow] CFlowNode_WeaponListener: no item/weapon."); return; } m_weapId = pItem->GetEntity()->GetId(); IWeapon* pWeapon = pItem->GetIWeapon(); // set initial ammo m_ammo = GetPortInt(pActInfo, IN_AMMO); if (m_ammo == 0) m_ammo = -1; // 0 input means infinite // set weapon listener pWeapon->AddEventListener(this, "CFlowNode_WeaponListener"); m_active = true; //CryLog("WeaponListener successfully created on %s", pItem->GetEntity()->GetName()); } break; } } }