[Add] A few more AI(Lua) calls.
[Add] A little more documentation for Lua.
This commit is contained in:
parent
1e19ae63c1
commit
c10b1f24fb
@ -46,6 +46,18 @@ minbrakedist()
|
||||
-- Returns the minimum required braking distance assuming all goes well.
|
||||
-- return number distance needed to brake.
|
||||
|
||||
// ================
|
||||
// BOOLEAN!
|
||||
// ================
|
||||
|
||||
ismaxval()
|
||||
-- Check if velocity is maximum.
|
||||
-- return true if velocity is max, false otherwise.
|
||||
|
||||
isstopped()
|
||||
-- Check if we are stopped.
|
||||
-- return true if stopped, false otherwise.
|
||||
|
||||
// ================
|
||||
// MOVEMENT!
|
||||
// ================
|
||||
|
@ -1,3 +1,11 @@
|
||||
-- Required control rate.
|
||||
control_rate = 2
|
||||
|
||||
-- Required "control" function.
|
||||
function control()
|
||||
pusttask(0, "follow");
|
||||
end
|
||||
|
||||
function follow()
|
||||
target =1
|
||||
dir = face(target)
|
||||
@ -7,20 +15,3 @@ function follow()
|
||||
end
|
||||
end
|
||||
|
||||
function goto()
|
||||
v = gettarget()
|
||||
face(v)
|
||||
|
||||
d = getdist(v)
|
||||
if d < minbrakedist()*1.05 then
|
||||
poptask()
|
||||
else
|
||||
accel(1)
|
||||
end
|
||||
end
|
||||
|
||||
function control()
|
||||
pushtask(0, "follow");
|
||||
--pushtask(0, "goto", createvect(1000, 0));
|
||||
end
|
||||
|
||||
|
63
src/ai.c
63
src/ai.c
@ -13,6 +13,24 @@
|
||||
#include "ai.h"
|
||||
|
||||
// == AI ======================================================
|
||||
//
|
||||
// -- Goal (Task) based AI with additional optimization.
|
||||
// AI uses the goal (task) based AI approach with tasks scripted
|
||||
// in lua. Additionally there is a task that is hardcoded and
|
||||
// obligatory in any AI script. The 'control' task, whose only
|
||||
// purpose is to assign tasks if there is none, and optimize
|
||||
// or change tasks if there are.
|
||||
//
|
||||
// Eg.. Pilot A is attacking Pilot B. Pilot C then comes along
|
||||
// the same system and is of the same faction as Pilot B. and
|
||||
// therefor attacks Pilot A. Pilot A would keep fighting pilot
|
||||
// B and until the control task comes in. Then the pilot could
|
||||
// run if it deems fit that Pilot C and Pilot B together are
|
||||
// both too strong for A. Or.. Attack C as it is an easy target
|
||||
// to finish.
|
||||
// Basically, there is many possibilities, and it's down to the
|
||||
// Lua fanatics to decide what to do.
|
||||
//
|
||||
// -- AI will follow basic tasks defined from Lua AI scripts.
|
||||
// -- If task is NULL, AI will run "control" task.
|
||||
// -- Task is continued every frame.
|
||||
@ -26,11 +44,14 @@
|
||||
// ============================================================
|
||||
|
||||
// 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_pcall(L, 0, 0, 0))
|
||||
|
||||
// Don't run the function if (n) params aren't passed.
|
||||
#define MIN_ARGS(n) if(lua_gettop(L) < n) return 0
|
||||
|
||||
#define MAX_DIR_ERR 5.0*M_PI/180.
|
||||
#define MIN_VEL_ERR 2.5
|
||||
|
||||
static int ai_minbrakedist(lua_State* L); // Minimal breaking distance.
|
||||
static int ai_accel(lua_State* L); // Accelerate.
|
||||
|
||||
@ -47,10 +68,14 @@ 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()
|
||||
// Boolean expressions.
|
||||
static int ai_ismaxvel(lua_State* L); // Boolean ismaxvel()
|
||||
static int ai_isstopped(lua_State* L); // Boolean isstopped()
|
||||
// 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)
|
||||
static int ai_brake(lua_State* L); // Brake()
|
||||
// Misc.
|
||||
static int ai_createvect(lua_State* L); // createvect(number, number)
|
||||
|
||||
@ -70,30 +95,41 @@ void ai_destroy(Pilot* p) {
|
||||
// Init the AI stuff. Which is basically Lua.
|
||||
int ai_init(void) {
|
||||
L = luaL_newstate();
|
||||
if(L == NULL)
|
||||
if(L == NULL) {
|
||||
ERR("Unable to create a new Lua state");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Open the standard Lua libraries.
|
||||
luaL_openlibs(L);
|
||||
|
||||
// Register C funstions in Lua.
|
||||
// Tasks.
|
||||
lua_register(L, "pushtask", ai_pushtask);
|
||||
lua_register(L, "poptask", ai_poptask);
|
||||
lua_register(L, "taskname", ai_taskname);
|
||||
// Consult.
|
||||
lua_register(L, "gettarget", ai_gettarget);
|
||||
lua_register(L, "gettargetid", ai_gettargetid);
|
||||
lua_register(L, "getdist", ai_getdistance);
|
||||
lua_register(L, "getpos", ai_getpos);
|
||||
lua_register(L, "minbrakedist", ai_minbrakedist);
|
||||
// Boolean.
|
||||
lua_register(L, "ismaxvel", ai_ismaxvel);
|
||||
lua_register(L, "isstopped", ai_isstopped);
|
||||
// Movement.
|
||||
lua_register(L, "accel", ai_accel);
|
||||
lua_register(L, "turn", ai_turn);
|
||||
lua_register(L, "face", ai_face);
|
||||
lua_register(L, "brake", ai_brake);
|
||||
// Misc.
|
||||
lua_register(L, "createvect", ai_createvect);
|
||||
|
||||
char* buf = pack_readfile(DATA, "../scripts/ai/test.lua", NULL);
|
||||
|
||||
if(luaL_dostring(L, buf) != 0) {
|
||||
WARN("Unable to load AI file: %s", "../scripts/ai/test.lua");
|
||||
ERR("loading AI file: %s", "../scripts/ai/test.lua");
|
||||
WARN("Most likely Lua file has improper syntax, please check it.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -247,6 +283,18 @@ static int ai_minbrakedist(lua_State* L) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Are we at max velocity?
|
||||
static int ai_ismaxvel(lua_State* L) {
|
||||
lua_pushboolean(L, VMOD(cur_pilot->solid->vel) == cur_pilot->ship->speed);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Have we stopped?
|
||||
static int ai_isstopped(lua_State* L) {
|
||||
lua_pushboolean(L, VMOD(cur_pilot->solid->vel) < MIN_VEL_ERR);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Accelerate the pilot based on a param.
|
||||
static int ai_accel(lua_State* L) {
|
||||
pilot_acc = (lua_gettop(L) > 1 && lua_isnumber(L, 1)) ? ABS((double)lua_tonumber(L, 1)) : 1.;
|
||||
@ -283,6 +331,15 @@ static int ai_face(lua_State* L) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// This is generally good for coming to a halt.
|
||||
static int ai_brake(lua_State* L) {
|
||||
double diff = angle_diff(cur_pilot->solid->dir, VANGLE(cur_pilot->solid->vel));
|
||||
pilot_turn = 10*diff;
|
||||
if(diff < MAX_DIR_ERR && VMOD(cur_pilot->solid->vel) > MIN_VEL_ERR)
|
||||
pilot_acc = 1.;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Create a vector.
|
||||
static int ai_createvect(lua_State* L) {
|
||||
MIN_ARGS(2);
|
||||
|
@ -52,7 +52,7 @@ static int SDL_VFlipSurface(SDL_Surface* surface) {
|
||||
Uint8* rowhi, *rowlo, *tmpbuf;
|
||||
int y;
|
||||
|
||||
tmpbuf = (Uint8*)malloc(surface->pitch);
|
||||
tmpbuf = malloc(surface->pitch);
|
||||
if(tmpbuf == NULL) {
|
||||
WARN("Out of memory");
|
||||
return -1;
|
||||
|
@ -165,7 +165,7 @@ int pack_files(const char* outfile, const char** infiles, const uint32_t nfiles)
|
||||
int pack_open(Packfile* file, const char* packfile, const char* filename) {
|
||||
int i, j;
|
||||
uint32_t nfiles;
|
||||
char* buf = (char*)malloc(MAX_FILENAME);
|
||||
char* buf = malloc(MAX_FILENAME);
|
||||
|
||||
file->start = file->end = 0;
|
||||
|
||||
|
@ -48,7 +48,7 @@ void input_init(void) {
|
||||
Keybind* tmp;
|
||||
int i;
|
||||
for(i = 0; keybindNames[i]; i++); // Get number of bindings.
|
||||
player_input = (Keybind**)malloc(i*sizeof(Keybind*));
|
||||
player_input = malloc(i*sizeof(Keybind*));
|
||||
|
||||
// Create a null keybinding for each.
|
||||
for(i = 0; keybindNames[i]; i++) {
|
||||
|
Loading…
Reference in New Issue
Block a user