Example #1
0
/* fly by attack, flies at the enemy firing and turns around once past and does it again */
void maneuver_fly_by(struct _ship *ship) {
	float dist;

	if (!ship->target) {
#ifndef NDEBUG
		printf("maneuver_fly_by() called but ship has no target\n");
#endif
		return;
	}

	/* we do this maneuver by checking distances - if we're a certain distance from the target, turn and face it, if we're within distance, aim and fire, however, if we're within distance but the target is generally behind us (like we just passed it), then we fly out of distance. */
	dist = get_distance_sqrd(ship->world_x, ship->world_y, ship->target->offender->world_x, ship->target->offender->world_y);

	/* 500 real world units but we're using squared distances for speed */
	if (dist > 250000.0f) {
		int facing;

		/* turn and go for the enemy */
		facing = ai_turn_towards(ship, ship->target->offender->world_x, ship->target->offender->world_y);

		/* slow down to turn */
		if (facing)
			ship->accel++;
		else
			slow_down(ship);

	} else {
		/* we're within range, find our angle to the target */
		float angle;

		angle = get_angle_to(ship->world_x, ship->world_y, ship->target->offender->world_x, ship->target->offender->world_y);

		/* whether we're escaping or attacking, we should go fast */
		ship->accel++;

		if (((ship->angle + 60) > angle) && (ship->angle - 60) < angle) {
			/* we're heading toward the ship, continue to do so and fire if close enough */
			/* turn toward the enemy unless we're close (within 175 real units) */
			if (dist > 40000)
				ai_turn_towards(ship, ship->target->offender->world_x, ship->target->offender->world_y);
			if (dist < 360000) {
				if (ship->w_slot[0] != -1)
					fire(ship, 0);
				if (ship->w_slot[1] != -1)
					fire(ship, 1);
			}
		} else {
			/* we're within range, but not heading toward the target, so it's most likely we just passed it, in which case keep heading away until we get out of range (so this maneuver can restart) */
			int escape_angle = (int)angle + 180;
			escape_angle %= 360;

			if (escape_angle > (ship->angle + 15))
				turn_ship(ship, 0);
			else if (escape_angle < (ship->angle - 15))
				turn_ship(ship, 1);
		}
	}
}
Example #2
0
/* turns ship so that the cloest weapon mount is facing the ship's target and fires that mount - good for heavy, slow ships with lots of turrets */
void maneuver_nearest_mount(struct _ship *ship) {
	int i;
	float angle_to;
	int closest_angle = 360;
	int closest_mount = -1;

	if (!ship->target) {
#ifndef NDEBUG
		printf("nearest_mount() called but ship has no target\n");
#endif
		return;
	}

	angle_to = get_angle_to(ship->world_x, ship->world_y, ship->target->offender->world_x, ship->target->offender->world_y);
	
	/* figure out which mount is closest to hitting the target, and make decisions for that mount */
	for (i = 0; i < MAX_WEAPON_SLOTS; i++) {
		if (ship->weapon_mount[i]) {
			int angle = angle_to - (ship->angle + ship->weapon_mount[i]->angle);
			angle %= 360;
			if (abs(angle) < closest_angle) {
				closest_angle = abs(angle_to - (ship->angle + ship->weapon_mount[i]->angle));
				closest_mount = i;
			}
		}
	}
	
	if (closest_mount != -1) {
		assert(ship->weapon_mount[closest_mount]);
		if (ship->weapon_mount[closest_mount]->range != 0) {
			/* okay, range weapon, let's turn just enough to get them in range (er, well in range) */
			/* if they're in range, fire, else, turn to get them in range */
			int weap_angle = ship->angle + ship->weapon_mount[closest_mount]->angle;
			int range = ship->weapon_mount[closest_mount]->range / 2;
			if (((weap_angle + range) > angle_to) && ((weap_angle - range) < angle_to)) {
				/* in range, fire away */
				fire(ship, closest_mount);
			} else {
				/* not in range, turn */
				if ((angle_to > weap_angle) && (angle_to < (weap_angle + 180))) {
					turn_ship(ship, 0);
				} else {
					turn_ship(ship, 1);
				}
			}
		}
	}
}
Example #3
0
/* flies in the direction opposite that of the target */
void maneuver_fly_away(struct _ship *ship) {
	float angle;

	if (!ship)
		return;
	if (!ship->target) {
#ifndef NDEBUG
		printf("maneuver_fly_away called with no target\n");
#endif
		return;
	}

	angle = get_angle_to(ship->world_x, ship->world_y, ship->target->offender->world_x, ship->target->offender->world_y);

	/* get the opposite angle */
	angle = (float)((int)(angle + 180) % 360);

	if (angle > (ship->angle + 15))
		turn_ship(ship, 0);
	else if (angle < (ship->angle - 15))
		turn_ship(ship, 1);

	ship->accel++;
}
Example #4
0
/* pass player struct and set ship to null if the player is firing, otherwise, keep player at null and pass ship */
void fire(struct _ship *ship, short int which_mount) {
	int i;
	
	assert(ship != NULL);
	
	if (which_mount == -1)
		return;
	
	if (ship->weapon_mount[which_mount] == NULL) {
		fprintf(stdout, "WARNING: fire() which_mount = (%d) but that weapon mount is invalid\n", which_mount);
		fprintf(stdout, "WARNING: model is \"%s\"\n", ship->model->name);
		return;
	}
	
	if ((ship->weapon_mount[which_mount]->ammo <= 0) && (ship->weapon_mount[which_mount]->weapon->uses_ammo))
		return;
	
	if (ship->weapon_mount[which_mount]->time > current_time)
		return;

	if (ship->hull_strength <= 0)
		return; /* dead ships can't fire */
	
	i = get_free_weapon_slot();
	if (i == -1) {
		return; /* no free weapon slots */
	} else {
		/* fire the weapon */
		int angle, fire_x, fire_y;
		
		angle = (ship->angle + ship->weapon_mount[which_mount]->angle) % 360;
		
		assert(ship);
		assert(ship->weapon_mount[which_mount]);
		assert(ship->weapon_mount[which_mount]->weapon);
		fires[i].surface = rotate(ship->weapon_mount[which_mount]->weapon->ammo_image, angle); /* cannot be void if creaated, set this to an image */
		fires[i].weapon = ship->weapon_mount[which_mount]->weapon;
		fires[i].velocity = fires[i].weapon->velocity;
		fires[i].owner = ship;
		/* assign the world x & y values */
		fire_x = (int)fires[i].world_x;
		fire_y = (int)fires[i].world_y;
		rotate_point(ship->weapon_mount[which_mount]->x, ship->weapon_mount[which_mount]->y, angle, &fire_x, &fire_y);
		fires[i].world_x = (float)fire_x;
		fires[i].world_y = (float)fire_y;
		fires[i].world_x += ship->world_x;
		fires[i].world_y = ship->world_y - fires[i].world_y;
		fires[i].screen_x = -1500;
		fires[i].screen_y = -1500;
		fires[i].angle = ship->angle + ship->weapon_mount[which_mount]->angle;
		if (ship->weapon_mount[which_mount]->range != 0) {
			/* the weapon has a range, meaning it can turn, let's apply this by aiming toward the target if there is one */
			if (ship->target) {
				float angle_to = get_angle_to(ship->world_x, ship->world_y, ship->target->offender->world_x, ship->target->offender->world_y);
				int range = ship->weapon_mount[which_mount]->range / 2; /* divided by 2 because the range is counting both left and right */
				int angle = fires[i].angle;

				/* if the angle is within our range, aim straight at the target */
				if (((angle + range) > angle_to) && ((angle - range) < angle_to))
					fires[i].angle = angle_to;
				else {
					/* it's not within range, so aim closest to it */
					if (angle_to > (angle + range))
						fires[i].angle = angle + range;
					else
						fires[i].angle = angle - range;
				}
			}
		}
		fires[i].angle %= 360;
		
		/* if it has auto-aim, fire towards the target if possible, if not, it fires at the closest angle */
		if (ship->weapon_mount[which_mount]->range) {
			/* somewhat diff. variables for player */
			if (ship == player.ship) {
				if (player.target.type != TARGET_NONE) {
					float new_angle;
					float world_x, world_y;
					int aim_angle = (int)player.ship->weapon_mount[which_mount]->angle;
					int range = (int)player.ship->weapon_mount[which_mount]->range;
					
					if (player.target.type == TARGET_GATE) {
						struct _gate *gate = (struct _gate *)player.target.target;
						world_x = gate->world_x;
						world_y = gate->world_y;
					} else if (player.target.type == TARGET_SHIP) {
						struct _ship *ship = (struct _ship *)player.target.target;
						world_x = ship->world_x;
						world_y = ship->world_y;
					}
					
					new_angle = (float)atan2((float)((-1 * world_y) - (-1 * fires[i].world_y)), (float)(world_x - fires[i].world_x));
					
					/* convert aim_angle and range to radians :-) */
					aim_angle = (int)(((float)aim_angle * M_PI) / 180.0f);
					range = (int)(((float)range * M_PI) / 180.0f);
					
					/* see if the angle is in the range, if not, get it as close as possible */
					if ((new_angle < (angle + range)) && (new_angle > (angle - range))) {
						angle = (int)((new_angle * 180.0f) / M_PI);
					} else {
						/* the angle is not in the range, but get it as close as possible */
						if (new_angle > (angle + range))
							angle = (int)(((float)(aim_angle + range) * 180.0f) / M_PI);
						else
							angle = (int)(((float)(aim_angle - range) * 180.0f) / M_PI);
					}
				}
			} else {
				if ((ship->target != NULL) && (ship->target->offender != NULL)) {
					float new_angle;
					int aim_angle = (int)ship->weapon_mount[which_mount]->angle;
					int range = (int)ship->weapon_mount[which_mount]->range;
					new_angle = (float)atan2((float)((-1 * ship->target->offender->world_y) - (-1 * fires[i].world_y)), (float)(ship->target->offender->world_x - fires[i].world_x));
					
					/* convert aim_angle and range to radians :-) */
					aim_angle = (int)(((float)aim_angle * M_PI) / 180.0f);
					range = (int)(((float)range * M_PI) / 180.0f);
					
					/* see if the angle is in the range, if not, get it as close as possible */
					if ((new_angle < (angle + range)) && (new_angle > (angle - range))) {
						angle = (int)((new_angle * 180.0f) / M_PI);
					} else {
						/* the angle is not in the range, but get it as close as possible */
						if (new_angle > (angle + range))
							angle = (int)(((float)(aim_angle + range) * 180.0f) / M_PI);
						else
							angle = (int)(((float)(aim_angle - range) * 180.0f) / M_PI);
					}
				}
			}
		}
		
		fires[i].expire_time = current_time + (Uint32)ship->weapon_mount[which_mount]->weapon->lifetime;
		
		/* subtract the fire from the ship's amount to fire and set their next firing time */
		ship->weapon_mount[which_mount]->ammo--;
		
		ship->weapon_mount[which_mount]->time = current_time + (Uint32)ship->weapon_mount[which_mount]->weapon->recharge;
		
		num_fires++;
	}
}
Example #5
0
void Node2D::look_at(const Vector2& p_pos) {

	rotate(get_angle_to(p_pos));
}