200 lines
4.8 KiB
C
200 lines
4.8 KiB
C
/**
|
|
* @file escorts.c
|
|
*
|
|
* @brief Handles the players escorts.
|
|
*/
|
|
|
|
#include "lephisto.h"
|
|
#include "log.h"
|
|
#include "player.h"
|
|
#include "llua.h"
|
|
#include "lluadef.h"
|
|
#include "llua_space.h"
|
|
#include "escort.h"
|
|
|
|
#define ESCORT_PREALLOC 8 /**< Number of escorts to automatically allocate first. */
|
|
|
|
#define ESCORT_ATTACK 1 /**< Attack order. */
|
|
#define ESCORT_HOLD 2 /**< Hold order. */
|
|
#define ESCORT_RETURN 3 /**< Return to ship order. */
|
|
#define ESCORT_CLEAR 4 /**< Clear orders. */
|
|
|
|
/* Static. */
|
|
static int escort_command(Pilot* parent, int cmd, int param);
|
|
/* Extern. */
|
|
extern void ai_setPilot(Pilot* p);
|
|
|
|
/**
|
|
* @fn int escort_create(unsigned int parent, char* ship,
|
|
* Vec2* pos, Vec2* vel, int carried)
|
|
*
|
|
* @brief Create an escort.
|
|
* @param parent Parent of the escort (who she's guarding).
|
|
* @param ship Name of the ship escort should have.
|
|
* @param pos Position to create escort at.
|
|
* @param vel Velocity to create escort with.
|
|
* @param carried Does escort come out of the parent?
|
|
*/
|
|
int escort_create(unsigned int parent, char* ship,
|
|
Vec2* pos, Vec2* vel, int carried) {
|
|
|
|
Ship* s;
|
|
Pilot* p, *pe;
|
|
char buf[16];
|
|
unsigned int e, f;
|
|
double dir;
|
|
|
|
/* Get important stuff. */
|
|
p = pilot_get(parent);
|
|
s = ship_get(ship);
|
|
snprintf(buf, 16, "tpl/escort*%u", parent);
|
|
|
|
/* Set flags. */
|
|
f = PILOT_ESCORT;
|
|
if(carried) f |= PILOT_CARRIED;
|
|
|
|
/* Get the direction. */
|
|
if(carried) dir = p->solid->dir;
|
|
else dir = 0.;
|
|
|
|
/* Create the pilot. */
|
|
e = pilot_create(s, NULL, p->faction, buf, dir, pos, vel, f);
|
|
pe = pilot_get(e);
|
|
pe->parent = parent;
|
|
|
|
/* Add to escort list. */
|
|
p->nescorts++;
|
|
if(p->nescorts == 1)
|
|
p->escorts = malloc(sizeof(unsigned int) * ESCORT_PREALLOC);
|
|
else if(p->nescorts > ESCORT_PREALLOC)
|
|
p->escorts = realloc(p->escorts, sizeof(unsigned int) * p->nescorts);
|
|
p->escorts[p->nescorts-1] = e;
|
|
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* @fn static int escort_command(Pilot* parent, int cmd, int param)
|
|
*
|
|
* @brief Run an escort command on all of a pilots escorts.
|
|
* @param parent Pilot who is giving orders.
|
|
* @param cmd Order to give.
|
|
* @param param Parameter for order.
|
|
* @return 0 on success, 1 if no orders given.
|
|
*/
|
|
static int escort_command(Pilot* parent, int cmd, int param) {
|
|
int i, n;
|
|
lua_State* L;
|
|
Pilot* e;
|
|
char* buf;
|
|
|
|
if(parent->nescorts == 0)
|
|
return 1;
|
|
|
|
n = 0;
|
|
for(i = 0; i < parent->nescorts; i++) {
|
|
e = pilot_get(parent->escorts[i]);
|
|
if(e == NULL) /* Most likely died. */
|
|
continue;
|
|
|
|
/* Check if command makes sense. */
|
|
if((cmd == ESCORT_RETURN) && !pilot_isFlag(e, PILOT_CARRIED))
|
|
continue;
|
|
|
|
n++; /* Amount of escorts left. */
|
|
|
|
/* Prepare ai. */
|
|
ai_setPilot(e);
|
|
|
|
/* Set up stack. */
|
|
L = e->ai->L;
|
|
switch(cmd) {
|
|
case ESCORT_ATTACK:
|
|
buf = "e_attack";
|
|
break;
|
|
case ESCORT_HOLD:
|
|
buf = "e_hold";
|
|
break;
|
|
case ESCORT_RETURN:
|
|
buf = "e_return";
|
|
break;
|
|
case ESCORT_CLEAR:
|
|
buf = "e_clear";
|
|
break;
|
|
}
|
|
lua_getglobal(L, buf);
|
|
if(param >= 0)
|
|
lua_pushnumber(L, param);
|
|
|
|
/* Run command. */
|
|
if(lua_pcall(L, (param >= 0) ? 1 : 0, 0, 0))
|
|
WARN("Pilot '%s' ai -> '%s' : %s", e->name,
|
|
buf, lua_tostring(L, -1));
|
|
}
|
|
return !n;
|
|
}
|
|
|
|
/**
|
|
* @fn int escorts_attack(Pilot* parent)
|
|
*
|
|
* @brief HAve a pilot order it's escorts to attack its target.
|
|
* @param parent Pilot giving the order.
|
|
*/
|
|
int escorts_attack(Pilot* parent) {
|
|
int ret;
|
|
Pilot* t;
|
|
|
|
ret = 1;
|
|
if(parent->target != parent->id)
|
|
ret = escort_command(parent, ESCORT_ATTACK, parent->target);
|
|
if((ret == 0) && (parent == player)) {
|
|
t = pilot_get(parent->target);
|
|
if(t != NULL)
|
|
player_message("Escorts: Attacking %s.", t->name);
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* @fn int escorts_hold(Pilot* parent)
|
|
*
|
|
* @brief Have a pilot order its escorts to hold position.
|
|
* @param parent Pilot giving the order.
|
|
*/
|
|
int escorts_hold(Pilot* parent) {
|
|
int ret;
|
|
ret = escort_command(parent, ESCORT_HOLD, -1);
|
|
if((ret == 0) && (parent == player))
|
|
player_message("Escorts: Holding position.");
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* @fn int escorts_return(Pilot* parent)
|
|
*
|
|
* @brief Have a pilot order its escorts to dock.
|
|
* @param parent Pilot giving the order.
|
|
*/
|
|
int escorts_return(Pilot* parent) {
|
|
int ret;
|
|
ret = escort_command(parent, ESCORT_RETURN, -1);
|
|
if((ret == 0) && (parent == player))
|
|
player_message("Escorts: Returning to ship.");
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* @fn int escorts_clear(Pilot* parent)
|
|
*
|
|
* @brief Have a pilot order its escorts to clear orders.
|
|
* @param parent Pilot giving the order.
|
|
*/
|
|
int escorts_clear(Pilot* parent) {
|
|
int ret;
|
|
ret = escort_command(parent, ESCORT_CLEAR, -1);
|
|
if((ret == 0) && (parent == player))
|
|
player_message("Escorts: Clearing orders.");
|
|
return ret;
|
|
}
|
|
|