//---------------------------------------------------------- bool CWeapon::OnActionZoom(EntityId actorId, const ActionId& actionId, int activationMode, float value) { COffHand * offHandWeapon = NULL; bool isOffHandSelected = false; GetOffHandInfo(this,isOffHandSelected,&offHandWeapon); if (!m_modifying && (!isOffHandSelected || (offHandWeapon->GetOffHandState()&eOHS_TRANSITIONING))) { if (activationMode == eAAM_OnPress && m_useViewMode) { IncrementViewmode(); } else { bool isDualWield = false; CWeapon *dualWield = NULL; GetDualWieldInfo(this,isDualWield,&dualWield); if (!isDualWield) { if (m_fm && !m_fm->IsReloading()) { if (activationMode == eAAM_OnPress) { if(!m_fm->AllowZoom()) { if(!IsTargetOn()) //Allow zoom-in, when using aiming helper return false; } if(m_weaponRaised) { return false; } //Use mouse wheel for scopes with several steps/stages if (m_zm && m_zm->IsZoomed() && m_zm->GetMaxZoomSteps()>1) m_zm->StopZoom(); else StartZoom(actorId,1); } else if (activationMode == eAAM_OnRelease) { if(m_zm && !m_zm->IsToggle()) m_zm->StopZoom(); } } } } } return true; }
//--------------------------------------------------------------- void CAmmoPickup::ShouldSwitchGrenade(IEntityClass* pClass) { bool flashbang = (pClass==CItem::sFlashbangGrenade); bool smoke = (pClass==CItem::sSmokeGrenade); bool emp = (pClass==CItem::sEMPGrenade); bool explosive = (pClass==CItem::sExplosiveGrenade); if(!flashbang && !smoke && !emp && !explosive) return; CActor* pPlayer = GetOwnerActor(); if(!pPlayer) return; COffHand* pOffHand = static_cast<COffHand*>(pPlayer->GetWeaponByClass(CItem::sOffHandClass)); if(pOffHand) { if(IFireMode* fm = pOffHand->GetFireMode(pOffHand->GetCurrentFireMode())) { if(fm->OutOfAmmo()) { if(explosive) pOffHand->RequestFireMode(EXPLOSIVE_GRENADE); else if(smoke) pOffHand->RequestFireMode(SMOKE_GRENADE); else if(flashbang) pOffHand->RequestFireMode(FLASHBANG_GRENADE); else if(emp) pOffHand->RequestFireMode(EMP_GRENADE); } } } }
bool CPlayerInput::OnActionUse(EntityId entityId, const ActionId& actionId, int activationMode, float value) { bool filterOut = true; IVehicle* pVehicle = m_pPlayer->GetLinkedVehicle(); //FIXME:on vehicles use cannot be used if (pVehicle) { filterOut = false; } if (activationMode==eAAM_OnPress) { COffHand* pOffHand = static_cast<COffHand*>(m_pPlayer->GetWeaponByClass(CItem::sOffHandClass)); IEntity *pEntity=gEnv->pEntitySystem->GetEntity(m_pPlayer->GetGameObject()->GetWorldQuery()->GetLookAtEntityId()); //Drop objects/npc before enter a vehicle if(pOffHand) { if(pOffHand->GetOffHandState()&(eOHS_HOLDING_OBJECT|eOHS_HOLDING_NPC)) { pOffHand->OnAction(m_pPlayer->GetEntityId(), actionId, activationMode, 0); return false; } } //--------------------------LADDERS----------------------------------------------- if(m_pPlayer->m_stats.isOnLadder) { m_pPlayer->RequestLeaveLadder(CPlayer::eLAT_Use); return false; } else { if(m_pPlayer->IsLadderUsable()) { m_pPlayer->RequestGrabOnLadder(CPlayer::eLAT_Use); return false; } } } return filterOut; }
//--------------------------------------------------------------------- bool CWeapon::OnActionSpecial(EntityId actorId, const ActionId& actionId, int activationMode, float value) { if (activationMode == eAAM_OnPress) { if(m_weaponRaised) { RaiseWeapon(false,true); } COffHand * offHandWeapon = NULL; bool isOffHandSelected = false; GetOffHandInfo(this,isOffHandSelected,&offHandWeapon); if (CanMeleeAttack() && (!isOffHandSelected || (offHandWeapon->GetOffHandState()&(eOHS_HOLDING_NPC|eOHS_TRANSITIONING)))) MeleeAttack(); } return true; }
//////////////////////////////////////////////////// // Execute // // Purpose: Execute the behavior for this motion //////////////////////////////////////////////////// virtual void Execute(void) { CBaseMotion::Execute(); CPlayer *pPlayer = GetPlayer(); const CGameActions &rGameActions = g_pGame->Actions(); // Throw item in your hand if you have one COffHand* pOffHand = static_cast<COffHand*>(pPlayer->GetWeaponByClass(CItem::sOffHandClass)); if (NULL != pOffHand) { int nOffHandState = pOffHand->GetOffHandState(); if ((nOffHandState&(eOHS_HOLDING_OBJECT|eOHS_THROWING_OBJECT|eOHS_HOLDING_NPC|eOHS_THROWING_NPC))) { /*pOffHand->OnAction(pPlayer->GetEntityId(), rGameActions.attack1, eIS_Pressed, 1.0f); pOffHand->OnAction(pPlayer->GetEntityId(), rGameActions.attack1, eIS_Released, 1.0f);*/ pOffHand->ThrowObject(eAAM_OnPress,nOffHandState&(eOHS_HOLDING_NPC|eOHS_THROWING_NPC)?true:false); pOffHand->ThrowObject(eAAM_OnRelease,nOffHandState&(eOHS_HOLDING_NPC|eOHS_THROWING_NPC)?true:false); g_pGame->GetWiiRemoteManager()->FreezeMovement(); return; } // Throw a grenade instead pOffHand->OnAction(pPlayer->GetEntityId(), rGameActions.grenade, eIS_Pressed, 1.0f); pOffHand->OnAction(pPlayer->GetEntityId(), rGameActions.grenade, eIS_Released, 1.0f); g_pGame->GetWiiRemoteManager()->FreezeMovement(); } }
bool CPlayerInput::OnActionProne(EntityId entityId, const ActionId& actionId, int activationMode, float value) { //No prone if holding something COffHand* pOffHand = static_cast<COffHand*>(m_pPlayer->GetWeaponByClass(CItem::sOffHandClass)); if(pOffHand && pOffHand->IsHoldingEntity()) return false; if (!m_pPlayer->m_stats.spectatorMode) { if(!m_pPlayer->GetActorStats()->inZeroG) { if(activationMode == eAAM_OnPress) { CItem *curItem = static_cast<CItem*>(gEnv->pGame->GetIGameFramework()->GetIItemSystem()->GetItem(m_pPlayer->GetInventory()->GetCurrentItem())); if(curItem && curItem->GetParams().prone_not_usable) { // go crouched instead. // Nope, actually do nothing // if (!(m_actions & ACTION_CROUCH)) // m_actions |= ACTION_CROUCH; // else // m_actions &= ~ACTION_CROUCH; } else { if (!(m_actions & ACTION_PRONE)) { if(!m_pPlayer->GetActorStats()->inAir) m_actions |= ACTION_PRONE; } else m_actions &= ~ACTION_PRONE; } } } } return false; }
//------------------------------------------------------------------------ void CItem::OnPickedUp(EntityId actorId, bool destroyed) { if(GetISystem()->IsSerializingFile() == 1) return; CActor *pActor=GetActor(actorId); if (!pActor) return; RegisterAsUser(); if(gEnv->bMultiplayer && pActor->IsClient() && IsSelected()) { COffHand* pOffHand = static_cast<COffHand*>(pActor->GetWeaponByClass(CItem::sOffHandClass)); if(pOffHand && pOffHand->GetOffHandState()==eOHS_HOLDING_GRENADE) pOffHand->FinishAction(eOHA_RESET); } if (!IsServer()) return; //if (destroyed && m_params.unique) { if (!m_bonusAccessoryAmmo.empty()) { for (TAccessoryAmmoMap::iterator it=m_bonusAccessoryAmmo.begin(); it!=m_bonusAccessoryAmmo.end(); ++it) { int count=it->second; AddAccessoryAmmoToInventory(it->first,count,pActor); } m_bonusAccessoryAmmo.clear(); } } m_pItemSystem->UnregisterForCollection(GetEntityId()); }
//--------------------------------------------------------------------- bool CWeapon::OnActionSpecial(EntityId actorId, const ActionId& actionId, int activationMode, float value) { if (activationMode == eAAM_OnPress) { if(m_weaponRaised) RaiseWeapon(false,true); CActor* pOwnerActor = GetOwnerActor(); if (pOwnerActor && g_pGameCVars->dt_enable) { CPlayer *pPlayer = static_cast<CPlayer*>(pOwnerActor); pPlayer->GetNanoSuit()->Tap(eNA_Melee); } COffHand * offHandWeapon = NULL; bool isOffHandSelected = false; GetOffHandInfo(this,isOffHandSelected,&offHandWeapon); if (CanMeleeAttack() && (!isOffHandSelected || (offHandWeapon->GetOffHandState()&(eOHS_HOLDING_NPC|eOHS_TRANSITIONING)))) MeleeAttack(); } return true; }
//-------------------------------------------------------------------- bool CWeapon::OnActionAttack(EntityId actorId, const ActionId& actionId, int activationMode, float value) { if(!m_modifying) { COffHand * offHandWeapon = NULL; bool isOffHandSelected = false; GetOffHandInfo(this,isOffHandSelected,&offHandWeapon); if(IsTwoHand()) { if(offHandWeapon && (offHandWeapon->GetOffHandState()&(eOHS_HOLDING_GRENADE|eOHS_SWITCHING_GRENADE|eOHS_PICKING_ITEM))) return false; } if (activationMode == eAAM_OnPress) { if(PreActionAttack(true)) return true; bool isDualWield = false; CWeapon *dualWield = NULL; GetDualWieldInfo(this,isDualWield,&dualWield); // EXPANSION: Dino has rewritten dual wield control! /*if (isDualWield) { m_fire_alternation = !m_fire_alternation; m_requestedFire = true; if (!m_fire_alternation && dualWield->OutOfAmmo(false) && dualWield->CanReload()) { dualWield->Reload(); return true; } else if(m_fire_alternation && OutOfAmmo(false) && CanReload()) { Reload(); return true; } if (m_fire_alternation || (!dualWield->CanFire() || !dualWield->IsSelected())) { if(!IsWeaponRaised() && CanFire()) StartFire(); else if(!dualWield->IsWeaponRaised() && dualWield->IsSelected()) dualWield->StartFire(); } else if (dualWield->CanFire()) { if(!dualWield->IsWeaponRaised() && dualWield->CanFire()) dualWield->StartFire(); else if(!IsWeaponRaised()) StartFire(); } }*/ // /EXPANSION if (isDualWield) { if (offHandWeapon && !(offHandWeapon->GetOffHandState() & (eOHS_INIT_STATE))) return false; m_fire_alternation = false; if (!dualWield->IsWeaponRaised())// && dualWield->CanFire()) { dualWield->StartFire(); } /* else if(dualWield->OutOfAmmo(false) && !dualWield->IsReloading()) { dualWield->Reload(); }*/ dualWield->m_requestedFire = true; } else { if(!m_weaponRaised) { StartFire(); } m_requestedFire = true; } } else if (activationMode == eAAM_OnRelease) { PreActionAttack(false); // EXP 1: Don't stop both slave and master simultaneously!!! //Stop slave if(IsDualWieldMaster()) { //FireSlave(actorId,false); CWeapon *dualWield = NULL; IItem *slave = GetDualWieldSlave(); if (slave && slave->GetIWeapon()) dualWield = static_cast<CWeapon *>(slave); if(dualWield) { dualWield->StopFire(); dualWield->m_requestedFire=false; } } else if (m_fm) { m_fm->StopFire(); m_requestedFire = false; } // StopFire(); // /EXP 1 } } return true; }
// (jh) this function is called on any input dispatching it to a relevant method and eventually to Lua onAction method void CPlayerInput::OnAction( const ActionId& actionId, int activationMode, float value ) { FUNCTION_PROFILER(GetISystem(), PROFILE_GAME); if (g_pGame->GetHostMigrationState() != CGame::eHMS_NotMigrating) { Reset(); return; } m_pPlayer->GetGameObject()->ChangedNetworkState( INPUT_ASPECT ); m_lastActions=m_actions; //this tell if OnAction have to be forwarded to scripts, now its true by default, only high framerate actions are ignored bool filterOut = true; m_checkZoom = false; const CGameActions& actions = g_pGame->Actions(); IVehicle* pVehicle = m_pPlayer->GetLinkedVehicle(); bool canMove = CanMove(); // disable movement while standing up if (!canMove) m_deltaMovement.zero(); // try to dispatch action to OnActionHandlers bool handled; { FRAME_PROFILER("New Action Processing", GetISystem(), PROFILE_GAME); handled = s_actionHandler.Dispatch(this, m_pPlayer->GetEntityId(), actionId, activationMode, value, filterOut); } { FRAME_PROFILER("Regular Action Processing", GetISystem(), PROFILE_GAME); if (!handled) { filterOut = true; if (!m_pPlayer->m_stats.spectatorMode) { if (actions.ulammo==actionId && m_pPlayer->m_pGameFramework->CanCheat() && gEnv->pSystem->IsDevMode()) { g_pGameCVars->i_unlimitedammo = 1; } else if (actions.debug_ag_step == actionId) { gEnv->pConsole->ExecuteString("ag_step"); } else if(actions.voice_chat_talk == actionId) { if(gEnv->bMultiplayer) { if(activationMode == eAAM_OnPress) g_pGame->GetIGameFramework()->EnableVoiceRecording(true); else if(activationMode == eAAM_OnRelease) g_pGame->GetIGameFramework()->EnableVoiceRecording(false); } } } } if (!m_pPlayer->m_stats.spectatorMode) { IInventory* pInventory = m_pPlayer->GetInventory(); if (!pInventory) return; bool scope = false; EntityId itemId = pInventory->GetCurrentItem(); CWeapon *pWeapon = 0; if (itemId) { pWeapon = m_pPlayer->GetWeapon(itemId); if (pWeapon) { scope = (pWeapon->IsZoomed() && pWeapon->GetMaxZoomSteps()>1); } } if (pVehicle) { if (m_pPlayer->m_pVehicleClient && !m_pPlayer->IsFrozen()) m_pPlayer->m_pVehicleClient->OnAction(pVehicle, m_pPlayer->GetEntityId(), actionId, activationMode, value); //FIXME:not really good m_actions = 0; m_deltaMovement.Set(0,0,0); } else if (m_pPlayer->GetHealth() > 0 && !m_pPlayer->m_stats.isFrozen.Value() && !m_pPlayer->m_stats.inFreefall.Value() && !m_pPlayer->m_stats.isOnLadder && !m_pPlayer->m_stats.isStandingUp && m_pPlayer->GetGameObject()->GetAspectProfile(eEA_Physics)!=eAP_Sleep) { m_pPlayer->CActor::OnAction(actionId, activationMode, value); if ((!scope || actionId == actions.use)) { COffHand* pOffHand = static_cast<COffHand*>(m_pPlayer->GetWeaponByClass(CItem::sOffHandClass)); if (pOffHand) { pOffHand->OnAction(m_pPlayer->GetEntityId(), actionId, activationMode, value); } if ((!pWeapon || !pWeapon->IsMounted())) { if ((actions.drop==actionId) && itemId) { float impulseScale=1.0f; if (activationMode==eAAM_OnPress) m_buttonPressure=2.5f; if (activationMode==eAAM_OnRelease) { m_buttonPressure=CLAMP(m_buttonPressure, 0.0f, 2.5f); impulseScale=1.0f+(1.0f-m_buttonPressure/2.5f)*15.0f; if (m_pPlayer->DropItem(itemId, impulseScale, true) && pOffHand && pOffHand->IsSelected()) { if (EntityId fistsId = pInventory->GetItemByClass(CItem::sFistsClass)) { m_pPlayer->SelectItem(fistsId, false); } pOffHand->PreExecuteAction(eOHA_REINIT_WEAPON, eAAM_OnPress); CItem* pItem = static_cast<CItem*>(m_pPlayer->GetCurrentItem()); if (pItem) { pItem->SetActionSuffix("akimbo_"); pItem->PlayAction(g_pItemStrings->idle); } } } } else if (actions.nextitem==actionId) m_pPlayer->SelectNextItem(1, true, 0); else if (actions.previtem==actionId) m_pPlayer->SelectNextItem(-1, true, 0); else if (actions.handgrenade==actionId) m_pPlayer->SelectNextItem(1, true, actionId.c_str()); else if (actions.explosive==actionId) m_pPlayer->SelectNextItem(1, true, actionId.c_str()); else if (actions.utility==actionId) m_pPlayer->SelectNextItem(1, true, actionId.c_str()); else if (actions.small==actionId) m_pPlayer->SelectNextItem(1, true, actionId.c_str()); else if (actions.medium==actionId) m_pPlayer->SelectNextItem(1, true, actionId.c_str()); else if (actions.heavy==actionId) m_pPlayer->SelectNextItem(1, true, actionId.c_str()); else if (actions.debug==actionId) { if (g_pGame) { if (!m_pPlayer->GetInventory()->GetItemByClass(CItem::sDebugGunClass)) g_pGame->GetWeaponSystem()->DebugGun(0); if (!m_pPlayer->GetInventory()->GetItemByClass(CItem::sRefWeaponClass)) g_pGame->GetWeaponSystem()->RefGun(0); } m_pPlayer->SelectNextItem(1, true, actionId.c_str()); } } } else { if (actions.handgrenade==actionId) m_pPlayer->SelectNextItem(1, true, actionId.c_str()); else if (actions.explosive==actionId) m_pPlayer->SelectNextItem(1, true, actionId.c_str()); else if (actions.utility==actionId) m_pPlayer->SelectNextItem(1, true, actionId.c_str()); else if (actions.small==actionId) m_pPlayer->SelectNextItem(1, true, actionId.c_str()); else if (actions.medium==actionId) m_pPlayer->SelectNextItem(1, true, actionId.c_str()); else if (actions.heavy==actionId) m_pPlayer->SelectNextItem(1, true, actionId.c_str()); else if (actions.drop==actionId && activationMode == eAAM_OnRelease && itemId) m_pPlayer->DropItem(itemId, 1.0f, true); } } if (m_checkZoom) { if (pWeapon) { IZoomMode *zm = pWeapon->GetZoomMode(pWeapon->GetCurrentZoomMode()); CScreenEffects* pScreenEffects = m_pPlayer->GetScreenEffects(); if (zm && !zm->IsZoomingInOrOut() && !zm->IsZoomed() && pScreenEffects != 0) { if (!m_moveButtonState && m_pPlayer->IsClient()) { IBlendedEffect *fovEffect = CBlendedEffect<CFOVEffect>::Create(CFOVEffect(m_pPlayer->GetEntityId(),1.0f)); IBlendType *blend = CBlendType<CLinearBlend>::Create(CLinearBlend(1.0f)); pScreenEffects->ResetBlendGroup(CScreenEffects::eSFX_GID_ZoomIn, false); pScreenEffects->ResetBlendGroup(CScreenEffects::eSFX_GID_ZoomOut, false); pScreenEffects->StartBlend(fovEffect, blend, 1.0f/.25f, CScreenEffects::eSFX_GID_ZoomIn); } else { pScreenEffects->EnableBlends(true, CScreenEffects::eSFX_GID_ZoomIn); pScreenEffects->EnableBlends(true, CScreenEffects::eSFX_GID_ZoomOut); pScreenEffects->EnableBlends(true, CScreenEffects::eSFX_GID_HitReaction); } } } } } } bool hudFilterOut = true; // FIXME: temporary method to dispatch Actions to HUD (it's not yet possible to register) hudFilterOut = true; //Filter must take into account offHand too COffHand* pOffHand = static_cast<COffHand*>(m_pPlayer->GetWeaponByClass(CItem::sOffHandClass)); if(pOffHand && pOffHand->IsSelected()) filterOut = false; //send the onAction to scripts, after filter the range of actions. for now just use and hold if (filterOut && hudFilterOut) { FRAME_PROFILER("Script Processing", GetISystem(), PROFILE_GAME); HSCRIPTFUNCTION scriptOnAction(NULL); IScriptTable *scriptTbl = m_pPlayer->GetEntity()->GetScriptTable(); if (scriptTbl) { scriptTbl->GetValue("OnAction", scriptOnAction); if (scriptOnAction) { char *activation = 0; switch(activationMode) { case eAAM_OnHold: activation = "hold"; break; case eAAM_OnPress: activation = "press"; break; case eAAM_OnRelease: activation = "release"; break; default: activation = ""; break; } Script::Call(gEnv->pScriptSystem,scriptOnAction,scriptTbl,actionId.c_str(),activation, value); } } gEnv->pScriptSystem->ReleaseFunc(scriptOnAction); } }
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; } }
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; } } } }
//-------------------------------------------------------------------- bool CWeapon::OnActionAttack(EntityId actorId, const ActionId& actionId, int activationMode, float value) { if(!m_modifying) { if(IsTwoHand()) { COffHand * offHandWeapon = NULL; bool isOffHandSelected = false; GetOffHandInfo(this,isOffHandSelected,&offHandWeapon); if(offHandWeapon && (offHandWeapon->GetOffHandState()&(eOHS_HOLDING_GRENADE|eOHS_SWITCHING_GRENADE|eOHS_PICKING_ITEM))) return false; } if (activationMode == eAAM_OnPress) { if(PreActionAttack(true)) return true; bool isDualWield = false; CWeapon *dualWield = NULL; GetDualWieldInfo(this,isDualWield,&dualWield); if (isDualWield) { m_fire_alternation = !m_fire_alternation; m_requestedFire = true; if (m_fire_alternation || !dualWield->CanFire()) { if(!IsWeaponRaised() && CanFire()) StartFire(); else if(!dualWield->IsWeaponRaised()) dualWield->StartFire(); } else if (dualWield->CanFire()) { if(!dualWield->IsWeaponRaised() && dualWield->CanFire()) dualWield->StartFire(); else if(!IsWeaponRaised()) StartFire(); } else if(OutOfAmmo(false)) { Reload(); dualWield->Reload(); } } else { if(!m_weaponRaised) StartFire(); m_requestedFire = true; } } else if (activationMode == eAAM_OnRelease) { PreActionAttack(false); StopFire(); m_requestedFire = false; } } return true; }