134 lines
3.5 KiB
C
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);
|
|
}
|
|
}
|
|
|