Example #1
0
void EarthlingCruiserMk3::calculate()
{
	STACKTRACE;
	Ship::calculate();

	double track_angle = 0;
	double track_min = PI2;
	double d_a;
	SpaceObject *tgt = 0;

								 //!!!
	pos += unit_vector(angle) * 28;
	int i;
	for (i=0; i < targets->N; i++) {
		tgt = targets->item[i];
		if ((tgt != this) && (!tgt->sameShip(this)) && (!tgt->sameTeam(this))
		&& (!tgt->isInvisible()) && (distance(tgt) <= 1.2*(weaponRange + abs(vel)*game->shot_relativity))) {

			d_a = trajectory_angle(tgt);
			double s = unit_vector(d_a + PI/2).dot(tgt->get_vel() - vel * game->shot_relativity) / weaponVelocity;
			if (fabs(s) > 0.99)
				track_angle = 0;
			else {
				s = atan(s/sqrt(1-s*s));
				s = normalize(s + d_a - angle - turn_step, PI2);
				if (s > PI) s -= PI2;
				if (fabs(s) <= weaponTrackingAngle) {
					d_a = s - launch_angle;
					if (tgt == target) {
						track_angle = s;
						break;
					}
					if (fabs(d_a) < track_min) {
						track_angle = s;
						track_min = fabs(d_a);
					}
				}
			}
		}
	}
								 //!!!
	pos -= unit_vector(angle) * 28;

	d_a = track_angle - launch_angle;
	double ta = weaponTrackingRate * frame_time;
	if (fabs(d_a) < ta) ta = fabs(d_a);
	if (d_a > 0) launch_angle += ta;
	else launch_angle -= ta;

}
Example #2
0
void AutoGun::calculate()
{
	STACKTRACE;
	BigShipPartDevice::calculate();

	if (!(ownerpart && !ownerpart->isdisabled()))
		return;

	// find the closest target
	Query a;
	SpaceObject *oclosest;
	double R;

	oclosest = 0;
	R = 1E99;

	double da_track;
	da_track = -a_track;		 // forces to go back into default position

	for (a.begin(this, OBJECT_LAYERS, 0.75*shotrange); a.current != 0; a.next()) {
		SpaceObject *o;
		o = a.currento;

		if (!o->isObject())
			continue;

		if (o->sameShip(this) || o->sameTeam(this))
			continue;

		if (o->isPlanet())
			continue;

		if (o->isInvisible())
			continue;

		double L = 0;
		L = distance(o);

		if (!oclosest || L < R) {
			// this is a possible candidate but, is it also within the view angle ?

			double a, b, da;
			a = trajectory_angle(o);
			// check relative to the gun's neutral position
			b = ownerpart->get_angle() + a_center;

			da = a - b;
			while (da < -PI)    da += PI2;
			while (da >  PI)    da -= PI2;

			if (da > -a_view && da < a_view) {
				// okay! it's close, within dist-range, and it's within angle-range
				oclosest = o;
				R = L;

				// required movement is relative to the gun's current position
				// note that at this moment, you cannot use the value of "angle"
				// which is overridden by the call to AyronShipPart::calculate; so,
				// use "b" instead.
				b += a_track;
				da_track = a - b;
				while (da_track < -PI)  da_track += PI2;
				while (da_track >  PI)  da_track -= PI2;
			}

		}

	}

	// track the target (or go back to neutral position)
	// max tracking speed per second (0.1 circles / second).
	// this tracking angle is relative to the neutral angle of the gun.

	double da;
	da = 100 * PI2 * frame_time * 1E-3;
	if (da_track > da)
		da_track = da;
	if (da_track < -da)
		da_track = -da;

	a_track += da_track;

	if (a_track < -a_view)
		a_track = -a_view;
	if (a_track > a_view)
		a_track = a_view;

	// absolute angle of the gun
	angle = ownerpart->get_angle() + a_center + a_track;
	sprite_index = get_index(angle);

	// fire the weapon ?
	if (oclosest && ownerpart->ship && ownerpart->ship->batt > shotdrain && !shotbusy) {

		Shot *s;
		s = new Shot(this, Vector2(0,0), angle, shotvel,
			shotdamage, shotrange, shotarmour, this,
			sprshot, 0);

		s->set_depth(DEPTH_SHIPS + 0.1);
		game->add( s );

		shotbusy = shotperiod;

		ownerpart->ship->handle_fuel_sap(this, shotdrain);
	}

	if (shotbusy > 0)
		shotbusy -= frame_time * 1E-3;
	else
		shotbusy = 0;

}