Lephisto/src/pilot.c
2013-02-02 00:39:48 +00:00

134 lines
3.5 KiB
C

#include <string.h>
#include <math.h>
#include <stdlib.h>
#include <assert.h>
#include "def.h"
#include "log.h"
#include "pilot.h"
// Stack of pilot id's to assure uniqueness.
static unsigned int pilot_id = 0;
// Stack of pilots - yes, they come in stacks now.
static Pilot** pilot_stack;
static int pilots = 0;
extern void player_think(Pilot* pilot, const FP dt); // Player.c
extern void ai_think(Pilot* pilot); // Ai.c
static void pilot_update(Pilot* pilot, const FP dt);
static void pilot_render(Pilot* pilot);
// Pull a pilot out of the pilot_stack based on id.
Pilot* get_pilot(unsigned int id) {
// Regular search.
#if 0
for(int i = 0; i < pilots; i++)
if(pilot_stack[i]->id == id)
return pilot_stack[i];
return NULL;
#endif
// Dichotomical search.
int i, n;
for(i = 0, n = pilots/2; n > 0; n /= 2)
i += (pilot_stack[i+n]->id > id) ? 0 : n;
return (pilot_stack[i]->id == id) ? pilot_stack[i] : NULL;
}
// Render the pilot.
static void pilot_render(Pilot* pilot) {
int sprite;
Vec2 pos;
gl_texture* texture = pilot->ship->gfx_ship;
pos.x = pilot->solid->pos.x;
pos.y = pilot->solid->pos.y;
// Get the sprite corresponding to the direction facing.
sprite = (int)(pilot->solid->dir / (2.0*M_PI / (texture->sy * texture->sx)));
gl_blitSprite(texture, &pos, sprite % (int)texture->sx, sprite / (int)texture->sy);
}
// Update the pilot.
static void pilot_update(Pilot* pilot, const FP dt) {
if(pilot->solid->dir > 2*M_PI) pilot->solid->dir -= 2*M_PI;
if(pilot->solid->dir < 0.0) pilot->solid->dir += 2*M_PI;
// Update the solid.
pilot->solid->update(pilot->solid, dt);
pilot_render(pilot);
}
// ==Init pilot.===========================================
// ship : Ship pilot is flying.
// name : Pilot's name, if NULL, ships name will be used.
// vel : Initial velocity.
// pos : Initial position.
// flags : Tweaking the pilot.
// ========================================================
void pilot_init(Pilot* pilot, Ship* ship, char* name, const Vec2* vel, const Vec2* pos, const int flags) {
pilot->id = ++pilot_id; // New unique pilot id based on pilot_id, Can't be 0.
pilot->ship = ship;
pilot->name = strdup((name == NULL) ? ship->name:name);
pilot->solid = solid_create(ship->mass, vel, pos);
// Max shields armor.
pilot->armor = ship->armor;
pilot->shield = ship->shield;
pilot->energy = ship->energy;
// Initially idle.
pilot->action = NULL;
if(flags & PILOT_PLAYER) {
pilot->think = (void*)player_think; // Players don't need to thing! :P
pilot->properties |= PILOT_PLAYER;
player = pilot;
} else
pilot->think = ai_think;
pilot->update = pilot_update;
}
// Create a new pilot - Params are same as pilot_init. Return pilot's id.
unsigned int pilot_create(Ship* ship, char* name, const Vec2* vel, const Vec2* pos, const int flags) {
Pilot* dyn = MALLOC_L(Pilot);
if(dyn == NULL) {
WARN("Unable to allocate memory.");
return 0;
}
pilot_init(dyn, ship, name, vel, pos, flags);
// Add to the stack.
pilot_stack = realloc(pilot_stack, ++pilots*sizeof(Pilot*));
pilot_stack[pilots-1] = dyn;
return dyn->id;
}
// Free the prisoned pilot!
void pilots_free(void) {
int i;
for(i = 0; i < pilots; i++) {
solid_free(pilot_stack[i]->solid);
free(pilot_stack[i]->name);
free(pilot_stack[i]);
}
free(pilot_stack);
}
// Update all pilots.
void pilots_update(FP dt) {
int i;
for(i = pilots-1; i >= 0; i--) {
if(pilot_stack[i]->think != NULL)
pilot_stack[i]->think(pilot_stack[i]);
pilot_stack[i]->update(pilot_stack[i], dt);
}
}