[Add] Smart seeker missiles. Not aquirable yet :P.
[Fix] Potential fix of a floating point exceoption.
This commit is contained in:
parent
27f4ddcd86
commit
1b77a4276b
@ -55,4 +55,38 @@
|
|||||||
</damage>
|
</damage>
|
||||||
</specific>
|
</specific>
|
||||||
</outfit>
|
</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>
|
</Outfits>
|
||||||
|
@ -14,7 +14,12 @@ double angle_diff(const double ref, double a) {
|
|||||||
return (d <= M_PI) ? d : d - 2*M_PI;
|
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;
|
double vmod;
|
||||||
vmod = VMOD(*vel);
|
vmod = VMOD(*vel);
|
||||||
if(vmod > speed) // Should not go faster.
|
if(vmod > speed) // Should not go faster.
|
||||||
|
@ -22,7 +22,8 @@ typedef struct Vec2_ {
|
|||||||
|
|
||||||
// Misc
|
// Misc
|
||||||
double angle_diff(const double ref, double a);
|
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.
|
// Vector manupulation.
|
||||||
void vect_cset(Vec2* v, const double x, const double y);
|
void vect_cset(Vec2* v, const double x, const double y);
|
||||||
|
@ -172,7 +172,7 @@ static void pilot_shootWeapon(Pilot* p, PilotOutfit* w, const unsigned int t) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Missile launchers.
|
// 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)) {
|
else if(outfit_isLauncher(w->outfit) && (w == p->secondary) && (p->id != t)) {
|
||||||
if(p->ammo && (p->ammo->quantity > 0)) {
|
if(p->ammo && (p->ammo->quantity > 0)) {
|
||||||
weapon_add(p->ammo->outfit, p->solid->dir, &p->solid->pos, &p->solid->vel, p->id, t);
|
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))
|
if(!pilot_isFlag(pilot, PILOT_HYPERSPACE))
|
||||||
// Should not go faster.
|
// 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.
|
// Pilot is getting ready or is in, hyperspace.
|
||||||
|
55
src/weapon.c
55
src/weapon.c
@ -113,14 +113,14 @@ void weapons_delay(unsigned int delay) {
|
|||||||
wfrontLayer[i]->timer += delay;
|
wfrontLayer[i]->timer += delay;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Seeker brain, You get what you pay for. :)
|
||||||
static void think_seeker(Weapon* w) {
|
static void think_seeker(Weapon* w) {
|
||||||
double diff;
|
double diff;
|
||||||
if(w->target == w->parent) return; // HEY! Self harm is not allowed.
|
if(w->target == w->parent) return; // HEY! Self harm is not allowed.
|
||||||
|
|
||||||
Pilot* p = pilot_get(w->target);
|
Pilot* p = pilot_get(w->target);
|
||||||
if(p == NULL) {
|
if(p == NULL) {
|
||||||
if(VMOD(w->solid->vel) > w->outfit->u.amm.speed) // Should not go faster.
|
limit_speed(&w->solid->vel, w->outfit->u.amm.speed);
|
||||||
vect_pset(&w->solid->vel, w->outfit->u.amm.speed, VANGLE(w->solid->vel));
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -134,10 +134,41 @@ static void think_seeker(Weapon* w) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
vect_pset(&w->solid->force, w->outfit->u.amm.thrust, w->solid->dir);
|
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.
|
// 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++) {
|
for(i = 0; i < (*nlayer); i++) {
|
||||||
w = wlayer[i];
|
w = wlayer[i];
|
||||||
switch(wlayer[i]->outfit->type) {
|
switch(wlayer[i]->outfit->type) {
|
||||||
|
// Most missiles behave the same.
|
||||||
case OUTFIT_TYPE_MISSILE_SEEK_AMMO:
|
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)) {
|
if(SDL_GetTicks() > (wlayer[i]->timer + wlayer[i]->outfit->u.amm.duration)) {
|
||||||
weapon_destroy(wlayer[i], layer);
|
weapon_destroy(wlayer[i], layer);
|
||||||
continue;
|
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);
|
if((rdir > 2.*M_PI) || (rdir < 0.)) rdir = fmod(rdir, 2.*M_PI);
|
||||||
vectcpy(&v, vel);
|
vectcpy(&v, vel);
|
||||||
vect_cadd(&v, outfit->u.wpn.speed*cos(rdir), outfit->u.wpn.speed*sin(rdir));
|
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->solid = solid_create(mass, rdir, pos, &v);
|
||||||
w->voice = sound_addVoice(VOICE_PRIORITY_BOLT,
|
w->voice = sound_addVoice(VOICE_PRIORITY_BOLT,
|
||||||
w->solid->pos.x, w->solid->pos.y,
|
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->voice = sound_addVoice(VOICE_PRIORITY_AMMO,
|
||||||
w->solid->pos.x, w->solid->pos.y,
|
w->solid->pos.x, w->solid->pos.y,
|
||||||
w->solid->vel.x, w->solid->vel.y, w->outfit->u.amm.sound, 0);
|
w->solid->vel.x, w->solid->vel.y, w->outfit->u.amm.sound, 0);
|
||||||
|
|
||||||
break;
|
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:
|
default:
|
||||||
// Just dump it where the player is.
|
// Just dump it where the player is.
|
||||||
w->voice = NULL;
|
w->voice = NULL;
|
||||||
|
Loading…
Reference in New Issue
Block a user