Beispiel #1
0
void CTacAlienBullet::HandleEvent(const SGameObjectEvent &event)
{
	if (m_destroying)
		return;

	CProjectile::HandleEvent(event);

	if (event.event == eGFE_OnCollision)
	{
		EventPhysCollision *pCollision = reinterpret_cast<EventPhysCollision *>(event.ptr);
		if (!pCollision)
			return;

		IEntity *pTarget = pCollision->iForeignData[1]==PHYS_FOREIGN_ID_ENTITY ? (IEntity*)pCollision->pForeignData[1]:0;
		if (pTarget)
		{
			EntityId targetId = pTarget->GetId();
			CActor* pActor = static_cast<CActor*>(g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(pTarget->GetId()));
			if(pActor && pActor->CanSleep())
			{
				SimpleHitInfo info(m_ownerId, targetId, m_weaponId, 1); // 0=tag,1=tac

				info.remote=IsRemote();

				g_pGame->GetGameRules()->ClientSimpleHit(info);
			}
		}

		Destroy();
	}
}
//------------------------------------------------------------------------
void CGameRules::ServerSimpleHit(const SimpleHitInfo &simpleHitInfo)
{
	if (my->CallHook(
		"OnEntityDamage", 
		oohh::GetEntityFromId(simpleHitInfo.targetId), 
		oohh::GetEntityFromId(simpleHitInfo.weaponId), 
		oohh::GetEntityFromId(simpleHitInfo.shooterId), 
		simpleHitInfo.value, 
		Vec3(0,0,0), 
		Vec3(0,0,0)
	))
	{
		if (true)
			return;
	}

	switch (simpleHitInfo.type)
	{
	case 0: // tag
		{
			if (!simpleHitInfo.targetId)
				return;

			// tagged entities are temporary in MP, not in SP.
			bool temp = gEnv->bMultiplayer;

			AddTaggedEntity(simpleHitInfo.shooterId, simpleHitInfo.targetId, temp);
		}
		break;
	case 1: // tac
		{
			if (!simpleHitInfo.targetId)
				return;

			CActor *pActor = (CActor *)gEnv->pGame->GetIGameFramework()->GetIActorSystem()->GetActor(simpleHitInfo.targetId);

			if (pActor && pActor->CanSleep())
				pActor->Fall(Vec3(0.0f,0.0f,0.0f),simpleHitInfo.value);
		}
		break;
	case 0xe: // freeze
		{
			if (!simpleHitInfo.targetId)
				return;
			
			// call OnFreeze
			bool allow=true;
			if (m_serverStateScript.GetPtr() && m_serverStateScript->GetValueType("OnFreeze")==svtFunction)
			{
				HSCRIPTFUNCTION func=0;
				m_serverStateScript->GetValue("OnFreeze", func);
				Script::CallReturn(m_serverStateScript->GetScriptSystem(), func, m_script, ScriptHandle(simpleHitInfo.targetId), ScriptHandle(simpleHitInfo.shooterId), ScriptHandle(simpleHitInfo.weaponId), simpleHitInfo.value, allow);
				gEnv->pScriptSystem->ReleaseFunc(func);
			}

			if (!allow)
				return;

			if (IEntity *pEntity=gEnv->pEntitySystem->GetEntity(simpleHitInfo.targetId))
			{
				IScriptTable *pScriptTable=pEntity->GetScriptTable();

				// call OnFrost
				if (pScriptTable && pScriptTable->GetValueType("OnFrost")==svtFunction)
				{
					HSCRIPTFUNCTION func=0;
					pScriptTable->GetValue("OnFrost", func);
					Script::Call(pScriptTable->GetScriptSystem(), func, pScriptTable, ScriptHandle(simpleHitInfo.shooterId), ScriptHandle(simpleHitInfo.weaponId), simpleHitInfo.value);
					gEnv->pScriptSystem->ReleaseFunc(func);
				}

				FreezeEntity(simpleHitInfo.targetId, true, true, simpleHitInfo.value>0.999f);
			}
		}
		break;
	default:
		assert(!"Unknown Simple Hit type!");
	}
}
void CTacBullet::HandleEvent(const SGameObjectEvent &event)
{
	if (m_destroying)
		return;

	CProjectile::HandleEvent(event);

	if (event.event == eGFE_OnCollision)
	{
		EventPhysCollision *pCollision = reinterpret_cast<EventPhysCollision *>(event.ptr);
		if (!pCollision)
			return;

		IEntity *pTarget = pCollision->iForeignData[1]==PHYS_FOREIGN_ID_ENTITY ? (IEntity*)pCollision->pForeignData[1]:0;
		if (pTarget)
		{
			CGameRules *pGameRules = g_pGame->GetGameRules();

			EntityId targetId = pTarget->GetId();
			CActor *pActor = (CActor *)gEnv->pGame->GetIGameFramework()->GetIActorSystem()->GetActor(targetId);
			
			if(pActor && pActor->CanSleep())
			{
				if(pActor->GetLinkedVehicle() && !gEnv->bMultiplayer)
				{
					SleepTargetInVehicle(m_ownerId,pActor);
				}
				else if(IEntity* pOwnerEntity = gEnv->pEntitySystem->GetEntity(m_ownerId))
				{
					if (pTarget->GetAI() && !pTarget->GetAI()->IsFriendly(pOwnerEntity->GetAI(), false))
					{
						float sleepTime = 30.0f;
						if(m_pAmmoParams)
							sleepTime = m_pAmmoParams->sleepTime;
						SimpleHitInfo info(m_ownerId, targetId, m_weaponId, 1, sleepTime); // 0=tag,1=tac
						info.remote=IsRemote();

						pGameRules->ClientSimpleHit(info);
					}
				}
			}
			else
			{
				Vec3 dir(0, 0, 0);
				if (pCollision->vloc[0].GetLengthSquared() > 1e-6f)
					dir = pCollision->vloc[0].GetNormalized();

				HitInfo hitInfo(m_ownerId, pTarget->GetId(), m_weaponId,
					(float)m_damage, 0.0f, pGameRules->GetHitMaterialIdFromSurfaceId(pCollision->idmat[1]), pCollision->partid[1],
					m_hitTypeId, pCollision->pt, dir, pCollision->n);

				hitInfo.remote = IsRemote();
				hitInfo.projectileId = GetEntityId();
				hitInfo.bulletType = m_pAmmoParams->bulletType;

				pGameRules->ClientHit(hitInfo);
			}

		}
		else if (pCollision->pEntity[0]->GetType() == PE_PARTICLE)
		{
			float bouncy, friction;
			uint32	pierceabilityMat;
			gEnv->pPhysicalWorld->GetSurfaceParameters(pCollision->idmat[1], bouncy, friction, pierceabilityMat);
			pierceabilityMat&=sf_pierceable_mask;

			pe_params_particle params;
			if(pCollision->pEntity[0]->GetParams(&params)==0)
				SetDefaultParticleParams(&params);

			if (pierceabilityMat>params.iPierceability && pCollision->idCollider!=-1) 
				return;
		}

		Destroy();
	}
}
//------------------------------------------------------------------------
void CGameRules::ServerSimpleHit(const SimpleHitInfo &simpleHitInfo)
{
	switch (simpleHitInfo.type)
	{
	case 0: // tag
		{
			if (!simpleHitInfo.targetId)
				return;

			// tagged entities are temporary in MP, not in SP.
//			bool temp = gEnv->bMultiplayer;
			//kirill: - not anymore - design says must stay on
			bool temp = false;

			AddTaggedEntity(simpleHitInfo.shooterId, simpleHitInfo.targetId, temp);
		}
		break;
	case 1: // tac
		{
			if (!simpleHitInfo.targetId)
				return;

			CActor *pActor = (CActor *)gEnv->pGame->GetIGameFramework()->GetIActorSystem()->GetActor(simpleHitInfo.targetId);

			if (pActor && pActor->CanSleep())
			{
				pActor->Fall(Vec3(0.0f,0.0f,0.0f),false,simpleHitInfo.value);
				//This is only used in SP by the player, so don't need further checks
				CPlayer* pPlayer = static_cast<CPlayer*>(g_pGame->GetIGameFramework()->GetClientActor());
				if(pPlayer)
					pPlayer->PlaySound(CPlayer::ESound_TacBulletFeedBack,true);
			}
		}
		break;
	case 0xe: // freeze
		{
			if (!simpleHitInfo.targetId)
				return;

			CActor *pActor=GetActorByEntityId(simpleHitInfo.targetId);

			if (pActor && pActor->IsPlayer() && pActor->GetActorClass()==CPlayer::GetActorClassType())
			{
				CPlayer *pPlayer=static_cast<CPlayer *>(pActor);
				if (CNanoSuit *pSuit=pPlayer->GetNanoSuit())
					if (pSuit->IsInvulnerable())
						return;
			}

			// call OnFreeze
			bool allow=true;
			if (m_serverStateScript.GetPtr() && m_serverStateScript->GetValueType("OnFreeze")==svtFunction)
			{
				HSCRIPTFUNCTION func=0;
				m_serverStateScript->GetValue("OnFreeze", func);
				Script::CallReturn(m_serverStateScript->GetScriptSystem(), func, m_script, ScriptHandle(simpleHitInfo.targetId), ScriptHandle(simpleHitInfo.shooterId), ScriptHandle(simpleHitInfo.weaponId), simpleHitInfo.value, allow);
				gEnv->pScriptSystem->ReleaseFunc(func);
			}

			if (!allow)
				return;

			if (IEntity *pEntity=gEnv->pEntitySystem->GetEntity(simpleHitInfo.targetId))
			{
				IScriptTable *pScriptTable=pEntity->GetScriptTable();

				// call OnFrost
				if (pScriptTable && pScriptTable->GetValueType("OnFrost")==svtFunction)
				{
					HSCRIPTFUNCTION func=0;
					pScriptTable->GetValue("OnFrost", func);
					Script::Call(pScriptTable->GetScriptSystem(), func, pScriptTable, ScriptHandle(simpleHitInfo.shooterId), ScriptHandle(simpleHitInfo.weaponId), simpleHitInfo.value);
					gEnv->pScriptSystem->ReleaseFunc(func);
				}

				FreezeEntity(simpleHitInfo.targetId, true, true, simpleHitInfo.value>0.999f);
			}
		}
		break;
	default:
		assert(!"Unknown Simple Hit type!");
	}
}