示例#1
0
int EarthlingCruiserMk3::activate_special()
{
	STACKTRACE;
	bool fire = false;;
	SpaceObject *o;
	double rng = 1e40;
	SpaceObject *tgt = NULL;

								 //!!!
	pos -= unit_vector(angle) * 6;
	Query q;
	for (q.begin(this, bit(LAYER_SHIPS) + bit(LAYER_SHOTS) + bit(LAYER_SPECIAL) +
	bit(LAYER_CBODIES), specialRange); q.current; q.next()) {
		o = q.currento;
		if (!o->isInvisible() && !o->sameTeam(this) && (o->collide_flag_anyone&bit(LAYER_LINES))
		&& (distance(o) < rng)) {
			tgt = o;
			rng = distance(o);
		}
	}
	q.end();
								 //!!!
	pos += unit_vector(angle) * 6;

	if (tgt) {
		game->add(new EarthlingCruiserMk3Beam(this, Vector2(0,-6), specialRange,
			specialDamage, specialDamageShots, specialFrames, tgt));
		play_sound(data->sampleSpecial[0]);
		fire = true;
	}

	return(fire);
}
示例#2
0
int EarthlingCruiser2::activate_special()
{
	STACKTRACE;
	int fire = FALSE;
	SpaceObject *o;

	Query q;
	for (q.begin(this, bit(LAYER_SHIPS) + bit(LAYER_SHOTS) + bit(LAYER_SPECIAL) +
	bit(LAYER_CBODIES), specialRange); q.current; q.next()) {
		o = q.currento;
		if (!o->isInvisible() && !o->sameTeam(this) && (o->collide_flag_anyone&bit(LAYER_LINES))) {
			SpaceLocation *l = new PointLaser(this, pallete_color[specialColor], 1,
				specialFrames, this, o, Vector2(0.0,0.0));
			add(l);
			if (l->exists()) {
				fire = TRUE;
				l->set_depth(LAYER_EXPLOSIONS);
			}
		}
	}
	q.end();
	if (fire) sound.play((SAMPLE *)(melee[MELEE_BOOM + 0].dat));

	return(fire);
}
示例#3
0
int VelronCruiser::fire_def_shot(double lowAngle, double highAngle, double defaultAngle)
{
	STACKTRACE;
	SpaceObject *o;
	double distance2, bestDistance2 = 99999999;
	double angleShift, relativeAngle;
	double firingAngle = defaultAngle;

	angleShift = ((double)(random()%2001-1000)/1000.0) * specialLaunchAngleDeflectionRange;

	Query a;
	for (a.begin(this, OBJECT_LAYERS, specialRange); a.current; a.next()) {
		o = a.currento;
		if ( (!o->isInvisible()) && !o->sameTeam(this)
		&& (o->collide_flag_anyone & bit(LAYER_SHOTS))) {
			distance2 = distance(o); relativeAngle = get_aim(o, lowAngle, highAngle);
			if ((distance2 < bestDistance2) && (relativeAngle > -1000)) {
				bestDistance2 = distance2;
				firingAngle = relativeAngle;
			}
		}
	}

	add(new VelronCrDefShot(this, 0.0, 0.0, normalize(angle + firingAngle + angleShift, PI2), specialVelocity,
		specialDamage, specialRange, specialArmour, data->spriteSpecial, specialRelativity));

	return(TRUE);
}
示例#4
0
void EarthlingCruiserMk3Beam::calculate()
{
	STACKTRACE;
	if (!(lpos && lpos->exists())) {
		lpos = 0;
		state = 0;
	}

	if ((frame < frame_count) && (lpos && lpos->exists())) {
		pos = lpos->normal_pos() + rotate(rel_pos, lpos->get_angle() - PI/2);
		vel = lpos->get_vel();
		SpaceLine::calculate();
		frame += frame_time;
	}
	else
		state = 0;

	if ((!target) && (switch_counter <= 0)) {
		SpaceObject *o;
		double rng = 1e40;
		SpaceObject *tgt = NULL;
		Query a;
		for (a.begin(this, bit(LAYER_SHIPS) + bit(LAYER_SHOTS) + bit(LAYER_SPECIAL) +
		bit(LAYER_CBODIES), base_length); a.current; a.next()) {
			o = a.currento;
			if (!o->isInvisible() && !o->sameTeam(this) && (o->collide_flag_anyone&bit(LAYER_LINES))
			&& (distance(o) < rng)) {
				tgt = o;
				rng = distance(o);
			}
		}
		if (tgt) {
			target = tgt;
			//			switch_counter = 55;
			got_spark = false;
		}
	}

	if (target && (distance(target) <= base_length)) {
		length = base_length;
		if (target->exists() && canCollide(target) && target->canCollide(this)) {
			angle = trajectory_angle(target);
		}
		if (!target->exists()) target = NULL;
	} else {
		target = NULL;
		if (switch_counter <= 0)
			//			die();
			length = 0;
		else
			switch_counter -= frame_time;
	}

	color = tw_makecol(100+tw_random()%105,100+tw_random()%105,255);
}
示例#5
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;

}
示例#6
0
void AndrosynthBubble::calculate()
{
	STACKTRACE;
	if (!(ship && ship->exists())) {
		state = 0;
		return;
	}

	double newAngle;

	AnimatedShot::calculate();
	courseFrames += frame_time;
	if (courseFrames >= 150) {
		courseFrames -= 150;

		newAngle = random(PI2);
		vel = v * unit_vector(newAngle);

		int i;
		double r = 99999;
		newAngle = 99999;

		// ship->control->ship == 0 (can happen ?!)
		// ... yeah ... look at control->select_ship. There you can see
		// that control->ship=0 if the ship does not exist. Perhaps there's
		// a de-synch between the two calculations (!exists() lags the control->ship) ?

		if (ship && ship->exists() && ship->control && ship->control->ship) {
			for (i = 0; i < targets->N; i += 1) {
				SpaceObject *s = targets->item[i];
				if (ship->control->valid_target(s) && (distance(s) < r) && !s->isInvisible()) {
					r = distance(s);
					newAngle = trajectory_angle(s);
				}
			}
		} else {
			for (i = 0; i < targets->N; i += 1) {
				SpaceObject *s = targets->item[i];
				if (s->sameTeam(this) && (distance(s) < r) && !s->isInvisible()) {
					r = distance(s);
					newAngle = trajectory_angle(s);
				}
			}
		}
		if (newAngle < PI * 4) {
			vel += unit_vector(newAngle) * v / 2;
		}
	}
	return;
}
示例#7
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;

}