void CPlayerEntityInteraction::UseEntityUnderPlayer(CPlayer* pPlayer) { if (PlayerCanInteract(pPlayer)) { IInteractor* pInteractor = pPlayer->GetInteractor(); const EntityId entityId = pInteractor->GetOverEntityId(); if(IEntity* pLinkedEnt = pPlayer->GetLinkedEntity()) { if(pLinkedEnt->GetId()==entityId) { // Can't use an entity you are already linked to. return; } } const int frameId = gEnv->pRenderer->GetFrameID(); if (m_lastUsedEntity.CanInteractThisFrame( frameId )) { CallEntityScriptMethod( entityId, "OnUsed", pPlayer, pInteractor->GetOverSlotIdx()); m_lastUsedEntity.Update( frameId ); } } }
void CVehicleMountedWeapon::Use( EntityId userId ) { IVehicle *pVehicle = gEnv->pGame->GetIGameFramework()->GetIVehicleSystem()->GetVehicle(m_vehicleId); if (!IsRippingOff() && pVehicle) { IActor* pUserActor = gEnv->pGame->GetIGameFramework()->GetIActorSystem()->GetActor(userId); if(pUserActor && pUserActor->IsPlayer()) { CPlayer* pPlayer = static_cast<CPlayer*>(pUserActor); IInteractor* pInteractor = pPlayer->GetInteractor(); pVehicle->OnUsed(userId, pInteractor->GetOverSlotIdx()); return; } } CHeavyMountedWeapon::Use(userId); }
void CPlayerEntityInteraction::Update(CPlayer* pPlayer, float frameTime) { if(m_useButtonPressed && m_autoPickupDeactivatedTime <= 0.f) { IInteractor* pInteractor = pPlayer->GetInteractor(); if (pInteractor->GetOverEntityId() != 0) { EInteractionType interactionType = pPlayer->GetCurrentInteractionInfo().interactionType; if(interactionType == eInteraction_PickupItem || interactionType == eInteraction_ExchangeItem) { UseEntityUnderPlayer(pPlayer); m_useButtonPressed = false; m_autoPickupDeactivatedTime = g_pGameCVars->pl_autoPickupMinTimeBetweenPickups; } } } else if(m_autoPickupDeactivatedTime > 0.f) { m_autoPickupDeactivatedTime -= frameTime; } }
void CPlayerEntityInteraction::ItemPickUpMechanic(CPlayer* pPlayer, const ActionId& actionId, int activationMode) { const CGameActions& actions = g_pGame->Actions(); if (actionId == actions.preUse) { if (activationMode == eAAM_OnPress) { // Interactor HUD needs to know when to start tracking a Use press // preUse is used instead of Use as adding an onPress to Use will need too many changes to its handling. preUse is the input as Use. SHUDEventWrapper::OnInteractionUseHoldTrack(true); } return; } if (actionId == actions.use) { if (activationMode == eAAM_OnPress) { m_useButtonPressed = true; } else if(activationMode == eAAM_OnRelease) { m_useButtonPressed = false; } } const bool isOnlyPickupAction = (actionId == actions.itemPickup); const bool isOnlyUseAction = (actionId == actions.use); const bool isOnlyHeavyWeaponRemove = (actionId == actions.heavyweaponremove); const bool isUseAction = (isOnlyUseAction || isOnlyPickupAction); if (isOnlyHeavyWeaponRemove && activationMode == eAAM_OnPress && PlayerCanStopUseHeavyWeapon(pPlayer)) { ReleaseHeavyWeapon(pPlayer); m_useHoldFiredAlready = true; } else if (isUseAction && activationMode == eAAM_OnPress) { // This will happen twice on keyboard since Use and itemPickup use same input // To avoid refactoring code right now, only allow self.UseEntity to be called once per input frame // But make sure this functions properly even if use and itemPickup inputs are changed bool fireUseEntity = false; if (isOnlyPickupAction) { if (m_usePressFiredForUse) // 2nd call this frame, don't call { m_usePressFiredForUse = false; // Reset m_usePressFiredForPickup = false; // Reset } else { fireUseEntity = true; m_usePressFiredForPickup = true; } } else if (isOnlyUseAction) { if (m_usePressFiredForPickup) // 2nd call this frame, don't call { m_usePressFiredForPickup = false; // Reset m_usePressFiredForUse = false; // Reset } else { fireUseEntity = true; m_usePressFiredForUse = true; } } if (fireUseEntity) { // Log("[tlh] @ Player:OnAction: action: "..action.." press path"); if (PlayerCanStopUseHeavyWeapon(pPlayer)) ReleaseHeavyWeapon(pPlayer); else UseEntityUnderPlayer(pPlayer); } } else if (isUseAction && activationMode == eAAM_OnHold && !m_useHoldFiredAlready) { bool bFired = false; IInteractor* pInteractor = pPlayer->GetInteractor(); if (pInteractor->GetOverEntityId() != 0) { m_useHoldFiredAlready = true; UseEntityUnderPlayer(pPlayer); bFired = true; } SHUDEventWrapper::OnInteractionUseHoldActivated(bFired); } else if (isUseAction && activationMode == eAAM_OnRelease) { m_useHoldFiredAlready = false; SHUDEventWrapper::OnInteractionUseHoldTrack(false); } }
//------------------------------------------------------------------------ int CScriptBind_Item::OnUsed(IFunctionHandler *pH, ScriptHandle userId) { CItem *pItem = GetItem(pH); if (!pItem) return pH->EndFunction(); CActor *pActor = GetActor((EntityId)userId.n); if (!pActor) return pH->EndFunction(); if (pItem->CanUse((EntityId)userId.n)) { if(IEntity* pParent = pItem->GetEntity()->GetParent()) { IVehicle* pVehicle = gEnv->pGame->GetIGameFramework()->GetIVehicleSystem()->GetVehicle(pParent->GetId()); if(pVehicle) { CPlayer* pPlayer = static_cast<CPlayer*>(pActor); IInteractor* pInteractor = pPlayer->GetInteractor(); return pH->EndFunction( pVehicle->OnUsed((EntityId)userId.n, pInteractor->GetOverSlotIdx()) ); } } pActor->UseItem(pItem->GetEntityId()); return pH->EndFunction(true); } else if (pItem->CanPickUp((EntityId)userId.n)) { //Should be always the client... if (pActor->IsClient()) { CPlayer* pClientPlayer = static_cast<CPlayer*>(pActor); const SInteractionInfo& interactionInfo = pClientPlayer->GetCurrentInteractionInfo(); bool expectedItem = (interactionInfo.interactiveEntityId == pItem->GetEntityId()); bool expectedInteraction = (interactionInfo.interactionType == eInteraction_PickupItem) || (interactionInfo.interactionType == eInteraction_ExchangeItem); if (!expectedItem || !expectedInteraction) { return pH->EndFunction(); } if (interactionInfo.interactionType == eInteraction_ExchangeItem) { IItemSystem* pItemSystem = g_pGame->GetIGameFramework()->GetIItemSystem(); CItem* pCurrentItem = static_cast<CItem*>(pActor->GetCurrentItem()); CItem* pExchangeItem = static_cast<CItem*>(pItemSystem->GetItem(interactionInfo.swapEntityId)); if (pExchangeItem && pCurrentItem) pExchangeItem->ScheduleExchangeToNextItem(pActor, pItem, pCurrentItem); } else { pActor->PickUpItem(pItem->GetEntityId(), true, true); } } else { pActor->PickUpItem(pItem->GetEntityId(), true, true); } return pH->EndFunction(true); } return pH->EndFunction(); }