//------------------------------------------------------------------------ int CScriptBind_Actor::SetInventoryAmmo(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->IsEditor()) && (amount > capacity)) { //If still there's some place, full inventory to maximum... if(current<capacity) { pInventory->SetAmmoCount(pClass,capacity); if (gEnv->bServer) pActor->GetGameObject()->InvokeRMI(CActor::ClSetAmmo(), CActor::AmmoParams(ammo, amount), eRMI_ToRemoteClients); } } else { pInventory->SetAmmoCount(pClass, amount); if (gEnv->bServer) pActor->GetGameObject()->InvokeRMI(CActor::ClSetAmmo(), CActor::AmmoParams(ammo, amount), eRMI_ToRemoteClients); } return pH->EndFunction(); }
//------------------------------------------------------------------------ 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(); }
//------------------------------------------------------------------------ float CGameRulesCommonDamageHandling::GetAIPlayerAgainstColliderEnergyScale(const IEntity& collider) const { const float energyScaleAgainstNonActor = 10.0f; const float energyScaleAgainstRagdoll = 50.0f; CActor* pColliderActor = static_cast<CActor*>(g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(collider.GetId())); if (pColliderActor) { uint8 physicsAspectProfile = pColliderActor->GetGameObject()->GetAspectProfile(eEA_Physics) ; if ((physicsAspectProfile == eAP_Ragdoll) || (physicsAspectProfile == eAP_Sleep)) { return energyScaleAgainstRagdoll; } if (pColliderActor->GetActorClass() == CPlayer::GetActorClassType()) { SPlayerStats* pColliderStats = static_cast<SPlayerStats*>(pColliderActor->GetActorStats()); if (pColliderStats != NULL && pColliderStats->followCharacterHead) { return 0.0f; } } } return energyScaleAgainstNonActor; }
//------------------------------------------------------------------------ int CScriptBind_Actor::SetPhysicalizationProfile(IFunctionHandler *pH, const char *profile) { CActor *pActor = GetActor(pH); if (!pActor) return pH->EndFunction(); uint p = 0; if (!stricmp(profile, "alive")) p = eAP_Alive; else if (!stricmp(profile, "unragdoll")) p = eAP_NotPhysicalized; else if (!stricmp(profile, "ragdoll")) { if (!pActor->GetLinkedVehicle()) p = eAP_Ragdoll; else p = eAP_Alive; } else if (!stricmp(profile, "spectator")) p = eAP_Spectator; else if (!stricmp(profile, "sleep")) p = eAP_Sleep; else if (!stricmp(profile, "frozen")) p = eAP_Frozen; else return pH->EndFunction(); //Don't turn ragdoll while grabbed if(p==eAP_Ragdoll && !pActor->CanRagDollize()) return pH->EndFunction(); pActor->GetGameObject()->SetAspectProfile(eEA_Physics, p); return pH->EndFunction(); }
//------------------------------------------------------------------------ int CScriptBind_Actor::SetExtensionActivation(IFunctionHandler *pH, const char *extension, bool activation) { CActor *pActor = GetActor(pH); if (!pActor) return pH->EndFunction(); bool ok = false; if (pActor) { if (activation) ok = pActor->GetGameObject()->ActivateExtension(extension); else { pActor->GetGameObject()->DeactivateExtension(extension); ok = true; } } if (!ok) pH->GetIScriptSystem()->RaiseError("Failed to %s extension %s", activation? "enable" : "disable", extension); return pH->EndFunction(); }
//------------------------------------------------------------------------ int CScriptBind_Actor::RagDollize(IFunctionHandler *pH) { CActor *pActor = GetActor(pH); if (!pActor) return pH->EndFunction(); pActor->GetGameObject()->SetAspectProfile(eEA_Physics, eAP_Ragdoll); //pActor->RagDollize(); return pH->EndFunction(); }
//------------------------------------------------------------------------ int CScriptBind_Actor::GetExtensionParams(IFunctionHandler* pH, const char *extension, SmartScriptTable params) { CActor * pActor = GetActor(pH); if (!pActor) return pH->EndFunction(); bool ok = false; if (pActor) ok = pActor->GetGameObject()->GetExtensionParams(extension, params); if (!ok) pH->GetIScriptSystem()->RaiseError("Failed to set params for extension %s", extension); return pH->EndFunction(); }
//------------------------------------------------------------------------ int CScriptBind_Actor::SelectItemByNameRemote(IFunctionHandler *pH, const char *name) { CActor *pActor = GetActor(pH); if (!pActor) return pH->EndFunction(); //Only send to this client if(gEnv->bServer) pActor->GetGameObject()->InvokeRMI(CActor::ClSelectItemByName(),CActor::SelectItemParams(name),eRMI_ToClientChannel,pActor->GetGameObject()->GetChannelId()); return pH->EndFunction(); }
//----------------------------------------------------------------------- void CSpectacularKill::DeathBlow(CActor& targetActor) { CRY_ASSERT_MESSAGE(m_isBusy, "spectacular kill should be in progress when triggering the death blow"); if (!m_isBusy) return; if (targetActor.IsDead()) return; Vec3 targetDir = targetActor.GetEntity()->GetForwardDir(); { HitInfo hitInfo; hitInfo.shooterId = m_pOwner->GetEntityId(); hitInfo.targetId = targetActor.GetEntityId(); hitInfo.damage = 99999.0f; // CERTAIN_DEATH hitInfo.dir = targetDir; hitInfo.normal = -hitInfo.dir; // this has to be in an opposite direction from the hitInfo.dir or the hit is ignored as a 'backface' hit hitInfo.type = CGameRules::EHitType::StealthKill; g_pGame->GetGameRules()->ClientHit(hitInfo); } // WARNING: RagDollize resets the entity's rotation! // [7/30/2010 davidr] FixMe: If the entity isn't dead here (because is immortal or any other reason) ragdollizing it will // leave it on an inconsistent state (usually only reproducible on debug scenarios) targetActor.GetGameObject()->SetAspectProfile(eEA_Physics, eAP_Ragdoll); // Give a small nudge in the hit direction to make the target fall over const SSpectacularKillParams* pSpectacularKillParams = GetParamsForClass(targetActor.GetEntity()->GetClass()); CRY_ASSERT(pSpectacularKillParams); if (pSpectacularKillParams && (pSpectacularKillParams->impulseScale > 0.0f) && (pSpectacularKillParams->impulseBone != -1)) { const float killDeathBlowVelocity = pSpectacularKillParams->impulseScale; // desired velocity after impulse in meters per second IPhysicalEntity* pTargetPhysics = targetActor.GetEntity()->GetPhysics(); if (pTargetPhysics) { pe_simulation_params simulationParams; pTargetPhysics->GetParams(&simulationParams); pe_action_impulse impulse; impulse.partid = pSpectacularKillParams->impulseBone; impulse.impulse = targetDir*killDeathBlowVelocity*simulationParams.mass; // RagDollize reset the entity's rotation so I have to use the value I cached earlier pTargetPhysics->Action(&impulse); } } m_deathBlowState = eDBS_Done; }
void CHeavyWeapon::StopUse(EntityId userId) { CActor *pActor = GetOwnerActor(); if (!pActor) return; EnableUpdate(false); m_stats.used = false; if (IsServer()) pActor->GetGameObject()->InvokeRMI(CActor::ClStopUse(), CActor::ItemIdParam(GetEntityId()), eRMI_ToAllClients|eRMI_NoLocalCalls); Drop(5.0f); }
//------------------------------------------------------------------------ int CScriptBind_Actor::EnableAspect(IFunctionHandler *pH, const char *aspect, bool enable) { CActor *pActor = GetActor(pH); if (!pActor) return pH->EndFunction(); uint8 aspectbit = 0; if (!stricmp(aspect, "physics")) aspectbit |= eEA_Physics; else if (!stricmp(aspect, "gameobject")) aspectbit |= eEA_GameClientDynamic | eEA_GameServerDynamic | eEA_GameClientStatic | eEA_GameServerStatic; else if (!stricmp(aspect, "script")) aspectbit |= eEA_Script; if (pActor) pActor->GetGameObject()->EnableAspect(aspectbit, enable); return pH->EndFunction(); }
//------------------------------------------------------------------------ int CScriptBind_Actor::GetPhysicalizationProfile(IFunctionHandler *pH) { CActor *pActor = GetActor(pH); if (!pActor) return pH->EndFunction(); uint8 profile=pActor->GetGameObject()->GetAspectProfile(eEA_Physics); const char *profileName; if (profile == eAP_Alive) profileName="alive"; else if (profile == eAP_NotPhysicalized) profileName = "unragdoll"; else if (profile == eAP_Ragdoll) profileName = "ragdoll"; else if (profile == eAP_Sleep) profileName = "sleep"; else if (profile == eAP_Spectator) profileName = "spectator"; else return pH->EndFunction(); return pH->EndFunction(profileName); }
//------------------------------------------------------------------------ void SSleepEffect::Activate(EntityId targetId, EntityId ownerId, EntityId weaponId, const char *effect, const char *defaultEffect) { CActor *pActor = (CActor *)gEnv->pGame->GetIGameFramework()->GetIActorSystem()->GetActor(targetId); if (pActor) { IAISystem *pAISystem=gEnv->pAISystem; if (pAISystem) { if(IEntity* pEntity=pActor->GetEntity()) { if(IAIObject* pAIObj=pEntity->GetAI()) { IAISignalExtraData *pEData = pAISystem->CreateSignalExtraData(); // no leak - this will be deleted inside SendAnonymousSignal // try to retrieve the shooter position if (IEntity* pOwnerEntity = gEnv->pEntitySystem->GetEntity(ownerId)) pEData->point = pOwnerEntity->GetWorldPos(); else pEData->point = pEntity->GetWorldPos(); IAIActor* pAIActor = pAIObj->CastToIAIActor(); if(pAIActor) pAIActor->SetSignal(1,"TRANQUILIZED",0,pEData); } } } pActor->CreateScriptEvent("sleep", 0); pActor->GetGameObject()->SetPhysicalizationProfile(eAP_Sleep); // no dropping weapons for AI if(pActor->IsPlayer()) pActor->DropItem(pActor->GetCurrentItemId(), 1.0f, false); pActor->SetSleepTimer(12.5f); } }
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 CHeavyWeapon::StartUse(EntityId userId) { // holster user item here SetOwnerId(userId); CActor* pOwner = GetOwnerActor(); if (!pOwner) return; HighlightWeapon(false); Physicalize(false, false); if(gEnv->bMultiplayer) { m_properties.usable &= strlen(g_pGameCVars->g_forceHeavyWeapon->GetString()) == 0; CHANGED_NETWORK_STATE(pOwner, CPlayer::ASPECT_CURRENT_ITEM); } if(IItem* pCurrentItem = pOwner->GetCurrentItem()) { //Don't keep history if we're switching from Pick & Throw otherwsie we'll switch back to it when we're done with the heavy weapon static IEntityClass* pPickAndThrowWeaponClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass("PickAndThrowWeapon"); m_pItemSystem->SetActorItem(pOwner, GetEntityId(), pCurrentItem->GetEntity()->GetClass() != pPickAndThrowWeaponClass); } else { m_pItemSystem->SetActorItem(pOwner, GetEntityId(), true); } TriggerRespawn(); EnableUpdate(true, eIUS_General); RequireUpdate(eIUS_General); RegisterAsUser(); HandleHeavyWeaponPro(*pOwner); m_stats.brandnew = false; m_stats.used = true; m_stats.detached = false; if(IsClient() && gEnv->pGame->GetIGameFramework()->GetClientActorId()==userId) { if(IEntity* pEntity = GetEntity()) { const char* collectibleId = pEntity->GetClass()->GetName(); CPersistantStats* pStats = g_pGame->GetPersistantStats(); if(pStats && pStats->GetStat(collectibleId, EMPS_SPWeaponByName) == 0) { pStats->SetMapStat(EMPS_SPWeaponByName, collectibleId, eDatabaseStatValueFlag_Available); if(!gEnv->bMultiplayer) { // Show hud unlock msg SHUDEventWrapper::DisplayWeaponUnlockMsg(collectibleId); } } } } if (IsServer()) { pOwner->GetGameObject()->InvokeRMIWithDependentObject(CActor::ClStartUse(), CActor::ItemIdParam(GetEntityId()), eRMI_ToAllClients|eRMI_NoLocalCalls, GetEntityId()); g_pGame->GetGameRules()->AbortEntityRemoval(GetEntityId()); } OnStartUsing(); }