diff --git a/src/weapon.c b/src/weapon.c index 650b348..c583029 100644 --- a/src/weapon.c +++ b/src/weapon.c @@ -73,6 +73,7 @@ static void weapon_destroy(Weapon* w, WeaponLayer layer); static void weapon_free(Weapon* w); /* Think. */ static void think_seeker(Weapon* w, const double dt); +static void think_beam(Weapon* w, const double dt); /*static void think_smart(Weapon* w, const double dt);*/ /* Extern. */ void weapon_minimap(const double res, const double w, @@ -177,48 +178,41 @@ static void think_seeker(Weapon* w, const double dt) { /*limit_speed(&w->solid->vel, w->outfit->u.amm.speed, dt);*/ } -/* ======================================================== - * Smart seeker brain. Much better at homing. - * ======================================================== +/** + * @fn static void think_beam(Weapon* w, const double dt) + * + * @brief The Pseudo-ai of the beam weapons. + * @param w Weapon to do the thinking. + * @return dt Current delta tick. */ -#if 0 -static void think_smart(Weapon* w, const double dt) { - Vec2 sv, tv; - double t; - - if(w->target == w->parent) return; /* No self shooting here. */ - - Pilot* p = pilot_get(w->target); /* No null pilots.. */ +static void think_beam(Weapon* w, const double dt) { + (void) dt; + Pilot* p; + /* Get pilot, if pilot is dead beam is destroyed too. */ + p = pilot_get(w->parent); if(p == NULL) { - limit_speed(&w->solid->vel, w->outfit->u.amm.speed, dt); + w->timer = -1; /* Hack to make it get destroyed next update. */ return; } - /* Ammo isn't locked on yet. */ - if(w->lockon < 0.) { - vect_cset(&tv, VX(p->solid->pos) + dt*VX(p->solid->vel), - VY(p->solid->pos) + dt*VY(p->solid->vel)); + /* Update beam position to match pilot. */ + w->solid->pos.x = p->solid->pos.x; + w->solid->pos.y = p->solid->pos.y; - vect_cset(&sv, VX(w->solid->pos) + dt*VX(w->solid->vel), - VY(w->solid->pos) + dt*VY(w->solid->vel)); - - t = -angle_diff(w->solid->dir, vect_angle(&tv, &sv)); - - w->solid->dir_vel = t * 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; + /* Handle aiming. */ + switch(w->outfit->type) { + case OUTFIT_TYPE_BEAM: + w->solid->dir = p->solid->dir; + break; + case OUTFIT_TYPE_TURRET_BEAM: + /** @todo Have beam turret aim independently. */ + w->solid->dir = p->solid->dir; + break; + default: + return; } - - vect_pset(&w->solid->vel, w->outfit->u.amm.speed, w->solid->dir); - - limit_speed(&w->solid->vel, w->outfit->u.amm.speed, dt); - } -#endif /* Update all the weapon layers. */ void weapons_update(const double dt) { @@ -339,7 +333,7 @@ static void weapon_render(const Weapon* w) { static void weapon_update(Weapon* w, const double dt, WeaponLayer layer) { int i, wsx, wsy, psx, psy; glTexture* gfx; - Vec2 crash; + Vec2 crash[2]; gfx = outfit_gfx(w->outfit); @@ -353,14 +347,30 @@ static void weapon_update(Weapon* w, const double dt, WeaponLayer layer) { if(w->parent == pilot_stack[i]->id) continue; /* Hey! That's you. */ + /* Beam weapons have special collisions. */ + if(outfit_isBeam(w->outfit)) { + if(!areAllies(w->faction, pilot_stack[i]->faction) && + CollideLineSprite(&w->solid->pos, w->solid->dir, + w->outfit->u.bem.range, + pilot_stack[i]->ship->gfx_space, psx, psy, + &pilot_stack[i]->solid->pos, + crash)) { + + /** @todo beam_hit Needs it's own function. */ + + /* No return because beam can still think, it's not + * destroyed like the other weapons. */ + } + } + /* Smart weapons only collide with their target. */ - if(weapon_isSmart(w)) { + else if(weapon_isSmart(w)) { if((pilot_stack[i]->id == w->target) && CollideSprite(gfx, wsx, wsy, &w->solid->pos, pilot_stack[i]->ship->gfx_space, psx, psy, &pilot_stack[i]->solid->pos, - &crash)) { + &crash[0])) { - weapon_hit(w, pilot_stack[i], layer, &crash); + weapon_hit(w, pilot_stack[i], layer, &crash[0]); return; } /* Dumb weapons hit anything not of the same faction. */ @@ -368,9 +378,9 @@ static void weapon_update(Weapon* w, const double dt, WeaponLayer layer) { !areAllies(w->faction, pilot_stack[i]->faction) && CollideSprite(gfx, wsx, wsy, &w->solid->pos, pilot_stack[i]->ship->gfx_space, psx, psy, &pilot_stack[i]->solid->pos, - &crash)) { + &crash[0])) { - weapon_hit(w, pilot_stack[i], layer, &crash); + weapon_hit(w, pilot_stack[i], layer, &crash[0]); return; } } @@ -474,6 +484,14 @@ static Weapon* weapon_create(const Outfit* outfit, const double dir, const Vec2* w->solid->pos.x + w->solid->vel.x, w->solid->pos.y + w->solid->vel.y); break; + + /* Beam weapons are treated together. */ + case OUTFIT_TYPE_BEAM: + case OUTFIT_TYPE_TURRET_BEAM: + mass = 1.; + w->solid = solid_create(mass, dir, pos, NULL); + w->think = think_beam; + break; /* Treat seekers togther. */ case OUTFIT_TYPE_MISSILE_SEEK_AMMO: