[Add] A few more AI(Lua) calls.

[Add] A little more documentation for Lua.
This commit is contained in:
Allanis 2013-02-04 14:10:59 +00:00
parent 1e19ae63c1
commit c10b1f24fb
6 changed files with 83 additions and 23 deletions

View File

@ -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!
// ================

View File

@ -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

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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++) {