Exemplo n.º 1
0
void KoloryFlamer :: calculate ()
{

    // check if the weapons exist
    weapon1 = flamer1 && flamer1->exists();
    weapon2 = flamer2 && flamer2->exists();

    // update the flamer pointers
    if (!weapon1)   flamer1 = 0;
    if (!weapon2)   flamer2 = 0;

    flame_active = weapon1 | weapon2;

    Ship::calculate();

    // regardless of whether the flames are activated or not:
    if ( this->fire_special ) {	 // DEFENSIVE MODE

        //		double HalfTime = 1000.0 * 0.5;	// 0.5 second to half the speed.
        // is nearly 1
        slowdownfactor = exp(-frame_time*1E-3 / specialHalfTime);

    } else {
        slowdownfactor = 1.0;
    }

    int layers = bit(LAYER_SHIPS) + bit(LAYER_SHOTS) + bit(LAYER_SPECIAL) +
                 bit(LAYER_CBODIES);
    double passiveRange = 1000.0;// outside this area, gravity doesn't do anything

    Query a;
    for (a.begin(this, layers, passiveRange); a.current; a.next()) {
        if (!a.current->isObject())
            continue;
        SpaceObject *o = a.currento;
        if (!(o->isPlanet()) && o != ship ) {

            // the special introduces drag around the ship, depending on distance

            o->vel *= slowdownfactor;

            if ( o->isShot() ) { // shot/missiles/homing-missiles have a different existtime/physics
                Shot *s = ((Shot*)o);
                double timeleft = (s->range - s->d) / s->v;
                s->v *= slowdownfactor;
                // express in lifetime instead of range
                s->range = s->d + s->v * timeleft;
            }

        }
    }

}
Exemplo n.º 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;

}