From 1b77a4276b286b5245a3a8987e2a9c07cbb6178f Mon Sep 17 00:00:00 2001 From: Allanis Date: Thu, 28 Feb 2013 01:23:52 +0000 Subject: [PATCH] [Add] Smart seeker missiles. Not aquirable yet :P. [Fix] Potential fix of a floating point exceoption. --- dat/outfit.xml | 34 +++++++++++++++++++++++++++++++ src/physics.c | 7 ++++++- src/physics.h | 3 ++- src/pilot.c | 4 ++-- src/weapon.c | 55 ++++++++++++++++++++++++++++++++++++++++++++------ 5 files changed, 93 insertions(+), 10 deletions(-) diff --git a/dat/outfit.xml b/dat/outfit.xml index 95eb030..8963d52 100644 --- a/dat/outfit.xml +++ b/dat/outfit.xml @@ -55,4 +55,38 @@ + + + 2 + 8 + 12 + 40000 + + + Headhunter + 1400 + + + + + 40 + 4 + 1 + 2000 + + + missile + missile + ExpM + 7 + 0.5 + 1200 + 200 + 600 + + 23 + 18 + + + diff --git a/src/physics.c b/src/physics.c index 07995ba..9c906da 100644 --- a/src/physics.c +++ b/src/physics.c @@ -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. diff --git a/src/physics.h b/src/physics.h index 6e70004..f5681b1 100644 --- a/src/physics.h +++ b/src/physics.h @@ -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); diff --git a/src/pilot.c b/src/pilot.c index e2bd618..acbc9a4 100644 --- a/src/pilot.c +++ b/src/pilot.c @@ -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. diff --git a/src/weapon.c b/src/weapon.c index f698c29..80701a2 100644 --- a/src/weapon.c +++ b/src/weapon.c @@ -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; } @@ -134,10 +134,41 @@ static void think_seeker(Weapon* w) { } vect_pset(&w->solid->force, w->outfit->u.amm.thrust, w->solid->dir); + + 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); - 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)); } // 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,8 +350,15 @@ 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. w->voice = NULL;