diff --git a/src/pilot.c b/src/pilot.c index b4dc430..e41f4df 100644 --- a/src/pilot.c +++ b/src/pilot.c @@ -313,12 +313,14 @@ void pilot_dead(Pilot* p) { void pilot_setSecondary(Pilot* p, const char* secondary) { int i; + // No need for ammo if there is no secondary. if(secondary == NULL) { p->secondary = NULL; p->ammo = NULL; return; } + // Find the secondary and set ammo appropriately. for(i = 0; i < p->noutfits; i++) { if(strcmp(secondary, p->outfits[i].outfit->name)==0) { p->secondary = &p->outfits[i];; @@ -337,22 +339,37 @@ void pilot_setAmmo(Pilot* p) { int i; char* name; + // Only launchers use ammo. if((p->secondary == NULL) || !outfit_isLauncher(p->secondary->outfit)) { p->ammo = NULL; return; } + // Find the ammo and set it. name = p->secondary->outfit->u.lau.ammo; for(i = 0; i < p->noutfits; i++) if(strcmp(p->outfits[i].outfit->name, name)==0) { - p->ammo = p->outfits + i; + p->ammo = &p->outfits[i]; return; } + // None found, so we assume if doesn't need ammo. p->ammo = NULL; } +// Set the pilots afterburner. +void pilot_setAfterburner(Pilot* p) { + int i; + + for(i = 0; i < p->noutfits; i++) + if(outfit_isAfterburner(p->outfits[i].outfit)) { + p->afterburner = &p->outfits[i]; + return; + } + p->afterburner = NULL; +} + // Render the pilot. void pilot_render(Pilot* p) { gl_blitSprite(p->ship->gfx_space, @@ -365,22 +382,25 @@ static void pilot_update(Pilot* pilot, const double dt) { unsigned int t, l; double a, px, py, vx, vy; + // She's dead D: if(pilot_isFlag(pilot, PILOT_DEAD)) { t = SDL_GetTicks(); - if(t > pilot->ptimer) { - if(pilot->id == PLAYER_ID) + if(t > pilot->ptimer) { // Completely destroyed with final explosion. + if(pilot->id == PLAYER_ID) // Player handled differently. player_destroyed(); pilot_setFlag(pilot, PILOT_DELETE); // It'll get deleted next frame. return; } + // Final explosion. if(!pilot_isFlag(pilot, PILOT_EXPLODED) && (t > pilot->ptimer - 200)) { spfx_add(spfx_get("ExpL"), VX(pilot->solid->pos), VY(pilot->solid->pos), VX(pilot->solid->vel), VY(pilot->solid->vel), SPFX_LAYER_BACK); pilot_setFlag(pilot, PILOT_EXPLODED); } + // Reset random explosion time. else if(t > pilot->timer[1]) { pilot->timer[1] = t + (unsigned int)(100*(double)(pilot->ptimer - pilot->timer[1]) / @@ -401,7 +421,7 @@ static void pilot_update(Pilot* pilot, const double dt) { } } else if(pilot->armour <= 0.) // PWNED! - pilot_dead(pilot); + pilot_dead(pilot); // Start death stuff. // Pupose fallthrough to get the movement similar to disabled. if(pilot != player && pilot->armour < PILOT_DISABLED_ARMOUR * pilot->armour_max) { @@ -410,7 +430,7 @@ static void pilot_update(Pilot* pilot, const double dt) { // Come to a halt slowly. vect_pset(&pilot->solid->vel, VMOD(pilot->solid->vel) * (1. - dt*0.10), VANGLE(pilot->solid->vel)); - vectnull(&pilot->solid->force); + vectnull(&pilot->solid->force); // No more accel. pilot->solid->dir_vel = 0.; // Stop it from turning. // Update the solid. @@ -421,13 +441,16 @@ static void pilot_update(Pilot* pilot, const double dt) { } // We are still alive. else if(pilot->armour < pilot->armour_max) { + // Regen armour. pilot->armour += pilot->armour_regen*dt; pilot->energy += pilot->energy_regen*dt; } else { + // And shields. pilot->shield += pilot->shield_regen*dt; pilot->energy += pilot->energy_regen*dt; } + // Check limits. if(pilot->armour > pilot->armour_max) pilot->armour = pilot->armour_max; if(pilot->shield > pilot->shield_max) pilot->shield = pilot->shield_max; if(pilot->energy > pilot->energy_max) pilot->energy = pilot->energy_max; @@ -438,14 +461,16 @@ static void pilot_update(Pilot* pilot, const double dt) { pilot->ship->gfx_space, pilot->solid->dir); if(!pilot_isFlag(pilot, PILOT_HYPERSPACE)) { // Limit the speed. + + // Pilot is afterburning. if(pilot_isFlag(pilot, PILOT_AFTERBURNER) && // Must have enough energy. (player->energy > pilot->afterburner->outfit->u.afb.energy * dt)) { - limit_speed(&pilot->solid->vel, + limit_speed(&pilot->solid->vel, // Limit is higher. pilot->speed * pilot->afterburner->outfit->u.afb.speed_perc + pilot->afterburner->outfit->u.afb.speed_abs, dt); spfx_shake(SHAKE_DECAY/2. * dt); // Shake goes down at half speed. pilot->energy -= pilot->afterburner->outfit->u.afb.energy * dt; // Energy loss. - } else + } else // Normal limit. limit_speed(&pilot->solid->vel, pilot->speed, dt); } } @@ -454,8 +479,10 @@ static void pilot_update(Pilot* pilot, const double dt) { static void pilot_hyperspace(Pilot* p) { double diff; + // Pilot is actually in hyperspace. if(pilot_isFlag(p, PILOT_HYPERSPACE)) { - // Pilot is actually in hyperspace. + + // Has the jump happened? if(SDL_GetTicks() > p->ptimer) { if(p == player) { player_brokeHyperspace(); @@ -463,8 +490,10 @@ static void pilot_hyperspace(Pilot* p) { pilot_setFlag(p, PILOT_DELETE); // Set flag to delete pilot. return; } - vect_pset(&p->solid->force, p->thrust * 3., p->solid->dir); + // Keep accelerating - hyperspace uses much bigger accel. + vect_pset(&p->solid->force, p->thrust * 5., p->solid->dir); } + // Engines getting ready for the jump. else if(pilot_isFlag(p, PILOT_HYP_BEGIN)) { if(SDL_GetTicks() > p->ptimer) { // Engines are ready. @@ -474,12 +503,14 @@ static void pilot_hyperspace(Pilot* p) { } else { // Pilot is getting ready for hyperspace. + // Brake. if(VMOD(p->solid->vel) > MIN_VEL_ERR) { diff = pilot_face(p, VANGLE(p->solid->vel) + M_PI); - if(ABS(diff) < MAX_DIR_ERR) // Brake. + if(ABS(diff) < MAX_DIR_ERR) vect_pset(&p->solid->force, p->thrust, p->solid->dir); } else { + // Face target. vectnull(&p->solid->force); // Stop accelerating. // Player should actually face the system she's headed to. @@ -498,10 +529,11 @@ static void pilot_hyperspace(Pilot* p) { int pilot_addOutfit(Pilot* pilot, Outfit* outfit, int quantity) { int i, q; - char* s; + char* osec; q = quantity; + // Does outfit already exist? for(i = 0; i < pilot->noutfits; i++) if(strcmp(outfit->name, pilot->outfits[i].outfit->name)==0) { pilot->outfits[i].quantity += quantity; @@ -510,20 +542,27 @@ int pilot_addOutfit(Pilot* pilot, Outfit* outfit, int quantity) { q -= pilot->outfits[i].quantity - outfit->max; pilot->outfits[i].quantity = outfit->max; } + // Recalculate the stats. pilot_calcStats(pilot); return q; } - s = (pilot->secondary) ? pilot->secondary->outfit->name : NULL; + // Hacks in case it reallocs. + osec = (pilot->secondary) ? pilot->secondary->outfit->name : NULL; + // No need for ammo since it's already handled in setSecondary, + // since pilot has only one afterburner it's handled at the end. + + // Grow the outfits. pilot->outfits = realloc(pilot->outfits, (pilot->noutfits+1)*sizeof(PilotOutfit)); pilot->outfits[pilot->noutfits].outfit = outfit; pilot->outfits[pilot->noutfits].quantity = quantity; + // Can't be over max. if(pilot->outfits[pilot->noutfits].quantity > outfit->max) { q -= pilot->outfits[pilot->noutfits].quantity - outfit->max; pilot->outfits[i].quantity = outfit->max; } - pilot->outfits[pilot->noutfits].timer = 0; + pilot->outfits[pilot->noutfits].timer = 0; // Reset time. (pilot->noutfits)++; if(outfit_isTurret(outfit)) @@ -531,7 +570,8 @@ int pilot_addOutfit(Pilot* pilot, Outfit* outfit, int quantity) { pilot_setFlag(pilot, PILOT_HASTURRET); // Hack due to realloc possibility. - pilot_setSecondary(pilot, s); + pilot_setSecondary(pilot, osec); + pilot_setAfterburner(pilot); pilot_calcStats(pilot); return q; @@ -540,7 +580,7 @@ int pilot_addOutfit(Pilot* pilot, Outfit* outfit, int quantity) { // Remove an outfit from the pilot. int pilot_rmOutfit(Pilot* pilot, Outfit* outfit, int quantity) { int i, q, c; - char* s; + char* osec; c = (outfit_isMod(outfit)) ? outfit->u.mod.cargo : 0; q = quantity; @@ -551,11 +591,9 @@ int pilot_rmOutfit(Pilot* pilot, Outfit* outfit, int quantity) { if(pilot->outfits[i].quantity <= 0) { // We didn't actually remove the full amount. q += pilot->outfits[i].quantity; + // Hack in case it reallocs - Can happen even when shrinking. - s = (pilot->secondary) ? pilot->secondary->outfit->name : NULL; - // Clear it if it's the afterburner. - if(&pilot->outfits[i] == pilot->afterburner) - pilot->afterburner = NULL; + osec = (pilot->secondary) ? pilot->secondary->outfit->name : NULL; // Remove the outfit. memmove(pilot->outfits+i, pilot->outfits+i+1, @@ -564,7 +602,9 @@ int pilot_rmOutfit(Pilot* pilot, Outfit* outfit, int quantity) { pilot->outfits = realloc(pilot->outfits, sizeof(PilotOutfit)*(pilot->noutfits)); - pilot_setSecondary(pilot, s); + // Set secondary and afterburner. + pilot_setSecondary(pilot, osec); + pilot_setAfterburner(pilot); } pilot_calcStats(pilot); // Recalculate stats. pilot->cargo_free -= c; @@ -647,10 +687,9 @@ void pilot_calcStats(Pilot* pilot) { // Misc. pilot->cargo_free += o->u.mod.cargo * q; } - else if(outfit_isAfterburner(pilot->outfits[i].outfit)) { + else if(outfit_isAfterburner(pilot->outfits[i].outfit)) // Set afterburner. // Set the afterburner. pilot->afterburner = &pilot->outfits[i]; - } } // Give the pilot her health proportion back. @@ -669,6 +708,7 @@ int pilot_cargoFree(Pilot* p) { int pilot_addCargo(Pilot* pilot, Commodity* cargo, int quantity) { int i, q; + // Check if pilot has it first. q = quantity; for(i = 0; i < pilot->ncommodities; i++) if(!pilot->commodities[i].id && (pilot->commodities[i].commodity == cargo)) { @@ -734,15 +774,17 @@ unsigned int pilot_addMissionCargo(Pilot* pilot, Commodity* cargo, int quantity) return pilot->commodities[pilot->ncommodities-1].id; } +// Remove special misssion cargo based on id. int pilot_rmMissionCargo(Pilot* pilot, unsigned int cargo_id) { int i; + // Check if pilot has it. for(i = 0; i < pilot->ncommodities; i++) if(pilot->commodities[i].id == cargo_id) break; if(i >= pilot->ncommodities) - return 1; + return 1; // Pilot doesn't have it. // Remove cargo. pilot->cargo_free += pilot->commodities[i].quantity; @@ -762,8 +804,10 @@ int pilot_rmMissionCargo(Pilot* pilot, unsigned int cargo_id) { int pilot_rmCargo(Pilot* pilot, Commodity* cargo, int quantity) { int i, q; + // Check if pilot has it. q = quantity; for(i = 0; i < pilot->ncommodities; i++) + // Doesn't remove mission cargo. if(!pilot->commodities[i].id && (pilot->commodities[i].commodity == cargo)) { if(quantity >= pilot->commodities[i].quantity) { q = pilot->commodities[i].quantity; @@ -782,7 +826,7 @@ int pilot_rmCargo(Pilot* pilot, Commodity* cargo, int quantity) { return q; } - return 0; + return 0; // Pilot didn't have it. } // Add a hook to the pilot. diff --git a/src/pilot.h b/src/pilot.h index 6c3b2f0..c5f2337 100644 --- a/src/pilot.h +++ b/src/pilot.h @@ -147,6 +147,7 @@ void pilot_hit(Pilot* p, const Solid* w, const unsigned int shooter, const DamageType dtype, const double damage); void pilot_setSecondary(Pilot* p, const char* secondary); void pilot_setAmmo(Pilot* p); +void pilot_setAfterburner(Pilot* p); double pilot_face(Pilot* p, const float dir); // Outfits. int pilot_freeSpace(Pilot* p); // Pilot space.