EEntityType GetEntityType(EntityId id) { int type = eET_Unknown; IEntitySystem *pEntitySystem = gEnv->pEntitySystem; if (pEntitySystem) { IEntity *pEntity = pEntitySystem->GetEntity(id); if (pEntity) { type = eET_Valid; IEntityClass *pClass = pEntity->GetClass(); if (pClass) { const char* className = pClass->GetName(); // Check AI if (pEntity->GetAI()) { type |= eET_AI; } // Check actor IActorSystem *pActorSystem = gEnv->pGame->GetIGameFramework()->GetIActorSystem(); if (pActorSystem) { IActor *pActor = pActorSystem->GetActor(id); if (pActor) { type |= eET_Actor; } } // Check vehicle IVehicleSystem *pVehicleSystem = gEnv->pGame->GetIGameFramework()->GetIVehicleSystem(); if (pVehicleSystem) { if (pVehicleSystem->IsVehicleClass(className)) { type |= eET_Vehicle; } } // Check item IItemSystem *pItemSystem = gEnv->pGame->GetIGameFramework()->GetIItemSystem(); if (pItemSystem) { if (pItemSystem->IsItemClass(className)) { type |= eET_Item; } } } } } return (EEntityType)type; }
//------------------------------------------------------------------------ int CScriptBind_Actor::AddInventoryAmmo(IFunctionHandler *pH, const char *ammo, int amount) { CActor * pActor = GetActor(pH); if (!pActor) return pH->EndFunction(); IInventory *pInventory=pActor->GetInventory(); if (!pInventory) return pH->EndFunction(); IEntityClass* pClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass(ammo); assert(pClass); int capacity = pInventory->GetAmmoCapacity(pClass); int current = pInventory->GetAmmoCount(pClass); if((!gEnv->pSystem->IsEditor()) && (amount > capacity)) { if(pActor->IsClient()) SAFE_HUD_FUNC(DisplayFlashMessage("@ammo_maxed_out", 2, ColorF(1.0f, 0,0), true, (string("@")+pClass->GetName()).c_str())); //If still there's some place, full inventory to maximum... if(current<capacity) { pInventory->SetAmmoCount(pClass,capacity); if(pActor->IsClient() && capacity - current > 0) { /*char buffer[5]; itoa(capacity - current, buffer, 10); SAFE_HUD_FUNC(DisplayFlashMessage("@grab_ammo", 3, Col_Wheat, true, (string("@")+pClass->GetName()).c_str(), buffer));*/ if(g_pGame->GetHUD()) g_pGame->GetHUD()->DisplayAmmoPickup(pClass->GetName(), capacity - current); } if (gEnv->bServer) pActor->GetGameObject()->InvokeRMI(CActor::ClAddAmmo(), CActor::AmmoParams(ammo, amount), eRMI_ToRemoteClients); } } else { pInventory->SetAmmoCount(pClass, amount); if(pActor->IsClient() && amount - current > 0) { /*char buffer[5]; itoa(amount - current, buffer, 10); SAFE_HUD_FUNC(DisplayFlashMessage("@grab_ammo", 3, Col_Wheat, true, (string("@")+pClass->GetName()).c_str(), buffer));*/ if(g_pGame->GetHUD()) g_pGame->GetHUD()->DisplayAmmoPickup(pClass->GetName(), amount - current); } if (gEnv->bServer) pActor->GetGameObject()->InvokeRMI(CActor::ClAddAmmo(), CActor::AmmoParams(ammo, amount), eRMI_ToRemoteClients); } return pH->EndFunction(); }
bool CJaw::OutOfAmmo(bool allFireModes) const { CActor* pOwner = GetOwnerActor(); IInventory* pOwnerInventory = pOwner ? pOwner->GetInventory() : 0; if (!pOwnerInventory) return true; IEntityClass* pJawClass = GetEntity()->GetClass(); IItemSystem* pItemSystem = gEnv->pGame->GetIGameFramework()->GetIItemSystem(); int jawUniqueId = pItemSystem->GetItemUniqueId(pJawClass->GetName()); int currentNumJaws = pOwnerInventory->GetCountOfUniqueId(jawUniqueId); return currentNumJaws == 0; }
bool CJaw::GiveExtraTubeToInventory(IActor* pPickerActor, IItemSystem* pItemSystem) const { if (m_weaponsharedparams->ammoParams.extraItems == 0 || !pPickerActor->IsPlayer()) return false; if (m_extraTubesAdded) return false; IEntityClass* pJawClass = GetEntity()->GetClass(); IInventory* pPickerInventory = pPickerActor ? pPickerActor->GetInventory() : 0; int jawUniqueId = pItemSystem->GetItemUniqueId(pJawClass->GetName()); int currentNumJaws = pPickerInventory ? pPickerInventory->GetCountOfUniqueId(jawUniqueId) : 0; bool giveExtraTube = (currentNumJaws == 0); return giveExtraTube; }
void execute(CItem *_this) { CShotgun *fm = (CShotgun *)pWep->GetFireMode(pWep->GetCurrentFireMode()); if(fm->m_reload_was_broken) return; IEntityClass *pAmmoType = fm->GetAmmoType(); if(pWep->IsServer()) { const int ammoCount = pWep->GetAmmoCount(pAmmoType); const int inventoryCount = pWep->GetInventoryAmmoCount(pAmmoType); const int refill = fm->m_pShared->shotgunparams.partial_reload ? 1 : min(inventoryCount, fm->GetClipSize() - ammoCount); pWep->SetAmmoCount(pAmmoType, ammoCount + refill); pWep->SetInventoryAmmoCount(pAmmoType, pWep->GetInventoryAmmoCount(pAmmoType) - refill); } g_pGame->GetIGameFramework()->GetIGameplayRecorder()->Event(pWep->GetOwner(), GameplayEvent(eGE_WeaponReload, pAmmoType->GetName(), 1, (void *)(pWep->GetEntityId()))); if(!fm->m_break_reload) fm->ReloadShell(rzoomed); else fm->EndReload(rzoomed); }
void CEditorGame::ResetClient(IConsoleCmdArgs*) { bool value = s_pEditorGame->m_bPlayer; s_pEditorGame->EnablePlayer(false); IEntityClass *pClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass("Player"); if (pClass) pClass->LoadScript(true); if (value) { s_pEditorGame->ConfigureNetContext(true); SetGameRules(); } s_pEditorGame->EnablePlayer(value); s_pEditorGame->HidePlayer(true); }
//------------------------------------------------------------------------ void CEditorGame::ToggleMultiplayerGameRules() { m_bUsingMultiplayerGameRules = !m_bUsingMultiplayerGameRules; bool value = s_pEditorGame->m_bPlayer; s_pEditorGame->EnablePlayer(false); s_pEditorGame->ConfigureNetContext(true); IEntityClass *pClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass("Player"); if (pClass) { pClass->LoadScript(true); } SetGameRules(); s_pEditorGame->EnablePlayer(value); s_pEditorGame->HidePlayer(true); gEnv->pConsole->ShowConsole(false); }
void CEditorGame::ResetClient(IConsoleCmdArgs*) { g_pGame->ReloadPlayerParamFiles(); bool value = s_pEditorGame->m_bPlayer; s_pEditorGame->EnablePlayer(false); IEntityClass *pClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass("Player"); if (pClass) pClass->LoadScript(true); if (value) { s_pEditorGame->ConfigureNetContext(true); const char *pGameRulesName = GetGameRulesName(); s_pEditorGame->m_pGame->GetIGameFramework()->GetIGameRulesSystem()->CreateGameRules(pGameRulesName); } s_pEditorGame->EnablePlayer(value); s_pEditorGame->HidePlayer(true); }
bool CEntityClassRegistry::RegisterEntityClass( IEntityClass *pClass ) { assert( pClass != NULL ); bool newClass = false; if ((pClass->GetFlags() & ECLF_MODIFY_EXISTING) == 0) { IEntityClass *pOldClass = FindClass(pClass->GetName()); if (pOldClass) { EntityWarning( "CEntityClassRegistry::RegisterEntityClass failed, class with name %s already registered", pOldClass->GetName() ); return false; } newClass = true; } m_mapClassName[pClass->GetName()] = pClass; NotifyListeners(newClass ? ECRE_CLASS_REGISTERED : ECRE_CLASS_MODIFIED, pClass); return true; }
bool CMonoEntityExtension::Init(IGameObject *pGameObject) { SetGameObject(pGameObject); pGameObject->EnablePhysicsEvent( true, eEPE_OnPostStepImmediate ); if (!GetGameObject()->BindToNetwork()) return false; IEntity *pEntity = GetEntity(); IEntityClass *pEntityClass = pEntity->GetClass(); m_pScript = g_pScriptSystem->InstantiateScript(pEntityClass->GetName(), eScriptFlag_Entity); IMonoClass *pEntityInfoClass = g_pScriptSystem->GetCryBraryAssembly()->GetClass("EntityInitializationParams", "CryEngine.Native"); SMonoEntityInfo entityInfo(pEntity); IMonoArray *pArgs = CreateMonoArray(1); pArgs->InsertMonoObject(pEntityInfoClass->BoxObject(&entityInfo)); g_pScriptSystem->InitializeScriptInstance(m_pScript, pArgs); pArgs->Release(); int numProperties; auto pProperties = static_cast<CEntityPropertyHandler *>(pEntityClass->GetPropertyHandler())->GetQueuedProperties(pEntity->GetId(), numProperties); if(pProperties) { for(int i = 0; i < numProperties; i++) { auto queuedProperty = pProperties[i]; SetPropertyValue(queuedProperty.propertyInfo, queuedProperty.value.c_str()); } } m_bInitialized = true; return true; }
void CEditorGame::InitEntityClassesEnums(IGameToEditorInterface* pGTE) { // init ActionFilter enums gEnv->pEntitySystem->GetClassRegistry()->IteratorMoveFirst(); IEntityClass* entClass = gEnv->pEntitySystem->GetClassRegistry()->IteratorNext(); const char** allEntities = new const char*[gEnv->pEntitySystem->GetClassRegistry()->GetClassCount()+2]; allEntities[0] = "AllClasses"; allEntities[1] = "CustomClasses"; unsigned int numEnts = 2; while (entClass) { const char* classname = entClass->GetName(); allEntities[numEnts++] = classname; entClass = gEnv->pEntitySystem->GetClassRegistry()->IteratorNext(); } pGTE->SetUIEnums("entity_classes", allEntities, numEnts); delete[] allEntities; }
// =========================================================================== // Cache the resources of an actor class (pre-load them). // // In: The LUA function handler. // In: The name of the actor entity class that we should pre-load // (case-sensitive) (NULL is invalid!) // int CScriptBind_Game::CacheActorClassResources(IFunctionHandler *pH, const char* actorEntityClassName) { if (actorEntityClassName == NULL) { CryWarning(VALIDATOR_MODULE_GAME, VALIDATOR_WARNING, "CacheActorClassResources(): Invalid entity actor class name!"); } else { IEntityClass* entityClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass(actorEntityClassName); if (entityClass == NULL) { CryWarning(VALIDATOR_MODULE_GAME, VALIDATOR_WARNING, "CacheActorClassResources(): Unable to cache entity actor class resource '%s'!", actorEntityClassName); } else { g_pGame->GetGameCache().CacheActorClass(entityClass, entityClass->GetScriptTable()); } } return pH->EndFunction(); }
void CVicinityDependentObjectMover::ActivateOutputPortBool( const char* szPortName ) { IEntity* pEntity = GetEntity(); CRY_ASSERT( pEntity ); IEntityClass::SEventInfo eventInfo; IEntityClass *pEntityClass = pEntity->GetClass(); if ( pEntityClass->FindEventInfo( szPortName,eventInfo ) ) { SEntityEvent event( ENTITY_EVENT_SCRIPT_EVENT ); event.nParam[0] = (INT_PTR)szPortName; event.nParam[1] = IEntityClass::EVT_BOOL; bool bValue = true; event.nParam[2] = (INT_PTR)&bValue; GetEntity()->SendEvent( event ); } else { GameWarning( "CVicinityDependentObjectMover::ActivateOutputPortBool: Called with undefined port %s", szPortName ); } }
void CScriptProxy::Reload( IEntity* pEntity,SEntitySpawnParams ¶ms ) { FUNCTION_PROFILER( GetISystem(), PROFILE_ENTITY ); IEntityClass* pClass = (pEntity ? pEntity->GetClass() : NULL); CEntityScript* pEntityScript = (pClass ? (CEntityScript*)pClass->GetIEntityScript() : NULL); if (pEntityScript && pEntityScript->LoadScript()) { // Release current SAFE_RELEASE(m_pThis); m_pEntity = (CEntity*)pEntity; m_pScript = pEntityScript; m_nCurrStateId = 0; m_fScriptUpdateRate = 0; m_fScriptUpdateTimer = 0; m_bEnableSoundAreaEvents = false; m_bUpdateScript = CurrentState()->IsStateFunctionImplemented(ScriptState_OnUpdate); // New object must be created here. CreateScriptTable(¶ms); } }
//----------------------------------------------------- void CThrow::ThrowGrenade() { //Grenade speed scale is always one (for player) CPlayer *pPlayer = static_cast<CPlayer *>(m_pWeapon->GetOwnerActor()); if(pPlayer) { if(pPlayer->IsPlayer()) { m_speed_scale = 1.0f; } else if(pPlayer->GetHealth() <= 0 || pPlayer->GetGameObject()->GetAspectProfile(eEA_Physics) == eAP_Sleep) { return; //Do not throw grenade is player is death (AI "ghost grenades") } //Hide grenade in hand (FP) if(pPlayer->IsClient() && m_pWeapon->GetEntity()->GetClass() == CItem::sOffHandClass) { if(COffHand *pOffHand = static_cast<COffHand *>(m_pWeapon)) { pOffHand->AttachGrenadeToHand(pOffHand->GetCurrentFireMode()); } } } m_pWeapon->SetBusy(false); Shoot(true); m_pWeapon->SetBusy(true); // Luciano - send ammo count game event if(pPlayer) { IEntityClass *pAmmo = m_pShared->fireparams.ammo_type_class; if(pAmmo) { int ammoCount = pPlayer->GetInventory()->GetAmmoCount(pAmmo); g_pGame->GetIGameFramework()->GetIGameplayRecorder()->Event(pPlayer->GetEntity(), GameplayEvent(eGE_AmmoCount, m_pWeapon->GetEntity()/*->GetClass()*/->GetName(), float(ammoCount), (void *)(pAmmo->GetName()))); } } }
void CGameStateRecorder::OnGameplayEvent(IEntity *pEntity, const GameplayEvent &event) { EntityId id; if(!pEntity || !(id = pEntity->GetId())) { GameWarning("TimeDemo:GameState::OnGamePlayEvent: Entity not found"); return; } CActor *pActor = (CActor*)(gEnv->pGame->GetIGameFramework()->GetIActorSystem()->GetActor(id)); if(!pActor) { GameWarning("TimeDemo:GameState::OnGamePlayEvent: Entity %s has no actor", pEntity->GetName()); return; } GameplayEvent event2 = event; event2.extra = 0;// event2 is the forwarded event, extra either will be not used by the listener or re-set as a string uint8 eType = event.event; bool bPlayer = (pActor->IsPlayer() && m_mode); if(bPlayer || m_mode==GPM_AllActors) { //items switch(eType) { case eGE_ItemPickedUp: { CheckInventory(pActor,0);//,*m_pRecordGameEventFtor); } break; case eGE_ItemDropped: { TItemName itemName = GetItemName(EntityId(event.extra)); if(!itemName ) //if(itemIdx < 0) break; event2.description = itemName; SendGamePlayEvent(pEntity,event2); IEntity* pItemEntity = gEnv->pEntitySystem->FindEntityByName(itemName); if(!pItemEntity) break; IItem* pItem = g_pGame->GetIGameFramework()->GetIItemSystem()->GetItem(pItemEntity->GetId()); if(!pItem) break; IEntityClass* pItemClass = pItem->GetEntity()->GetClass(); if(pItemClass && !strcmpi(pItemClass->GetName(),"SOCOM")) { IItem* pCurrentItem = pActor->GetCurrentItem(); if(pCurrentItem) { IEntityClass* pCurrentItemClass = pCurrentItem->GetEntity()->GetClass(); if(pCurrentItemClass && !strcmpi(pCurrentItemClass->GetName(),"SOCOM")) { GameplayEvent event3; event3.event = eGE_ItemSelected; TItemName itemName = GetItemName(pCurrentItem->GetEntity()->GetId()); if(!itemName) break; event3.value = 0; event3.description = (const char*)itemName; SendGamePlayEvent(pEntity,event3); } } } } break; case eGE_WeaponFireModeChanged: { TItemName itemIdx = GetItemName(EntityId(event.extra)); if(!itemIdx)//if(itemIdx < 0) break; event2.description = (const char*)itemIdx; SendGamePlayEvent(pEntity,event2); } break; case eGE_ItemSelected: { EntityId itemId = EntityId(event.extra); TItemName itemIdx = GetItemName(itemId); if(itemId && !itemIdx) break; event2.value = 0; event2.description = (const char*)itemIdx; SendGamePlayEvent(pEntity,event2); } break; case eGE_AttachedAccessory: { if(!IsGrenade(event.description)) // NOT OffHandGrenade SendGamePlayEvent(pEntity,event2); } break; case eGE_AmmoCount: { const char* itemIdx = event.description; if(!itemIdx) break; TGameStates::iterator itGS; /*if(pActor->IsPlayer()) itGS = m_itSingleActorGameState; else */if(pActor->GetEntity()) itGS = m_GameStates.find(pActor->GetEntity()->GetId()); else break; if(itGS == m_GameStates.end()) break; SActorGameState& gstate = itGS->second; IEntity* pItemEntity = gEnv->pEntitySystem->FindEntityByName(itemIdx); if(!pItemEntity) break; IItem* pItem = g_pGame->GetIGameFramework()->GetIItemSystem()->GetItem(pItemEntity->GetId()); if(!pItem) break; CWeapon* pWeapon = (CWeapon*)(pItem->GetIWeapon()); if(pWeapon && pWeapon->GetEntity()) { TItemContainer::iterator it = gstate.Items.find(itemIdx); if(it==gstate.Items.end()) break; SItemProperties& recItem = it->second; SWeaponAmmo weaponAmmo = pWeapon->GetFirstAmmo(); bool bGrenade = false; if(!weaponAmmo.pAmmoClass) { // special case for grenades if(IsAmmoGrenade((const char*)(event.extra))) { weaponAmmo.pAmmoClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass((const char*)event.extra); weaponAmmo.count = (int)event.value; bGrenade = true; } } for(; weaponAmmo.pAmmoClass ; weaponAmmo = pWeapon->GetNextAmmo()) { int ammoCount = weaponAmmo.count; const char* ammoClass; if(weaponAmmo.pAmmoClass && (ammoClass = weaponAmmo.pAmmoClass->GetName())) { TAmmoContainer& recAmmo = bGrenade? gstate.AmmoMags : recItem.Ammo; if(recAmmo.find(ammoClass) == recAmmo.end()) recAmmo.insert(std::make_pair(ammoClass,0)); if(ammoCount != recAmmo[ammoClass]) { event2.event = eGE_AmmoCount; event2.value = (float)ammoCount; if(event2.value < 0) event2.value = 0; event2.extra = (void*)ammoClass; event2.description = (const char*)itemIdx; SendGamePlayEvent(pEntity,event2); } } } } } break; case eGE_EntityGrabbed: { EntityId entityId = EntityId(event.extra); IEntity * pGrabbedEntity = gEnv->pEntitySystem->GetEntity(entityId); if(pGrabbedEntity) { event2.description = pGrabbedEntity->GetName(); SendGamePlayEvent(pEntity,event2); } } break; case eGE_WeaponReload: case eGE_ZoomedIn: case eGE_ZoomedOut: case eGE_HealthChanged: case eGE_ItemExchanged: SendGamePlayEvent(pEntity,event2); 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 CShotgun::NetShootEx(const Vec3 &pos, const Vec3 &dir, const Vec3 &vel, const Vec3 &hit, float extra, int ph) { CCCPOINT(Shotgun_NetShoot); assert(0 == ph); IEntityClass* ammo = m_fireParams->fireparams.ammo_type_class; FragmentID action = m_fireParams->fireparams.no_cock ? GetFragmentIds().fire : GetFragmentIds().fire_cock; CActor *pActor = m_pWeapon->GetOwnerActor(); bool playerIsShooter = pActor?pActor->IsPlayer():false; int ammoCount = m_pWeapon->GetAmmoCount(ammo); int clipSize = GetClipSize(); if (clipSize == 0) ammoCount = m_pWeapon->GetInventoryAmmoCount(ammo); if (ammoCount == 1) action = GetFragmentIds().fire; if (IsProceduralRecoilEnabled() && pActor) { pActor->ProceduralRecoil(m_fireParams->proceduralRecoilParams.duration, m_fireParams->proceduralRecoilParams.strength, m_fireParams->proceduralRecoilParams.kickIn,m_fireParams->proceduralRecoilParams.arms); } m_pWeapon->PlayAction(action, 0, false, CItem::eIPAF_Default); Vec3 pdir; int quad = cry_random(0, 3); CRY_ASSERT_MESSAGE(m_fireParams->fireparams.hitTypeId, string().Format("Invalid hit type '%s' in fire params for '%s'", m_fireParams->fireparams.hit_type.c_str(), m_pWeapon->GetEntity()->GetName())); CRY_ASSERT_MESSAGE(m_fireParams->fireparams.hitTypeId == g_pGame->GetGameRules()->GetHitTypeId(m_fireParams->fireparams.hit_type.c_str()), "Sanity Check Failed: Stored hit type id does not match the type string, possibly CacheResources wasn't called on this weapon type"); int ammoCost = m_fireParams->fireparams.fake_fire_rate ? m_fireParams->fireparams.fake_fire_rate : 1; ammoCost = min(ammoCost, ammoCount); // SHOT HERE for (int i = 0; i < m_fireParams->shotgunparams.pellets; i++) { CProjectile *pAmmo = m_pWeapon->SpawnAmmo(m_fireParams->fireparams.spawn_ammo_class, true); if (pAmmo) { pdir = ApplySpread(dir, m_fireParams->shotgunparams.spread, quad); quad = (quad+1)%4; CProjectile::SProjectileDesc projectileDesc( m_pWeapon->GetOwnerId(), m_pWeapon->GetHostId(), m_pWeapon->GetEntityId(), m_fireParams->shotgunparams.pelletdamage, m_fireParams->fireparams.damage_drop_min_distance, m_fireParams->fireparams.damage_drop_min_damage, m_fireParams->fireparams.damage_drop_per_meter, m_fireParams->fireparams.hitTypeId, m_fireParams->fireparams.bullet_pierceability_modifier, m_pWeapon->IsZoomed()); projectileDesc.pointBlankAmount = m_fireParams->fireparams.point_blank_amount; projectileDesc.pointBlankDistance = m_fireParams->fireparams.point_blank_distance; projectileDesc.pointBlankFalloffDistance = m_fireParams->fireparams.point_blank_falloff_distance; if (m_fireParams->fireparams.ignore_damage_falloff) projectileDesc.damageFallOffAmount = 0.0f; pAmmo->SetParams(projectileDesc); pAmmo->SetDestination(m_pWeapon->GetDestination()); pAmmo->SetRemote(true); pAmmo->Launch(pos, pdir, vel); bool emit = false; if(m_pWeapon->GetStats().fp) emit = (!m_fireParams->tracerparams.geometryFP.empty() || !m_fireParams->tracerparams.effectFP.empty()) && ((ammoCount == clipSize) || (ammoCount%m_fireParams->tracerparams.frequency==0)); else emit = (!m_fireParams->tracerparams.geometry.empty() || !m_fireParams->tracerparams.effect.empty()) && ((ammoCount == clipSize) || (ammoCount%m_fireParams->tracerparams.frequency==0)); if (emit) { EmitTracer(pos, hit, &m_fireParams->tracerparams, pAmmo); } m_projectileId = pAmmo->GetEntity()->GetId(); pAmmo->SetAmmoCost(ammoCost); } } if (m_pWeapon->IsServer()) { const char *ammoName = ammo != NULL ? ammo->GetName() : NULL; g_pGame->GetIGameFramework()->GetIGameplayRecorder()->Event(m_pWeapon->GetOwner(), GameplayEvent(eGE_WeaponShot, ammoName, m_fireParams->shotgunparams.pellets, (void *)(EXPAND_PTR)m_pWeapon->GetEntityId())); } m_muzzleEffect.Shoot(this, hit, m_barrelId); m_fired = true; m_next_shot = 0.0f; ammoCount -= ammoCost; if (m_pWeapon->IsServer()) { if (clipSize != -1) { if (clipSize != 0) m_pWeapon->SetAmmoCount(ammo, ammoCount); else m_pWeapon->SetInventoryAmmoCount(ammo, ammoCount); } } OnShoot(m_pWeapon->GetOwnerId(), 0, ammo, pos, dir, vel); m_pWeapon->RequireUpdate(eIUS_FireMode); }
//------------------------------------------------------------------------ void CInventory::SerializeInventoryForLevelChange( TSerialize ser ) { IActor *pActor = GetActor(); if(!pActor) return; if(ser.IsReading()) { m_stats.ammoInfo.clear(); } m_bSerializeLTL = true; //Items by class (accessories) ser.BeginGroup("accessorySlots"); int exSize = m_stats.accessorySlots.size(); ser.Value("Size", exSize); if(ser.IsReading()) { m_stats.accessorySlots.resize(0); if(exSize>0) m_stats.accessorySlots.reserve(exSize); } for(int i = 0; i<exSize; ++i) { string accessoryName; if(ser.IsWriting()) accessoryName = m_stats.accessorySlots[i]->GetName(); ser.BeginGroup("Class"); ser.Value("AccessoryName", accessoryName); ser.EndGroup(); if(ser.IsReading()) { IEntityClass* pAccessoryClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass(accessoryName); CRY_ASSERT(pAccessoryClass); if (pAccessoryClass) { m_stats.accessorySlots.push_back(pAccessoryClass); } } } ser.EndGroup();//"accessorySlots" if(ser.IsReading()) { for(int r = 0; r < m_stats.slots.size(); ++r) { IItem *pItem = m_pGameFrameWork->GetIItemSystem()->GetItem(m_stats.slots[r]); if(pItem) { pItem->Drop(); pItem->GetEntity()->SetFlags(pItem->GetEntity()->GetFlags()|ENTITY_FLAG_UPDATE_HIDDEN); pItem->GetEntity()->Hide(true); gEnv->pEntitySystem->RemoveEntity(m_stats.slots[r]); } } } int numItems = 0; string currentItemNameOnReading; if(ser.IsReading()) { m_stats.slots.clear(); m_stats.currentItemId = 0; m_stats.holsteredItemId = 0; m_stats.lastItemId = 0; string itemName; ser.Value("numOfItems", numItems); for(int i = 0; i < numItems; ++i) { ser.BeginGroup("Items"); bool nextItemExists = false; ser.Value("nextItemExists", nextItemExists); if(nextItemExists) { ser.Value("ItemName", itemName); EntityId id = m_pGameFrameWork->GetIItemSystem()->GiveItem(pActor, itemName.c_str(), false, false, false); IItem *pItem = m_pGameFrameWork->GetIItemSystem()->GetItem(id); if(pItem) { //actual serialization pItem->SerializeLTL(ser); } else CryWarning(VALIDATOR_MODULE_GAME, VALIDATOR_ERROR, "Couldn't spawn inventory item %s, got id %i.", itemName.c_str(), id); } ser.EndGroup(); } ser.Value("CurrentItemName", itemName); if(stricmp(itemName.c_str(), "none")) { currentItemNameOnReading = itemName; IEntityClass *pClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass(itemName.c_str()); if(pClass) { if(IItem* pItem = m_pGameFrameWork->GetIItemSystem()->GetItem(GetItemByClass(pClass))) { if (pActor->GetCurrentItem() && pActor->GetCurrentItem() != pItem) pActor->GetCurrentItem()->Select(false); pItem->Select(true); m_stats.currentItemId = pItem->GetEntityId(); } else m_stats.currentItemId = m_pGameFrameWork->GetIItemSystem()->GiveItem(pActor, itemName.c_str(), false, true, false); } } } else { numItems = m_stats.slots.size(); ser.Value("numOfItems", numItems); for(int i = 0; i < numItems; ++i) { ser.BeginGroup("Items"); IItem *pItem = m_pGameFrameWork->GetIItemSystem()->GetItem(m_stats.slots[i]); bool nextItem = true; if(pItem) { ser.Value("nextItemExists", nextItem); ser.Value("ItemName", pItem->GetEntity()->GetClass()->GetName()); pItem->SerializeLTL(ser); } else { nextItem = false; ser.Value("nextItemExists", nextItem); } ser.EndGroup(); } bool currentItemIsInInventory = stl::find(m_stats.slots, m_stats.currentItemId); IItem* pCurrentItem = NULL; if (currentItemIsInInventory) { pCurrentItem = m_pGameFrameWork->GetIItemSystem()->GetItem(m_stats.currentItemId); } else { pCurrentItem = m_pGameFrameWork->GetIItemSystem()->GetItem(GetHolsteredItem()); //Fallback to last selected one... if (!pCurrentItem) { pCurrentItem = m_pGameFrameWork->GetIItemSystem()->GetItem(GetLastItem()); // desperate fallback to any weapon... // this fallback should never be needed. However, right now it happens if the player loads a savegame where a heavyweapon is being used, right before the end of the mission. // that is a bug, but at this point is safer to just do this bruteforce fallback instead of fixing it // TODO: to fix that and remove this fallback... if (!pCurrentItem) { for(int i = 0; i < numItems; ++i) { IItem *pItem = m_pGameFrameWork->GetIItemSystem()->GetItem( m_stats.slots[i] ); if (pItem) { const char* pCategoryName = m_pGameFrameWork->GetIItemSystem()->GetItemCategory( pItem->GetEntity()->GetClass()->GetName() ); if (pCategoryName) { EInventorySlots slotType = GetSlotForItemCategory( pCategoryName ); if (slotType==eInventorySlot_Weapon) { pCurrentItem = pItem; break; } } } } } } } if (pCurrentItem) { ser.Value("CurrentItemName", pCurrentItem->GetEntity()->GetClass()->GetName()); } else { string name("none"); ser.Value("CurrentItemName", name); } } //**************************************AMMO ser.BeginGroup("Ammo"); TAmmoInfoMap::iterator ammoInfoIt = m_stats.ammoInfo.begin(); int ammoAmount = m_stats.ammoInfo.size(); ser.Value("AmmoAmount", ammoAmount); for(int i = 0; i < ammoAmount; ++i) { string name; int amount = 0; int users = 0; int capacity = 0; if(ser.IsWriting()) { IEntityClass* pAmmoClass = ammoInfoIt->first; CRY_ASSERT(pAmmoClass); name = (pAmmoClass) ? pAmmoClass->GetName() : ""; const SAmmoInfo& ammoInfo = ammoInfoIt->second;; amount = ammoInfo.GetCount(); capacity = ammoInfo.GetCapacity(); ++ammoInfoIt; } ser.BeginGroup("Ammo"); ser.Value("AmmoName", name); ser.Value("Bullets", amount); ser.Value("Capacity", capacity); ser.EndGroup(); if(ser.IsReading()) { IEntityClass* pClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass(name); CRY_ASSERT(pClass); TAmmoInfoMap::iterator it = m_stats.ammoInfo.find(pClass); if (it == m_stats.ammoInfo.end()) { m_stats.ammoInfo[pClass] = SAmmoInfo(amount, capacity); } else { it->second.SetCount(amount); it->second.SetCapacity(capacity); } } } ser.EndGroup(); m_bSerializeLTL = false; }
void CFlashUICheckAccessoryState ::ProcessEvent( EFlowEvent event, SActivationInfo *pActInfo ) { if(event == eFE_Activate && IsPortActive(pActInfo, 0)) { IActor* pActor = GetInputActor( pActInfo ); bool is_equipped = false; bool is_inInventory = false; if(pActor) { IInventory* pInventory = pActor->GetInventory(); if(pInventory) { IEntityClassRegistry *pRegistry = gEnv->pEntitySystem->GetClassRegistry(); //Find the accessory's class in the registry const string accessory_name = GetPortString(pActInfo, eI_Accessory); IEntityClass* pClass = pRegistry->FindClass(accessory_name); //Check if its in inventory if(pInventory->HasAccessory(pClass) != 0) { is_inInventory = true; } //if it is, check if its equipped as well if(is_inInventory) { //Get the weapon ID via the Input string const char* weapon_name = GetPortString(pActInfo, eI_Weapon).c_str(); EntityId item = pInventory->GetItemByClass(pRegistry->FindClass(weapon_name)); //Fetch the actual weapon via the ID IEntity* pEntity = gEnv->pEntitySystem->GetEntity(item); if(pEntity) { CGameObject * pGameObject = (CGameObject*)pEntity->GetProxy(ENTITY_PROXY_USER); const char* ext = pGameObject->GetEntity()->GetClass()->GetName(); CWeapon* pWeapon = (CWeapon*)pGameObject->QueryExtension(pGameObject->GetEntity()->GetClass()->GetName()); bool selectable = pWeapon->CanSelect(); if(pWeapon) { if(pWeapon->GetAccessory(pClass->GetName()) != 0) { is_equipped = true; } } } } } } if(!is_inInventory) ActivateOutput(pActInfo, eO_DontHave, true); else if(is_equipped) ActivateOutput(pActInfo, eO_Equipped, true); else ActivateOutput(pActInfo, eO_InInventory, true); } }
// initialize an entity for networked methods void CScriptRMI::SetupEntity( EntityId eid, IEntity * pEntity, bool client, bool server ) { if (!m_pParent) { GameWarning( "Trying to setup an entity for network with no game started... failing" ); return; } IEntityClass * pClass = pEntity->GetClass(); stack_string className = pClass->GetName(); IScriptTable * pEntityTable = pEntity->GetScriptTable(); IScriptSystem * pSS = pEntityTable->GetScriptSystem(); SmartScriptTable clientDispatchTable, serverDispatchTable, serverSynchedTable; pEntityTable->GetValue( CLIENT_DISPATCH_FIELD, clientDispatchTable ); pEntityTable->GetValue( SERVER_DISPATCH_FIELD, serverDispatchTable ); pEntityTable->GetValue( SERVER_SYNCHED_FIELD, serverSynchedTable ); bool validated; if (clientDispatchTable.GetPtr()) { if (!clientDispatchTable->GetValue(VALIDATED_FIELD, validated)) return; if (!validated) { SmartScriptTable methods; if (!pEntityTable->GetValue( "Client", methods )) { GameWarning( "No Client table, but has a client dispatch on class %s", pEntity->GetClass()->GetName() ); return; } if (!ValidateDispatchTable( pEntity->GetClass()->GetName(), clientDispatchTable, methods, false )) return; } } if (serverDispatchTable.GetPtr()) { if (!serverDispatchTable->GetValue(VALIDATED_FIELD, validated)) return; if (!validated) { SmartScriptTable methods; if (!pEntityTable->GetValue( "Server", methods )) { GameWarning( "No Server table, but has a server dispatch on class %s", pEntity->GetClass()->GetName() ); return; } if (!ValidateDispatchTable( pEntity->GetClass()->GetName(), serverDispatchTable, methods, true )) return; } } ScriptHandle id; id.n = eid; ScriptHandle flags; if (client && serverDispatchTable.GetPtr()) { flags.n = eDF_ToServer; AddProxyTable( pEntityTable, id, flags, "server", serverDispatchTable ); } if (server && clientDispatchTable.GetPtr()) { // only expose ownClient, otherClients for actors with a channelId flags.n = eDF_ToClientOnChannel; AddProxyTable( pEntityTable, id, flags, "onClient", clientDispatchTable ); flags.n = eDF_ToClientOnOtherChannels; AddProxyTable( pEntityTable, id, flags, "otherClients", clientDispatchTable ); flags.n = eDF_ToClientOnChannel | eDF_ToClientOnOtherChannels; AddProxyTable( pEntityTable, id, flags, "allClients", clientDispatchTable ); } if (serverSynchedTable.GetPtr()) { AddSynchedTable( pEntityTable, id, "synched", serverSynchedTable ); } CryAutoCriticalSection lkDispatch(m_dispatchMutex); std::map<string, size_t>::iterator iter = m_entityClassToEntityTypeID.find(CONST_TEMP_STRING(pEntity->GetClass()->GetName())); if (iter == m_entityClassToEntityTypeID.end()) { //[Timur] commented out as spam. //GameWarning("[scriptrmi] unable to find class %s", pEntity->GetClass()->GetName()); } else m_entities[eid] = iter->second; }
//------------------------------------------------------------------------ void CShotgun::NetShootEx(const Vec3 &pos, const Vec3 &dir, const Vec3 &vel, const Vec3 &hit, float extra, int ph) { assert(0 == ph); IEntityClass *ammo = m_pShared->fireparams.ammo_type_class; const char *action = m_pShared->actions.fire_cock.c_str(); CActor *pActor = m_pWeapon->GetOwnerActor(); bool playerIsShooter = pActor?pActor->IsPlayer():false; int ammoCount = m_pWeapon->GetAmmoCount(ammo); if(m_pShared->fireparams.clip_size==0) ammoCount = m_pWeapon->GetInventoryAmmoCount(ammo); if(ammoCount == 1) action = m_pShared->actions.fire.c_str(); m_pWeapon->ResetAnimation(); m_pWeapon->PlayAction(action, 0, false, CItem::eIPAF_Default|CItem::eIPAF_NoBlend); Vec3 pdir; // SHOT HERE for(int i = 0; i < m_pShared->shotgunparams.pellets; i++) { CProjectile *pAmmo = m_pWeapon->SpawnAmmo(ammo, true); if(pAmmo) { pdir = ApplySpread(dir, m_pShared->shotgunparams.spread); int hitTypeId = g_pGame->GetGameRules()->GetHitTypeId(m_pShared->fireparams.hit_type.c_str()); pAmmo->SetParams(m_pWeapon->GetOwnerId(), m_pWeapon->GetHostId(), m_pWeapon->GetEntityId(), m_pShared->shotgunparams.pelletdamage, hitTypeId, playerIsShooter?m_pShared->fireparams.damage_drop_per_meter:0.0f, m_pShared->fireparams.damage_drop_min_distance); pAmmo->SetDestination(m_pWeapon->GetDestination()); pAmmo->SetRemote(true); pAmmo->Launch(pos, pdir, vel); bool emit = false; if(m_pWeapon->GetStats().fp) emit = (!m_pShared->tracerparams.geometryFP.empty() || !m_pShared->tracerparams.effectFP.empty()) && (ammoCount==GetClipSize() || (ammoCount%m_pShared->tracerparams.frequency==0)); else emit = (!m_pShared->tracerparams.geometry.empty() || !m_pShared->tracerparams.effect.empty()) && (ammoCount==GetClipSize() || (ammoCount%m_pShared->tracerparams.frequency==0)); if(emit) EmitTracer(pos,hit,false); m_projectileId = pAmmo->GetEntity()->GetId(); } } m_pWeapon->OnShoot(m_pWeapon->GetOwnerId(), 0, ammo, pos, dir, vel); if(m_pWeapon->IsServer()) { const char *ammoName = ammo != NULL ? ammo->GetName() : NULL; g_pGame->GetIGameFramework()->GetIGameplayRecorder()->Event(m_pWeapon->GetOwner(), GameplayEvent(eGE_WeaponShot, ammoName, m_pShared->shotgunparams.pellets, (void *)m_pWeapon->GetEntityId())); } MuzzleFlashEffect(true); RejectEffect(); m_fired = true; m_next_shot = 0.0f; ammoCount--; if(m_pWeapon->IsServer()) { if(m_pShared->fireparams.clip_size != -1) { if(m_pShared->fireparams.clip_size!=0) m_pWeapon->SetAmmoCount(ammo, ammoCount); else m_pWeapon->SetInventoryAmmoCount(ammo, ammoCount); } } if((ammoCount<1) && !m_pShared->fireparams.slider_layer.empty()) { const char *slider_back_layer = m_pShared->fireparams.slider_layer.c_str(); m_pWeapon->PlayLayer(slider_back_layer, CItem::eIPAF_Default|CItem::eIPAF_NoBlend); } m_pWeapon->RequireUpdate(eIUS_FireMode); }
bool CShotgun::Shoot(bool resetAnimation, bool autoreload/* =true */, bool noSound /* =false */) { IEntityClass *ammo = m_pShared->fireparams.ammo_type_class; int ammoCount = m_pWeapon->GetAmmoCount(ammo); if(m_pShared->fireparams.clip_size==0) ammoCount = m_pWeapon->GetInventoryAmmoCount(ammo); CActor *pActor = m_pWeapon->GetOwnerActor(); bool playerIsShooter = pActor?pActor->IsPlayer():false; if(!CanFire(true)) { if((ammoCount <= 0) && (!m_reloading)) { m_pWeapon->PlayAction(m_pShared->actions.empty_clip); //Auto reload m_pWeapon->Reload(); } return false; } else if(m_pWeapon->IsWeaponLowered()) { m_pWeapon->PlayAction(m_pShared->actions.null_fire); return false; } if(m_reloading) { if(m_pWeapon->IsBusy()) m_pWeapon->SetBusy(false); if(CanFire(true) && !m_break_reload) { m_break_reload = true; m_pWeapon->RequestCancelReload(); } return false; } // Aim assistance m_pWeapon->AssistAiming(); const char *action = m_pShared->actions.fire_cock.c_str(); if(ammoCount == 1 || (m_pShared->fireparams.no_cock && m_pWeapon->IsZoomed())) action = m_pShared->actions.fire.c_str(); m_pWeapon->PlayAction(action, 0, false, CItem::eIPAF_Default|CItem::eIPAF_RestartAnimation|CItem::eIPAF_CleanBlending); Vec3 hit = GetProbableHit(WEAPON_HIT_RANGE); Vec3 pos = GetFiringPos(hit); Vec3 fdir = ApplySpread(GetFiringDir(hit, pos), GetSpread()); Vec3 vel = GetFiringVelocity(fdir); Vec3 dir; CheckNearMisses(hit, pos, fdir, WEAPON_HIT_RANGE, m_pShared->shotgunparams.spread); bool serverSpawn = m_pWeapon->IsServerSpawn(ammo); // SHOT HERE for(int i = 0; i < m_pShared->shotgunparams.pellets; i++) { CProjectile *pAmmo = m_pWeapon->SpawnAmmo(ammo, false); if(pAmmo) { dir = ApplySpread(fdir, m_pShared->shotgunparams.spread); int hitTypeId = g_pGame->GetGameRules()->GetHitTypeId(m_pShared->fireparams.hit_type.c_str()); pAmmo->SetParams(m_pWeapon->GetOwnerId(), m_pWeapon->GetHostId(), m_pWeapon->GetEntityId(), m_pShared->shotgunparams.pelletdamage, hitTypeId, playerIsShooter?m_pShared->fireparams.damage_drop_per_meter:0.0f, m_pShared->fireparams.damage_drop_min_distance); pAmmo->SetDestination(m_pWeapon->GetDestination()); pAmmo->Launch(pos, dir, vel); if((!m_pShared->tracerparams.geometry.empty() || !m_pShared->tracerparams.effect.empty()) && (ammoCount==GetClipSize() || (ammoCount%m_pShared->tracerparams.frequency==0))) { EmitTracer(pos,hit,false); } m_projectileId = pAmmo->GetEntity()->GetId(); } } m_pWeapon->OnShoot(m_pWeapon->GetOwnerId(), 0, ammo, pos, dir, vel); if(m_pWeapon->IsServer()) { const char *ammoName = ammo != NULL ? ammo->GetName() : NULL; g_pGame->GetIGameFramework()->GetIGameplayRecorder()->Event(m_pWeapon->GetOwner(), GameplayEvent(eGE_WeaponShot, ammoName, m_pShared->shotgunparams.pellets, (void *)m_pWeapon->GetEntityId())); } MuzzleFlashEffect(true); RejectEffect(); m_fired = true; m_next_shot += m_next_shot_dt; m_zoomtimeout = m_next_shot + 0.5f; ammoCount--; if(playerIsShooter) { if(pActor->InZeroG()) { IEntityPhysicalProxy *pPhysicsProxy = (IEntityPhysicalProxy *)pActor->GetEntity()->GetProxy(ENTITY_PROXY_PHYSICS); SMovementState ms; pActor->GetMovementController()->GetMovementState(ms); CPlayer *plr = (CPlayer *)pActor; if(m_recoilparams.back_impulse > 0.0f) { Vec3 impulseDir = ms.aimDirection * -1.0f; Vec3 impulsePos = ms.pos; float impulse = m_recoilparams.back_impulse; pPhysicsProxy->AddImpulse(-1, impulsePos, impulseDir * impulse * 100.0f, true, 1.0f); } if(m_recoilparams.angular_impulse > 0.0f) { float impulse = m_recoilparams.angular_impulse; pActor->AddAngularImpulse(Ang3(0,impulse,0), 1.0f); } } if(pActor->IsClient()) if(gEnv->pInput) gEnv->pInput->ForceFeedbackEvent(SFFOutputEvent(eDI_XI, eFF_Rumble_Basic, 0.15f, 0.0f, fabsf(m_recoilparams.back_impulse)*3.0f)); } if(m_pShared->fireparams.clip_size != -1) { if(m_pShared->fireparams.clip_size!=0) m_pWeapon->SetAmmoCount(ammo, ammoCount); else m_pWeapon->SetInventoryAmmoCount(ammo, ammoCount); } if((ammoCount<1) && !m_pShared->fireparams.slider_layer.empty()) { const char *slider_back_layer = m_pShared->fireparams.slider_layer.c_str(); m_pWeapon->PlayLayer(slider_back_layer, CItem::eIPAF_Default|CItem::eIPAF_NoBlend); } if(OutOfAmmo()) { m_pWeapon->OnOutOfAmmo(ammo); if(autoreload) { m_pWeapon->GetScheduler()->TimerAction(m_pWeapon->GetCurrentAnimationTime(eIGS_FirstPerson), CSchedulerAction<ScheduleReload>::Create(m_pWeapon), false); } } m_pWeapon->RequestShoot(ammo, pos, dir, vel, hit, 1.0f, 0, false); return true; }
//------------------------------------------------------------------------ IMPLEMENT_RMI(CWeapon, SvRequestShootEx) { CHECK_OWNER_REQUEST(); bool ok=true; CActor *pActor=GetActorByNetChannel(pNetChannel); if (!pActor || pActor->IsDead()) { ok=false; } #ifdef SERVER_CHECKS CAntiCheatManager * pAntiCheatManager = static_cast<CAntiCheatManager*>(g_pGame->GetAntiCheatManager()); bool validatePrediction = pAntiCheatManager ? pAntiCheatManager->GetAntiCheatVar(eAV_IP_UseTest_ValidatePredicatedSpawn, 1) != 0 : false; if(ok && validatePrediction && params.predictionHandle) { CFireMode *pFireMode = (CFireMode*)GetFireMode(params.fireModeId); if (pFireMode) { const SFireModeParams *pFireModeParams = pFireMode->GetShared(); if(pFireModeParams) { IEntityClass *pAmmoClass = pFireModeParams->fireparams.ammo_type_class; if(pAmmoClass) { int totalAmmoCount = GetAmmoCount(pAmmoClass) + GetInventoryAmmoCount(pAmmoClass); if(totalAmmoCount <= 0) { CryLog("actor %s does not have enough ammo for predicted spawn of %s, not spawning...", pActor->GetEntity()->GetName(), pAmmoClass->GetName()); ok = false; } } } } } #endif if (ok) { m_fireCounter++; m_expended_ammo++; IActor *pLocalActor=m_pGameFramework->GetClientActor(); bool isLocal = pLocalActor && (pLocalActor->GetChannelId() == pActor->GetChannelId()); if (!isLocal) { NetShootEx(params.pos, params.dir, params.vel, params.hit, params.extra, params.predictionHandle, params.fireModeId); } CHANGED_NETWORK_STATE(this, ASPECT_STREAM); } else { if(params.predictionHandle) { CGameRules::SPredictionParams predictionParams(params.predictionHandle); g_pGame->GetGameRules()->GetGameObject()->InvokeRMI(CGameRules::ClPredictionFailed(), predictionParams, eRMI_ToClientChannel, m_pGameFramework->GetGameChannelId(pNetChannel)); } } return true; }
//------------------------------------------------------------------------ void CInventory::FullSerialize( TSerialize ser ) { MEMSTAT_CONTEXT(EMemStatContextTypes::MSC_Other, 0, "Inventory serialization"); IEntityPoolManager* pMgr = gEnv->pEntitySystem->GetIEntityPoolManager(); if(pMgr && !gEnv->pSystem->IsSerializingFile()) { // Entities being activated from the pool shouldn't // serialize their inventories. The item ids in the bookmark // refer to the previous entities which no longer exist, instead the // actor will have been given a new equipment pack instead. // In that case just holster the default weapon. We will have to // select it after on the behavior or on the entity side if (ser.IsReading()) { EntityId currentItemId = 0; bool isUsing = false; ser.Value("using", isUsing); ser.Value("CurrentItem", currentItemId); if (currentItemId) { IItem *pItem = m_pGameFrameWork->GetIItemSystem()->GetItem(currentItemId); if(pItem && isUsing && !pItem->IsUsed()) { pItem->Use(GetEntityId()); return; } } HolsterItem(true); } else { bool isUsing = false; if (IItem *pItem = m_pGameFrameWork->GetIItemSystem()->GetItem(m_stats.currentItemId)) isUsing = pItem->IsUsed() && pItem->GetOwnerId() == GetEntityId(); ser.Value("using", isUsing); ser.Value("CurrentItem", m_stats.currentItemId); } return; } ser.BeginGroup("InventoryItems"); ser.Value("CurrentItem", m_stats.currentItemId); ser.Value("HolsterItem", m_stats.holsteredItemId); ser.Value("LastItem", m_stats.lastItemId); int s = m_stats.slots.size(); ser.Value("InventorySize", s); if(ser.IsReading()) m_stats.slots.resize(s); ser.Value("Slots", m_stats.slots ); ser.BeginGroup("accessorySlots"); int exSize = m_stats.accessorySlots.size(); ser.Value("Size", exSize); for(int i = 0; i < IInventory::eInventorySlot_Last; ++i) { ser.BeginGroup("SlotInfo"); ser.Value("slotInfoCount", m_stats.slotsInfo[i].count); ser.Value("slotInfoLastSelected", m_stats.slotsInfo[i].lastSelected); ser.EndGroup(); } if(ser.IsReading()) { m_stats.accessorySlots.resize(0); if(exSize>0) m_stats.accessorySlots.reserve(exSize); } for(int i = 0; i<exSize; ++i) { string accessoryName; if(ser.IsWriting()) accessoryName = m_stats.accessorySlots[i]->GetName(); ser.BeginGroup("Class"); ser.Value("AccessoryName", accessoryName); ser.EndGroup(); if(ser.IsReading()) { IEntityClass* pAccessoryClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass(accessoryName); CRY_ASSERT(pAccessoryClass); if (pAccessoryClass != NULL) { m_stats.accessorySlots.push_back(pAccessoryClass); } } } ser.EndGroup();//"accessorySlots" ser.BeginGroup("Ammo"); if(ser.IsReading()) { m_stats.ammoInfo.clear(); } TAmmoInfoMap::iterator ammoInfoIt = m_stats.ammoInfo.begin(); int ammoAmount = m_stats.ammoInfo.size(); ser.Value("AmmoAmount", ammoAmount); for(int i = 0; i < ammoAmount; ++i) { string name; int amount = 0; int capacity = 0; if(ser.IsWriting()) { IEntityClass* pAmmoClass = ammoInfoIt->first; CRY_ASSERT(pAmmoClass); name = (pAmmoClass) ? pAmmoClass->GetName() : ""; const SAmmoInfo& ammoInfo = ammoInfoIt->second; amount = ammoInfo.GetCount(); //users = ammoInfo.GetUserCount(); capacity = ammoInfo.GetCapacity(); // Only use this iterator writing. If we're reading, we change the size // of the map and end up with an out of sync (and invalid) iterator. ++ammoInfoIt; } ser.BeginGroup("Ammo"); ser.Value("AmmoName", name); ser.Value("Bullets", amount); ser.Value("Capacity", capacity); ser.EndGroup(); if(ser.IsReading()) { IEntityClass* pClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass(name); CRY_ASSERT(pClass); TAmmoInfoMap::iterator it = m_stats.ammoInfo.find(pClass); if (it == m_stats.ammoInfo.end()) { m_stats.ammoInfo[pClass] = SAmmoInfo(amount, capacity); } else { it->second.SetCount(amount); it->second.SetCapacity(capacity); } } } ser.EndGroup(); /* ser.BeginGroup("CategorySlots"); for (TSlotsInfo::iterator it = m_stats.slotsInfo.begin(); it != m_stats.slotsInfo.end(); ++it) { ser.Value("Count", it->second.count); } ser.EndGroup();*/ ser.EndGroup(); }
bool CSpammer::ShootRocket(EntityId target) { IEntityClass* pAmmoClass = m_fireParams->fireparams.ammo_type_class; int ammoCount = m_pWeapon->GetAmmoCount(pAmmoClass); CActor *pOwnerActor = m_pWeapon->GetOwnerActor(); const bool playerIsShooter = pOwnerActor ? pOwnerActor->IsPlayer() : false; const bool clientIsShooter = pOwnerActor ? pOwnerActor->IsClient() : false; bool bHit = false; ray_hit rayhit; rayhit.pCollider = 0; Vec3 hit = GetProbableHit(WEAPON_HIT_RANGE, &bHit, &rayhit); Vec3 pos = GetFiringPos(hit); Vec3 dir = GetFiringDir(hit, pos); Vec3 vel = GetFiringVelocity(dir); int flags = CItem::eIPAF_Default; if (IsProceduralRecoilEnabled() && pOwnerActor) { pOwnerActor->ProceduralRecoil(m_fireParams->proceduralRecoilParams.duration, m_fireParams->proceduralRecoilParams.strength, m_fireParams->proceduralRecoilParams.kickIn, m_fireParams->proceduralRecoilParams.arms); } float speedOverride = -1.f; GetWeapon()->PlayAction(GetFragmentIds().fire, 0, false, flags, speedOverride); CheckNearMisses(hit, pos, dir, (hit-pos).len(), 1.0f); CProjectile* pAmmo = m_pWeapon->SpawnAmmo(m_fireParams->fireparams.spawn_ammo_class, false); const EntityId weaponOwnerId = m_pWeapon->GetOwnerId(); EntityId ammoId = 0; if (pAmmo) { ammoId = pAmmo->GetEntityId(); CRY_ASSERT_MESSAGE(m_fireParams->fireparams.hitTypeId, string().Format("Invalid hit type '%s' in fire params for '%s'", m_fireParams->fireparams.hit_type.c_str(), m_pWeapon->GetEntity()->GetName())); CRY_ASSERT_MESSAGE(m_fireParams->fireparams.hitTypeId == g_pGame->GetGameRules()->GetHitTypeId(m_fireParams->fireparams.hit_type.c_str()), "Sanity Check Failed: Stored hit type id does not match the type string, possibly CacheResources wasn't called on this weapon type"); pAmmo->SetParams(CProjectile::SProjectileDesc( weaponOwnerId, m_pWeapon->GetHostId(), m_pWeapon->GetEntityId(), m_fireParams->fireparams.damage, m_fireParams->fireparams.damage_drop_min_distance, m_fireParams->fireparams.damage_drop_per_meter, m_fireParams->fireparams.damage_drop_min_damage, m_fireParams->fireparams.hitTypeId, m_fireParams->fireparams.bullet_pierceability_modifier, m_pWeapon->IsZoomed())); // this must be done after owner is set pAmmo->InitWithAI(); pAmmo->SetDestination(target); pAmmo->Launch(pos, dir, vel, m_speed_scale); m_projectileId = ammoId; if (clientIsShooter && pAmmo->IsPredicted() && gEnv->IsClient() && gEnv->bServer) { pAmmo->GetGameObject()->BindToNetwork(); } } if (m_pWeapon->IsServer()) { const char *ammoName = pAmmoClass != NULL ? pAmmoClass->GetName() : NULL; g_pGame->GetIGameFramework()->GetIGameplayRecorder()->Event(m_pWeapon->GetOwner(), GameplayEvent(eGE_WeaponShot, ammoName, 1, (void *)(EXPAND_PTR)m_pWeapon->GetEntityId())); } OnShoot(weaponOwnerId, ammoId, pAmmoClass, pos, dir, vel); if(playerIsShooter) { const SThermalVisionParams& thermalParams = m_fireParams->thermalVisionParams; m_pWeapon->AddShootHeatPulse(pOwnerActor, thermalParams.weapon_shootHeatPulse, thermalParams.weapon_shootHeatPulseTime, thermalParams.owner_shootHeatPulse, thermalParams.owner_shootHeatPulseTime); } m_muzzleEffect.Shoot(this, hit, m_barrelId); RecoilImpulse(pos, dir); m_fired = true; m_next_shot += m_next_shot_dt; if (++m_barrelId == m_fireParams->fireparams.barrel_count) m_barrelId = 0; ammoCount--; int clipSize = GetClipSize(); if (clipSize != -1) { if (clipSize!=0) m_pWeapon->SetAmmoCount(pAmmoClass, ammoCount); else m_pWeapon->SetInventoryAmmoCount(pAmmoClass, ammoCount); } m_pWeapon->RequestShoot(pAmmoClass, pos, dir, vel, hit, m_speed_scale, pAmmo? pAmmo->GetGameObject()->GetPredictionHandle() : 0, false); return true; }
void CLTagSingle::NetShootEx(const Vec3 &pos, const Vec3 &dir, const Vec3 &vel, const Vec3 &hit, float extra, int predictionHandle) { IEntityClass* ammo = m_fireParams->fireparams.ammo_type_class; int weaponAmmoCount = m_pWeapon->GetAmmoCount(ammo); int ammoCount = weaponAmmoCount; CActor* pOwnerActor = m_pWeapon->GetOwnerActor(); bool playerIsShooter = pOwnerActor ? pOwnerActor->IsPlayer() : false; if (IsProceduralRecoilEnabled() && pOwnerActor) { pOwnerActor->ProceduralRecoil(m_fireParams->proceduralRecoilParams.duration, m_fireParams->proceduralRecoilParams.strength, m_fireParams->proceduralRecoilParams.kickIn, m_fireParams->proceduralRecoilParams.arms); } m_pWeapon->PlayAction(GetFragmentIds().fire, 0, false, CItem::eIPAF_Default); CProjectile *pAmmo = m_pWeapon->SpawnAmmo(m_fireParams->fireparams.spawn_ammo_class, true); CLTAGGrenade* pGrenade = static_cast<CLTAGGrenade*>(pAmmo); if (pGrenade) { CRY_ASSERT_MESSAGE(m_fireParams->fireparams.hitTypeId, string().Format("Invalid hit type '%s' in fire params for '%s'", m_fireParams->fireparams.hit_type.c_str(), m_pWeapon->GetEntity()->GetName())); CRY_ASSERT_MESSAGE(m_fireParams->fireparams.hitTypeId == g_pGame->GetGameRules()->GetHitTypeId(m_fireParams->fireparams.hit_type.c_str()), "Sanity Check Failed: Stored hit type id does not match the type string, possibly CacheResources wasn't called on this weapon type"); pGrenade->SetParams(CProjectile::SProjectileDesc( m_pWeapon->GetOwnerId(), m_pWeapon->GetHostId(), m_pWeapon->GetEntityId(), m_fireParams->fireparams.damage, 0.f, 0.f, 0.f, m_fireParams->fireparams.hitTypeId, m_fireParams->fireparams.bullet_pierceability_modifier, m_pWeapon->IsZoomed())); // this must be done after owner is set pGrenade->InitWithAI(); pGrenade->SetDestination(m_pWeapon->GetDestination()); pGrenade->SetGrenadeType(m_grenadeType); pGrenade->Launch(pos, dir, vel, m_speed_scale); m_projectileId = pGrenade->GetEntity()->GetId(); } if (m_pWeapon->IsServer()) { const char *ammoName = ammo != NULL ? ammo->GetName() : NULL; g_pGame->GetIGameFramework()->GetIGameplayRecorder()->Event(m_pWeapon->GetOwner(), GameplayEvent(eGE_WeaponShot, ammoName, 1, (void *)(EXPAND_PTR)m_pWeapon->GetEntityId())); #ifdef SERVER_CHECKS if (pOwnerActor && m_pWeapon->IsServerSpawn(ammo)) { int inventoryAmmoCount = m_pWeapon->GetInventoryAmmoCount(ammo); int totalAmmoCount=weaponAmmoCount+inventoryAmmoCount; // this needed seeing as how this seems to use weaponAmmo or inventoryAmmo but NOT both? if (totalAmmoCount <= 0) { g_pGame->GetAntiCheatManager()->FlagActivity(eCT_ServerSpawnedAmmoUsed, pOwnerActor->GetChannelId()); } } #endif } m_muzzleEffect.Shoot(this, hit, m_barrelId); RecoilImpulse(pos, dir); m_fired = true; m_next_shot = 0.0f; ammoCount--; if(ammoCount<0) ammoCount = 0; if (m_pWeapon->IsServer()) { int clipSize = GetClipSize(); if (clipSize != -1) { if (clipSize != 0) m_pWeapon->SetAmmoCount(ammo, ammoCount); else m_pWeapon->SetInventoryAmmoCount(ammo, ammoCount); } } OnShoot(m_pWeapon->GetOwnerId(), pAmmo?pAmmo->GetEntity()->GetId():0, ammo, pos, dir, vel); if(playerIsShooter) { const SThermalVisionParams& thermalParams = m_fireParams->thermalVisionParams; m_pWeapon->AddShootHeatPulse(pOwnerActor, thermalParams.weapon_shootHeatPulse, thermalParams.weapon_shootHeatPulseTime, thermalParams.owner_shootHeatPulse, thermalParams.owner_shootHeatPulseTime); } if (OutOfAmmo()) m_pWeapon->OnOutOfAmmo(ammo); if (pAmmo && predictionHandle && pOwnerActor) { pAmmo->GetGameObject()->RegisterAsValidated(pOwnerActor->GetGameObject(), predictionHandle); pAmmo->GetGameObject()->BindToNetwork(); } else if (pAmmo && pAmmo->IsPredicted() && gEnv->IsClient() && gEnv->bServer && pOwnerActor && pOwnerActor->IsClient()) { pAmmo->GetGameObject()->BindToNetwork(); } m_pWeapon->RequireUpdate(eIUS_FireMode); }
//----------------------------------------------------------------------- void CSpectacularKill::ReadXmlData( const IItemParamsNode* pRootNode) { CRY_ASSERT(pRootNode); ISharedParamsManager* pSharedParamsManager = gEnv->pGame->GetIGameFramework()->GetISharedParamsManager(); CRY_ASSERT(pSharedParamsManager); // If we change the SharedParamsManager to accept CRCs on its interface we could compute this once and store // the name's CRC32 instead of constructing it here each time this method is invoked (it shouldn't be invoked // too often, though) const char* szEntityClassName = m_pOwner->GetEntityClassName(); CryFixedStringT<64> sharedParamsName; sharedParamsName.Format("%s_%s", SSharedSpectacularParams::s_typeInfo.GetName(), szEntityClassName); ISharedParamsConstPtr pSharedParams = pSharedParamsManager->Get(sharedParamsName); if (pSharedParams) { m_pParams = CastSharedParamsPtr<SSharedSpectacularParams>(pSharedParams); return; } m_pParams.reset(); const IItemParamsNode* pParams = pRootNode->GetChild("SpectacularKill"); if (pParams) { SSharedSpectacularParams newParams; const int childCount = pParams->GetChildCount(); newParams.paramsList.reserve(childCount); for (int i = 0; i < childCount; ++i) { const IItemParamsNode* pTargetParams = pParams->GetChild(i); CRY_ASSERT(pTargetParams); IEntityClass* pTargetClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass(pTargetParams->GetName()); if (pTargetClass) { SSpectacularKillParams targetParams; const IItemParamsNode* pChildParamsNode = pTargetParams->GetChild("Params"); const IItemParamsNode* pChildAnimsNode = pTargetParams->GetChild("Anims"); targetParams.pEnemyClass = pTargetClass; if(pChildParamsNode) { pChildParamsNode->GetAttribute("impulseScale", targetParams.impulseScale); const char* szImpulseBone = pChildParamsNode->GetAttributeSafe("impulseBone"); ICharacterInstance* pCharacter = m_pOwner->GetEntity()->GetCharacter(0); targetParams.impulseBone = pCharacter ? pCharacter->GetIDefaultSkeleton().GetJointIDByName(szImpulseBone) : -1; } if(pChildAnimsNode) { const int animCount = pChildAnimsNode->GetChildCount(); targetParams.animations.reserve(animCount); for(int j = 0; j < animCount; j++) { const IItemParamsNode* pAnimNode = pChildAnimsNode->GetChild(j); if(pAnimNode) { SSpectacularKillAnimation newAnimation; newAnimation.victimAnimation = pAnimNode->GetAttributeSafe("victimAnimation"); newAnimation.killerAnimation = pAnimNode->GetAttributeSafe("killerAnimation"); pAnimNode->GetAttribute("optimalDist", newAnimation.optimalDist); if (pAnimNode->GetAttribute("targetToKillerAngle", newAnimation.targetToKillerAngle)) newAnimation.targetToKillerAngle = DEG2RAD(newAnimation.targetToKillerAngle); if (pAnimNode->GetAttribute("targetToKillerAngleRange", newAnimation.targetToKillerMinDot)) newAnimation.targetToKillerMinDot = cos_tpl(DEG2RAD(newAnimation.targetToKillerMinDot) / 2.0f); pAnimNode->GetAttribute("obstacleCheckStartOffset", newAnimation.vKillerObstacleCheckOffset); pAnimNode->GetAttribute("obstacleCheckLength", newAnimation.fObstacleCheckLength); targetParams.animations.push_back(newAnimation); } } } CRY_ASSERT_MESSAGE(targetParams.animations.size() > 0, string().Format("No Animations defined for %s spectacular kill", pTargetClass->GetName())); newParams.paramsList.push_back(targetParams); } #ifdef SPECTACULAR_KILL_DEBUG else { GameWarning("spectacular Kill: Couldn't find entity of class '%s', skipping", pTargetParams->GetName()); } #endif } m_pParams = CastSharedParamsPtr<SSharedSpectacularParams>(pSharedParamsManager->Register(sharedParamsName, newParams)); } }