[Fix]? Attempted to fix seg fault on AI trying to switch to secondary weapons when there is none available.

This commit is contained in:
Allanis 2013-02-17 23:30:40 +00:00
parent 8eb62f218f
commit 268b5dcaa0
4 changed files with 44 additions and 30 deletions

View File

@ -33,6 +33,7 @@ extern void ai_think(Pilot* pilot); // Ai.c
extern void player_think(Pilot* pilot); // Player.c extern void player_think(Pilot* pilot); // Player.c
extern int gui_load(const char* name); // Player.c extern int gui_load(const char* name); // Player.c
// Internal. // Internal.
static void pilot_shootWeapon(Pilot* p, PilotOutfit* w, const unsigned int t);
static void pilot_update(Pilot* pilot, const double dt); static void pilot_update(Pilot* pilot, const double dt);
void pilot_render(Pilot* pilot); void pilot_render(Pilot* pilot);
static void pilot_free(Pilot* p); static void pilot_free(Pilot* p);
@ -108,37 +109,50 @@ Pilot* pilot_get(const unsigned int id) {
// Mkay, this is how we shoot. Listen up. // Mkay, this is how we shoot. Listen up.
void pilot_shoot(Pilot* p, const unsigned int target, const int secondary) { void pilot_shoot(Pilot* p, const unsigned int target, const int secondary) {
int i; int i;
if(!p->outfits) return; // No outfits.
if(!secondary) { if(!secondary) {
// Primary weapons. // Primary weapons.
if(!p->outfits) return; // No outfits. for(i = 0; i < p->noutfits; i++)
// Cycle through outfits to find primary weapons.
for(i = 0; i < p->noutfits; i++) // Cycle through outfits to find weapons. if(!outfit_isProp(p->outfits[i].outfit, OUTFIT_PROP_WEAP_SECONDARY))
if(outfit_isWeapon(p->outfits[i].outfit)) // Are we a weapon? pilot_shootWeapon(p, &p->outfits[i], target);
// Ready to shoot again.
if((SDL_GetTicks()-p->outfits[i].timer) > (p->outfits[i].outfit->delay/p->outfits[i].quantity))
// Different weapons have different behaviours.
switch(p->outfits[i].outfit->type) {
case OUTFIT_TYPE_BOLT:
weapon_add(p->outfits[i].outfit, p->solid->dir, &p->solid->pos,
&p->solid->vel, p->id, target, (p==player) ? WEAPON_LAYER_FG : WEAPON_LAYER_BG);
p->outfits[i].timer = SDL_GetTicks(); // Let's not try this again for a while.
break;
default:
break;
}
} else { } else {
if(!p->secondary) return; // No secondary weapon. if(!p->secondary) return; // No secondary weapon.
pilot_shootWeapon(p, p->secondary, target);
}
}
if(outfit_isLauncher(p->secondary->outfit)) { static void pilot_shootWeapon(Pilot* p, PilotOutfit* w, const unsigned int t) {
if(((SDL_GetTicks()-p->secondary->timer) > // WElll... Trying to shoot when you have no ammo?? FUUU
(p->secondary->outfit->delay/p->secondary->quantity)) && int quantity = (outfit_isAmmo(w->outfit) && p->secondary) ?
p->ammo && (p->ammo->quantity > 0)) { p->secondary->quantity : w->quantity;
weapon_add(p->ammo->outfit, p->solid->dir, &p->solid->pos, &p->solid->vel, // Check to see if weapon is ready.
p->id, target, (p==player) ? WEAPON_LAYER_FG : WEAPON_LAYER_BG); if((SDL_GetTicks() - w->timer) < (w->outfit->delay / quantity)) return;
p->secondary->timer = SDL_GetTicks(); // Let's not try this again for a while. // Regular weapons.
p->ammo->quantity -= 1; // No getting this one back. if(outfit_isWeapon(w->outfit)) {
} // Different weapons.
switch(w->outfit->type) {
case OUTFIT_TYPE_BOLT:
weapon_add(w->outfit, p->solid->dir, &p->solid->pos, &p->solid->vel, p->id, t);
// Can't shoot for a while.
w->timer = SDL_GetTicks();
break;
default:
break;
}
}
// Missile launchers.
// Must be secondary weapon, Shootee 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);
w->timer = SDL_GetTicks(); // Can't shoot for a while.
p->ammo->quantity -= 1; // There's no getting this one back.
} }
} }
} }

View File

@ -767,7 +767,7 @@ void player_think(Pilot* player) {
player->solid->dir_vel -= player->ship->turn * player_turn; player->solid->dir_vel -= player->ship->turn * player_turn;
if(player_isFlag(PLAYER_PRIMARY)) pilot_shoot(player, 0, 0); if(player_isFlag(PLAYER_PRIMARY)) pilot_shoot(player, 0, 0);
if(player_isFlag(PLAYER_SECONDARY) && (player_target != PLAYER_ID)) // Needs a target. if(player_isFlag(PLAYER_SECONDARY)) // Needs a target.
pilot_shoot(player, player_target, 1); pilot_shoot(player, player_target, 1);
vect_pset(&player->solid->force, player->ship->thrust * player_acc, player->solid->dir); vect_pset(&player->solid->force, player->ship->thrust * player_acc, player->solid->dir);

View File

@ -276,13 +276,14 @@ static Weapon* weapon_create(const Outfit* outfit, const double dir, const Vec2*
// Add a new weapon. // Add a new weapon.
void weapon_add(const Outfit* outfit, const double dir, const Vec2* pos, const Vec2* vel, void weapon_add(const Outfit* outfit, const double dir, const Vec2* pos, const Vec2* vel,
unsigned int parent, unsigned int target, const WeaponLayer layer) { unsigned int parent, unsigned int target) {
if(!outfit_isWeapon(outfit) && !outfit_isAmmo(outfit)) { if(!outfit_isWeapon(outfit) && !outfit_isAmmo(outfit)) {
ERR("Trying to create a weapon from a non-Weapon type Outfit"); ERR("Trying to create a weapon from a non-Weapon type Outfit");
return; return;
} }
WeaponLayer layer = (parent == PLAYER_ID) ? WEAPON_LAYER_FG : WEAPON_LAYER_BG;
Weapon* w = weapon_create(outfit, dir, pos, vel, parent, target); Weapon* w = weapon_create(outfit, dir, pos, vel, parent, target);
// Set the propper layer. // Set the propper layer.

View File

@ -4,9 +4,8 @@
typedef enum { WEAPON_LAYER_BG, WEAPON_LAYER_FG } WeaponLayer; typedef enum { WEAPON_LAYER_BG, WEAPON_LAYER_FG } WeaponLayer;
void weapon_add(const Outfit* outfit, const double dir, void weapon_add(const Outfit* outfit, const double dir, const Vec2* pos,
const Vec2* pos, const Vec2* vel, unsigned int parent, const Vec2* vel, unsigned int parent, const unsigned int target);
const unsigned int target, const WeaponLayer layer);
// Pausing. // Pausing.
void weapons_pause(void); void weapons_pause(void);