[Add] Lua function calls.
This commit is contained in:
parent
57dc51fb91
commit
b3c21a5c4e
14
dat/SHIP
Normal file
14
dat/SHIP
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
// ================
|
||||||
|
// NOTES.
|
||||||
|
// ================
|
||||||
|
|
||||||
|
Units:
|
||||||
|
Thrust, speed is in pixels/second.
|
||||||
|
turn is in degrees per half a second.
|
||||||
|
|
||||||
|
energy, armor and shield regen are in points a minute.
|
||||||
|
|
||||||
|
crew is in, uh.. people.
|
||||||
|
mass is in tons.
|
||||||
|
cargo and weapon capacity are int tons.
|
||||||
|
|
@ -3,7 +3,7 @@
|
|||||||
<fleet name="Test">
|
<fleet name="Test">
|
||||||
<faction>2</faction>
|
<faction>2</faction>
|
||||||
<pilots>
|
<pilots>
|
||||||
<pilot chance='100'>Mr. Test</pilot>
|
<pilot chance='100'>Miss. Test</pilot>
|
||||||
</pilots>
|
</pilots>
|
||||||
</fleet>
|
</fleet>
|
||||||
<fleet name="Merchant Ship">
|
<fleet name="Merchant Ship">
|
||||||
|
214
src/ai.c
214
src/ai.c
@ -3,6 +3,8 @@
|
|||||||
#include <lauxlib.h>
|
#include <lauxlib.h>
|
||||||
#include <lualib.h>
|
#include <lualib.h>
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
#include "def.h"
|
#include "def.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "pilot.h"
|
#include "pilot.h"
|
||||||
@ -25,19 +27,31 @@
|
|||||||
// Call the AI function with name f.
|
// Call the AI function with name f.
|
||||||
#define AI_LCALL(f) (lua_getglobal(L, f), lua_call(L, 0, 0))
|
#define AI_LCALL(f) (lua_getglobal(L, f), lua_call(L, 0, 0))
|
||||||
|
|
||||||
|
// Don't run the function if (n) params aren't passed.
|
||||||
|
#define MIN_ARGS(n) if(lua_gettop(L) < n) return 0
|
||||||
|
|
||||||
static int ai_minbrakedist(lua_State* L); // Minimal breaking distance.
|
static int ai_minbrakedist(lua_State* L); // Minimal breaking distance.
|
||||||
static int ai_accel(lua_State* L); // Accelerate.
|
static int ai_accel(lua_State* L); // Accelerate.
|
||||||
|
|
||||||
// Basic task.
|
// Internal C routines.
|
||||||
// name : Tasks name (Lua function.)
|
static void ai_freetask(Task* t);
|
||||||
// target : Target, this will depend on the task itself.
|
// Ai routines for Lua.
|
||||||
typedef struct {
|
// Tasks.
|
||||||
char* name;
|
static int ai_pushtask(lua_State* L); // pushtask(string, number/pointer, number)
|
||||||
union {
|
static int ai_poptask(lua_State* L); // poptask()
|
||||||
void* target;
|
static int ai_taskname(lua_State* L); // Number taskname.
|
||||||
unsigned int ID;
|
// Consult values.
|
||||||
};
|
static int ai_gettarget(lua_State* L); // Pointer gettarget()
|
||||||
} Task;
|
static int ai_gettargetid(lua_State* L); // Number gettargetis()
|
||||||
|
static int ai_getdistance(lua_State* L); // Number getdist(Vec2)
|
||||||
|
static int ai_getpos(lua_State* L); // getpos(number/pilot)
|
||||||
|
static int ai_minbrakedist(lua_State* L); // Number minbrakedist()
|
||||||
|
// Movement.
|
||||||
|
static int ai_accel(lua_State* L); // accel(number); nuimber <= 1.
|
||||||
|
static int ai_turn(lua_State* L); // turn(number); abs(number) <= 1.
|
||||||
|
static int ai_face(lua_State* L); // face(number/pointer)
|
||||||
|
// Misc.
|
||||||
|
static int ai_createvect(lua_State* L); // createvect(number, number)
|
||||||
|
|
||||||
// Global Lua interpreter.
|
// Global Lua interpreter.
|
||||||
static lua_State* L = NULL;
|
static lua_State* L = NULL;
|
||||||
@ -52,11 +66,24 @@ int ai_init(void) {
|
|||||||
if(L == NULL)
|
if(L == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
// Register C funstions in Lua.
|
// Open the standard Lua libraries.
|
||||||
lua_register(L, "minbrakedist", ai_minbrakedist);
|
luaL_openlibs(L);
|
||||||
lua_register(L, "accel", ai_accel);
|
|
||||||
|
|
||||||
if(luaL_dofile(L, "ai_test.lua") != 0) {
|
// Register C funstions in Lua.
|
||||||
|
lua_register(L, "pushtask", ai_pushtask);
|
||||||
|
lua_register(L, "poptask", ai_poptask);
|
||||||
|
lua_register(L, "taskname", ai_taskname);
|
||||||
|
lua_register(L, "gettarget", ai_gettarget);
|
||||||
|
lua_register(L, "gettargetid", ai_gettargetid);
|
||||||
|
lua_register(L, "getdistance", ai_getdistance);
|
||||||
|
lua_register(L, "getpos", ai_getpos);
|
||||||
|
lua_register(L, "minbrakedist", ai_minbrakedist);
|
||||||
|
lua_register(L, "accel", ai_accel);
|
||||||
|
lua_register(L, "turn", ai_turn);
|
||||||
|
lua_register(L, "face", ai_face);
|
||||||
|
lua_register(L, "createvect", ai_createvect);
|
||||||
|
|
||||||
|
if(luaL_dofile(L, "../scripts/ai/test.lua") != 0) {
|
||||||
WARN("Unable to load AI file: %s", "ai_test.lua");
|
WARN("Unable to load AI file: %s", "ai_test.lua");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -72,41 +99,184 @@ void ai_exit(void) {
|
|||||||
void ai_think(Pilot* pilot) {
|
void ai_think(Pilot* pilot) {
|
||||||
cur_pilot = pilot; // Set current pilot being processed.
|
cur_pilot = pilot; // Set current pilot being processed.
|
||||||
pilot_acc = pilot_turn = 0.; // Clean up some variables.
|
pilot_acc = pilot_turn = 0.; // Clean up some variables.
|
||||||
if(pilot->action == NULL) {
|
if(cur_pilot->task == NULL)
|
||||||
// Idle git!
|
// Idle git!
|
||||||
AI_LCALL("control");
|
AI_LCALL("control");
|
||||||
}
|
else
|
||||||
|
// Pilot has a currently running task.
|
||||||
|
AI_LCALL(cur_pilot->task->name);
|
||||||
|
|
||||||
|
// Make sure pilot_acc and pilot_turn are legal moves.
|
||||||
|
if(pilot_acc > 1.) pilot_acc = 1.; // Value must be <= 1.
|
||||||
|
if(pilot_turn > 1.) pilot_turn = 1.; // Value must be between -1 and 1.
|
||||||
|
else if(pilot_turn < -1.) pilot_turn = -1.;
|
||||||
|
|
||||||
cur_pilot->solid->dir_vel = 0.;
|
cur_pilot->solid->dir_vel = 0.;
|
||||||
if(pilot_turn)
|
if(pilot_turn) // Set the turning velocity.
|
||||||
cur_pilot->solid->dir_vel -= cur_pilot->ship->turn * pilot_turn;
|
cur_pilot->solid->dir_vel -= cur_pilot->ship->turn * pilot_turn;
|
||||||
vect_pset(&cur_pilot->solid->force, cur_pilot->ship->thrust * pilot_acc, cur_pilot->solid->dir);
|
vect_pset(&cur_pilot->solid->force, cur_pilot->ship->thrust * pilot_acc, cur_pilot->solid->dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// =====================
|
||||||
|
// INTERNAL C FUNCTIONS.
|
||||||
|
// =====================
|
||||||
|
|
||||||
|
// Free the task.
|
||||||
|
static void ai_freetask(Task* t) {
|
||||||
|
if(t->next) ai_freetask(t->next); // Woot, recursive freeing!
|
||||||
|
|
||||||
|
if(t->name) free(t->name);
|
||||||
|
if(t->target) free(t->target);
|
||||||
|
free(t);
|
||||||
|
}
|
||||||
|
|
||||||
// ========================================================
|
// ========================================================
|
||||||
// C functions to call from Lua.
|
// C functions to call from Lua.
|
||||||
// -----------------------------
|
// ========================================================
|
||||||
|
|
||||||
|
// Push the current stack.
|
||||||
|
static int ai_pushtask(lua_State* L) {
|
||||||
|
int pos;
|
||||||
|
if(lua_isnumber(L, 1)) pos = (int) lua_tonumber(L, 1);
|
||||||
|
else return 0; // Invalid param.
|
||||||
|
|
||||||
|
Task* t = MALLOC_L(Task);
|
||||||
|
t->name = (lua_isstring(L, 2)) ? strdup((char*) lua_tostring(L, 2)) : NULL;
|
||||||
|
t->next = NULL;
|
||||||
|
|
||||||
|
if(lua_gettop(L) > 2) {
|
||||||
|
if(lua_isnumber(L, 3))
|
||||||
|
t->ID = (unsigned int) lua_tonumber(L, 3);
|
||||||
|
else if(lua_islightuserdata(L, 3))
|
||||||
|
t->target = (void*)lua_topointer(L, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(cur_pilot->task == NULL) // No other tasks.
|
||||||
|
cur_pilot->task = t;
|
||||||
|
else if(pos == 1) {
|
||||||
|
// Put at the end.
|
||||||
|
Task* pointer;
|
||||||
|
for(pointer = cur_pilot->task; pointer->next; pointer = pointer->next);
|
||||||
|
pointer->next = t;
|
||||||
|
} else {
|
||||||
|
// Default put at the beginning.
|
||||||
|
t->next = cur_pilot->task;
|
||||||
|
cur_pilot->task = t;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pop the current task.
|
||||||
|
static int ai_poptask(lua_State* L) {
|
||||||
|
Task* t = cur_pilot->task;
|
||||||
|
cur_pilot->task = t->next;
|
||||||
|
t->next = NULL;
|
||||||
|
ai_freetask(t);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Grab the current tasks name.
|
||||||
|
static int ai_taskname(lua_State* L) {
|
||||||
|
if(cur_pilot->task) lua_pushstring(L, cur_pilot->task->name);
|
||||||
|
else lua_pushnil(L);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Grab the targer pointer.
|
||||||
|
static int ai_gettarget(lua_State* L) {
|
||||||
|
lua_pushlightuserdata(L, cur_pilot->task->target);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the ID.
|
||||||
|
static int ai_gettargetid(lua_State* L) {
|
||||||
|
lua_pushnumber(L, cur_pilot->task->ID);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the distance from the pointer.
|
||||||
|
static int ai_getdistance(lua_State* L) {
|
||||||
|
MIN_ARGS(1);
|
||||||
|
Vec2* vect = (Vec2*)lua_topointer(L,1);
|
||||||
|
lua_pushnumber(L, MOD(vect->x-cur_pilot->solid->pos.x, vect->y-cur_pilot->solid->pos.y));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the pilots position.
|
||||||
|
static int ai_getpos(lua_State* L) {
|
||||||
|
Pilot* p;
|
||||||
|
if(lua_isnumber(L, 1)) p = get_pilot((int)lua_tonumber(L,1)); // Pilot ID.
|
||||||
|
else if(lua_islightuserdata(L, 1)) p = (Pilot*)lua_topointer(L, 1); // Pilot pointer.
|
||||||
|
else p = cur_pilot; // Default to ones self.
|
||||||
|
|
||||||
|
lua_pushlightuserdata(L, &p->solid->pos);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ========================================================
|
||||||
// Get the minimum braking distance.
|
// Get the minimum braking distance.
|
||||||
//
|
//
|
||||||
// Braking vel ==> v*t = 0.5 a * t^2 => t = 2*v / a
|
// Braking vel ==> 0 = v - a*dt
|
||||||
// Add turn around time (to initial velocity) :
|
// Add turn around time (to initial velocity) :
|
||||||
// ==> 180.*360./cur_pilot->ship->turn
|
// ==> 180.*360./cur_pilot->ship->turn
|
||||||
// Add it to general euler equation x = v*t + 0.5 * a * t^2
|
// Add it to general euler equation x = v*t + 0.5 * a * t^2
|
||||||
// Have fun.
|
// Have fun.
|
||||||
// ========================================================
|
// ========================================================
|
||||||
static int ai_minbrakedist(lua_State* L) {
|
static int ai_minbrakedist(lua_State* L) {
|
||||||
double time = 2. * VMOD(cur_pilot->solid->vel) /
|
double time = VMOD(cur_pilot->solid->vel) /
|
||||||
(cur_pilot->ship->thrust / cur_pilot->solid->mass);
|
(cur_pilot->ship->thrust / cur_pilot->solid->mass);
|
||||||
|
|
||||||
double dist = VMOD(cur_pilot->solid->vel) * (time + 0.5 * (180. * 360. / cur_pilot->ship->turn)) -
|
double dist = VMOD(cur_pilot->solid->vel) * (time + cur_pilot->ship->turn/360.) -
|
||||||
0.5 * (cur_pilot->ship->thrust / cur_pilot->solid->mass)*time*time;
|
0.5 * (cur_pilot->ship->thrust / cur_pilot->solid->mass)*time*time;
|
||||||
|
|
||||||
lua_pushnumber(L, dist); // return
|
lua_pushnumber(L, dist); // return
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Accelerate the pilot based on a param.
|
||||||
static int ai_accel(lua_State* L) {
|
static int ai_accel(lua_State* L) {
|
||||||
pilot_acc = (lua_isnumber(L, 1)) ? (double)lua_tonumber(L, 1) : 1.;
|
MIN_ARGS(1);
|
||||||
|
pilot_acc = (lua_isnumber(L, 1)) ? ABS((double)lua_tonumber(L, 1)) : 1.;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Turn the pilot based on a param.
|
||||||
|
static int ai_turn(lua_State* L) {
|
||||||
|
MIN_ARGS(1);
|
||||||
|
pilot_turn = (lua_isnumber(L, 1)) ? (double)lua_tonumber(L, 1) : 0.;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Face the target.
|
||||||
|
static int ai_face(lua_State* L) {
|
||||||
|
MIN_ARGS(1);
|
||||||
|
Vec2* v; // Grab the position to face.
|
||||||
|
if(lua_isnumber(L,1)) v = &get_pilot((unsigned int)lua_tonumber(L,1))->solid->pos;
|
||||||
|
else if(lua_islightuserdata(L,1)) v = (Vec2*)lua_topointer(L,1);
|
||||||
|
|
||||||
|
double mod;
|
||||||
|
if(lua_gettop(L) > 1 && lua_isnumber(L,2))
|
||||||
|
switch((int)lua_tonumber(L,2)) {
|
||||||
|
case 1: mod *= -1; break;
|
||||||
|
case 2: break;
|
||||||
|
}
|
||||||
|
|
||||||
|
pilot_turn = mod * angle_diff(cur_pilot->solid->dir, vect_angle(&cur_pilot->solid->pos, v));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a vector.
|
||||||
|
static int ai_createvect(lua_State* L) {
|
||||||
|
MIN_ARGS(2);
|
||||||
|
Vec2* v = MALLOC_L(Vec2);
|
||||||
|
double x = (lua_isnumber(L, 1)) ? (double)lua_tonumber(L,1) : 0.;
|
||||||
|
double y = (lua_isnumber(L, 2)) ? (double)lua_tonumber(L,2) : 0.;
|
||||||
|
|
||||||
|
vect_cset(v, x, y);
|
||||||
|
|
||||||
|
lua_pushlightuserdata(L, (void*)v);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
11
src/ai.h
11
src/ai.h
@ -1,5 +1,16 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
struct Task {
|
||||||
|
struct Task* next;
|
||||||
|
char* name;
|
||||||
|
|
||||||
|
union {
|
||||||
|
void* target; // Vec2 etc.
|
||||||
|
unsigned int ID; // Pilot ID etc.
|
||||||
|
};
|
||||||
|
};
|
||||||
|
typedef struct Task Task;
|
||||||
|
|
||||||
int ai_init(void);
|
int ai_init(void);
|
||||||
void ai_exit(void);
|
void ai_exit(void);
|
||||||
|
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
#define CALLOC_L(type)(calloc(1, sizeof(type)))
|
#define CALLOC_L(type)(calloc(1, sizeof(type)))
|
||||||
|
|
||||||
#define ABS(X) ((X<0)?-X:X)
|
#define ABS(X) ((X<0)?-X:X)
|
||||||
#define FABS(X) ((X<0.)?-X:X)
|
|
||||||
|
|
||||||
#define DATA "data"
|
#define DATA "data"
|
||||||
|
|
||||||
|
@ -4,12 +4,21 @@
|
|||||||
|
|
||||||
#include "physics.h"
|
#include "physics.h"
|
||||||
|
|
||||||
#ifndef M_PI
|
// ================
|
||||||
#define M_PI 3.14159265358979323846f
|
// MISC
|
||||||
#endif
|
// ================
|
||||||
|
double angle_diff(const double ref, double a) {
|
||||||
|
if(a < M_PI) a += 2*M_PI;
|
||||||
|
double d = fmod((a-ref), 2*M_PI);
|
||||||
|
return (d <= M_PI) ? d : d - 2*M_PI;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ================
|
||||||
|
// VEC2
|
||||||
|
// ================
|
||||||
|
|
||||||
// Set the vector value using cartesian coords.
|
// Set the vector value using cartesian coords.
|
||||||
void vect_cset(Vec2* v, double x, double y) {
|
void vect_cset(Vec2* v, const double x, const double y) {
|
||||||
v->x = x;
|
v->x = x;
|
||||||
v->y = y;
|
v->y = y;
|
||||||
v->mod = MOD(x,y);
|
v->mod = MOD(x,y);
|
||||||
@ -17,7 +26,7 @@ void vect_cset(Vec2* v, double x, double y) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Set the vector value using polar coords.
|
// Set the vector value using polar coords.
|
||||||
void vect_pset(Vec2* v, double mod, double angle) {
|
void vect_pset(Vec2* v, const double mod, const double angle) {
|
||||||
v->mod = mod;
|
v->mod = mod;
|
||||||
v->angle = angle;
|
v->angle = angle;
|
||||||
v->x = v->mod*cos(v->angle);
|
v->x = v->mod*cos(v->angle);
|
||||||
@ -37,6 +46,16 @@ void vectnull(Vec2* v) {
|
|||||||
v->x = v->y = v->mod = v->angle = 0.;
|
v->x = v->y = v->mod = v->angle = 0.;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get the direction pointed to by two vectors (from ref to v).
|
||||||
|
double vect_angle(const Vec2* ref, const Vec2* v) {
|
||||||
|
return ANGLE(VX(*v)-VX(*ref), VY(*v)-VY(*ref));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ================
|
||||||
|
// SOLID!
|
||||||
|
// ================
|
||||||
|
|
||||||
// ==Update method.========================================
|
// ==Update method.========================================
|
||||||
// d^2 x(t) / d t^2 = a, a = constant (acceleration)
|
// d^2 x(t) / d t^2 = a, a = constant (acceleration)
|
||||||
// x'(0) = v, x(0) = p
|
// x'(0) = v, x(0) = p
|
||||||
@ -50,7 +69,7 @@ void vectnull(Vec2* v) {
|
|||||||
#if 0 // Simply commenting this out to avoid silly warnings.
|
#if 0 // Simply commenting this out to avoid silly warnings.
|
||||||
static void simple_update(Solid* obj, const double dt) {
|
static void simple_update(Solid* obj, const double dt) {
|
||||||
// Make sure angle doesn't flip.
|
// Make sure angle doesn't flip.
|
||||||
obj->dir += obj->dir_vel/360.*dt;
|
obj->dir += M_PI/360.*obj->dir_vel*dt;
|
||||||
if(obj->dir > 2*M_PI) obj->dir -= 2*M_PI;
|
if(obj->dir > 2*M_PI) obj->dir -= 2*M_PI;
|
||||||
if(obj->dir < 0.) obj->dir += 2*M_PI;
|
if(obj->dir < 0.) obj->dir += 2*M_PI;
|
||||||
|
|
||||||
@ -100,7 +119,7 @@ static void simple_update(Solid* obj, const double dt) {
|
|||||||
#define RK4_MIN_H 0.01 // Minimal pass we want.
|
#define RK4_MIN_H 0.01 // Minimal pass we want.
|
||||||
static void rk4_update(Solid* obj, const double dt) {
|
static void rk4_update(Solid* obj, const double dt) {
|
||||||
// Make sure angle doesn't flip.
|
// Make sure angle doesn't flip.
|
||||||
obj->dir += obj->dir_vel/360.0*dt;
|
obj->dir += M_PI/360.*obj->dir_vel*dt;
|
||||||
if(obj->dir > 2*M_PI) obj->dir -= 2*M_PI;
|
if(obj->dir > 2*M_PI) obj->dir -= 2*M_PI;
|
||||||
if(obj->dir < 0.0) obj->dir += 2*M_PI;
|
if(obj->dir < 0.0) obj->dir += 2*M_PI;
|
||||||
|
|
||||||
@ -123,20 +142,20 @@ static void rk4_update(Solid* obj, const double dt) {
|
|||||||
for(i = 0; i < N; i++) {
|
for(i = 0; i < N; i++) {
|
||||||
// X component.
|
// X component.
|
||||||
tx = ix = vx;
|
tx = ix = vx;
|
||||||
tx += 2*ix + h*tx;
|
tx += 2.*ix + h*tx;
|
||||||
tx += 2*ix + h*tx;
|
tx += 2.*ix + h*tx;
|
||||||
tx += ix + h*tx;
|
tx += ix + h*tx;
|
||||||
tx *= h/6;
|
tx *= h/6.;
|
||||||
|
|
||||||
px += tx;
|
px += tx;
|
||||||
vx += ax*h;
|
vx += ax*h;
|
||||||
|
|
||||||
// Y component.
|
// Y component.
|
||||||
ty = iy = vy;
|
ty = iy = vy;
|
||||||
ty += 2*(iy + h/2*ty);
|
ty += 2.*(iy + h/2.*ty);
|
||||||
ty += 2*(iy + h/2*ty);
|
ty += 2.*(iy + h/2.*ty);
|
||||||
ty += iy +h*ty;
|
ty += iy +h*ty;
|
||||||
ty *= h/6;
|
ty *= h/6.;
|
||||||
|
|
||||||
py += ty;
|
py += ty;
|
||||||
vy += ay*h;
|
vy += ay*h;
|
||||||
@ -153,8 +172,8 @@ static void rk4_update(Solid* obj, const double dt) {
|
|||||||
void solid_init(Solid* dest, const double mass, const Vec2* vel, const Vec2* pos) {
|
void solid_init(Solid* dest, const double mass, const Vec2* vel, const Vec2* pos) {
|
||||||
dest->mass = mass;
|
dest->mass = mass;
|
||||||
|
|
||||||
dest->force.mod = 0;
|
vect_cset(&dest->force, 0., 0.);
|
||||||
dest->dir = 0;
|
dest->dir = 0.;
|
||||||
|
|
||||||
if(vel == NULL) vectnull(&dest->vel);
|
if(vel == NULL) vectnull(&dest->vel);
|
||||||
else vectcpy(&dest->vel, vel);
|
else vectcpy(&dest->vel, vel);
|
||||||
|
@ -6,8 +6,11 @@
|
|||||||
#define VMOD(v) ((v).mod)
|
#define VMOD(v) ((v).mod)
|
||||||
#define VANGLE(v) ((v).angle)
|
#define VANGLE(v) ((v).angle)
|
||||||
|
|
||||||
#define MOD(x,y) (sqrt(x*x + y*y))
|
#define MOD(x,y) (sqrt((x)*(x) + (y)*(y)))
|
||||||
#define ANGLE(x,y)((x==0.) ? 0. : ((x<0.)?atan(y/x)+M_PI:atan(y/x)))
|
#define ANGLE(x,y)(((x)==0.) ? 0. : (((x)<0.)?atan((y)/(x))+M_PI:atan((y)/(x))))
|
||||||
|
|
||||||
|
// Misc
|
||||||
|
double angle_diff(const double ref, double a);
|
||||||
|
|
||||||
// Base of 2D vectors.
|
// Base of 2D vectors.
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -16,10 +19,11 @@ typedef struct {
|
|||||||
} Vec2;
|
} Vec2;
|
||||||
|
|
||||||
// Vector manupulation.
|
// Vector manupulation.
|
||||||
void vect_cset(Vec2* v, double x, double y);
|
void vect_cset(Vec2* v, const double x, const double y);
|
||||||
void vect_pset(Vec2* v, double mod, double angle);
|
void vect_pset(Vec2* v, const double mod, const double angle);
|
||||||
void vectcpy(Vec2* dest, const Vec2* src);
|
void vectcpy(Vec2* dest, const Vec2* src);
|
||||||
void vectnull(Vec2* v);
|
void vectnull(Vec2* v);
|
||||||
|
double vect_angle(const Vec2* ref, const Vec2* v);
|
||||||
|
|
||||||
// Describe any solid in 2D space.
|
// Describe any solid in 2D space.
|
||||||
struct Solid {
|
struct Solid {
|
||||||
|
@ -83,7 +83,7 @@ void pilot_init(Pilot* pilot, Ship* ship, char* name, const Vec2* vel, const Vec
|
|||||||
pilot->energy = ship->energy;
|
pilot->energy = ship->energy;
|
||||||
|
|
||||||
// Initially idle.
|
// Initially idle.
|
||||||
pilot->action = NULL;
|
pilot->task = NULL;
|
||||||
|
|
||||||
if(flags & PILOT_PLAYER) {
|
if(flags & PILOT_PLAYER) {
|
||||||
pilot->think = (void*)player_think; // Players don't need to thing! :P
|
pilot->think = (void*)player_think; // Players don't need to thing! :P
|
||||||
|
18
src/pilot.h
18
src/pilot.h
@ -1,25 +1,11 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "def.h"
|
#include "def.h"
|
||||||
#include "physics.h"
|
#include "physics.h"
|
||||||
|
#include "ai.h"
|
||||||
#include "ship.h"
|
#include "ship.h"
|
||||||
|
|
||||||
#define PILOT_PLAYER 1 // Pilot is a player.
|
#define PILOT_PLAYER 1 // Pilot is a player.
|
||||||
|
|
||||||
// =========================================================
|
|
||||||
// AI:
|
|
||||||
// Ai is based on an action list which contains the current
|
|
||||||
// action (FIFO). Actions will run the appropriate Lua code.
|
|
||||||
// =========================================================
|
|
||||||
typedef enum { ACT_ATTACK, ACT_TRAVEL, ACT_BRAKE } action_type;
|
|
||||||
|
|
||||||
// Actions.
|
|
||||||
struct Action {
|
|
||||||
struct Action* next;
|
|
||||||
action_type type;
|
|
||||||
void* target;
|
|
||||||
};
|
|
||||||
typedef struct Action Action;
|
|
||||||
|
|
||||||
// Primary pilot structure.
|
// Primary pilot structure.
|
||||||
struct Pilot {
|
struct Pilot {
|
||||||
unsigned int id; // Pilots id.
|
unsigned int id; // Pilots id.
|
||||||
@ -38,7 +24,7 @@ struct Pilot {
|
|||||||
|
|
||||||
// AI.
|
// AI.
|
||||||
void (*think)(struct Pilot*); // Ai thinking for the pilot.
|
void (*think)(struct Pilot*); // Ai thinking for the pilot.
|
||||||
Action* action; // Current action.
|
Task* task; // Current action.
|
||||||
};
|
};
|
||||||
typedef struct Pilot Pilot;
|
typedef struct Pilot Pilot;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user