//------------------------------------------------------------------------ void CItem::InitClient(int channelId) { // send the differences between the current, and the initial setup for (TAccessoryMap::iterator it = m_accessories.begin(); it != m_accessories.end(); ++it) { GetGameObject()->InvokeRMI(ClAttachAccessory(), RequestAttachAccessoryParams(it->first.c_str()), eRMI_ToClientChannel, channelId); } IActor *pOwner = GetOwnerActor(); if (!pOwner) { return; } // only send the pickup message if the player is connecting // for items spawned during gameplay, CItem::PickUp is already sending the pickup message INetChannel *pNetChannel = m_pGameFramework->GetNetChannel(channelId); if (pNetChannel && pNetChannel->GetContextViewState() < eCVS_InGame) { if (!m_stats.mounted && !m_stats.used) { pOwner->GetGameObject()->InvokeRMIWithDependentObject(CActor::ClPickUp(), CActor::PickItemParams(GetEntityId(), m_stats.selected, false), eRMI_ToClientChannel, GetEntityId(), channelId); //GetOwnerActor()->GetGameObject()->InvokeRMI(CActor::ClPickUp(), // CActor::PickItemParams(GetEntityId(), m_stats.selected, false), eRMI_ToClientChannel, channelId); } } if (m_stats.mounted && m_stats.used) { pOwner->GetGameObject()->InvokeRMIWithDependentObject(CActor::ClStartUse(), CActor::ItemIdParam(GetEntityId()), eRMI_ToClientChannel, GetEntityId(), channelId); } }
void CFlowNode_AISequenceAction_ApproachAndEnterVehicle::HandleSequenceEvent(AIActionSequence::SequenceEvent sequenceEvent) { switch(sequenceEvent) { case AIActionSequence::StartAction: { if (!m_actInfo.pEntity) { // the entity has gone for some reason, at least make sure the action gets finished properly and the FG continues UnregisterFromVehicleEvent(NULL); CancelSequenceAndActivateOutputPort(OutputPort_Done); return; } m_entityId = m_actInfo.pEntity->GetId(); m_vehicleId = GetPortEntityId(&m_actInfo, InputPort_VehicleId); m_seatNumber = GetPortInt(&m_actInfo, InputPort_SeatNumber); m_fast = GetPortBool(&m_actInfo, InputPort_Fast); const bool alsoCheckForCrewHostility = true; IVehicle* pVehicle = GetVehicle(alsoCheckForCrewHostility); if (!pVehicle) { CryLog("Actor %s failed to enter vehicle (specified vehicle not found or its crew is hostile towards the actor returned true)", m_actInfo.pEntity->GetName()); CancelSequenceAndActivateOutputPort(OutputPort_Done); return; } IVehicleSeat* pSeat = GetVehicleSeat(pVehicle); if (!pSeat) { CryLog("Actor %s failed to enter vehicle (bad seat number provided: %i)", m_actInfo.pEntity->GetName(), m_seatNumber); CancelSequenceAndActivateOutputPort(OutputPort_Done); return; } const IVehicleHelper* pEnterHelper = static_cast<CVehicleSeat*>(pSeat)->GetEnterHelper(); if (!pEnterHelper) { CryLog("Actor %s failed to enter vehicle (vehicle has no enter-helper)", m_actInfo.pEntity->GetName()); CancelSequenceAndActivateOutputPort(OutputPort_Done); return; } m_vehicleSeatEnterPosition = pEnterHelper->GetWorldSpaceTranslation(); assert(gEnv && gEnv->pGame && gEnv->pGame->GetIGameFramework() && gEnv->pGame->GetIGameFramework()->GetIActorSystem()); IActor* pActor = gEnv->pGame->GetIGameFramework()->GetIActorSystem()->GetActor(m_actInfo.pEntity->GetId()); // if it's the player, have him enter quickly (we assume that the user moved him close enough to the vehicle) if (pActor && pActor->IsPlayer()) { EnterVehicleSeat(true, pSeat); } else if (m_actInfo.pEntity->GetAI()) { if (m_fast) { TeleportToVehicleSeat(); EnterVehicleSeat(false, pSeat); } else { MovementRequest request; request.callback = functor(*this, &CFlowNode_AISequenceAction_ApproachAndEnterVehicle::MovementRequestCallback); request.entityID = m_actInfo.pEntity->GetId(); request.type = MovementRequest::MoveTo; request.destination = m_vehicleSeatEnterPosition; request.style.SetSpeed((MovementStyle::Speed)GetPortInt(&m_actInfo, InputPort_Speed)); request.style.SetStance((MovementStyle::Stance)GetPortInt(&m_actInfo, InputPort_Stance)); m_movementRequestID = gEnv->pAISystem->GetMovementSystem()->QueueRequest(request); } } else if (pActor) { pActor->HolsterItem(true); pActor->MountedGunControllerEnabled(false); pActor->GetGameObject()->SetAspectProfile(eEA_Physics, eAP_Alive); TeleportToVehicleSeat(); EnterVehicleSeat(GetAnimationTransitionEnabled(), pSeat); } else { CRY_ASSERT_MESSAGE(0, "no compatible entity was provided"); CryWarning(VALIDATOR_MODULE_AI, VALIDATOR_WARNING, "Actor %s failed to enter vehicle (no compatible entity was provided)", m_actInfo.pEntity->GetName()); CancelSequenceAndActivateOutputPort(OutputPort_Done); } } break; case AIActionSequence::SequenceStopped: { if (m_movementRequestID) { gEnv->pAISystem->GetMovementSystem()->CancelRequest(m_movementRequestID); m_movementRequestID = MovementRequestID::Invalid(); UnregisterFromVehicleEvent(NULL); } } break; } }
// //----------------------------------------------------------------------------------------------------------- // (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 CProceduralContextRagdoll::QueueRagdoll( bool bAlive ) { if( m_targetEntityId == 0 ) { m_targetEntityId = m_entity->GetId(); } IActor* piActor = g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor( m_targetEntityId ); // NOTE: The case where piActor is NULL is when you're - in the CryMann preview! if(piActor) { if( gEnv->bServer && !m_bDispatchedAspectProfile && (piActor->GetGameObject()->GetAspectProfile(eEA_Physics) != eAP_Ragdoll) ) { m_bEntityAlive = bAlive; piActor->GetGameObject()->SetAspectProfile( eEA_Physics, bAlive ? eAP_Sleep : eAP_Ragdoll ); } else if( !m_bInRagdoll || (m_bInRagdoll && !bAlive && m_bEntityAlive) ) { SRagdollizeParams params; params.mass = static_cast<CActor*>(piActor)->GetActorPhysics().mass; params.sleep = m_bEntityAlive = bAlive; params.stiffness = m_stiffness; SGameObjectEvent event( eGFE_QueueRagdollCreation, eGOEF_ToExtensions ); event.ptr = ¶ms; piActor->GetGameObject()->SendEvent( event ); m_bInRagdoll = true; } else { m_bInBlendOut = true; } } #ifndef _RELEASE else { if( IEntity* pEntity = gEnv->pEntitySystem->GetEntity( m_targetEntityId ) ) { ICharacterInstance *pCharacter = pEntity->GetCharacter(0); if (pCharacter) { // dead guys shouldn't blink pCharacter->EnableProceduralFacialAnimation(false); //Anton :: SetDefaultPose on serialization if(gEnv->pSystem->IsSerializingFile() && pCharacter->GetISkeletonPose()) pCharacter->GetISkeletonPose()->SetDefaultPose(); } SEntityPhysicalizeParams pp; pp.fStiffnessScale = m_stiffness; pp.type = PE_ARTICULATED; pp.nSlot = 0; pp.bCopyJointVelocities = true; //never ragdollize without mass [Anton] pp.mass = (float)__fsel(-pp.mass, 80.0f, pp.mass); pe_player_dimensions playerDim; pe_player_dynamics playerDyn; playerDyn.gravity = Vec3( 0.f, 0.f, -15.0f ); playerDyn.kInertia = 5.5f; pp.pPlayerDynamics = &playerDyn; // Joints velocities are copied by default for now pp.bCopyJointVelocities = !gEnv->pSystem->IsSerializingFile(); pp.nFlagsOR = pef_monitor_poststep; pEntity->Physicalize(pp); m_bInRagdoll = true; } } #endif }
//------------------------------------------------------------------------- void CGameRulesStandardState::ChangeState( EGR_GameState newState ) { if (gEnv->bServer) { if (newState == EGRS_InGame) { CCCPOINT(GameRulesStandardState_EnterInGame); #if !defined(_RELEASE) || defined(PERFORMANCE_BUILD) if (m_state != EGRS_InGame) { if (g_pGameCVars->g_gameRules_startCmd[0] != '\0') { gEnv->pConsole->ExecuteString(g_pGameCVars->g_gameRules_startCmd, false, true); } } #endif // #if !defined(_RELEASE) || defined(PERFORMANCE_BUILD) m_pGameRules->ResetGameTime(); IGameRulesStatsRecording *st=m_pGameRules->GetStatsRecordingModule(); if (st) { st->OnInGameBegin(); } } else if (newState == EGRS_PostGame) { m_timeInPostGame = 0.0f; IGameRulesStatsRecording *st=m_pGameRules->GetStatsRecordingModule(); if (st) { st->OnPostGameBegin(); } #if defined(DEDICATED_SERVER) if ( gEnv->bMultiplayer ) { // Stop cvar probes. CGameRules::TPlayers players; m_pGameRules->GetPlayers(players); const int numPlayers = players.size(); for (int i = 0; i < numPlayers; ++ i) { const EntityId playerId = players[i]; IActor * pActor = g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(playerId); if ( pActor ) { IGameObject * pGameObject = NULL; INetChannel * pNetChannel = NULL; IDefenceContext * pDefenceContext = NULL; if ( (pGameObject = pActor->GetGameObject()) ) { if ( (pNetChannel = pGameObject->GetNetChannel()) ) { if ( (pDefenceContext = pNetChannel->GetDefenceContext()) ) { pDefenceContext->EndCvarRequests(); } } } } } } #endif CGameLobby *pGameLobby = g_pGame->GetGameLobby(); if (pGameLobby) { CryLog("[GameRules] GameFinished, telling clients"); pGameLobby->SvFinishedGame(0.0f); } } } const bool bIsClient = gEnv->IsClient(); if (bIsClient) { if (newState == EGRS_PostGame) { m_timeInPostGame = 0.0f; EnterPostGameState(ePGS_Starting); } else if (newState == EGRS_InGame) { CHUDEventDispatcher::CallEvent( SHUDEvent(eHUDEvent_OnGameStart) ); } else if (newState == EGRS_Reset) { m_introMessageShown = false; } ClientChangeStateFeedback(newState); } m_state = newState; OnStateEntered_NotifyListeners(); if (newState == EGRS_PostGame) { m_pGameRules->FreezeInput(true); g_pGame->GetUI()->ActivateDefaultState(); // must be after settings newState to pick endgame OnGameEnd_NotifyListeners(); } else if (newState == EGRS_InGame) { OnGameStart_NotifyListeners(); if (bIsClient && g_pGameCVars->g_gameRules_preGame_StartSpawnedFrozen) { g_pGameActions->FilterMPPreGameFreeze()->Enable(false); g_pGame->GetUI()->ActivateDefaultState(); // must be after settings newState } // Have to explicitly call the spawning module, can't use the listener since that would make the modules // dependent on the initialisation order - which comes from xml IGameRulesSpawningModule *pSpawningModule = m_pGameRules->GetSpawningModule(); if (pSpawningModule) { pSpawningModule->OnInGameBegin(); } } if (gEnv->bServer) { CHANGED_NETWORK_STATE(m_pGameRules, STANDARD_STATE_ASPECT); if (m_state == EGRS_InGame) { // Revive players - has to be done after setting m_state since we don't revive players in PreGame IGameRulesSpawningModule *pSpawningModule = m_pGameRules->GetSpawningModule(); if (pSpawningModule) { const bool bOnlyIfDead = (g_pGameCVars->g_gameRules_preGame_StartSpawnedFrozen!=0); pSpawningModule->ReviveAllPlayers(false, bOnlyIfDead); } } } }
void CHUDCrosshair::UpdateCrosshair() { IActor *pClientActor = g_pGame->GetIGameFramework()->GetClientActor(); if(!pClientActor) return; int iNewFriendly = 0; if(pClientActor->GetLinkedVehicle()) { // JanM/MichaelR: // Get status from the VehicleWeapon, which raycasts considering the necessary SkipEntities (in contrast to WorldQuery) // Julien: this is now done in MP as well iNewFriendly = g_pHUD->GetVehicleInterface()->GetFriendlyFire(); } else { if(!gEnv->bMultiplayer) { CWeapon *pWeapon = g_pHUD->GetCurrentWeapon(); if(pWeapon) { iNewFriendly = pWeapon->IsWeaponLowered() && pWeapon->IsPendingFireRequest(); if(iNewFriendly && pWeapon->GetEntity()->GetClass() == CItem::sTACGunFleetClass) iNewFriendly = 0; } else{ //Two handed pickups need the red X as well CPlayer *pPlayer= static_cast<CPlayer*>(pClientActor); if(CWeapon *pOffHand = static_cast<CWeapon*>(pPlayer->GetItemByClass(CItem::sOffHandClass))) iNewFriendly = pOffHand->IsWeaponLowered(); } } else { EntityId uiCenterId = pClientActor->GetGameObject()->GetWorldQuery()->GetLookAtEntityId(); if(uiCenterId) { iNewFriendly = IsFriendlyEntity(gEnv->pEntitySystem->GetEntity(uiCenterId)); } } } // SNH: if player is carrying a claymore or mine, ask the weapon whether it is possible to place it currently // (takes into account player speed / stance / aim direction). // So 'friendly' is a bit of a misnomer here, but we want the "don't/can't fire" crosshair... if(iNewFriendly != 1 && g_pHUD) { CWeapon *pWeapon = g_pHUD->GetCurrentWeapon(); if(pWeapon) { static IEntityClass* pClaymoreClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass("Claymore"); static IEntityClass* pAVMineClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass("AVMine"); IEntityClass* pClass = pWeapon->GetEntity()->GetClass(); if(pClass == pClaymoreClass || pClass == pAVMineClass) { if(IFireMode* pfm = pWeapon->GetFireMode(pWeapon->GetCurrentFireMode())) { if(!pfm->IsFiring()) iNewFriendly = pWeapon->CanFire() ? 0 : 1; } } } } if(iNewFriendly != m_iFriendlyTarget) { m_iFriendlyTarget = iNewFriendly; //m_animCrossHair.Invoke("setFriendly", m_iFriendlyTarget); if(iNewFriendly) m_animFriendCross.SetVisible(true); else m_animFriendCross.SetVisible(false); } if(m_animInterActiveIcons.GetVisible()) { m_bHideUseIconTemp = false; CItem *pItem = static_cast<CItem*>(pClientActor->GetCurrentItem()); if(pItem) { IWeapon *pWeapon = pItem->GetIWeapon(); if(pWeapon) { CItem::SStats stats = pItem->GetStats(); if(stats.mounted && stats.used) m_bHideUseIconTemp = true; } } if(!m_bHideUseIconTemp) { EntityId offHandId = pClientActor->GetInventory()->GetItemByClass(CItem::sOffHandClass); IItem *pOffHandItem = g_pGame->GetIGameFramework()->GetIItemSystem()->GetItem(offHandId); if(pOffHandItem) { COffHand *pOffHand = static_cast<COffHand*>(pOffHandItem); uint32 offHandState = pOffHand->GetOffHandState(); if(offHandState == eOHS_HOLDING_OBJECT || offHandState == eOHS_THROWING_OBJECT || offHandState == eOHS_HOLDING_NPC || offHandState == eOHS_THROWING_NPC) m_bHideUseIconTemp = true; } } } }