Exemple #1
0
void CCannon::FireImpl(const bool scriptCall)
{
	float3 diff = currentTargetPos - weaponMuzzlePos;
	float3 dir = (diff.SqLength() > 4.0f) ? GetWantedDir(diff) : diff; // prevent vertical aim when emit-sfx firing the weapon

	dir += (gsRNG.NextVector() * SprayAngleExperience() + SalvoErrorExperience());
	dir.SafeNormalize();

	int ttl = 0;
	const float sqSpeed2D = dir.SqLength2D() * projectileSpeed * projectileSpeed;
	const int predict = math::ceil((sqSpeed2D == 0.0f) ?
		(-2.0f * projectileSpeed * dir.y / gravity):
		math::sqrt(diff.SqLength2D() / sqSpeed2D));

	if (weaponDef->flighttime > 0) {
		ttl = weaponDef->flighttime;
	} else if (weaponDef->selfExplode) {
		ttl = (predict + gsRNG.NextFloat() * 2.5f - 0.5f);
	} else if ((weaponDef->groundBounce || weaponDef->waterBounce) && weaponDef->numBounce > 0) {
		ttl = (predict * (1 + weaponDef->numBounce * weaponDef->bounceRebound));
	} else {
		ttl = predict * 2;
	}

	ProjectileParams params = GetProjectileParams();
	params.pos = weaponMuzzlePos;
	params.end = currentTargetPos;
	params.speed = dir * projectileSpeed;
	params.ttl = ttl;
	params.gravity = gravity;

	WeaponProjectileFactory::LoadProjectile(params);
}
Exemple #2
0
void CCannon::FireImpl()
{
	float3 diff = targetPos - weaponMuzzlePos;
	float3 dir = (diff.SqLength() > 4.0) ? GetWantedDir(diff) : diff; // prevent vertical aim when emit-sfx firing the weapon
	dir += 
		(gs->randVector() * sprayAngle + salvoError) *
		(1.0f - owner->limExperience * weaponDef->ownerExpAccWeight);
	dir.SafeNormalize();

	int ttl = 0;
	float sqSpeed2D = dir.SqLength2D() * projectileSpeed * projectileSpeed;
	int predict = (int)math::ceil((sqSpeed2D == 0) ? (-2 * projectileSpeed * dir.y / gravity)
			: math::sqrt(diff.SqLength2D() / sqSpeed2D));
	if(weaponDef->flighttime > 0) {
		ttl = weaponDef->flighttime;
	} else if(selfExplode) {
		ttl = (int)(predict + gs->randFloat() * 2.5f - 0.5f);
	} else if((weaponDef->groundBounce || weaponDef->waterBounce)
			&& weaponDef->numBounce > 0) {
		ttl = (int)(predict * (1 + weaponDef->numBounce * weaponDef->bounceRebound));
	} else {
		ttl=predict*2;
	}

	ProjectileParams params = GetProjectileParams();
	params.pos = weaponMuzzlePos;
	params.speed = dir * projectileSpeed;
	params.ttl = ttl;

	new CExplosiveProjectile(params, damageAreaOfEffect, gravity);
}
Exemple #3
0
void CCannon::FireImpl(void)
{
	float3 diff = targetPos-weaponMuzzlePos;
	float3 dir=(diff.SqLength() > 4.0) ? GetWantedDir(diff) : diff; //prevent vertical aim when emit-sfx firing the weapon
	dir+=(gs->randVector()*sprayAngle+salvoError)*(1-owner->limExperience*0.9f);
	dir.Normalize();

	int ttl = 0;
	float sqSpeed2D = dir.SqLength2D() * projectileSpeed * projectileSpeed;
	int predict = (int)ceil((sqSpeed2D == 0) ? (-2 * projectileSpeed * dir.y / gravity)
			: sqrt(diff.SqLength2D() / sqSpeed2D));
	if(weaponDef->flighttime > 0) {
		ttl = weaponDef->flighttime;
	} else if(selfExplode) {
		ttl = (int)(predict + gs->randFloat() * 2.5f - 0.5f);
	} else if((weaponDef->groundBounce || weaponDef->waterBounce)
			&& weaponDef->numBounce > 0) {
		ttl = (int)(predict * (1 + weaponDef->numBounce * weaponDef->bounceRebound));
	} else {
		ttl=predict*2;
	}

	new CExplosiveProjectile(weaponMuzzlePos, dir * projectileSpeed, owner,
		weaponDef, ttl, areaOfEffect, gravity);
}
void CCannon::Fire(void)
{
	float3 diff = targetPos-weaponMuzzlePos;
	float3 dir=(diff.Length() > 2.0) ? GetWantedDir(diff) : diff; //prevent vertical aim when emit-sfx firing the weapon
	dir+=(gs->randVector()*sprayAngle+salvoError)*(1-owner->limExperience*0.9f);
	dir.Normalize();
#ifdef TRACE_SYNC
	tracefile << "Cannon fire: ";
	tracefile << owner->pos.x << " " << dir.x << " " << targetPos.x << " " << targetPos.y << " " << targetPos.z << "\n";
#endif
	int ttl = 0;
	float sqSpeed2D = dir.SqLength2D() * projectileSpeed * projectileSpeed;
	int predict = (int)ceil((sqSpeed2D == 0) ? (-2 * projectileSpeed * dir.y / gravity)
			: sqrt(diff.SqLength2D() / sqSpeed2D));
	if(weaponDef->flighttime > 0) {
		ttl = weaponDef->flighttime;
	} else if(selfExplode) {
		ttl = (int)(predict + gs->randFloat() * 2.5f - 0.5f);
	} else if((weaponDef->groundBounce || weaponDef->waterBounce)
			&& weaponDef->numBounce > 0) {
		ttl = (int)(predict * (1 + weaponDef->numBounce * weaponDef->bounceRebound));
	} else {
		ttl=predict*2;
	}

	SAFE_NEW CExplosiveProjectile(weaponMuzzlePos, dir * projectileSpeed, owner,
		weaponDef, ttl, areaOfEffect, gravity);

	if(fireSoundId && (!weaponDef->soundTrigger || salvoLeft==salvoSize-1))
		sound->PlaySample(fireSoundId,owner,fireSoundVolume);
//	if(weaponMuzzlePos.y < 30)
//		water->AddExplosion(weaponMuzzlePos, weaponDef->damages[0] * 0.1f, sqrt(weaponDef->damages[0]) + 80);
}
Exemple #5
0
bool CCannon::TryTarget(const float3 &pos, bool userTarget, CUnit* unit)
{
	if (!CWeapon::TryTarget(pos, userTarget, unit)) {
		return false;
	}

	if (!weaponDef->waterweapon) {
		if (unit) {
			if (unit->isUnderWater) {
				return false;
			}
		} else {
			if (pos.y < 0) {
				return false;
			}
		}
	}

	if (projectileSpeed == 0) {
		return true;
	}

	float3 dif(pos - weaponMuzzlePos);
	float3 dir(GetWantedDir(dif));

	if (dir.SqLength() == 0) {
		return false;
	}

	float3 flatdir(dif.x, 0, dif.z);
	float flatlength = flatdir.Length();
	if (flatlength == 0) {
		return true;
	}
	flatdir /= flatlength;

	float gc = ground->TrajectoryGroundCol(weaponMuzzlePos, flatdir, flatlength - 10,
			dir.y , gravity / (projectileSpeed * projectileSpeed) * 0.5f);
	if (gc > 0) {
		return false;
	}

	const float quadratic = gravity / (projectileSpeed * projectileSpeed) * 0.5f;
	const float spread =
		((accuracy + sprayAngle) * 0.6f) *
		((1.0f - owner->limExperience * weaponDef->ownerExpAccWeight) * 0.9f);

	if (avoidFriendly && helper->TestTrajectoryCone(weaponMuzzlePos, flatdir,
		flatlength - 30, dir.y, quadratic, spread, 3, owner, CGameHelper::TEST_ALLIED)) {
		return false;
	}
	if (avoidNeutral && helper->TestTrajectoryCone(weaponMuzzlePos, flatdir,
		flatlength - 30, dir.y, quadratic, spread, 3, owner, CGameHelper::TEST_NEUTRAL)) {
		return false;
	}

	return true;
}
Exemple #6
0
void CCannon::Update()
{
	if(targetType!=Target_None){
		weaponPos=owner->pos + owner->frontdir*relWeaponPos.z
				 + owner->updir*relWeaponPos.y + owner->rightdir*relWeaponPos.x;
		weaponMuzzlePos=owner->pos + owner->frontdir*relWeaponMuzzlePos.z
				 + owner->updir*relWeaponMuzzlePos.y + owner->rightdir*relWeaponMuzzlePos.x;
		float3 diff = targetPos-weaponPos;
		wantedDir = GetWantedDir(diff);
		float speed2D = wantedDir.Length2D() * projectileSpeed;
		predict = ((speed2D == 0) ? 1 : (diff.Length2D()/speed2D));
	} else {
		predict=0;
	}
	CWeapon::Update();
}
Exemple #7
0
void CCannon::Update()
{
	if (targetType != Target_None) {
		weaponPos = owner->GetObjectSpacePos(relWeaponPos);
		weaponMuzzlePos = owner->GetObjectSpacePos(relWeaponMuzzlePos);

		const float3 targetVec = targetPos - weaponPos;
		const float speed2D = (wantedDir = GetWantedDir(targetVec)).Length2D() * projectileSpeed;

		predict = ((speed2D == 0.0f) ? 1.0f : (targetVec.Length2D() / speed2D));
	} else {
		predict = 0.0f;
	}

	CWeapon::Update();
}
void CCannon::Fire(void)
{
	float3 diff = targetPos-weaponMuzzlePos;
	float3 dir=GetWantedDir(diff);
	dir+=(gs->randVector()*sprayangle+salvoError)*(1-owner->limExperience*0.9f);
	dir.Normalize();
#ifdef TRACE_SYNC
	tracefile << "Cannon fire: ";
	tracefile << owner->pos.x << " " << dir.x << " " << targetPos.x << " " << targetPos.y << " " << targetPos.z << "\n";
#endif
	int ttl = 0;
	float sqSpeed2D = dir.SqLength2D() * projectileSpeed * projectileSpeed;
	int predict = (int)ceil((sqSpeed2D == 0) ? (-2 * projectileSpeed * dir.y / gravity)
			: sqrt(diff.SqLength2D() / sqSpeed2D));
	if(weaponDef->flighttime > 0) {
		ttl = weaponDef->flighttime;
	} else if(selfExplode) {
		ttl = (int)(predict + gs->randFloat() * 2.5f - 0.5f);
	} else if((weaponDef->groundBounce || weaponDef->waterBounce)
			&& weaponDef->numBounce > 0) {
		ttl = (int)(predict * (1 + weaponDef->numBounce * weaponDef->bounceRebound));
	} else {
		ttl=predict*2;
	}
	SAFE_NEW CExplosiveProjectile(weaponMuzzlePos, dir * projectileSpeed, owner,
		weaponDef, ttl, areaOfEffect, gravity);
	//CWeaponProjectile::CreateWeaponProjectile(weaponPos,owner->speed,owner, NULL, float3(0,0,0), weaponDef);

//	SAFE_NEW CSmokeProjectile(weaponPos,dir*0.01f,90,0.1f,0.02f,owner,0.6f);
//	CHeatCloudProjectile* p=SAFE_NEW CHeatCloudProjectile(weaponPos,dir*0.02f,8,0.6f,owner);
//	p->Update();
//	p->maxheat=p->heat;
	if(fireSoundId && (!weaponDef->soundTrigger || salvoLeft==salvoSize-1))
		sound->PlaySample(fireSoundId,owner,fireSoundVolume);
//	if(weaponMuzzlePos.y < 30)
//		water->AddExplosion(weaponMuzzlePos, weaponDef->damages[0] * 0.1f, sqrt(weaponDef->damages[0]) + 80);
}
Exemple #9
0
void CCannon::UpdateWantedDir()
{
	const float3 targetVec = currentTargetPos - aimFromPos;
	wantedDir = GetWantedDir(targetVec);
}
Exemple #10
0
bool CCannon::TryTarget(const float3 &pos, bool userTarget, CUnit* unit)
{
	if (!CWeapon::TryTarget(pos, userTarget, unit)) {
		return false;
	}

	if (!weaponDef->waterweapon) {
		if (unit) {
			if (unit->isUnderWater) {
				return false;
			}
		} else {
			if (pos.y < 0) {
				return false;
			}
		}
	}

	if (projectileSpeed == 0) {
		return true;
	}

	float3 dif(pos - weaponMuzzlePos);
	float3 dir(GetWantedDir(dif));

	if (dir.SqLength() == 0) {
		return false;
	}

	float3 flatdir(dif.x, 0, dif.z);
	float flatlength = flatdir.Length();
	if (flatlength == 0) {
		return true;
	}
	flatdir /= flatlength;

	const float linear = dir.y;
	const float quadratic = gravity / (projectileSpeed * projectileSpeed) * 0.5f;
	const float gc = ((collisionFlags & Collision::NOGROUND) == 0)?
		ground->TrajectoryGroundCol(weaponMuzzlePos, flatdir, flatlength - 10, linear, quadratic):
		-1.0f;

	if (gc > 0.0f) {
		return false;
	}

	const float spread =
		((accuracy + sprayAngle) * 0.6f) *
		((1.0f - owner->limExperience * weaponDef->ownerExpAccWeight) * 0.9f);

	if (avoidFriendly && TraceRay::TestTrajectoryAllyCone(weaponMuzzlePos, flatdir,
		flatlength - 30, dir.y, quadratic, spread, 3, owner->allyteam, owner)) {
		return false;
	}
	if (avoidNeutral && TraceRay::TestTrajectoryNeutralCone(weaponMuzzlePos, flatdir,
		flatlength - 30, dir.y, quadratic, spread, 3, owner)) {
		return false;
	}

	return true;
}
bool CCannon::TryTarget(const float3 &pos,bool userTarget,CUnit* unit)
{

	if(!CWeapon::TryTarget(pos,userTarget,unit))
	{
		return false;
	}

	if(!weaponDef->waterweapon) {
		if(unit)
		{
			if(unit->isUnderWater)
			{
				return false;
			}
		} else {
			if(pos.y<0)
			{
				return false;
			}
		}
	}

	if (projectileSpeed == 0)
	{
		return true;
	}
	float3 dif(pos-weaponMuzzlePos);

	float3 dir(GetWantedDir(dif));

	if(dir.SqLength() == 0){
		return false;
	}

	float3 flatdir(dif.x,0,dif.z);
	float flatlength=flatdir.Length();
	if(flatlength==0) {
		return true;
	}
	flatdir/=flatlength;

	float gc=ground->TrajectoryGroundCol(weaponMuzzlePos, flatdir, flatlength-10,
			dir.y , gravity / (projectileSpeed * projectileSpeed) * 0.5f);
	if(gc>0) {
		return false;
	}

/*	gc=ground->LineGroundCol(wpos+dir*(length*0.5f),pos,false);
	if(gc>0 && gc<length*0.40f)
		return false;
*/
	if(avoidFriendly && helper->TestTrajectoryCone(weaponMuzzlePos, flatdir,
		flatlength-30, dir.y, gravity /
		(projectileSpeed * projectileSpeed) * 0.5f,
		(accuracy+sprayangle) * 0.6f * (1-owner->limExperience * 0.9f) * 0.9f,
		3, owner->allyteam, owner))
	{
		return false;
	}
/*	if(helper->TestCone(weaponPos,dir,length*0.5f,(accuracy+sprayangle)*1.2f*(1-owner->limExperience*0.9f)*0.9f,owner->allyteam,owner)){
		return false;
	}
	float3 dir2(dif);
	dir2.y+=predictTime*predictTime*gs->gravity;		//compensate for the earlier up prediction
	dir2.Normalize();
	if(helper->TestCone(weaponPos+dir*(length*0.5f),dir2,length*0.5f,(accuracy+sprayangle)*!userTarget*(1-owner->limExperience*0.9f)*0.6f,owner->allyteam,owner)){
		return false;
	}*/
	return true;
}