From 66028742b528ab88173a29483ede2db4760f1b29 Mon Sep 17 00:00:00 2001 From: Allanis Date: Sun, 15 Dec 2013 01:16:52 +0000 Subject: [PATCH] [Add] ai.shipclass() also added a but more documentation to ai. --- src/ai.c | 102 ++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 75 insertions(+), 27 deletions(-) diff --git a/src/ai.c b/src/ai.c index 2adc59a..d15ea47 100644 --- a/src/ai.c +++ b/src/ai.c @@ -13,11 +13,11 @@ * 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 + * 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 + * B 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 + * both too strong for her. 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. @@ -33,6 +33,12 @@ * Lua global "control_rate") to choose optimal behaviour * (task). * + * Memory: + * The AI currently has per-pilot memory which is accessible as "mem". This + * memory is actually stored in the table pilotmem[cur_pilot->id]. This allows + * the pilot to keep some memory always accessible between runs without having + * to rely on the storage space a task has. + * * @todo Clean up most of the code, it was written as one of the first * subsystems and is pretty lacking in quite a few aspects. Notably * removing the entire lightuserdata and actually go with full userdata. @@ -122,6 +128,7 @@ static int ai_getdistance(lua_State* L); /* Number getdist(Vec2) */ static int ai_getpos(lua_State* L); /* getpos(number) */ static int ai_minbrakedist(lua_State* L); /* Number minbrakedist() */ static int ai_cargofree(lua_State* L); /* Number cargofree(). */ +static int ai_shipclass(lua_State* L); /* string shipclass(). */ /* Boolean expressions. */ static int ai_exists(lua_State* L); /* boolean exists */ static int ai_ismaxvel(lua_State* L); /* Boolean ismaxvel() */ @@ -137,9 +144,9 @@ static int ai_turn(lua_State* L); /* turn(number); abs(number) <= static int ai_face(lua_State* L); /* face(number/pointer) */ static int ai_aim(lua_State* L); /* aim(number). */ static int ai_brake(lua_State* L); /* Brake() */ -static int ai_getnearestplanet(lua_State* L); /* pointer getnearestplanet() */ -static int ai_getrndplanet(lua_State* L); /* pointer getrndplanet() */ -static int ai_getlandplanet(lua_State* L); /* pointer getlandplanet() */ +static int ai_getnearestplanet(lua_State* L); /* Vec2 getnearestplanet() */ +static int ai_getrndplanet(lua_State* L); /* Vec2 getrndplanet() */ +static int ai_getlandplanet(lua_State* L); /* Vec2 getlandplanet() */ static int ai_hyperspace(lua_State* L); /* [number] hyperspace() */ static int ai_stop(lua_State* L); /* stop() */ /* Combat. */ @@ -188,10 +195,11 @@ static const luaL_Reg ai_methods[] = { { "pos", ai_getpos }, { "minbrakedist", ai_minbrakedist }, { "cargofree", ai_cargofree }, + { "shipclass", ai_shipclass }, + /* Movement. */ { "nearestplanet", ai_getnearestplanet }, { "rndplanet", ai_getrndplanet }, { "landplanet", ai_getlandplanet }, - /* Movement. */ { "accel", ai_accel }, { "turn", ai_turn }, { "face", ai_face }, @@ -222,16 +230,16 @@ static const luaL_Reg ai_methods[] = { }; /* Current pilot "thinking" and assorted variables. */ -static Pilot* cur_pilot = NULL; -static double pilot_acc = 0.; -static double pilot_turn = 0.; -static int pilot_flags = 0; -static int pilot_target = 0; +static Pilot* cur_pilot = NULL; /**< Current pilot. All functions use this. */ +static double pilot_acc = 0.; /**< Current pilots acceleration. */ +static double pilot_turn = 0.; /**< Current pilots turning. */ +static int pilot_flags = 0; /**< Handle stuff like weapon firing. */ +static int pilot_target = 0; /**< Indicate the target to aim at for the pilot. */ /* Ai status: 'Create' functions that can't be used elsewhere. */ -#define AI_STATUS_NORMAL 1 /**< Normal AI function behaviour. */ -#define AI_STATUS_CREATE 2 /**< AI is running create function. */ -static int ai_status = AI_STATUS_NORMAL; +#define AI_STATUS_NORMAL 1 /**< Normal AI function behaviour. */ +#define AI_STATUS_CREATE 2 /**< AI is running create function. */ +static int ai_status = AI_STATUS_NORMAL; /**< Current AI run statis. */ /** * @fn static void ai_run(lua_State* L, const char* funcname) @@ -256,7 +264,13 @@ static void ai_run(lua_State* L, const char* funcname) { } /** - * @fn + * @fn void ai_pinit(Pilot* p, AI_Profile* ai) + * + * @brief Initializes the pilot in the ai. + * + * Mainly used to create the pilot's memory table. + * @param p Pilot to initialize in AI. + * @param ai AI to initialize pilot. */ void ai_pinit(Pilot* p, AI_Profile* ai) { lua_State* L; @@ -518,11 +532,28 @@ static void ai_freetask(Task* t) { free(t); } -/* ======================================================== */ -/* C functions to call from Lua. */ -/* ======================================================== */ +/** + * @group AI Lua AI Bindings + * + * @brief Handles how the AI interacts with the universe. + * + * Usage: + * @code + * ai.function(params) + * @endcode + * + * @{ + */ -/* Push the current stack. */ +/** + * @fn static int ai_pushtask(lua_State* L) + * + * @brief pushtask(number pos, string func [, data]) + * @param pos Position to push into stack, 0 is front, 1 is back. + * @param func Function to call for task. + * @param data Data to pass to the function. Only lightuserdata or number + * is currently supported. + */ static int ai_pushtask(lua_State* L) { int pos; if(lua_isnumber(L, 1)) pos = (int) lua_tonumber(L, 1); @@ -566,7 +597,13 @@ static int ai_pushtask(lua_State* L) { return 0; } -/* Pop the current task. */ +/** + * @fn static int ai_poptask(lua_State* L) + * + * @brief poptask(nil) + * + * Pops the current running task. + */ static int ai_poptask(lua_State* L) { (void)L; /* Just a hack to avoid -W -Wall warnings. */ Task* t = cur_pilot->task; @@ -745,6 +782,11 @@ static int ai_cargofree(lua_State* L) { return 1; } +static int ai_shipclass(lua_State* L) { + lua_pushstring(L, ship_class(cur_pilot->ship)); + return 1; +} + static int ai_exists(lua_State* L) { Pilot* p; int i; @@ -902,10 +944,11 @@ static int ai_brake(lua_State* L) { /* Return the nearest friendly planet's position to the pilot. */ static int ai_getnearestplanet(lua_State* L) { - if(cur_system->nplanets == 0) return 0; /* No planets. */ - double dist, d; int i, j; + LuaVector lv; + + if(cur_system->nplanets == 0) return 0; /* No planets. */ /* Cycle through planets. */ for(dist = 0., j = -1, i = 0; i < cur_system->nplanets; i++) { @@ -921,13 +964,15 @@ static int ai_getnearestplanet(lua_State* L) { /* No friendly planet found. */ if(j == -1) return 0; - lua_pushlightuserdata(L, &cur_system->planets[j]->pos); + vectcpy(&lv.vec, &cur_system->planets[j]->pos); + lua_pushvector(L, lv); + return 1; } /* Return a random planet's position to the pilot. */ static int ai_getrndplanet(lua_State* L) { - Vec2 v; + LuaVector lv; int p; if(cur_system->nplanets == 0) return 0; /* No planets. */ @@ -936,8 +981,8 @@ static int ai_getrndplanet(lua_State* L) { p = RNG(0, cur_system->nplanets-1); /* Copy the data into a vector. */ - vectcpy(&v, &cur_system->planets[p]->pos); - lua_pushlightuserdata(L, &v); + vectcpy(&lv.vec, &cur_system->planets[p]->pos); + lua_pushvector(L, lv); return 1; } @@ -1303,4 +1348,7 @@ static int ai_shipprice(lua_State* L) { lua_pushnumber(L, cur_pilot->ship->price); return 1; } +/** + * @} + */