Example #1
0
void CProjectileHandler::CheckGroundCollisions(ProjectileContainer& pc) {
	ProjectileContainer::iterator pci;

	for (pci = pc.begin(); pci != pc.end(); ++pci) {
		CProjectile* p = *pci;

		if (!p->checkCol) {
			continue;
		}

		// NOTE: if <p> is a MissileProjectile and does not
		// have selfExplode set, it will never be removed (!)
		if (p->GetCollisionFlags() & Collision::NOGROUND) {
			continue;
		}

		// NOTE: don't add p->radius to groundHeight, or most
		// projectiles will collide with the ground too early
		const float groundHeight = ground->GetHeightReal(p->pos.x, p->pos.z);
		const bool belowGround = (p->pos.y < groundHeight);
		const bool insideWater = (p->pos.y <= 0.0f && !belowGround);
		const bool ignoreWater = p->ignoreWater;

		if (belowGround || (insideWater && !ignoreWater)) {
			// if position has dropped below terrain or into water
			// where we cannot live, adjust it and explode us now
			// (if the projectile does not set deleteMe = true, it
			// will keep hugging the terrain)
			p->pos.y = belowGround? groundHeight: 0.0f;
			p->Collision();
		}
	}
}
Example #2
0
void CJaw::OnShoot(EntityId shooterId, EntityId ammoId, IEntityClass* pAmmoType, const Vec3 &pos, const Vec3 &dir, const Vec3 &vel)
{
	BaseClass::OnShoot(shooterId, ammoId, pAmmoType, pos, dir, vel);

	CActor *pOwnerActor = GetOwnerActor();
	if (pOwnerActor)
	{
		// Set the projectile to target the forced entity
		if (m_forcedTargetId > 0)
		{
			CProjectile *pProjectile = g_pGame->GetWeaponSystem()->GetProjectile(ammoId);
			if (pProjectile)
			{
				pProjectile->SetDestination(m_forcedTargetId);
			}
		}

		if (pOwnerActor->IsClient() && m_laserGuider.IsLaserActivated())
		{
			SHUDEvent event(eHUDEvent_InfoSystemsEvent);
			event.AddData(SHUDEventData(1));
			event.AddData(SHUDEventData(2.f));
			event.AddData(SHUDEventData("@hud_guided"));
			CHUDEventDispatcher::CallEvent(event);
		}

		if (pOwnerActor->IsClient())
			m_fired = true;
	}

	SvActivateMissileCountermeasures(shooterId, pos, dir);
}
void CCustomExplosionGenerator::Explosion(const float3 &pos, const DamageArray& damages, float radius, CUnit *owner,float gfxMod, CUnit *hit)
{
    float h2=ground->GetHeight2(pos.x,pos.z);

    unsigned int flags = 0;
    if (h2<-3) flags = SPW_WATER;
    else if (pos.y<-15) flags = SPW_UNDERWATER;
    else if (pos.y-max((float)0,h2)>20) flags = SPW_AIR;
    else flags = SPW_GROUND;
    if (hit) flags |= SPW_UNIT;
    else flags |= SPW_NO_UNIT;

    for (int a=0; a<projectileSpawn.size(); a++)
    {
        ProjectileSpawnInfo *psi = projectileSpawn[a];

        if (!(psi->flags & flags))
            continue;

        for (int c=0; c<psi->count; c++)
        {
            CProjectile *projectile = (CProjectile*)psi->projectileClass->CreateInstance ();

            ExecuteExplosionCode (&psi->code[0], damages.damages[0], (char*)projectile, c);
            projectile->Init(pos, owner);
        }
    }

    if ((flags & SPW_GROUND) && groundFlash)
        new CStandarGroundFlash(pos, groundFlash->circleAlpha, groundFlash->flashAlpha, groundFlash->flashSize, groundFlash->circleGrowth, groundFlash->ttl, groundFlash->color);

    if (useDefaultExplosions)
        CStdExplosionGenerator::Explosion(pos, damages, radius, owner, gfxMod, hit);
}
Example #4
0
int CLuaFile::ProjectileFind(lua_State *L)
{
    lua_getglobal(L, "pLUA");
    CLuaFile *pSelf = (CLuaFile *)lua_touserdata(L, -1);
    lua_Debug Frame;
    lua_getstack(L, 1, &Frame);
    lua_getinfo(L, "nlSf", &Frame);

    if (!lua_isnumber(L, 1) || !lua_isnumber(L, 2) || !lua_isnumber(L, 3) || !lua_isnumber(L, 4))
        return 0;

    vec2 Pos = vec2(lua_tonumber(L, 1), lua_tonumber(L, 2));

    int Max = clamp((int)lua_tointeger(L, 4), 1, 256);
    int Num = 0;

    for (CProjectile *pPrj = (CProjectile *)pSelf->m_pServer->m_World.FindFirst(0); pPrj; pPrj = (CProjectile *)pPrj->TypeNext())
    {
		if(distance(pPrj->GetPos((pSelf->m_pServer->Server()->Tick()-pPrj->GetStartTick())/(float)pSelf->m_pServer->Server()->TickSpeed()), Pos) < lua_tonumber(L, 3)+pPrj->m_ProximityRadius)
		{
            lua_pushinteger(L, pPrj->GetID());
			Num++;
			if(Num == Max)
				break;
		}
    }
    return Num;
}
Example #5
0
//------------------------------------------------------------------------
CProjectile *CWeaponSystem::DoSpawnAmmo(IEntityClass *pAmmoType, bool isRemote, const SAmmoParams *pAmmoParams)
{
	bool isServer=gEnv->bServer;
	bool isClient=gEnv->IsClient();

	if(pAmmoParams->serverSpawn && (!isServer || IsDemoPlayback()))
	{
		if(!pAmmoParams->predictSpawn || isRemote)
			return 0;
	}

	SEntitySpawnParams spawnParams;
	spawnParams.pClass = pAmmoType;
	spawnParams.sName = "ammo";
	spawnParams.nFlags = pAmmoParams->flags | ENTITY_FLAG_NO_PROXIMITY; // No proximity for this entity.

	IEntity *pEntity = gEnv->pEntitySystem->SpawnEntity(spawnParams);

	if(!pEntity)
	{
		GameWarning("Failed to spawn ammo '%s'! Entity creation failed...", pAmmoType->GetName());
		return 0;
	}

	CProjectile *pProjectile = GetProjectile(pEntity->GetId());

	if(pProjectile && !isServer && !isRemote && pAmmoParams->predictSpawn)
		pProjectile->GetGameObject()->RegisterAsPredicted();

	return pProjectile;
}
Example #6
0
void CDeflectorShield::ShootDeflectedEnergy(const CDeflectorShield::SDeflectedEnergy& energy)
{
	if (!m_pAmmoClass)
		return;
	CProjectile* pEnergyBlast = g_pGame->GetWeaponSystem()->SpawnAmmo(m_pAmmoClass, false);
	if (!pEnergyBlast)
		return;

	const Matrix34& worldTransform = GetEntity()->GetWorldTM();

	const float positionBias = 0.05f;

	const Vec3 worldReflectPos = worldTransform.TransformPoint(energy.m_localPosition);
	const Vec3 worldReflectDir = worldTransform.TransformVector(energy.m_localDirection);

	const Vec3 worldSpreadU = worldReflectDir.GetOrthogonal();
	const Vec3 worldSpreadV = worldReflectDir.Cross(worldSpreadU);

	const float spreadOffset = cry_random(0.0f, m_spread);
	
	const Vec3 position = worldReflectPos + worldReflectDir * positionBias;
	Vec3 direction = 
		worldReflectDir + 
		(worldSpreadU * cry_random(0.0f, m_spread)) + 
		(worldSpreadV * cry_random(0.0f, m_spread));
	direction.Normalize();

	CProjectile::SProjectileDesc projectileDesc(
		0, 0, 0, energy.m_damage, m_dropMinDistance, m_dropPerMeter, float(m_minDamage), m_hitTypeId,
		0, false);
	pEnergyBlast->SetParams(projectileDesc);
	pEnergyBlast->Launch(position, direction, Vec3(ZERO));
}
//-----------------------------------------------------------------------------
// Прорисовываем все объекты
//-----------------------------------------------------------------------------
void DrawAllProjectile(bool VertexOnlyPass, unsigned int ShadowMap)
{

	CProjectile *tmp = StartProjectile;
	while (tmp!=0)
	{
		CProjectile *tmp2 = tmp->Next;
		tmp->Draw(VertexOnlyPass, ShadowMap);
		tmp = tmp2;
	}

}
Example #8
0
int CLuaFile::ProjectileCreate(lua_State *L)
{
    lua_getglobal(L, "pLUA");
    CLuaFile *pSelf = (CLuaFile *)lua_touserdata(L, -1);
    lua_Debug Frame;
    lua_getstack(L, 1, &Frame);
    lua_getinfo(L, "nlSf", &Frame);

    if (!lua_isnumber(L, 1) || !lua_isnumber(L, 2))
        return 0;

    int ID = -1;
    vec2 Dir = vec2(0, -1);
    int Lifespan = 50;
    int Type = WEAPON_GUN;
    int Damage = 1;
    float Force = 0;
    bool Explosive = false;
    int ImpactSound = -1;


    if (lua_isnumber(L, 3) && lua_isnumber(L, 4))
        Dir = vec2(lua_tonumber(L, 3), lua_tonumber(L, 4));
    if (lua_isnumber(L, 5))
        ID = lua_tointeger(L, 5);
    if (lua_isnumber(L, 6))
        Lifespan = lua_tointeger(L, 6);
    if (lua_isnumber(L, 7))
        Type = lua_tointeger(L, 7);
    if (lua_isnumber(L, 8))
        Damage = lua_tointeger(L, 8);
    if (lua_isnumber(L, 9))
        Force = lua_tonumber(L, 9);
    if (lua_isboolean(L, 10))
        Explosive = lua_toboolean(L, 10);
    if (lua_isnumber(L, 11))
        ImpactSound = lua_tonumber(L, 11);

    int Weapon = Type;
    if (lua_isnumber(L, 7))
        Weapon = lua_tointeger(L, 7);

    CProjectile *pProj = new CProjectile(&pSelf->m_pServer->m_World, Type,
        ID,
        vec2(lua_tonumber(L, 1), lua_tonumber(L, 2)),
        Dir,
        Lifespan,
        Damage, Explosive, Force, ImpactSound, Weapon);

    CNetObj_Projectile p;
    pProj->FillInfo(&p);
    return 0;
}
//-----------------------------------------------------------------------------
// Проверяем все объекты, обновляем данные
//-----------------------------------------------------------------------------
void UpdateAllProjectile(float Time)
{
	CProjectile *tmp = StartProjectile;
	while (tmp!=0)
	{
		CProjectile *tmp2 = tmp->Next;
		// делаем обновление данных по объекту
		if (!tmp->Update(Time))
		{
			// если его нужно уничтожить - делаем это
			delete tmp; tmp = 0;
		}
		tmp = tmp2;
	}
}
Example #10
0
void CGround::CheckCol(CProjectileHandler* ph)
{
    Projectile_List::iterator psi;

    for (psi = ph->ps.begin(); psi != ph->ps.end(); ++psi) {
        CProjectile* p = *psi;
        if (p->checkCol) {
            if (GetHeight(p->pos.x, p->pos.z) > p->pos.y /* - p->radius*/) {
                // too many projectiles seem to hit the ground before hitting
                // so remove the radius till a better fix is done
                p->Collision();
            }
        }
    }
}
void CProjectileHandler::DrawProjectilesShadow(const ProjectileContainer& pc) {
	for (ProjectileContainer::render_iterator pci = pc.render_begin(); pci != pc.render_end(); ++pci) {
		CProjectile* p = *pci;

		if ((gu->spectatingFullView || loshandler->InLos(p, gu->myAllyTeam) ||
			(p->owner() && teamHandler->Ally(p->owner()->allyteam, gu->myAllyTeam)))) {

			if (p->s3domodel) {
				p->DrawUnitPart();
			} else if (p->castShadow) {
				p->Draw();
			}
		}
	}
}
void CProjectileHandler::CheckGroundCollisions(ProjectileContainer& pc) {
	ProjectileContainer::iterator pci;

	for (pci = pc.begin(); pci != pc.end(); ++pci) {
		CProjectile* p = *pci;

		if (p->checkCol) {
			// too many projectiles seem to impact the ground before
			// actually hitting so don't subtract the projectile radius
			if (ground->GetHeight(p->pos.x, p->pos.z) > p->pos.y /* - p->radius*/) {
				p->Collision();
			}
		}
	}
}
Example #13
0
//------------------------------------------------------------------------
CProjectile *CWeaponSystem::SpawnAmmo(IEntityClass* pAmmoType, bool isRemote)
{
	TAmmoTypeParams::const_iterator it = m_ammoparams.find(pAmmoType);
	if (it == m_ammoparams.end())
	{
		GameWarning("Failed to spawn ammo '%s'! Unknown class or entity class not registered...", pAmmoType?pAmmoType->GetName():"");
		return 0;
	}

	const SAmmoParams* pAmmoParams = it->second.params;
	if (!m_config.empty())
	{
		std::map<string, const SAmmoParams *>::const_iterator cit=it->second.configurations.find(m_config);
		if (cit != it->second.configurations.end())
			pAmmoParams=cit->second;
		else
			pAmmoParams=it->second.params;
	}

	bool isServer=gEnv->bServer;
	bool isClient=gEnv->bClient;

	if ( pAmmoParams->serverSpawn && (!isServer || IsDemoPlayback()) )
	{
		if (!pAmmoParams->predictSpawn || isRemote)
			return 0;
	}

	SEntitySpawnParams spawnParams;
	spawnParams.pClass = pAmmoType;
	spawnParams.sName = "ammo";
	spawnParams.nFlags = pAmmoParams->flags | ENTITY_FLAG_NO_PROXIMITY; // No proximity for this entity.

	IEntity *pEntity = gEnv->pEntitySystem->SpawnEntity(spawnParams);
	if (!pEntity)
	{
		GameWarning("Failed to spawn ammo '%s'! Entity creation failed...", pAmmoType->GetName());
		return 0;
	}

	CProjectile *pProjectile = GetProjectile(pEntity->GetId());

	if (pProjectile && !isServer && !isRemote && pAmmoParams->predictSpawn)
		pProjectile->GetGameObject()->RegisterAsPredicted();
	
	return pProjectile;
}
Example #14
0
CProjectile mod::makeProjectile(CGameWorld *pGameWorld, int Type, int Owner,CPlayer* sender,vec2 Pos, vec2 Dir, int Span, int Damage,
                                bool Explosive, float Force, int SoundImpact, int Weapon, IServer* server) {
    CProjectile *pProj = new CProjectile(pGameWorld, Type,
                                         Owner,
                                         Pos,
                                         Dir,
                                         Span,
                                         Damage, Explosive, Force, SoundImpact, Weapon);

    // pack the Projectile and send it to the client Directly
    CNetObj_Projectile p;
    pProj->FillInfo(&p);
    CMsgPacker Msg(NETMSGTYPE_SV_EXTRAPROJECTILE);
    Msg.AddInt(1);
    for(unsigned i = 0; i < sizeof(CNetObj_Projectile)/sizeof(int); i++)
        Msg.AddInt(((int *)&p)[i]);
    server->SendMsg(&Msg, 0, sender->GetCID());
}
Example #15
0
int CLuaFile::ProjectileGetSoundImpact(lua_State *L)
{
    lua_getglobal(L, "pLUA");
    CLuaFile *pSelf = (CLuaFile *)lua_touserdata(L, -1);
    lua_Debug Frame;
    lua_getstack(L, 1, &Frame);
    lua_getinfo(L, "nlSf", &Frame);

    if (!lua_isnumber(L, 1))
        return 0;

    CProjectile *pPrj = (CProjectile *)pSelf->m_pServer->m_World.GetEntityByID(lua_tointeger(L, 1));
    if (pPrj)
    {
        lua_pushinteger(L, pPrj->GetSoundImpact());
        return 1;
    }
    return 0;
}
Example #16
0
//------------------------------------------------------------------------
bool CGunTurret::IsTACBullet(IEntity *pTarget) const
{
	const static IEntityClass *pTacClass    = gEnv->pEntitySystem->GetClassRegistry()->FindClass("tacprojectile");
	const static IEntityClass *pTacGunClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass("tacgunprojectile");

	if(pTarget->GetClass() != pTacClass && pTarget->GetClass() != pTacGunClass)
		return false;

	CProjectile *p = g_pGame->GetWeaponSystem()->GetProjectile(pTarget->GetId());

	if(!p)
		return false;

	IActor *pActor = GetActor(p->GetOwnerId());

	if(!pActor || !IsTargetHostile(pActor))
		return false;

	return true;
}
Example #17
0
int CLuaFile::ProjectileGetPos(lua_State *L)
{
    lua_getglobal(L, "pLUA");
    CLuaFile *pSelf = (CLuaFile *)lua_touserdata(L, -1);
    lua_Debug Frame;
    lua_getstack(L, 1, &Frame);
    lua_getinfo(L, "nlSf", &Frame);

    if (!lua_isnumber(L, 1))
        return 0;

    CProjectile *pPrj = (CProjectile *)pSelf->m_pServer->m_World.GetEntityByID(lua_tointeger(L, 1));
    if (pPrj)
    {
        vec2 Pos = pPrj->GetPos((pSelf->m_pServer->Server()->Tick()-pPrj->GetStartTick())/(float)pSelf->m_pServer->Server()->TickSpeed());
        lua_pushnumber(L, Pos.x);
        lua_pushnumber(L, Pos.y);
        return 2;
    }
    return 0;
}
Example #18
0
void CProjectileHandler::CheckGroundCollisions(ProjectileContainer& pc)
{
	for (size_t i = 0; i < pc.size(); ++i) {
		CProjectile* p = pc[i];

		if (!p->checkCol)
			continue;

		// NOTE:
		//   if <p> is a MissileProjectile and does not have
		//   selfExplode set, tbis will cause it to never be
		//   removed (!)
		if (p->GetCollisionFlags() & Collision::NOGROUND)
			continue;

		// don't collide with ground yet if last update scheduled a bounce
		if (p->weapon && static_cast<const CWeaponProjectile*>(p)->HasScheduledBounce())
			continue;

		// NOTE:
		//   don't add p->radius to groundHeight, or most (esp. modelled)
		//   projectiles will collide with the ground one or more frames
		//   too early
		const float groundHeight = CGround::GetHeightReal(p->pos.x, p->pos.z);

		const bool belowGround = (p->pos.y < groundHeight);
		const bool insideWater = (p->pos.y <= 0.0f && !belowGround);
		const bool ignoreWater = p->ignoreWater;

		if (belowGround || (insideWater && !ignoreWater)) {
			// if position has dropped below terrain or into water
			// where we can not live, adjust it and explode us now
			// (if the projectile does not set deleteMe = true, it
			// will keep hugging the terrain)
			p->SetPosition(p->pos * XZVector + UpVector * groundHeight * belowGround);
			p->Collision();
		}
	}
}
Example #19
0
void CSingularity::Suck()
{
	float Len;
	
	CCharacter *p = (CCharacter *)GameServer()->m_World.FindFirst(CGameWorld::ENTTYPE_CHARACTER);
	for(; p; p = (CCharacter *)p->TypeNext())
	{
		if(!p || !p->IsAlive())
			continue;	
		
		Len = distance(m_Pos, p->m_Pos);
		if(Len < m_KillRange)
		{
			if(m_Owner > -1)
				p->Die(m_Owner,WEAPON_RIFLE);
			else
				p->Die(p->GetPlayer()->GetCID(),WEAPON_WORLD);
		}
		else if(Len < m_Range)
			p->SetVel(p->GetVel() + (normalize(m_Pos - p->m_Pos) * exp((m_Range - Len)/(m_Range/2.5f))));
	}

	// save CPU for projectiles
	if(m_SkipTick)
		return;
	
	CProjectile *s = (CProjectile *)GameServer()->m_World.FindFirst(CGameWorld::ENTTYPE_PROJECTILE);
	for(; s; s = (CProjectile *)s->TypeNext())
	{
		if(!s)
			continue;
		
		Len = distance(m_Pos, s->m_Pos);
		if(Len < m_Range*1.5)
			s->SetVel(s->GetVel() + ((normalize(m_Pos - s->m_Pos) * exp((m_Range*1.5 - Len)/(m_Range*0.6f)))*0.04f));
	}
}
void CProjectileHandler::UpdateProjectileContainer(ProjectileContainer& pc, bool synced) {
	ProjectileContainer::iterator pci = pc.begin();

	while (pci != pc.end()) {
		CProjectile* p = *pci;

		if (p->deleteMe) {
			if (p->synced) {
				assert(synced);
				if(p->weapon || p->piece) {

					//! iterator is always valid
					const ProjectileMap::iterator it = syncedProjectileIDs.find(p->id);
					const ProjectileMapPair& pp = it->second;

					eventHandler.ProjectileDestroyed(pp.first, pp.second);
					syncedProjectileIDs.erase(it);

					if (p->id != 0) {
						freeIDs.push_back(p->id);
					}
				}
				//! push_back this projectile for deletion
				pci = pc.erase_delete_synced(pci);
			}
			else {
				assert(!synced);
				pci = pc.erase_delete(pci);
			}
		} else {
			p->Update();
			GML_GET_TICKS(p->lastProjUpdate);
			++pci;
		}
	}
}
void CProjectileHandler::DrawProjectilesMiniMap(const ProjectileContainer& pc) {
	if (pc.render_size() > 0) {
		CVertexArray* lines = GetVertexArray();
		CVertexArray* points = GetVertexArray();

		lines->Initialize();
		lines->EnlargeArrays(pc.render_size() * 2, 0, VA_SIZE_C);

		points->Initialize();
		points->EnlargeArrays(pc.render_size(), 0, VA_SIZE_C);

		for (ProjectileContainer::render_iterator pci = pc.render_begin(); pci != pc.render_end(); ++pci) {
			CProjectile* p = *pci;

			if ((p->owner() && (p->owner()->allyteam == gu->myAllyTeam)) ||
				gu->spectatingFullView || loshandler->InLos(p, gu->myAllyTeam)) {
				p->DrawOnMinimap(*lines, *points);
			}
		}

		lines->DrawArrayC(GL_LINES);
		points->DrawArrayC(GL_POINTS);
	}
}
void CProjectileHandler::DrawProjectiles(const ProjectileContainer& pc, bool drawReflection, bool drawRefraction) {
	for (ProjectileContainer::render_iterator pci = pc.render_begin(); pci != pc.render_end(); ++pci) {
		CProjectile* pro = *pci;

		pro->UpdateDrawPos();

		if (camera->InView(pro->pos, pro->drawRadius) && (gu->spectatingFullView || loshandler->InLos(pro, gu->myAllyTeam) ||
			(pro->owner() && teamHandler->Ally(pro->owner()->allyteam, gu->myAllyTeam)))) {

			CUnit* owner = pro->owner();
			bool stunned = owner? owner->stunned: false;

			if (owner && stunned && dynamic_cast<CShieldPartProjectile*>(pro)) {
				// if the unit that fired this projectile is stunned and the projectile
				// forms part of a shield (ie., the unit has a CPlasmaRepulser weapon but
				// cannot fire it), prevent the projectile (shield segment) from being drawn
				//
				// also prevents shields being drawn at unit's pre-pickup position
				// (since CPlasmaRepulser::Update() is responsible for updating
				// CShieldPartProjectile::centerPos) if the unit is in a non-fireplatform
				// transport
				continue;
			}

			if (drawReflection) {
				if (pro->pos.y < -pro->drawRadius)
					continue;

				float dif = pro->pos.y - camera->pos.y;
				float3 zeroPos = camera->pos * (pro->pos.y / dif) + pro->pos * (-camera->pos.y / dif);

				if (ground->GetApproximateHeight(zeroPos.x, zeroPos.z) > 3 + 0.5f * pro->drawRadius)
					continue;
			}

			if (drawRefraction && pro->pos.y > pro->drawRadius)
				continue;

			if (pro->s3domodel) {
				if (pro->s3domodel->type == MODELTYPE_S3O) {
					unitDrawer->QueS3ODraw(pro, pro->s3domodel->textureType);
				} else {
					pro->DrawUnitPart();
				}
			}

			pro->tempdist = pro->pos.dot(camera->forward);
			distset.insert(pro);
		}
	}
}
Example #23
0
void CLaser::Fire()
{
	//Get matrix for current player location and forward vector
	tlx::CMatrix4x4 matrix;
	GetParent()->GetMatrix(matrix.m);

	//Create forward vector (z axis)
	CVector3 direction(matrix.m[8], matrix.m[9], matrix.m[10]);

	//Get position from matrix
	//Since we've already got the matrix it's slightly more efficient than calling GetParent()->GetCenterPoint()
	CVector3 pos(matrix.m[12], OFF_SCREEN_Y, matrix.m[14]);

	//Calculate the rotation of the parent entity, just so it only needs to be calculated once
	float rotation = GetParent()->GetRotation();

	//Makes the space between invisible bullets 2.0f instead of 1.0f
	direction *= 2.0f;

	for (int i = 0; i < 70; i++)
	{
		CProjectile* bullet = new CProjectile();

		bullet->SetPosition(pos);
		bullet->SetRotation(rotation);

		bullet->SetDamage(GetDamage());
		bullet->SetSpeed(GetProjSpeed());
		bullet->SetParent(GetParent());
		bullet->SetExplodeable(false);

		GetBulletList()->push_back(unique_ptr<CProjectile>(bullet));

		//Increment position of next bullet
		pos += direction;
	}

}
Example #24
0
//bool IGameController::OnEntity(int Index, vec2 Pos)
bool IGameController::OnEntity(int Index, vec2 Pos, int Layer, int Flags, int Number)
{
	if (Index < 0)
		return false;

	int Type = -1;
	int SubType = 0;

	int x,y;
	x=(Pos.x-16.0f)/32.0f;
	y=(Pos.y-16.0f)/32.0f;
	int sides[8];
	sides[0]=GameServer()->Collision()->Entity(x,y+1, Layer);
	sides[1]=GameServer()->Collision()->Entity(x+1,y+1, Layer);
	sides[2]=GameServer()->Collision()->Entity(x+1,y, Layer);
	sides[3]=GameServer()->Collision()->Entity(x+1,y-1, Layer);
	sides[4]=GameServer()->Collision()->Entity(x,y-1, Layer);
	sides[5]=GameServer()->Collision()->Entity(x-1,y-1, Layer);
	sides[6]=GameServer()->Collision()->Entity(x-1,y, Layer);
	sides[7]=GameServer()->Collision()->Entity(x-1,y+1, Layer);


	if(Index == ENTITY_SPAWN)
		m_aaSpawnPoints[0][m_aNumSpawnPoints[0]++] = Pos;
	else if(Index == ENTITY_SPAWN_RED)
		m_aaSpawnPoints[1][m_aNumSpawnPoints[1]++] = Pos;
	else if(Index == ENTITY_SPAWN_BLUE)
		m_aaSpawnPoints[2][m_aNumSpawnPoints[2]++] = Pos;

	else if(Index == ENTITY_DOOR)
	{
		for(int i = 0; i < 8;i++)
		{
			if (sides[i] >= ENTITY_LASER_SHORT && sides[i] <= ENTITY_LASER_LONG)
			{
				new CDoor
				(
					&GameServer()->m_World, //GameWorld
					Pos, //Pos
					pi / 4 * i, //Rotation
					32 * 3 + 32 *(sides[i] - ENTITY_LASER_SHORT) * 3, //Length
					Number //Number
				);
			}
		}
	}
	else if(Index == ENTITY_CRAZY_SHOTGUN_EX)
	{
		int Dir;
		if(!Flags)
			Dir = 0;
		else if(Flags == ROTATION_90)
			Dir = 1;
		else if(Flags == ROTATION_180)
			Dir = 2;
		else
			Dir = 3;
		float Deg = Dir * (pi / 2);
		CProjectile *bullet = new CProjectile
			(
			&GameServer()->m_World,
			WEAPON_SHOTGUN, //Type
			-1, //Owner
			Pos, //Pos
			vec2(sin(Deg), cos(Deg)), //Dir
			-2, //Span
			true, //Freeze
			true, //Explosive
			0, //Force
			(g_Config.m_SvShotgunBulletSound)?SOUND_GRENADE_EXPLODE:-1,//SoundImpact
			WEAPON_SHOTGUN,//Weapon
			Layer,
			Number
			);
		bullet->SetBouncing(2 - (Dir % 2));
	}
	else if(Index == ENTITY_CRAZY_SHOTGUN)
	{
		int Dir;
		if(!Flags)
			Dir=0;
		else if(Flags == (TILEFLAG_ROTATE))
			Dir = 1;
		else if(Flags == (TILEFLAG_VFLIP|TILEFLAG_HFLIP))
			Dir = 2;
		else
			Dir = 3;
		float Deg = Dir * ( pi / 2);
		CProjectile *bullet = new CProjectile
			(
			&GameServer()->m_World,
			WEAPON_SHOTGUN, //Type
			-1, //Owner
			Pos, //Pos
			vec2(sin(Deg), cos(Deg)), //Dir
			-2, //Span
			true, //Freeze
			false, //Explosive
			0,
			SOUND_GRENADE_EXPLODE,
			WEAPON_SHOTGUN, //Weapon
			Layer,
			Number
			);
		bullet->SetBouncing(2 - (Dir % 2));
	}

	if(Index == ENTITY_ARMOR_1)
		Type = POWERUP_ARMOR;
	else if(Index == ENTITY_HEALTH_1)
		Type = POWERUP_HEALTH;
	else if(Index == ENTITY_WEAPON_SHOTGUN)
	{
		Type = POWERUP_WEAPON;
		SubType = WEAPON_SHOTGUN;
	}
	else if(Index == ENTITY_WEAPON_GRENADE)
	{
		Type = POWERUP_WEAPON;
		SubType = WEAPON_GRENADE;
	}
	else if(Index == ENTITY_WEAPON_RIFLE)
	{
		Type = POWERUP_WEAPON;
		SubType = WEAPON_RIFLE;
	}
	//else if(Index == ENTITY_POWERUP_NINJA && g_Config.m_SvPowerups)
	else if(Index == ENTITY_POWERUP_NINJA)
	{
		Type = POWERUP_NINJA;
		SubType = WEAPON_NINJA;
	}
	else if(Index >= ENTITY_LASER_FAST_CW && Index <= ENTITY_LASER_FAST_CCW)
	{
		int sides2[8];
		sides2[0]=GameServer()->Collision()->Entity(x, y + 2, Layer);
		sides2[1]=GameServer()->Collision()->Entity(x + 2, y + 2, Layer);
		sides2[2]=GameServer()->Collision()->Entity(x + 2, y, Layer);
		sides2[3]=GameServer()->Collision()->Entity(x + 2, y - 2, Layer);
		sides2[4]=GameServer()->Collision()->Entity(x,y - 2, Layer);
		sides2[5]=GameServer()->Collision()->Entity(x - 2, y - 2, Layer);
		sides2[6]=GameServer()->Collision()->Entity(x - 2, y, Layer);
		sides2[7]=GameServer()->Collision()->Entity(x - 2, y + 2, Layer);

		float AngularSpeed = 0.0;
		int Ind=Index-ENTITY_LASER_STOP;
		int M;
		if( Ind < 0)
		{
			Ind = -Ind;
			M = 1;
		}
		else if(Ind == 0)
			M = 0;
		else
			M = -1;


		if(Ind == 0)
			AngularSpeed = 0.0f;
		else if(Ind == 1)
			AngularSpeed = pi / 360;
		else if(Ind == 2)
			AngularSpeed = pi / 180;
		else if(Ind == 3)
			AngularSpeed = pi / 90;
		AngularSpeed *= M;

		for(int i=0; i<8;i++)
		{
			if(sides[i] >= ENTITY_LASER_SHORT && sides[i] <= ENTITY_LASER_LONG)
			{
				CLight *Lgt = new CLight(&GameServer()->m_World, Pos, pi / 4 * i, 32 * 3 + 32 * (sides[i] - ENTITY_LASER_SHORT) * 3, Layer, Number);
				Lgt->m_AngularSpeed = AngularSpeed;
				if(sides2[i] >= ENTITY_LASER_C_SLOW && sides2[i] <= ENTITY_LASER_C_FAST)
				{
					Lgt->m_Speed = 1 + (sides2[i] - ENTITY_LASER_C_SLOW) * 2;
					Lgt->m_CurveLength = Lgt->m_Length;
				}
				else if(sides2[i] >= ENTITY_LASER_O_SLOW && sides2[i] <= ENTITY_LASER_O_FAST)
				{
					Lgt->m_Speed = 1 + (sides2[i] - ENTITY_LASER_O_SLOW) * 2;
					Lgt->m_CurveLength = 0;
				}
				else
					Lgt->m_CurveLength = Lgt->m_Length;
			}
		}

	}
	else if(Index >= ENTITY_DRAGGER_WEAK && Index <= ENTITY_DRAGGER_STRONG)
	{
		new CDraggerTeam(&GameServer()->m_World, Pos, Index - ENTITY_DRAGGER_WEAK + 1, false, Layer, Number);
	}
	else if(Index >= ENTITY_DRAGGER_WEAK_NW && Index <= ENTITY_DRAGGER_STRONG_NW)
	{
		new CDraggerTeam(&GameServer()->m_World, Pos, Index - ENTITY_DRAGGER_WEAK_NW + 1, true, Layer, Number);
	}
	else if(Index == ENTITY_PLASMAE)
	{
		new CGun(&GameServer()->m_World, Pos, false, true, Layer, Number);
	}
	else if(Index == ENTITY_PLASMAF)
	{
		new CGun(&GameServer()->m_World, Pos, true, false, Layer, Number);
	}
	else if(Index == ENTITY_PLASMA)
	{
		new CGun(&GameServer()->m_World, Pos, true, true, Layer, Number);
	}
	else if(Index == ENTITY_PLASMAU)
	{
		new CGun(&GameServer()->m_World, Pos, false, false, Layer, Number);
	}
	
	if(Type != -1)
	{
		//CPickup *pPickup = new CPickup(&GameServer()->m_World, Type, SubType);
		CPickup *pPickup = new CPickup(&GameServer()->m_World, Type, SubType, Layer, Number);
		pPickup->m_Pos = Pos;
		return true;
	}

	return false;
}
Example #25
0
void CCharacter::FireWeapon()
{
	if(m_ReloadTimer != 0)
		return;

	DoWeaponSwitch();
	vec2 Direction = normalize(vec2(m_LatestInput.m_TargetX, m_LatestInput.m_TargetY));

	bool FullAuto = false;
	if(m_ActiveWeapon == WEAPON_GRENADE || m_ActiveWeapon == WEAPON_SHOTGUN || m_ActiveWeapon == WEAPON_LASER)
		FullAuto = true;


	// check if we gonna fire
	bool WillFire = false;
	if(CountInput(m_LatestPrevInput.m_Fire, m_LatestInput.m_Fire).m_Presses)
		WillFire = true;

	if(FullAuto && (m_LatestInput.m_Fire&1) && m_aWeapons[m_ActiveWeapon].m_Ammo)
		WillFire = true;

	if(!WillFire)
		return;

	// check for ammo
	if(!m_aWeapons[m_ActiveWeapon].m_Ammo)
	{
		// 125ms is a magical limit of how fast a human can click
		m_ReloadTimer = 125 * Server()->TickSpeed() / 1000;
		GameServer()->CreateSound(m_Pos, SOUND_WEAPON_NOAMMO);
		return;
	}

	vec2 ProjStartPos = m_Pos+Direction*m_ProximityRadius*0.75f;

	switch(m_ActiveWeapon)
	{
		case WEAPON_HAMMER:
		{
			// reset objects Hit
			m_NumObjectsHit = 0;
			GameServer()->CreateSound(m_Pos, SOUND_HAMMER_FIRE);

			CCharacter *apEnts[MAX_CLIENTS];
			int Hits = 0;
			int Num = GameServer()->m_World.FindEntities(ProjStartPos, m_ProximityRadius*0.5f, (CEntity**)apEnts,
														MAX_CLIENTS, CGameWorld::ENTTYPE_CHARACTER);

			for (int i = 0; i < Num; ++i)
			{
				CCharacter *pTarget = apEnts[i];

				if ((pTarget == this) || GameServer()->Collision()->IntersectLine(ProjStartPos, pTarget->m_Pos, NULL, NULL))
					continue;

				// set his velocity to fast upward (for now)
				if(length(pTarget->m_Pos-ProjStartPos) > 0.0f)
					GameServer()->CreateHammerHit(pTarget->m_Pos-normalize(pTarget->m_Pos-ProjStartPos)*m_ProximityRadius*0.5f);
				else
					GameServer()->CreateHammerHit(ProjStartPos);

				vec2 Dir;
				if (length(pTarget->m_Pos - m_Pos) > 0.0f)
					Dir = normalize(pTarget->m_Pos - m_Pos);
				else
					Dir = vec2(0.f, -1.f);

				pTarget->TakeDamage(vec2(0.f, -1.f) + normalize(Dir + vec2(0.f, -1.1f)) * 10.0f, g_pData->m_Weapons.m_Hammer.m_pBase->m_Damage,
					m_pPlayer->GetCID(), m_ActiveWeapon);
				Hits++;
			}

			// if we Hit anything, we have to wait for the reload
			if(Hits)
				m_ReloadTimer = Server()->TickSpeed()/3;

		} break;

		case WEAPON_GUN:
		{
			CProjectile *pProj = new CProjectile(GameWorld(), WEAPON_GUN,
				m_pPlayer->GetCID(),
				ProjStartPos,
				Direction,
				(int)(Server()->TickSpeed()*GameServer()->Tuning()->m_GunLifetime),
				1, 0, 0, -1, WEAPON_GUN);

			// pack the Projectile and send it to the client Directly
			CNetObj_Projectile p;
			pProj->FillInfo(&p);

			CMsgPacker Msg(NETMSGTYPE_SV_EXTRAPROJECTILE);
			Msg.AddInt(1);
			for(unsigned i = 0; i < sizeof(CNetObj_Projectile)/sizeof(int); i++)
				Msg.AddInt(((int *)&p)[i]);

			Server()->SendMsg(&Msg, 0, m_pPlayer->GetCID());

			GameServer()->CreateSound(m_Pos, SOUND_GUN_FIRE);
		} break;

		case WEAPON_SHOTGUN:
		{
			int ShotSpread = 2;

			CMsgPacker Msg(NETMSGTYPE_SV_EXTRAPROJECTILE);
			Msg.AddInt(ShotSpread*2+1);

			for(int i = -ShotSpread; i <= ShotSpread; ++i)
			{
				float Spreading[] = {-0.185f, -0.070f, 0, 0.070f, 0.185f};
				float a = GetAngle(Direction);
				a += Spreading[i+2];
				float v = 1-(absolute(i)/(float)ShotSpread);
				float Speed = mix((float)GameServer()->Tuning()->m_ShotgunSpeeddiff, 1.0f, v);
				CProjectile *pProj = new CProjectile(GameWorld(), WEAPON_SHOTGUN,
					m_pPlayer->GetCID(),
					ProjStartPos,
					vec2(cosf(a), sinf(a))*Speed,
					(int)(Server()->TickSpeed()*GameServer()->Tuning()->m_ShotgunLifetime),
					1, 0, 0, -1, WEAPON_SHOTGUN);

				// pack the Projectile and send it to the client Directly
				CNetObj_Projectile p;
				pProj->FillInfo(&p);

				for(unsigned i = 0; i < sizeof(CNetObj_Projectile)/sizeof(int); i++)
					Msg.AddInt(((int *)&p)[i]);
			}

			Server()->SendMsg(&Msg, 0,m_pPlayer->GetCID());

			GameServer()->CreateSound(m_Pos, SOUND_SHOTGUN_FIRE);
		} break;

		case WEAPON_GRENADE:
		{
			CProjectile *pProj = new CProjectile(GameWorld(), WEAPON_GRENADE,
				m_pPlayer->GetCID(),
				ProjStartPos,
				Direction,
				(int)(Server()->TickSpeed()*GameServer()->Tuning()->m_GrenadeLifetime),
				1, true, 0, SOUND_GRENADE_EXPLODE, WEAPON_GRENADE);

			// pack the Projectile and send it to the client Directly
			CNetObj_Projectile p;
			pProj->FillInfo(&p);

			CMsgPacker Msg(NETMSGTYPE_SV_EXTRAPROJECTILE);
			Msg.AddInt(1);
			for(unsigned i = 0; i < sizeof(CNetObj_Projectile)/sizeof(int); i++)
				Msg.AddInt(((int *)&p)[i]);
			Server()->SendMsg(&Msg, 0, m_pPlayer->GetCID());

			GameServer()->CreateSound(m_Pos, SOUND_GRENADE_FIRE);
		} break;

		case WEAPON_LASER:
		{
			new CLaser(GameWorld(), m_Pos, Direction, GameServer()->Tuning()->m_LaserReach, m_pPlayer->GetCID());
			GameServer()->CreateSound(m_Pos, SOUND_LASER_FIRE);
		} break;

		case WEAPON_NINJA:
		{
			// reset Hit objects
			m_NumObjectsHit = 0;

			m_Ninja.m_ActivationDir = Direction;
			m_Ninja.m_CurrentMoveTime = g_pData->m_Weapons.m_Ninja.m_Movetime * Server()->TickSpeed() / 1000;
			m_Ninja.m_OldVelAmount = length(m_Core.m_Vel);

			GameServer()->CreateSound(m_Pos, SOUND_NINJA_FIRE);
		} break;

	}

	m_AttackTick = Server()->Tick();

	if(m_aWeapons[m_ActiveWeapon].m_Ammo > 0) // -1 == unlimited
		m_aWeapons[m_ActiveWeapon].m_Ammo--;

	if(!m_ReloadTimer)
		m_ReloadTimer = g_pData->m_Weapons.m_aId[m_ActiveWeapon].m_Firedelay * Server()->TickSpeed() / 1000;
}
Example #26
0
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 CProjectileDrawer::DrawProjectilesMiniMap()
{
	GML_RECMUTEX_LOCK(proj); // DrawProjectilesMiniMap

	typedef std::set<CProjectile*> ProjectileSet;
	typedef std::set<CProjectile*>::const_iterator ProjectileSetIt;
	typedef std::map<int, ProjectileSet> ProjectileBin;
	typedef std::map<int, ProjectileSet>::const_iterator ProjectileBinIt;

	for (int modelType = MODELTYPE_3DO; modelType < MODELTYPE_OTHER; modelType++) {
		const ProjectileBin& projectileBin = modelRenderers[modelType]->GetProjectileBin();

		if (!projectileBin.empty()) {

			for (ProjectileBinIt binIt = projectileBin.begin(); binIt != projectileBin.end(); ++binIt) {
				CVertexArray* lines = GetVertexArray();
				CVertexArray* points = GetVertexArray();

				lines->Initialize();
				lines->EnlargeArrays((binIt->second).size() * 2, 0, VA_SIZE_C);
				points->Initialize();
				points->EnlargeArrays((binIt->second).size(), 0, VA_SIZE_C);

				for (ProjectileSetIt setIt = (binIt->second).begin(); setIt != (binIt->second).end(); ++setIt) {
					CProjectile* p = *setIt;

					CUnit *owner = p->owner();
					if ((owner && (owner->allyteam == gu->myAllyTeam)) ||
						gu->spectatingFullView || loshandler->InLos(p, gu->myAllyTeam)) {
							p->DrawOnMinimap(*lines, *points);
					}
				}

				lines->DrawArrayC(GL_LINES);
				points->DrawArrayC(GL_POINTS);
			}

		}
	}

	if (!renderProjectiles.empty()) {
		CVertexArray* lines = GetVertexArray();
		CVertexArray* points = GetVertexArray();

		lines->Initialize();
		lines->EnlargeArrays(renderProjectiles.size() * 2, 0, VA_SIZE_C);

		points->Initialize();
		points->EnlargeArrays(renderProjectiles.size(), 0, VA_SIZE_C);

		for (std::set<CProjectile*>::iterator it = renderProjectiles.begin(); it != renderProjectiles.end(); ++it) {
			CProjectile* p = *it;

			const CUnit* owner = p->owner();
			if ((owner && (owner->allyteam == gu->myAllyTeam)) ||
				gu->spectatingFullView || loshandler->InLos(p, gu->myAllyTeam)) {
				p->DrawOnMinimap(*lines, *points);
			}
		}

		lines->DrawArrayC(GL_LINES);
		points->DrawArrayC(GL_POINTS);
	}
}
Example #28
0
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 CProjectile::HandleTouch(HOBJECT hObj)
{
	if (m_bObjectRemoved) return;

	// Don't process any touches until this has been cleared...

	if (m_bProcessInvImpact) return;

	 // Let it get out of our bounding box...

	if (hObj == m_hFiredFrom) return;

	CCharacterHitBox* pHitBox = LTNULL;

	// If we've hit a character (or body), let its hit box take control...

	if (IsCharacter(hObj))
	{
       CCharacter* pChar = (CCharacter*)g_pLTServer->HandleToObject(hObj);
		if (pChar)
		{
			hObj = pChar->GetHitBox();
		}
	}
	else if (IsBody(hObj))
	{
	    Body* pBody = (Body*)g_pLTServer->HandleToObject(hObj);
		if (pBody)
		{
			hObj = pBody->GetHitBox();
		}
	}


	if (IsCharacterHitBox(hObj))
	{
        pHitBox = (CCharacterHitBox*)g_pLTServer->HandleToObject(hObj);
		if (!pHitBox) return;

		if (pHitBox->GetModelObject() == m_hFiredFrom) return;
	}


	// Don't hit our own type of projectiles (for multi-projectile weapons
	// and projectiles that stick to objects)...

	if (IsKindOf(hObj, m_hObject))
	{
        CProjectile* pObj = (CProjectile*)g_pLTServer->HandleToObject(hObj);
		if (pObj)
		{
			if (pObj->GetFiredFrom() == m_hFiredFrom)
			{
				return;
			}
		}
	}



	// See if we want to impact on this object...

    uint32 dwUsrFlags = g_pLTServer->GetObjectUserFlags(hObj);
	if (dwUsrFlags & USRFLG_IGNORE_PROJECTILES) return;

    LTBOOL bIsWorld = IsMainWorld(hObj);


	// Don't impact on non-solid objects...unless it is a CharacterHitBox
	// object...

    uint32 dwFlags = g_pLTServer->GetObjectFlags(hObj);
	if (!bIsWorld && !(dwFlags & FLAG_SOLID))
	{
		if (pHitBox)
		{
			// See if we really impacted on the box...

			if (pHitBox->DidProjectileImpact(this))
			{
				// This is the object that we really hit...

				hObj = pHitBox->GetModelObject();
			}
			else
			{
				return;
			}
		}
		else if (!(dwFlags & FLAG_RAYHIT))
		{
			// If we have ray hit set to true, projectiles should
			// impact on us too...

			return;
		}
	}


	// See if we hit the sky...

	if (bIsWorld || (OT_WORLDMODEL == g_pLTServer->GetObjectType(hObj)))
	{
		CollisionInfo info;
        g_pLTServer->GetLastCollision(&info);

		SurfaceType eType = GetSurfaceType(info);

		if (eType == ST_SKY)
		{
			RemoveObject();
			return;
		}
		else if (eType == ST_INVISIBLE)
		{
			// Update 1.002 [KLS] - If multiplayer and we hit an invisible
			// surface, just treat it like a normal surface...
			if (!IsMultiplayerGame())
			{
				m_bProcessInvImpact = LTTRUE;

				g_pLTServer->GetObjectPos(m_hObject, &m_vInvisNewPos);
				g_pLTServer->GetVelocity(m_hObject, &m_vInvisVel);
				m_vInvisNewPos += (m_vInvisVel * g_pLTServer->GetFrameTime());

				// Make sure this new position is inside the world...else
				// just blow up...

				if (LT_INSIDE == g_pLTServer->Common()->GetPointStatus(&m_vInvisNewPos))
				{
					return;
				}
			}
		}
	}


	HandleImpact(hObj);
}
Example #30
0
//------------------------------------------------------------------------
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);
}