//------------------------------------------------------------------------ float CGameRulesMPDamageHandling::AdjustPlayerCollisionDamage(const IEntity *pEntity, const IEntity *pCollider, const CGameRules::SCollisionHitInfo& colHitInfo, float colInfo_damage) { float result = colInfo_damage; if (colHitInfo.target_velocity.len() == 0.f) { result = colInfo_damage * 0.2f; } CActor *pEntityActor = static_cast<CActor*>(g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(pEntity->GetId())); if (pEntityActor) { float healthThreshold = (float)g_pGameCVars->pl_health.collision_health_threshold; float currentHealth = pEntityActor->GetHealth(); if (currentHealth <= healthThreshold) { result = 0.f; } else if ((currentHealth - result) < healthThreshold) { result = currentHealth - healthThreshold; } } return result; }
//------------------------------------------------------------------------ int CScriptBind_Actor::GetHealth(IFunctionHandler *pH) { CActor *pActor = GetActor(pH); if (!pActor) return pH->EndFunction(); if (pActor) return pH->EndFunction(pActor->GetHealth()); return pH->EndFunction(); }
//======================================== void CRocketLauncher::Drop(float impulseScale, bool selectNext, bool byDeath) { CActor* pOwner = GetOwnerActor(); //Don't let the player drop it if it has not been opened if(m_stats.first_selection && pOwner && pOwner->IsPlayer() && pOwner->GetHealth()>0 && !byDeath) return; if(pOwner && !pOwner->IsPlayer()) { //In this case goes to the clip, no the inventory for(TAmmoMap::const_iterator it = m_minDroppedAmmo.begin();it!=m_minDroppedAmmo.end();it++) m_ammo[it->first] = it->second; m_minDroppedAmmo.clear(); } PlayAction(g_pItemStrings->deselect); GetScheduler()->TimerAction(GetCurrentAnimationTime(eIGS_FirstPerson), CSchedulerAction<EndDropAction>::Create(EndDropAction(this)), true); }
//------------------------------------------------------------------------ void CGameRules::ProcessServerHit(const HitInfo &hitInfo) { bool ok=true; // check if shooter is alive CActor *pShooter = GetActorByEntityId(hitInfo.shooterId); CActor *pTarget = GetActorByEntityId(hitInfo.targetId); if (hitInfo.shooterId) { if (pShooter && pShooter->GetHealth()<=0) ok=false; } if (hitInfo.targetId) { if (pTarget && pTarget->GetSpectatorMode()) ok=false; } if (ok) { float fTargetHealthBeforeHit = 0.0f; if(pTarget) { fTargetHealthBeforeHit = pTarget->GetHealth(); } CreateScriptHitInfo(m_scriptHitInfo, hitInfo); CallScript(m_serverStateScript, "OnHit", m_scriptHitInfo); if(pTarget && !pTarget->IsDead()) { const float fCausedDamage = fTargetHealthBeforeHit - pTarget->GetHealth(); ProcessLocalHit(hitInfo, fCausedDamage); } // call hit listeners if any if (m_hitListeners.empty() == false) { for (size_t i = 0; i < m_hitListeners.size(); ) { size_t count = m_hitListeners.size(); m_hitListeners[i]->OnHit(hitInfo); if (count == m_hitListeners.size()) i++; else continue; } } if (pShooter && hitInfo.shooterId!=hitInfo.targetId && hitInfo.weaponId!=hitInfo.shooterId && hitInfo.weaponId!=hitInfo.targetId && hitInfo.damage>=0) { EntityId params[2]; params[0] = hitInfo.weaponId; params[1] = hitInfo.targetId; m_pGameplayRecorder->Event(pShooter->GetEntity(), GameplayEvent(eGE_WeaponHit, 0, 0, (void *)params)); } if (pShooter) m_pGameplayRecorder->Event(pShooter->GetEntity(), GameplayEvent(eGE_Hit, 0, 0, (void *)hitInfo.weaponId)); if (pShooter) m_pGameplayRecorder->Event(pShooter->GetEntity(), GameplayEvent(eGE_Damage, 0, hitInfo.damage, (void *)hitInfo.weaponId)); } }
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; } }
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; }
//----------------------------------------------- //This function is only executed on the server void CC4Projectile::Stick(EventPhysCollision *pCollision) { assert(pCollision); int trgId = 1; IPhysicalEntity *pTarget = pCollision->pEntity[trgId]; if(pTarget == GetEntity()->GetPhysics()) { trgId = 0; pTarget = pCollision->pEntity[trgId]; } //Do not stick to breakable glass if(ISurfaceType *pSurfaceType = gEnv->p3DEngine->GetMaterialManager()->GetSurfaceType(pCollision->idmat[trgId])) { if(pSurfaceType->GetBreakability()==1) { m_notStick = true; return; } } IEntity *pTargetEntity = pTarget ? gEnv->pEntitySystem->GetEntityFromPhysics(pTarget) : 0; if(pTarget && (!pTargetEntity || (pTargetEntity->GetId() != m_ownerId))) { //Special cases if(pTargetEntity) { //Stick to actors using a character attachment CActor *pActor = static_cast<CActor *>(gEnv->pGame->GetIGameFramework()->GetIActorSystem()->GetActor(pTargetEntity->GetId())); //Not in MP if(pActor && gEnv->bMultiplayer) { m_notStick = true; return; } if(pActor && pActor->GetHealth()>0) { if(pActor->GetActorSpecies()!=eGCT_HUMAN) { m_notStick = true; return; } if(StickToCharacter(true,pTargetEntity)) { GetGameObject()->SetAspectProfile(eEA_Physics, ePT_None); m_stuck = true; } m_notStick = true; return; } //Do not stick to small objects... if(!pActor) { pe_params_part pPart; pPart.ipart = 0; if(pTarget->GetParams(&pPart) && pPart.pPhysGeom && pPart.pPhysGeom->V<0.15f) { m_notStick = true; return; } } } else if(pTarget->GetType()==PE_LIVING) { m_notStick = true; return; } if(!pTargetEntity) StickToStaticObject(pCollision,pTarget); else { //Do not attach to items if(g_pGame->GetIGameFramework()->GetIItemSystem()->GetItem(pTargetEntity->GetId())) { m_notStick = true; return; } Matrix34 mat = pTargetEntity->GetWorldTM(); mat.Invert(); Vec3 pos = mat.TransformPoint(pCollision->pt); mat.SetIdentity(); mat.SetRotation33(Matrix33::CreateOrientation(-pCollision->n,GetEntity()->GetWorldTM().TransformVector(Vec3(0,0,1)),gf_PI)); mat.SetTranslation(pos); //Dephysicalize and stick GetGameObject()->SetAspectProfile(eEA_Physics, ePT_None); StickToEntity(pTargetEntity,mat); if(gEnv->bMultiplayer) { Quat rot(Matrix33::CreateOrientation(-pCollision->n,GetEntity()->GetWorldTM().TransformVector(Vec3(0,0,1)),gf_PI*0.5f)); GetGameObject()->InvokeRMI(CC4Projectile::ClStickToEntity(),ProjectileStickToEntity(pTargetEntity->GetId(),pos,rot),eRMI_ToAllClients); } } m_stuck = true; } }