[Add] Smart seeker missiles. Not aquirable yet :P.

[Fix] Potential fix of a floating point exceoption.
This commit is contained in:
Allanis 2013-02-28 01:23:52 +00:00
parent 27f4ddcd86
commit 1b77a4276b
5 changed files with 93 additions and 10 deletions

View File

@ -55,4 +55,38 @@
</damage>
</specific>
</outfit>
<outfit name="Headhunter Launcer">
<general>
<max>2</max>
<tech>8</tech>
<mass>12</mass>
<price>40000</price>
</general>
<specific type="5" secondary="1">
<ammo>Headhunter</ammo>
<delay>1400</delay>
</specific>
</outfit>
<outfit name="Headhunter">
<general>
<max>40</max>
<tech>4</tech>
<mass>1</mass>
<price>2000</price>
</general>
<specific type="6">
<gfx>missile</gfx>
<sound>missile</sound>
<spfx>ExpM</spfx>
<duration>7</duration>
<lockon>0.5</lockon>
<thrust>1200</thrust>
<turn>200</turn>
<speed>600</speed>
<damage>
<armour>23</armour>
<shield>18</shield>
</damage>
</specific>
</outfit>
</Outfits>

View File

@ -14,7 +14,12 @@ double angle_diff(const double ref, double a) {
return (d <= M_PI) ? d : d - 2*M_PI;
}
void limit_speed(Vec2* vel, const double speed, const double dt) {
void limit_speed(Vec2* vel, const double speed) {
if(VMOD(*vel) > speed) // Should not go faster.
vect_pset(vel, speed, VANGLE(*vel));
}
void limit_speeddt(Vec2* vel, const double speed, const double dt) {
double vmod;
vmod = VMOD(*vel);
if(vmod > speed) // Should not go faster.

View File

@ -22,7 +22,8 @@ typedef struct Vec2_ {
// Misc
double angle_diff(const double ref, double a);
void limit_speed(Vec2* vel, const double speed, const double dt);
void limit_speed(Vec2* vel, const double speed);
void limit_speeddt(Vec2* vel, const double speed, const double dt);
// Vector manupulation.
void vect_cset(Vec2* v, const double x, const double y);

View File

@ -172,7 +172,7 @@ static void pilot_shootWeapon(Pilot* p, PilotOutfit* w, const unsigned int t) {
}
}
// Missile launchers.
// Must be secondary weapon, Shootee can't be the target.
// Must be secondary weapon, Shooter can't be the target.
else if(outfit_isLauncher(w->outfit) && (w == p->secondary) && (p->id != t)) {
if(p->ammo && (p->ammo->quantity > 0)) {
weapon_add(p->ammo->outfit, p->solid->dir, &p->solid->pos, &p->solid->vel, p->id, t);
@ -329,7 +329,7 @@ static void pilot_update(Pilot* pilot, const double dt) {
if(!pilot_isFlag(pilot, PILOT_HYPERSPACE))
// Should not go faster.
limit_speed(&pilot->solid->vel, pilot->ship->speed, dt);
limit_speeddt(&pilot->solid->vel, pilot->ship->speed, dt);
}
// Pilot is getting ready or is in, hyperspace.

View File

@ -113,14 +113,14 @@ void weapons_delay(unsigned int delay) {
wfrontLayer[i]->timer += delay;
}
// Seeker brain, You get what you pay for. :)
static void think_seeker(Weapon* w) {
double diff;
if(w->target == w->parent) return; // HEY! Self harm is not allowed.
Pilot* p = pilot_get(w->target);
if(p == NULL) {
if(VMOD(w->solid->vel) > w->outfit->u.amm.speed) // Should not go faster.
vect_pset(&w->solid->vel, w->outfit->u.amm.speed, VANGLE(w->solid->vel));
limit_speed(&w->solid->vel, w->outfit->u.amm.speed);
return;
}
@ -135,9 +135,40 @@ static void think_seeker(Weapon* w) {
vect_pset(&w->solid->force, w->outfit->u.amm.thrust, w->solid->dir);
if(VMOD(w->solid->vel) > w->outfit->u.amm.speed)
// We should not go any faster.
vect_pset(&w->solid->vel, w->outfit->u.amm.speed, VANGLE(w->solid->vel));
limit_speed(&w->solid->vel, w->outfit->u.amm.speed);
}
// Smart seeker brain. Much better at homing.
static void think_smart(Weapon* w) {
double diff;
Vec2 tv, sv;
if(w->target == w->parent) return; // No self shooting here.
Pilot* p = pilot_get(w->target); // No null pilots..
if(p == NULL) {
limit_speed(&w->solid->vel, w->outfit->u.amm.speed);
return;
}
if(SDL_GetTicks() > (w->timer + w->outfit->u.amm.lockon)) {
vect_cset(&tv, VX(p->solid->pos) + VX(p->solid->vel),
VY(p->solid->pos) + VY(p->solid->vel));
vect_cset(&sv, VX(w->solid->pos) + VX(w->solid->vel),
VY(w->solid->pos) + VY(w->solid->vel));
diff = angle_diff(w->solid->dir, vect_angle(&tv, &sv));
w->solid->dir_vel = 10*diff*w->outfit->u.amm.turn; // Face the target.
if(w->solid->dir_vel > w->outfit->u.amm.turn)
w->solid->dir_vel = w->outfit->u.amm.turn;
else if(w->solid->dir_vel < -w->outfit->u.amm.turn)
w->solid->dir_vel = -w->outfit->u.amm.turn;
}
vect_pset(&w->solid->force, w->outfit->u.amm.thrust, w->solid->dir);
limit_speed(&w->solid->vel, w->outfit->u.amm.speed);
}
// Update all the weapon layers.
@ -166,7 +197,11 @@ static void weapons_updateLayer(const double dt, const WeaponLayer layer) {
for(i = 0; i < (*nlayer); i++) {
w = wlayer[i];
switch(wlayer[i]->outfit->type) {
// Most missiles behave the same.
case OUTFIT_TYPE_MISSILE_SEEK_AMMO:
case OUTFIT_TYPE_MISSILE_SEEK_SMART_AMMO:
case OUTFIT_TYPE_MISSILE_SWARM_AMMO:
case OUTFIT_TYPE_MISSILE_SWARM_SMART_AMMO:
if(SDL_GetTicks() > (wlayer[i]->timer + wlayer[i]->outfit->u.amm.duration)) {
weapon_destroy(wlayer[i], layer);
continue;
@ -302,6 +337,7 @@ static Weapon* weapon_create(const Outfit* outfit, const double dir, const Vec2*
if((rdir > 2.*M_PI) || (rdir < 0.)) rdir = fmod(rdir, 2.*M_PI);
vectcpy(&v, vel);
vect_cadd(&v, outfit->u.wpn.speed*cos(rdir), outfit->u.wpn.speed*sin(rdir));
w->timer += 1000*(unsigned int)outfit->u.wpn.range/outfit->u.wpn.speed;
w->solid = solid_create(mass, rdir, pos, &v);
w->voice = sound_addVoice(VOICE_PRIORITY_BOLT,
w->solid->pos.x, w->solid->pos.y,
@ -314,7 +350,14 @@ static Weapon* weapon_create(const Outfit* outfit, const double dir, const Vec2*
w->voice = sound_addVoice(VOICE_PRIORITY_AMMO,
w->solid->pos.x, w->solid->pos.y,
w->solid->vel.x, w->solid->vel.y, w->outfit->u.amm.sound, 0);
break;
case OUTFIT_TYPE_MISSILE_SEEK_SMART_AMMO:
mass = w->outfit->mass;
w->solid = solid_create(mass, dir, pos, vel);
w->think = think_smart; // Smartass.
w->voice = sound_addVoice(VOICE_PRIORITY_AMMO,
w->solid->pos.x, w->solid->pos.y,
w->solid->vel.x, w->solid->vel.y, w->outfit->u.amm.sound, 0);
break;
default:
// Just dump it where the player is.