From 7db6ad52f953c80d1798131c3d426ce2bbe69176 Mon Sep 17 00:00:00 2001 From: Allanis Date: Sat, 28 Dec 2013 16:49:56 +0000 Subject: [PATCH] [Add] Allow for passing parameters to pilot ai on creation. --- src/ai.c | 97 ++++++++++++++++++++++++++++++++++++++++++------ src/llua_pilot.c | 2 +- src/pilot.c | 43 ++++++++++----------- src/pilot.h | 10 ++--- 4 files changed, 110 insertions(+), 42 deletions(-) diff --git a/src/ai.c b/src/ai.c index d15ea47..ce6a743 100644 --- a/src/ai.c +++ b/src/ai.c @@ -102,11 +102,12 @@ static int ai_accel(lua_State* L); /* Accelerate. */ static void ai_run(lua_State* L, const char* funcname); static int ai_loadProfile(char* filename); static void ai_freetask(Task* t); +static void ai_setmemory(void); +static void ai_create(Pilot* pilot, char* param); /* External C routines. */ void ai_attacked(Pilot* attacked, const unsigned int attacker); /* weapon.c */ -void ai_create(Pilot* pilot); /* C routines made external. */ -void ai_pinit(Pilot* p, AI_Profile* ai); +int ai_pinit(Pilot* p, char* ai); void ai_destroy(Pilot* p); void ai_think(Pilot* pilot); @@ -241,6 +242,21 @@ static int pilot_target = 0; /**< Indicate the target to aim at for the p #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_setmemory(void) + * + * @brief Set the cur_pilots ai. + */ +static void ai_setmemory(void) { + lua_State* L; + L = cur_pilot->ai->L; + + lua_getglobal(L, "pilotmem"); + lua_pushnumber(L, cur_pilot->id); + lua_gettable(L, -2); + lua_setglobal(L, "mem"); +} + /** * @fn static void ai_run(lua_State* L, const char* funcname) * @@ -251,10 +267,7 @@ static int ai_status = AI_STATUS_NORMAL; /**< Current AI run statis. */ */ static void ai_run(lua_State* L, const char* funcname) { /* Set the pilot's memory. */ - lua_getglobal(L, "pilotmem"); - lua_pushnumber(L, cur_pilot->id); - lua_gettable(L, -2); - lua_setglobal(L, "mem"); + ai_setmemory(); lua_getglobal(L, funcname); if(lua_pcall(L, 0, 0, 0)) @@ -264,7 +277,7 @@ static void ai_run(lua_State* L, const char* funcname) { } /** - * @fn void ai_pinit(Pilot* p, AI_Profile* ai) + * @fn int ai_pinit(Pilot* p, char* ai) * * @brief Initializes the pilot in the ai. * @@ -272,15 +285,48 @@ static void ai_run(lua_State* L, const char* funcname) { * @param p Pilot to initialize in AI. * @param ai AI to initialize pilot. */ -void ai_pinit(Pilot* p, AI_Profile* ai) { +int ai_pinit(Pilot* p, char* ai) { + int i, n; + AI_Profile* prof; lua_State* L; - L = ai->L; + char buf[PATH_MAX], param[PATH_MAX]; + + /* Split parameter from ai itself. */ + n = 0; + for(i = 0; ai[i] != '\0'; i++) { + /* Overflow protection. */ + if(i > PATH_MAX) + break; + + /* Check to see if we find the splitter. */ + if(ai[i] == '*') { + buf[i] = '\0'; + n = i+1; + continue; + } + + if(n == 0) + buf[i] = ai[i]; + else + param[i-n] = ai[i]; + } + + if(n != 0) param[i-n] = '\0'; /* Terminate string if needed. */ + + prof = ai_getProfile(buf); + p->ai = prof; + L = p->ai->L; /* Adds a new pilot memory in the memory table. */ lua_getglobal(L, "pilotmem"); lua_pushnumber(L, p->id); lua_newtable(L); lua_settable(L, -3); + + /* Create the pilot. */ + ai_create(p, (n != 0) ? param : NULL); + + return 0; } /** @@ -501,21 +547,48 @@ void ai_attacked(Pilot* attacked, const unsigned int attacker) { } /** - * @fn void ai_create(Pilot* pilot) + * @fn static void ai_create(Pilot* pilot, char* param) * * @brief Run the create() function in the pilot. * * Should create all the gear and such the pilot has. * * @param pilot Pilot to "create". + * @param param Parameter to pass to "create" function. */ -void ai_create(Pilot* pilot) { +static void ai_create(Pilot* pilot, char* param) { lua_State* L; cur_pilot = pilot; L = cur_pilot->ai->L; + + /* Set the pilots memory. */ + ai_setmemory(); + + /* Set creation mode. */ ai_status = AI_STATUS_CREATE; - ai_run(L, "create"); + + /* Prepare stack. */ + lua_getglobal(L, "create"); + + /* Parse parameters. */ + if(param != NULL) { + /* Number. */ + if(isdigit(param[0])) + lua_pushnumber(L, atoi(param)); + /* Special case player. */ + else if(strcmp(param, "player")==0) + lua_pushnumber(L, PLAYER_ID); + /* Default. */ + else + lua_pushstring(L, param); + } + + /* Run function. */ + if(lua_pcall(L, (param!=NULL) ? 1 : 0, 0, 0)) /* Error has occured. */ + WARN("Pilot '%s' ai -> '%s' : %s", cur_pilot->name, "create", lua_tostring(L, -1)); + + /* Recover normal mode. */ ai_status = AI_STATUS_NORMAL; } diff --git a/src/llua_pilot.c b/src/llua_pilot.c index 34fcd9c..7447d71 100644 --- a/src/llua_pilot.c +++ b/src/llua_pilot.c @@ -264,7 +264,7 @@ static int pilot_addFleet(lua_State* L) { plt->name, flt->faction, (fltai != NULL) ? /* Lua AI override. */ - ai_getProfile(fltai) : + fltai : (plt->ai != NULL) ? /* Pilot AI override */ plt->ai : flt->ai, a, diff --git a/src/pilot.c b/src/pilot.c index c89a6e3..be2442e 100644 --- a/src/pilot.c +++ b/src/pilot.c @@ -46,10 +46,9 @@ static int nfleets = 0; /** Number of fleets. */ /* External. */ /* AI. */ -extern void ai_pinit(Pilot* p, AI_Profile* ai); +extern AI_Profile* ai_pinit(Pilot* p, char* ai); extern void ai_destroy(Pilot* p); extern void ai_think(Pilot* pilot); -extern void ai_create(Pilot* pilot); /* Player. */ extern void player_think(Pilot* pilot); extern void player_brokeHyperspace(void); @@ -1180,21 +1179,21 @@ void pilot_addHook(Pilot* pilot, int type, int hook) { /** * @fn void pilot_init(Pilot* pilot, Ship* ship, char* name, int faction, - * AI_Profile* ai, const double dir, const Vec2* pos, + * char* ai, const double dir, const Vec2* pos, * const Vec2* vel, const int flags) * * @brief Initialize pilot. * @param ship Ship pilot will be flying. * @param name Pilots name, if NULL ships name will be used. * @param faction Faction of the pilot. - * @param ai AI profile to use for the pilot. + * @param ai Name of the AI profile to use for the pilot. * @param dir Initial direction to face (radians). * @param vel Initial velocity. * @param pos Initial position. * @param flags Used for tweaking the pilot. */ void pilot_init(Pilot* pilot, Ship* ship, char* name, int faction, - AI_Profile* ai, const double dir, const Vec2* pos, + char* ai, const double dir, const Vec2* pos, const Vec2* vel, const int flags) { ShipOutfit* so; @@ -1213,12 +1212,6 @@ void pilot_init(Pilot* pilot, Ship* ship, char* name, int faction, /* Faction. */ pilot->faction = faction; - /* AI. */ - if(ai != NULL) { - ai_pinit(pilot, ai); /* Must run before ai_create. */ - pilot->ai = ai; - } - /* Solid. */ pilot->solid = solid_create(ship->mass, dir, pos, vel); @@ -1262,15 +1255,18 @@ void pilot_init(Pilot* pilot, Ship* ship, char* name, int faction, } else { pilot->think = ai_think; pilot->render = pilot_render; - ai_create(pilot); /* Will run the create function in ai. */ } /* All update the same way. */ pilot->update = pilot_update; + + /* AI. */ + if(ai != NULL) + ai_pinit(pilot, ai); /* Must run before ai_create. */ } /** * @fn unsigned int pilot_create(Ship* ship, char* name, int faction, - * AI_Profile* ai, const double dir, const Vec2* pos, + * char* ai, const double dir, const Vec2* pos, * const Vec2* vel, const int flags) * * @brief Create a new pilot. @@ -1281,7 +1277,7 @@ void pilot_init(Pilot* pilot, Ship* ship, char* name, int faction, * @sa pilot_init */ unsigned int pilot_create(Ship* ship, char* name, int faction, - AI_Profile* ai, const double dir, const Vec2* pos, + char* ai, const double dir, const Vec2* pos, const Vec2* vel, const int flags) { Pilot** tp, *dyn; @@ -1309,7 +1305,7 @@ unsigned int pilot_create(Ship* ship, char* name, int faction, /** * @fn Pilot* pilot_CreateEmpty(Ship* ship, char* name, - * int faction, AI_Profile* ai, const int flags) + * int faction, char* ai, const int flags) * * @brief Create a pilot without adding it to the stack. * @param ship Ship for the pilot to use. @@ -1320,7 +1316,7 @@ unsigned int pilot_create(Ship* ship, char* name, int faction, * @return Pointer to the new pilot (not added to stack). */ Pilot* pilot_createEmpty(Ship* ship, char* name, - int faction, AI_Profile* ai, const int flags) { + int faction, char* ai, const int flags) { Pilot* dyn; dyn = MALLOC_L(Pilot); @@ -1511,7 +1507,7 @@ static Fleet* fleet_parse(const xmlNodePtr parent) { if(xml_isNode(node, "faction")) tmp->faction = faction_get(xml_get(node)); else if(xml_isNode(node, "ai")) - tmp->ai = ai_getProfile(xml_get(node)); + tmp->ai = strdup(xml_get(node)); else if(xml_isNode(node, "pilots")) { cur = node->children; do { @@ -1524,12 +1520,7 @@ static Fleet* fleet_parse(const xmlNodePtr parent) { pilot->name = c; /* No need to free since it will have to later. */ /* Check for ai override. */ - xmlr_attr(cur, "ai", c); - if(c != NULL) { - pilot->ai = ai_getProfile(c); - free(c); - } - else pilot->ai = NULL; + xmlr_attr(cur, "ai", pilot->ai); /* Load pilots ship. */ pilot->ship = ship_get(xml_get(cur)); @@ -1603,11 +1594,15 @@ void fleet_free(void) { int i, j; if(fleet_stack != NULL) { for(i = 0; i < nfleets; i++) { - for(j = 0; j < fleet_stack[i].npilots; j++) + for(j = 0; j < fleet_stack[i].npilots; j++) { if(fleet_stack[i].pilots[j].name) free(fleet_stack[i].pilots[j].name); + if(fleet_stack[i].pilots[j].ai) + free(fleet_stack[i].pilots[j].ai); + } free(fleet_stack[i].name); free(fleet_stack[i].pilots); + free(fleet_stack[i].ai); } free(fleet_stack); fleet_stack = NULL; diff --git a/src/pilot.h b/src/pilot.h index c152f91..803f09c 100644 --- a/src/pilot.h +++ b/src/pilot.h @@ -181,7 +181,7 @@ typedef struct FleetPilot_ { Ship* ship; /**< Ship that the pilot is flying. */ char* name; /**< For special 'unique' names. */ int chance; /**< Chance of this pilot appearing in the fleet. */ - AI_Profile* ai; /**< AI different of fleets global ai. */ + char* ai; /**< Ai difference of fleet's global ai. */ } FleetPilot; /** @@ -198,7 +198,7 @@ typedef struct Fleet_ { char* name; /**< Fleet name, used as an identifier. */ int faction; /**< Faction of the fleet. */ - AI_Profile* ai; /**< AI profile to use. */ + char* ai; /**< AI profile to use. */ FleetPilot* pilots; /**< The pilots in the fleet. */ int npilots; /**< Total number of pilots. */ @@ -249,15 +249,15 @@ int pilot_rmMissionCargo(Pilot* pilot, unsigned int cargo_id); /* Creation. */ void pilot_init(Pilot* dest, Ship* ship, char* name, int faction, - AI_Profile* ai, const double dir, const Vec2* pos, + char* ai, const double dir, const Vec2* pos, const Vec2* vel, const int flags); unsigned int pilot_create(Ship* ship, char* name, int faction, - AI_Profile* ai, const double dir, const Vec2* pos, + char* ai, const double dir, const Vec2* pos, const Vec2* vel, const int flags); Pilot* pilot_createEmpty(Ship* ship, char* name, - int faction, AI_Profile* ai, const int flags); + int faction, char* ai, const int flags); Pilot* pilot_copy(Pilot* src);