[Add] Allow for passing parameters to pilot ai on creation.

This commit is contained in:
Allanis 2013-12-28 16:49:56 +00:00
parent dd9bbfaa3b
commit 7db6ad52f9
4 changed files with 110 additions and 42 deletions

View File

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

View File

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

View File

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

View File

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