//------------------------------------------------------------------------ int CScriptBind_Weapon::SetAmmoCount(IFunctionHandler *pH) { CWeapon *pWeapon = GetWeapon(pH); if (!pWeapon) return pH->EndFunction(); IFireMode *pFireMode = pWeapon->GetFireMode(pWeapon->GetCurrentFireMode()); if (pFireMode) { if (pH->GetParamType(2) != svtNumber) return pH->EndFunction(); const char *ammoName = 0; if (pH->GetParamType(1) == svtString) pH->GetParam(1, ammoName); IEntityClass* pAmmoType = pFireMode->GetAmmoType(); if (ammoName) pAmmoType = gEnv->pEntitySystem->GetClassRegistry()->FindClass(ammoName); int ammo = 0; pH->GetParam(2, ammo); pWeapon->SetAmmoCount(pAmmoType, ammo); } return pH->EndFunction(); }
EStatus Update(float timePassed) { if (IsTransitioningOut()) { const float ROTATION_LERP_SPEED = 10.0f; //--- Blend body rotation to match current view Ang3 targetViewDir = m_player.GetAngles(); Quat targetRotation = Quat::CreateRotationZ(targetViewDir.z); Quat newRotation = Quat::CreateNlerp(m_player.GetEntity()->GetRotation(), targetRotation, timePassed*ROTATION_LERP_SPEED); m_player.GetEntity()->SetRotation(newRotation); } else { static uint32 leanParamCRC = gEnv->pSystem->GetCrc32Gen()->GetCRC32Lowercase("SlideFactor"); const Matrix34 &worldTM = m_player.GetEntity()->GetWorldTM(); const Vec3 baseRgt = worldTM.GetColumn0(); const Vec3 baseFwd = worldTM.GetColumn1(); const Vec3 lookFwd = m_player.GetViewQuatFinal().GetColumn1(); const float leanAngle = cry_acosf(baseFwd.Dot(lookFwd)); float targetLeanFactor = clamp(leanAngle / MAX_LEAN_ANGLE, 0.0f, 1.0f); if (baseRgt.Dot(lookFwd) < 0.0f) { targetLeanFactor *= -1.0f; } CWeapon *pWeapon = m_player.GetWeapon(m_player.GetCurrentItemId()); if (pWeapon) { IFireMode *pFiremode = pWeapon->GetFireMode(pWeapon->GetCurrentFireMode()); if (pFiremode && (pFiremode->GetNextShotTime() > 0.0f)) { targetLeanFactor = 0.0f; } } const float delta = targetLeanFactor - m_leanFactor; const float step = LEAN_RATE * timePassed; const float newLeanFactor = (float)__fsel(delta, min(m_leanFactor + step, targetLeanFactor), max(m_leanFactor - step, targetLeanFactor)); SWeightData weightData; weightData.weights[0] = newLeanFactor; SetParam(leanParamCRC, weightData); m_leanFactor = newLeanFactor; if (GetRootScope().IsDifferent(m_fragmentID, m_fragTags)) { SetFragment(m_fragmentID, m_fragTags); } } return TPlayerAction::Update(timePassed); }
//------------------------------------------------------------------------ int CScriptBind_Weapon::GetCrosshair(IFunctionHandler *pH) { CWeapon *pWeapon = GetWeapon(pH); if (!pWeapon) return pH->EndFunction(); IFireMode *pFireMode = pWeapon->GetFireMode(pWeapon->GetCurrentFireMode()); if (pFireMode) return pH->EndFunction(pFireMode->GetCrosshair()); return pH->EndFunction(); }
//------------------------------------------------------------------------ int CScriptBind_Weapon::GetAmmoType(IFunctionHandler *pH) { CWeapon *pWeapon = GetWeapon(pH); if (!pWeapon) return pH->EndFunction(); IFireMode *pFireMode = pWeapon->GetFireMode(pWeapon->GetCurrentFireMode()); if (pFireMode) if (IEntityClass * pCls = pFireMode->GetAmmoType()) return pH->EndFunction(pCls->GetName()); return pH->EndFunction(); }
//------------------------------------------------------------------------ int CScriptBind_Weapon::GetCurrentFireMode(IFunctionHandler *pH) { CWeapon *pWeapon = GetWeapon(pH); if (!pWeapon) return pH->EndFunction(); int idx = pWeapon->GetCurrentFireMode(); IFireMode* pFireMode = pWeapon->GetFireMode(idx); if (pFireMode) { return pH->EndFunction(pFireMode->GetName()); } return pH->EndFunction(); }
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 CGameStateRecorder::DumpWholeGameState(const CActor* pActor) { GameplayEvent event; IEntity* pEntity = pActor->GetEntity(); // health float health = (float)pActor->GetHealth(); event.event = eGE_HealthChanged; event.value = health; SendGamePlayEvent(pEntity,event); // Inventory CInventory *pInventory = (CInventory*)(pActor->GetInventory()); if(!pInventory) return; int count = pInventory->GetCount(); for(int i=0; i<count; ++i) { EntityId itemId = pInventory->GetItem(i); CItem* pItem=NULL; TItemName itemName = GetItemName(itemId,&pItem); if(pItem && itemName) { event.event = eGE_ItemPickedUp; event.description = itemName; SendGamePlayEvent(pEntity,event); if(pActor->GetCurrentItem() == pItem) { event.event = eGE_ItemSelected; event.description = itemName; event.value = 1; // for initialization SendGamePlayEvent(pEntity,event); } CWeapon* pWeapon = (CWeapon*)(pItem->GetIWeapon()); if(pWeapon) { IEntityClass* pItemClass = pWeapon->GetEntity()->GetClass(); if(pItemClass && !strcmpi(pItemClass->GetName(),"binoculars")) continue; // no fire mode or ammo recorded for binocular (which is a weapon) // fire mode int fireModeIdx = pWeapon->GetCurrentFireMode(); event.event = eGE_WeaponFireModeChanged; event.value = (float)fireModeIdx; event.description = itemName; SendGamePlayEvent(pEntity,event); // count ammo for(SWeaponAmmo weaponAmmo = pWeapon->GetFirstAmmo(); weaponAmmo.pAmmoClass ; weaponAmmo = pWeapon->GetNextAmmo()) { const char* ammoClass; if(weaponAmmo.pAmmoClass && (ammoClass = weaponAmmo.pAmmoClass->GetName())) { event.event = eGE_AmmoCount; event.value = (float)weaponAmmo.count; event.extra = (void*)ammoClass; event.description = (const char*)itemName; SendGamePlayEvent(pEntity,event); } } } } } count = pInventory->GetAccessoryCount(); for(int i=0; i< count; i++) { const char* accessory = pInventory->GetAccessory(i); if(accessory && strlen(accessory)) { IEntityClass* pClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass(accessory); if(pClass) { TItemName classItem = pClass->GetName(); event.event = eGE_AccessoryPickedUp; //event.value = classIdx; event.description = classItem; SendGamePlayEvent(pEntity,event); } } } int nInvAmmo = pInventory->GetAmmoPackCount(); pInventory->AmmoIteratorFirst(); for(int j=0 ; !pInventory->AmmoIteratorEnd(); j++, pInventory->AmmoIteratorNext()) { const IEntityClass* pAmmoClass = pInventory->AmmoIteratorGetClass(); if(pAmmoClass) { const char* ammoClassName = pAmmoClass->GetName(); int ammoCount = pInventory->AmmoIteratorGetCount(); GameplayEvent event; event.event = eGE_AmmoPickedUp; event.description = ammoClassName; event.value = (float)ammoCount; SendGamePlayEvent(pEntity,event); } } }
/*template <class EventHandlerFunc> */void CGameStateRecorder::CheckInventory(CActor* pActor, IItem *pItem)//, EventHandlerFunc eventHandler) { if(pActor) { TGameStates::iterator itGS; if(pActor->IsPlayer()) itGS = m_itSingleActorGameState; else if(pActor->GetEntity()) itGS = m_GameStates.find(pActor->GetEntity()->GetId()); else return; if(itGS != m_GameStates.end()) { SActorGameState& gstate = itGS->second; // items CInventory *pInventory = (CInventory*)(pActor->GetInventory()); if(pInventory) { bool bSingleItem = (pItem!=0); int nInvItems = (bSingleItem ? 1 : pInventory->GetCount()); TItemContainer& Items = gstate.Items; for(int i=0; i< nInvItems; i++) { if(!bSingleItem) pItem = g_pGame->GetIGameFramework()->GetIItemSystem()->GetItem(pInventory->GetItem(i)); if(pItem) { TItemName szItemName = GetItemName(pItem->GetEntityId()); TItemContainer::iterator it = Items.find(szItemName); if(it==Items.end()) { it = (Items.insert(std::make_pair(szItemName,SItemProperties()))).first; GameplayEvent event; event.event = eGE_ItemPickedUp; event.description = szItemName; //eventHandler(pActor,event); SendGamePlayEvent(pActor->GetEntity(),event); SItemProperties& recItem = it->second; CWeapon *pWeapon = (CWeapon*)(pItem->GetIWeapon()); if(pWeapon) { // ammo for(SWeaponAmmo weaponAmmo = pWeapon->GetFirstAmmo(); weaponAmmo.pAmmoClass ; weaponAmmo = pWeapon->GetNextAmmo()) { int ammoCount = weaponAmmo.count; string ammoClass; if(weaponAmmo.pAmmoClass && (ammoClass = weaponAmmo.pAmmoClass->GetName())) { TAmmoContainer& recAmmo = recItem.Ammo; if(recAmmo.find(ammoClass) == recAmmo.end()) recAmmo.insert(std::make_pair(ammoClass,0)); int recAmmoCount = recAmmo[ammoClass]; if(ammoCount!=recAmmoCount) { GameplayEvent event; event.event = eGE_AmmoCount; event.value = (float)ammoCount; event.extra = (void*)(ammoClass.c_str()); event.description = (const char*)szItemName; //eventHandler(pActor,event); SendGamePlayEvent(pActor->GetEntity(),event); } } } // current fire mode int curFireModeIdx = pWeapon->GetCurrentFireMode(); int recFireModeIdx = recItem.fireMode; if(curFireModeIdx!= recFireModeIdx) { GameplayEvent event; event.event = eGE_WeaponFireModeChanged; event.value = (float)curFireModeIdx; event.description = (const char*)szItemName; //eventHandler(pActor,event); SendGamePlayEvent(pActor->GetEntity(),event); } } } } } /// Accessories int nInvAccessories = pInventory->GetAccessoryCount(); TAccessoryContainer& Accessories = gstate.Accessories; int nRecAccessories = Accessories.size(); for(int j=0 ; j< nInvAccessories; j++) { const char* accessory = pInventory->GetAccessory(j); if(accessory && strlen(accessory)) { IEntityClass* pClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass(accessory); if(pClass) { TItemName itemClass = pClass->GetName(); TAccessoryContainer::iterator it = Accessories.find(itemClass); if(it==Accessories.end()) { GameplayEvent event; event.event = eGE_AccessoryPickedUp; //event.value = accIdx; event.description = itemClass; // eventHandler(pActor,event); SendGamePlayEvent(pActor->GetEntity(),event); } } } } /// Ammo TAmmoContainer& Ammo = gstate.AmmoMags; int nRecAmmo = Ammo.size(); int nInvAmmo = pInventory->GetAmmoPackCount(); pInventory->AmmoIteratorFirst(); for(int j=0 ; !pInventory->AmmoIteratorEnd(); j++, pInventory->AmmoIteratorNext()) { TAmmoContainer& Mags = gstate.AmmoMags; const IEntityClass* pAmmoClass = pInventory->AmmoIteratorGetClass(); if(pAmmoClass) { const char* ammoClassName = pAmmoClass->GetName(); int ammoCount = pInventory->AmmoIteratorGetCount(); if(Mags.find(ammoClassName) == Mags.end() || ammoCount!= Mags[ammoClassName]) { GameplayEvent event; event.event = eGE_AmmoPickedUp; event.description = ammoClassName; event.value = (float)ammoCount; // eventHandler(pActor,event); SendGamePlayEvent(pActor->GetEntity(),event); } } } } } } }
float CGameStateRecorder::RenderInfo(float y, bool bRecording) { float retY = 0; IRenderer *pRenderer = gEnv->pRenderer; if (bRecording) { float fColor[4] = {1,0,0,1}; pRenderer->Draw2dLabel( 1,y+retY, 1.3f, fColor,false," Recording game state"); retY +=15; } else { const float xp = 300; const float xr = 400; const float xri = 600; float fColor[4] = {0,1,0,1}; float fColorWarning[4] = {1,1,0,1}; const char* actorName = m_demo_actorInfo->GetString(); CActor *pActor = GetActorOfName(actorName); if(pActor) { pRenderer->Draw2dLabel( 1,y+retY, 1.3f, fColor,false," Game state - Actor: %s --------------------------------------------------",pActor->GetEntity()? pActor->GetEntity()->GetName(): "(no entity)"); retY +=15; if(m_itSingleActorGameState != m_GameStates.end() && pActor->GetEntity() && m_itSingleActorGameState->first == pActor->GetEntity()->GetId()) { ICVar *pVar = gEnv->pConsole->GetCVar( "demo_force_game_state" ); if(pVar) { int demo_forceGameState = pVar->GetIVal(); if(demo_forceGameState) { pRenderer->Draw2dLabel( 1,y+retY, 1.3f, fColor,false,demo_forceGameState==1 ? " Override mode = (health, suit energy)" : " Override mode = (all)"); retY +=15; } } pRenderer->Draw2dLabel( xp,y+retY, 1.3f, fColor,false,"Current"); pRenderer->Draw2dLabel( xr,y+retY, 1.3f, fColor,false,"Recorded"); retY +=15; SActorGameState& gstate = m_itSingleActorGameState->second; float recordedHealth = (float)gstate.health; float health = (float)pActor->GetHealth(); bool bError = CHECK_MISMATCH(health, recordedHealth,10); pRenderer->Draw2dLabel( 1,y+retY, 1.3f, fColor,false," Health:"); pRenderer->Draw2dLabel( xp,y+retY, 1.3f, bError? fColorWarning : fColor, false,"%d",(int)health); pRenderer->Draw2dLabel( xr,y+retY, 1.3f, bError? fColorWarning : fColor, false,"%d",(int)recordedHealth); retY +=15; // items pRenderer->Draw2dLabel( 1,y+retY, 1.3f, fColor,false," Inventory ---------------------------------------------------------------------------------------"); retY +=15; pRenderer->Draw2dLabel( xp,y+retY, 1.3f, fColor,false,"Current"); pRenderer->Draw2dLabel( xri,y+retY, 1.3f, fColor,false,"Recorded"); retY +=15; CInventory *pInventory = (CInventory*)(pActor->GetInventory()); if(pInventory) { int nInvItems = pInventory->GetCount(); TItemContainer& Items = gstate.Items; int nRecItems = Items.size(); int maxItems = max(nRecItems,nInvItems); int i=0; EntityId curSelectedId = pActor->GetCurrentItemId(); TItemName curSelClass = GetItemName(curSelectedId); bool bSelectedError = !equal_strings(gstate.itemSelected,curSelClass); for(; i< nInvItems; i++) { IItem *pItem = g_pGame->GetIGameFramework()->GetIItemSystem()->GetItem(pInventory->GetItem(i)); if(pItem) { TItemName szItemName = GetItemName(pItem->GetEntityId()); TItemContainer::iterator it = Items.find(szItemName); bError = it==Items.end(); pRenderer->Draw2dLabel( 1,y+retY, 1.3f, fColor,false," %2d)",i+1); EntityId curId = pItem->GetEntityId(); TItemName curClass = GetItemName(curId); if(equal_strings(curClass,curSelClass) ) pRenderer->Draw2dLabel( xp-16,y+retY, 1.3f,bSelectedError ? fColorWarning:fColor, false, "[]"); if(equal_strings(szItemName, gstate.itemSelected)) pRenderer->Draw2dLabel( xri-16,y+retY, 1.3f,bSelectedError ? fColorWarning:fColor, false, "[]"); char itemName[32]; const char* originalItemName = pItem->GetEntity() ? pItem->GetEntity()->GetName():"(null)"; int length = strlen(originalItemName); length = min(length,31); strncpy(itemName,originalItemName,length); itemName[length]=0; pRenderer->Draw2dLabel( 1,y+retY, 1.3f, bError? fColorWarning : fColor, false," %s",itemName); if(bError) pRenderer->Draw2dLabel( xp,y+retY, 1.3f, fColorWarning, false, "Missing"); else { SItemProperties& recItem = it->second; CWeapon *pWeapon = (CWeapon*)(pItem->GetIWeapon()); IEntityClass* pItemClass = pItem->GetEntity()->GetClass(); if(pItemClass && !strcmpi(pItemClass->GetName(),"binoculars")) pWeapon = NULL; // no fire mode or ammo recorded for binocular (which is a weapon) if(pWeapon) { int idx = 0; // ammo float xa = 0; for(SWeaponAmmo weaponAmmo = pWeapon->GetFirstAmmo(); weaponAmmo.pAmmoClass ; weaponAmmo = pWeapon->GetNextAmmo()) { int ammoCount = weaponAmmo.count; const char* ammoClass; if(weaponAmmo.pAmmoClass && (ammoClass = weaponAmmo.pAmmoClass->GetName())) { TAmmoContainer::iterator it = recItem.Ammo.find(ammoClass); if(it!=recItem.Ammo.end()) { int recAmmoCount = recItem.Ammo[ammoClass]; bool bError2 = ammoCount!=recAmmoCount; pRenderer->Draw2dLabel( xp+xa,y+retY, 1.3f, bError2? fColorWarning : fColor, false,"Am%d:%d",idx,ammoCount); pRenderer->Draw2dLabel( xri+xa,y+retY, 1.3f, bError2? fColorWarning : fColor, false,"Am%d:%d",idx,recAmmoCount); xa += 50; ++idx; if(idx%5 ==0) { xa=0; retY+=15; } } } } // current fire mode int curFireModeIdx = pWeapon->GetCurrentFireMode(); int recFireModeIdx = recItem.fireMode; bool bError3 = curFireModeIdx!= recFireModeIdx; pRenderer->Draw2dLabel( xp+xa,y+retY, 1.3f, bError3? fColorWarning : fColor, false,"FMode:%d",curFireModeIdx); pRenderer->Draw2dLabel( xri+xa,y+retY, 1.3f, bError3? fColorWarning : fColor, false,"FMode:%d",recFireModeIdx); } else { pRenderer->Draw2dLabel( xp,y+retY, 1.3f, fColor, false, "Ok"); } } } retY +=15; } /// Accessories int nInvAccessories = pInventory->GetAccessoryCount(); TAccessoryContainer& Accessories = gstate.Accessories; int nRecAccessories = Accessories.size(); if(nRecAccessories) { pRenderer->Draw2dLabel( 1,y+retY, 1.3f, bError? fColorWarning : fColor, false," Accessories"); retY +=15; } for(int j=0 ; j< nInvAccessories; j++,i++) { const char* accessory = pInventory->GetAccessory(j); if(accessory && strlen(accessory)) { IEntityClass* pClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass(accessory); if(pClass) { TItemName szItemName = pClass->GetName(); TAccessoryContainer::iterator it = Accessories.find(szItemName); bError = it==Accessories.end(); pRenderer->Draw2dLabel( 1,y+retY, 1.3f, fColor,false," %2d)",i+1); char itemName[32]; int length = strlen(accessory); length = min(length,31); strncpy(itemName,accessory,length); itemName[length]=0; pRenderer->Draw2dLabel( 1,y+retY, 1.3f, bError? fColorWarning : fColor, false," %s",itemName); if(bError) pRenderer->Draw2dLabel( xp,y+retY, 1.3f, fColorWarning, false, "Missing"); else pRenderer->Draw2dLabel( xp,y+retY, 1.3f, fColor, false, "Ok"); retY +=15; } } } /// Ammo Mags TAmmoContainer& Ammo = gstate.AmmoMags; int nRecAmmo = Ammo.size(); int nInvAmmo = pInventory->GetAmmoPackCount(); if(nInvAmmo) { pRenderer->Draw2dLabel( 1,y+retY, 1.3f, bError? fColorWarning : fColor, false," Ammo Packs"); retY +=15; } pInventory->AmmoIteratorFirst(); for(int j=0 ; !pInventory->AmmoIteratorEnd(); j++, pInventory->AmmoIteratorNext()) { TAmmoContainer& Mags = gstate.AmmoMags; const IEntityClass* pAmmoClass = pInventory->AmmoIteratorGetClass(); if(pAmmoClass) { int invAmmoCount = pInventory->AmmoIteratorGetCount(); const char* ammoClassName = pAmmoClass->GetName(); bool bNotFound = Mags.find(ammoClassName) == Mags.end(); int recAmmoCount = bNotFound ? 0 :Mags[ammoClassName]; bool bError = bNotFound || invAmmoCount!= recAmmoCount; pRenderer->Draw2dLabel( 1,y+retY, 1.3f, bError? fColorWarning : fColor, false," %s:",ammoClassName); pRenderer->Draw2dLabel( xp,y+retY, 1.3f, bError? fColorWarning : fColor, false,"%d",invAmmoCount); if(bNotFound) pRenderer->Draw2dLabel( xr,y+retY, 1.3f, fColorWarning, false,"NotRecd"); else pRenderer->Draw2dLabel( xr,y+retY, 1.3f, bError? fColorWarning : fColor, false,"%d",recAmmoCount); retY +=15; } } } } else // m_itSingleActorGameState != m_GameStates.end() { pRenderer->Draw2dLabel( 1,y+retY, 1.3f, fColor,false, "<<Not Recorded>>"); retY +=15; } } else // pActor { pRenderer->Draw2dLabel( 1,y+retY, 1.3f, fColor,false, "<<Actor %s not in the map>>",actorName ? actorName:"(no name)"); retY +=15; } } return retY; }
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; } } } }