예제 #1
0
파일: mmain.cpp 프로젝트: Yurand/tw-light
void NormalGame::calculate()
{
	STACKTRACE;
	Game::calculate();
	if (next_choose_new_ships_time <= game_time) {
		choose_new_ships();
		next_choose_new_ships_time = game_time + 24*60*60*1000;
	}

	// specially for play-testers:
	// kill all ships and ship-objects in the melee-game
	if (kill_all_delay_counter > 0) {
		kill_all_delay_counter -= frame_time;
	} else {

		if (key[KEY_LCONTROL] && key[KEY_ALT] && key[KEY_K]) {
								 // 1 second delay
			kill_all_delay_counter += 1000;

			for(std::list<SpaceLocation*>::iterator i=physics->item.begin();i!=physics->item.end();i++) {
				SpaceLocation *o;
				o = *i;
				if (!(o && o->exists()))
					continue;
				if (o->isPlanet() || o->isAsteroid())
					continue;
				o->die();
			}
		}
	}

	return;
}
예제 #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
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);
}
예제 #4
0
void BoggCenturionExhaustShot::calculate()
{
	STACKTRACE;
	Shot::calculate();
	if (!amt->exists()) state = 0;
	//x = amt->normal_x();
	//y = amt->normal_y();
	pos = amt->normal_pos();
	//vx = amt->get_vx();
	//vy = amt->get_vy();
	vel = amt->get_vel();
}
예제 #5
0
void PulseLaser2::calculate()
{
	STACKTRACE;
	if (!lpos && lpos->exists()) {
		lpos = 0;
		state = 0;
		return;
	}
	if ((frame < frame_count) && (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;
	return;
}
예제 #6
0
void TauDaggerBeam::calculate()
{
	STACKTRACE;
	if ((frame < frame_count) && (lpos->exists())) {
		length = base_length;
		pos = lpos->normal_pos() + rotate(rel_pos, lpos->get_angle() - PI/2);
		vel = lpos->get_vel();
		//		angle = lpos->get_angle();
		angle = normalize(lpos->get_angle() + relative_angle, PI2);
		SpaceLine::calculate();
		frame += frame_time;
	}
	else
		state = 0;

	int rrr = tw_random()%85;
	color = tw_makecol(100+rrr,100+rrr+tw_random()%55,205+tw_random()%51);
}
예제 #7
0
void AktunComSat::calculate()
{
	STACKTRACE;

	if (!(ship && ship->exists())) {
		state = 0;
		return;
	}

	SpaceObject::calculate();

	sprite_index++;
	if (sprite_index == 40)
		sprite_index = 0;

	if (lRecharge > 0) {
		lRecharge -= frame_time;
		return;
	}

	vel *= 1 - .0005 * frame_time;

	if (magnitude_sqr(vel) < 0.05 * 0.05) {
		vel = 0;
	}

	Query q;
	for (q.begin(this, OBJECT_LAYERS &~ bit(LAYER_CBODIES), lRange); q.currento; q.next()) {
		if (!q.currento->isInvisible() && !q.currento->sameTeam(this)) {
			SpaceLocation *l;
			l = new PointLaser(this, tw_get_palete_color(lColor), 1, lFrames,
				this, q.currento, 0);
			game->add(l);
			if (l->exists()) {
				sound.play(ship->data->sampleExtra[0]);
				lRecharge += lRechargeRate;
				break;
			}
			else l->state = 0;
		}
	}
	return;
}
예제 #8
0
void Hook2::calculate()
{
	STACKTRACE;
	exist_time += frame_time * 1E-3;
	if ( exist_time > life_time )
		state = 0;

	// if it's completely unrolled ...
	if ( hooklocked && Nnodes <= 0 )
		state = 0;

	// or if the host ship has gone
	if ( !(ship && ship->exists()) ) {
		ship = 0;
		state = 0;
	}

	if ( hooktarget && hooktarget->exists() ) {
		vel = hooktarget->vel;
		angle = hooktarget->angle + hookfixangle;
		sprite_index = get_index(angle);
		pos = hooktarget->pos + hookfixdist * unit_vector(hooktarget->angle + hookfixorientation);
	}
	else if (hooklocked) {
		state = 0;
		hooktarget = 0;
	}

	if ( state == 0 )
		return;

	SpaceObject::calculate();

	if ( !hooklocked)
		roll_time += frame_time * 1E-3;
	else						 // otherwise it keeps pumping energy into the line
		roll_time = 0.0;

	Vector2 hookendpos;
	hookendpos = pos - hooksize * unit_vector(angle);

	Vector2 ejpos;
	if (ship && ship->exists() ) {
		ejpos = ship->pos + ropestart * unit_vector(ship->angle) +
			15 * sin(oscperiod*roll_time) * unit_vector(ship->angle + 0.5*PI);

	}
	else
		ejpos = 0;

	if (ship && ship->exists() && !hooklocked ) {
		// extend the elastic rope slowly

		double dL;
		if ( Nnodes > 0 )
			dL = magnitude(min_delta(ropenode[Nnodes-1].pos, ejpos, map_size));
		else
			dL = magnitude(min_delta(hookendpos, ejpos, map_size));

		if ( dL > ropeseglen && Nnodes < maxnodes ) {

			ropenode[Nnodes].pos = ejpos;
								 // *1E+3 because from now we do calculations in seconds instead of ms.
			ropenode[Nnodes].vel = (ship->vel + ejvel * unit_vector(ship->angle)) * 1E+3;
								 // changes color every 4 pieces ?
			ropenode[Nnodes].col = pallete_color[11 + (Nnodes/4) % 3];
			dL = ropeseglen;
								 // relaxed length of the segment between nodes i and i-1.
			ropenode[Nnodes].dL = dL;

			++ Nnodes;

			if ( Nnodes == maxnodes )
				state = 0;		 // no target found ... poor thing ;)

		}

	}

	// calculate the nodes on the elastic rope (except the end-points, which are fixed:

	double k = springconst;		 // 250.0

	int i;

	Vector2 D;
	double  R;

	//	ropenode[0].acc = ..;
	//	ropenode[Nnodes-1].acc = ..;

	int Ninterpol, iinterpol;

	// this may be needed if values of the spring constant are high
	Ninterpol = 10;
	double dt = frame_time * 1E-3 / Ninterpol;

	for ( iinterpol = 0; iinterpol < Ninterpol; ++iinterpol ) {

		// reset forces
		for ( i = 0; i < Nnodes; ++i )
			ropenode[i].acc = 0;

		// forces between rope nodes
		for ( i = 0; i < Nnodes; ++i ) {
			if ( i > 0 ) {
				D = min_delta(ropenode[i-1].pos - ropenode[i].pos, map_size);
				R = D.length();
				L = ropenode[i].dL;

				if ( R != 0 )
					ropenode[i].acc += k * (R - L) * D / R;
			}

			if ( i < Nnodes-1 ) {
				D = min_delta(ropenode[i+1].pos - ropenode[i].pos, map_size);
				R = D.length();
				L = ropenode[i+1].dL;

				if ( R != 0 )
					ropenode[i].acc += k * (R - L) * D / R;
			}
		}

		// attached to the hook
		Vector2 hookacc;
		hookacc = 0;

		if ( Nnodes > 0 ) {
			i = 0;

			D = min_delta(hookendpos - ropenode[i].pos, map_size);
			R = D.length();
			L = ropenode[i].dL;

			hookacc = k * (R - L) * D / R;

			if ( R != 0 )
				ropenode[i].acc += hookacc;
		}

		// attached to the ship, if it still exists...
		if ( ship && ship->exists() && Nnodes > 0 ) {
			i = Nnodes-1;

			D = min_delta(ejpos - ropenode[i].pos, map_size);
			R = D.length();
			L = ropeseglen;		 // should be i+1, but that doesn't exist
			if ( R != 0 )
				ropenode[i].acc += k * (R - L) * D / R;;
		}

		// slow down a little, for stability
		for ( i = 0; i < Nnodes; ++i )
			ropenode[i].acc -= 10.0 * ropenode[i].vel * dt;

		// apply accelerations (also to the end points)
		for ( i = 0; i < Nnodes; ++i ) {
			ropenode[i].vel += ropenode[i].acc * dt;
			ropenode[i].pos += ropenode[i].vel * dt;
		}

		// apply acceleration to the target:
		if ( hooktarget && hooktarget->exists() ) {
			hooktarget->vel -= 0.1 * 1E-3 * hookacc * dt;

			// and also some deceleration ...
			double a = 1 - 0.1*dt;
			if ( a < 0 ) a = 0;
			if ( a > 1 ) a = 1;
			hooktarget->vel *= a;

			// influence the angle of the enemy ship:

			a = atan(hookendpos - hooktarget->pos);

			double b, da, rotacc;
			b = atan(hookacc);

			da = b - a;

			rotacc = magnitude(hookacc) * sin(da);

			hooktarget->angle -= 0.25 * 1E-3 * rotacc * dt;

			// angle must never exceed half PI with the end of the rope...

			b = atan(ropenode[0].pos - hookendpos);

			da = b - a;

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

			if ( da < -0.5*PI || da > 0.5*PI ) {
				double dacorr = fabs(da) - 0.5*PI;
				if ( dacorr > 5*PI2*dt )
					dacorr = 5*PI2*dt;

				if ( da < 0.0 )
					hooktarget->angle -= dacorr;
				else
					hooktarget->angle += dacorr;
			}

			// to stabilize, make sure neither vessels' speed ever exceeds the maximum:

			double V1, V2;

			if ( ship && ship->exists() ) {
				V1 = magnitude(ship->vel);
				V2 = 2 * ship->speed_max;
				if ( V1 > V2 )
					ship->vel *= V2 / V1;
			}

			if ( hooktarget->isShip() ) {
				V1 = magnitude(hooktarget->vel);
				V2 = 2 * ((Ship*) hooktarget)->speed_max;
				if ( V1 > V2 )
					hooktarget->vel *= V2 / V1;
			}

		}

	}

}