src/hcode/btech/autopilot.h File Reference

#include "mech.events.h"
#include "dllist.h"
#include "p.autopilot.h"
#include "p.ai.h"
#include "p.autopilot_command.h"
#include "p.autopilot_commands.h"
#include "p.autogun.h"

Include dependency graph for autopilot.h:

This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  profile_node_t
struct  AUTO
struct  command_node_t
struct  ACOM
struct  astar_node_t
struct  weapon_node_t
struct  target_node_t

Defines

#define AUTOPILOT_MEMORY   100
#define AUTOPILOT_MAX_ARGS   5
#define AUTOPILOT_AUTOGUN   1
#define AUTOPILOT_GUNZOMBIE   2
#define AUTOPILOT_PILZOMBIE   4
#define AUTOPILOT_ROAM   8
#define AUTOPILOT_LSENS   16
#define AUTOPILOT_CHASETARG   32
#define AUTOPILOT_WAS_CHASE_ON   64
#define AUTOPILOT_SWARMCHARGE   128
#define AUTOPILOT_ASSIGNED_TARGET   256
#define AUTOPILOT_NC_DELAY   1
#define AUTOPILOT_GOTO_TICK   3
#define AUTOPILOT_LEAVE_TICK   5
#define AUTOPILOT_WAITFOE_TICK   4
#define AUTOPILOT_PURSUE_TICK   3
#define AUTOPILOT_FOLLOW_TICK   3
#define AUTOPILOT_FOLLOW_UPDATE_TICK   10
#define AUTOPILOT_CHASETARG_UPDATE_TICK   30
#define AUTOPILOT_STARTUP_TICK   STARTUP_TIME + AUTOPILOT_NC_DELAY
#define AUTO_GUN_TICK   1
#define AUTO_GUN_MAX_HEAT   6.0
#define AUTO_GUN_MAX_TARGETS   100
#define AUTO_GUN_MAX_RANGE   30
#define AUTO_GUN_UPDATE_TICK   30
#define AUTO_GUN_IDLE_TICK   10
#define AUTO_GUN_PHYSICAL_RANGE_MIN   3.0
#define AUTO_PROFILE_TICK   180
#define AUTO_PROFILE_MAX_SIZE   30
#define AUTO_SENSOR_TICK   30
#define Gunning(a)   ((a)->flags & AUTOPILOT_AUTOGUN)
#define StartGun(a)   (a)->flags |= AUTOPILOT_AUTOGUN
#define StopGun(a)   (a)->flags &= ~(AUTOPILOT_AUTOGUN|AUTOPILOT_GUNZOMBIE)
#define AssignedTarget(a)   ((a)->flags & AUTOPILOT_ASSIGNED_TARGET)
#define AssignTarget(a)   (a)->flags |= AUTOPILOT_ASSIGNED_TARGET
#define UnassignTarget(a)   (a)->flags &= ~(AUTOPILOT_ASSIGNED_TARGET)
#define AUTO_CHASETARGET_ON   1
#define AUTO_CHASETARGET_OFF   2
#define AUTO_CHASETARGET_REMEMBER   3
#define AUTO_CHASETARGET_SAVE   4
#define ChasingTarget(a)   ((a)->flags & AUTOPILOT_CHASETARG)
#define StartChasingTarget(a)   (a)->flags |= AUTOPILOT_CHASETARG
#define StopChasingTarget(a)   (a)->flags &= ~(AUTOPILOT_CHASETARG)
#define WasChasingTarget(a)   ((a)->flags & AUTOPILOT_WAS_CHASE_ON)
#define RememberChasingTarget(a)   (a)->flags |= AUTOPILOT_WAS_CHASE_ON
#define ForgetChasingTarget(a)   (a)->flags &= ~(AUTOPILOT_WAS_CHASE_ON)
#define AUTO_ROAM_MAP   1
#define AUTO_ROAM_SPOT   2
#define AUTO_ROAM_TICK   3
#define AUTO_ROAM_NEW_HEX_TICK   100
#define AUTO_ROAM_MAX_RADIUS   30
#define AUTO_ROAM_MAX_MAP_DISTANCE   50
#define AUTO_ROAM_MAX_ITERATIONS   3
#define AUTO_GOET   15
#define AUTO_GOTT   240
#define DoStartGun(a)
#define DoStopGun(a)   StopGun(a)
#define Zombify(a)   do { a->flags |= AUTOPILOT_GUNZOMBIE; StopGun(a); } while (0)
#define PilZombify(a)   do { a->flags |= AUTOPILOT_PILZOMBIE; } while (0)
#define UnZombify(a)
#define UnZombifyAuto(a)
#define UnZombifyMech(mech)
#define GVAL(a, b)
#define CCLEN(a)   (1 + acom[a->commands[a->program_counter]].argcount)
#define PG(a)   a->program_counter
#define AUTO_CHECKS(a)
#define AUTO_COM(a, n)   AUTOEVENT(a, EVENT_AUTOCOM, auto_com_event, (n), 0);
#define ADVANCE_PG(a)   PG(a) += CCLEN(a); REDO(a,AUTOPILOT_NC_DELAY)
#define AUTO_PSTART(a, mech)   if (!Started(mech)) { auto_command_startup(a, mech); return; }
#define AUTO_GSTART(a, mech)
#define HexOffSet(x, y)   (x * MAPY + y)
#define HexOffSetNode(node)   (HexOffSet(node->x, node->y))
#define WhichByte(hex_offset)   ((hex_offset) >> 3)
#define WhichBit(hex_offset)   ((hex_offset) & 7)
#define CheckHexBit(array, offset)   (array[WhichByte(offset)] & (1 << WhichBit(offset)) ? 1 : 0)
#define SetHexBit(array, offset)
#define ClearHexBit(array, offset)
#define print_autogun_log(autopilot, args...)

Typedefs

typedef profile_node_t profile_node
typedef command_node_t command_node
typedef astar_node_t astar_node
typedef weapon_node_t weapon_node
typedef target_node_t target_node

Enumerations

enum  {
  GOAL_CHASETARGET, GOAL_DUMBFOLLOW, GOAL_DUMBGOTO, GOAL_ENTERBASE,
  GOAL_FOLLOW, GOAL_GOTO, GOAL_LEAVEBASE, GOAL_OLDGOTO,
  GOAL_ROAM, GOAL_WAIT, COMMAND_ATTACKLEG, COMMAND_AUTOGUN,
  COMMAND_CHASEMODE, COMMAND_CMODE, COMMAND_DROPOFF, COMMAND_EMBARK,
  COMMAND_ENTERBAY, COMMAND_JUMP, COMMAND_LOAD, COMMAND_PICKUP,
  COMMAND_REPORT, COMMAND_ROAMMODE, COMMAND_SHUTDOWN, COMMAND_SPEED,
  COMMAND_STARTUP, COMMAND_STOPGUN, COMMAND_SWARM, COMMAND_SWARMMODE,
  COMMAND_UDISEMBARK, COMMAND_UNLOAD, AUTO_NUM_COMMANDS
}

Functions

void auto_destroy_command_node (command_node *node)
void auto_save_commands (FILE *file, AUTO *autopilot)
void auto_load_commands (FILE *file, AUTO *autopilot)
void auto_delcommand (dbref player, void *data, char *buffer)
void auto_addcommand (dbref player, void *data, char *buffer)
void auto_listcommands (dbref player, void *data, char *buffer)
void auto_eventstats (dbref player, void *data, char *buffer)
void auto_set_comtitle (AUTO *autopilot, MECH *mech)
void auto_init (AUTO *autopilot, MECH *mech)
void auto_engage (dbref player, void *data, char *buffer)
void auto_disengage (dbref player, void *data, char *buffer)
void auto_goto_next_command (AUTO *autopilot, int time)
char * auto_get_command_arg (AUTO *autopilot, int command_number, int arg_number)
int auto_get_command_enum (AUTO *autopilot, int command_number)
void auto_newautopilot (dbref key, void **data, int selector)
void auto_cal_mapindex (MECH *mech)
void auto_set_chasetarget_mode (AUTO *autopilot, int mode)
void auto_command_startup (AUTO *autopilot, MECH *mech)
void auto_command_shutdown (AUTO *autopilot, MECH *mech)
void auto_command_pickup (AUTO *autopilot, MECH *mech)
void auto_command_dropoff (MECH *mech)
void auto_command_speed (AUTO *autopilot)
void auto_com_event (MUXEVENT *muxevent)
void auto_astar_goto_event (MUXEVENT *muxevent)
void auto_astar_follow_event (MUXEVENT *muxevent)
void auto_dumbgoto_event (MUXEVENT *muxevent)
void auto_dumbfollow_event (MUXEVENT *muxevent)
void auto_leave_event (MUXEVENT *muxevent)
void auto_enter_event (MUXEVENT *muxevent)
void auto_command_roam (AUTO *autopilot, MECH *mech)
void auto_astar_roam_event (MUXEVENT *muxevent)
int auto_astar_generate_path (AUTO *autopilot, MECH *mech, short end_x, short end_y)
void auto_destroy_astar_path (AUTO *autopilot)
int SearchLightInRange (MECH *mech, MAP *map)
int PrefVisSens (MECH *mech, MAP *map, int slite, MECH *target)
void auto_sensor_event (AUTO *muxevent)
void auto_gun_event (AUTO *AUTOPILOT)
void auto_destroy_weaplist (AUTO *autopilot)
void auto_update_profile_event (AUTO *autopilot)
void auto_reply_event (MUXEVENT *muxevent)
void auto_reply (MECH *mech, char *buf)
void auto_parse_command (AUTO *autopilot, MECH *mech, int chn, char *buffer)
void auto_radio_command_autogun (AUTO *autopilot, MECH *mech, char **args, int argc, char *mesg)
void auto_radio_command_chasetarg (AUTO *autopilot, MECH *mech, char **args, int argc, char *mesg)
void auto_radio_command_dfollow (AUTO *autopilot, MECH *mech, char **args, int argc, char *mesg)
void auto_radio_command_dgoto (AUTO *autopilot, MECH *mech, char **args, int argc, char *mesg)
void auto_radio_command_dropoff (AUTO *autopilot, MECH *mech, char **args, int argc, char *mesg)
void auto_radio_command_embark (AUTO *autopilot, MECH *mech, char **args, int argc, char *mesg)
void auto_radio_command_enterbase (AUTO *autopilot, MECH *mech, char **args, int argc, char *mesg)
void auto_radio_command_follow (AUTO *autopilot, MECH *mech, char **args, int argc, char *mesg)
void auto_radio_command_goto (AUTO *autopilot, MECH *mech, char **args, int argc, char *mesg)
void auto_radio_command_heading (AUTO *autopilot, MECH *mech, char **args, int argc, char *mesg)
void auto_radio_command_help (AUTO *autopilot, MECH *mech, char **args, int argc, char *mesg)
void auto_radio_command_hide (AUTO *autopilot, MECH *mech, char **args, int argc, char *mesg)
void auto_radio_command_jumpjet (AUTO *autopilot, MECH *mech, char **args, int argc, char *mesg)
void auto_radio_command_leavebase (AUTO *autopilot, MECH *mech, char **args, int argc, char *mesg)
void auto_radio_command_ogoto (AUTO *autopilot, MECH *mech, char **args, int argc, char *mesg)
void auto_radio_command_pickup (AUTO *autopilot, MECH *mech, char **args, int argc, char *mesg)
void auto_radio_command_position (AUTO *autopilot, MECH *mech, char **args, int argc, char *mesg)
void auto_radio_command_prone (AUTO *autopilot, MECH *mech, char **args, int argc, char *mesg)
void auto_radio_command_report (AUTO *autopilot, MECH *mech, char **args, int argc, char *mesg)
void auto_radio_command_reset (AUTO *autopilot, MECH *mech, char **args, int argc, char *mesg)
void auto_radio_command_sensor (AUTO *autopilot, MECH *mech, char **args, int argc, char *mesg)
void auto_radio_command_shutdown (AUTO *autopilot, MECH *mech, char **args, int argc, char *mesg)
void auto_radio_command_speed (AUTO *autopilot, MECH *mech, char **args, int argc, char *mesg)
void auto_radio_command_stand (AUTO *autopilot, MECH *mech, char **args, int argc, char *mesg)
void auto_radio_command_startup (AUTO *autopilot, MECH *mech, char **args, int argc, char *mesg)
void auto_radio_command_stop (AUTO *autopilot, MECH *mech, char **args, int argc, char *mesg)
void auto_radio_command_sweight (AUTO *autopilot, MECH *mech, char **args, int argc, char *mesg)
void auto_radio_command_target (AUTO *autopilot, MECH *mech, char **args, int argc, char *mesg)


Define Documentation

#define ADVANCE_PG (  )     PG(a) += CCLEN(a); REDO(a,AUTOPILOT_NC_DELAY)

Todo:
{Get rid of this once we're done}

Definition at line 166 of file autopilot.h.

Referenced by auto_com_event().

#define AssignedTarget (  )     ((a)->flags & AUTOPILOT_ASSIGNED_TARGET)

Definition at line 74 of file autopilot.h.

Referenced by auto_command_autogun(), auto_gun_event(), auto_radio_command_autogun(), and auto_radio_command_target().

#define AssignTarget (  )     (a)->flags |= AUTOPILOT_ASSIGNED_TARGET

Definition at line 75 of file autopilot.h.

Referenced by auto_command_autogun(), and auto_radio_command_target().

#define AUTO_CHASETARGET_OFF   2

Definition at line 80 of file autopilot.h.

Referenced by auto_radio_command_chasetarg(), auto_radio_command_stop(), and auto_set_chasetarget_mode().

#define AUTO_CHASETARGET_ON   1

Definition at line 79 of file autopilot.h.

Referenced by auto_radio_command_chasetarg(), and auto_set_chasetarget_mode().

#define AUTO_CHASETARGET_REMEMBER   3

Definition at line 81 of file autopilot.h.

Referenced by auto_set_chasetarget_mode().

#define AUTO_CHASETARGET_SAVE   4

Definition at line 83 of file autopilot.h.

Referenced by auto_set_chasetarget_mode().

#define AUTO_CHECKS (  ) 

Value:

if (Location(a->mynum) != a->mymechnum) return; \
    if (Destroyed(mech)) return;

Definition at line 157 of file autopilot.h.

Referenced by auto_com_event(), and auto_goto_event().

#define AUTO_COM ( a,
 )     AUTOEVENT(a, EVENT_AUTOCOM, auto_com_event, (n), 0);

Definition at line 162 of file autopilot.h.

Referenced by auto_goto_next_command().

#define AUTO_GOET   15

Todo:
{Not sure what these are look into it}

Definition at line 112 of file autopilot.h.

Referenced by ai_check_path().

#define AUTO_GOTT   240

Definition at line 113 of file autopilot.h.

Referenced by ai_check_path().

#define AUTO_GSTART ( a,
mech   ) 

Value:

AUTO_PSTART(a,mech); \
    if (MechType(mech) == CLASS_MECH && Fallen(mech) && \
            !(CountDestroyedLegs(mech) > 0)) { \
        if (!Standing(mech)) mech_stand(a->mynum, mech, ""); \
        AUTO_COM(a, AUTOPILOT_NC_DELAY); return; \
    }; \
    if (MechType(mech) == CLASS_VTOL && Landed(mech) && \
            !SectIsDestroyed(mech, ROTOR)) { \
        if (!TakingOff(mech)) aero_takeoff(a->mynum, mech, ""); \
        AUTO_COM(a, AUTOPILOT_NC_DELAY); return; \
    }

Definition at line 174 of file autopilot.h.

Referenced by auto_com_event(), auto_command_autogun(), auto_command_embark(), and auto_goto_event().

#define AUTO_GUN_IDLE_TICK   10

Definition at line 60 of file autopilot.h.

#define AUTO_GUN_MAX_HEAT   6.0

Definition at line 56 of file autopilot.h.

#define AUTO_GUN_MAX_RANGE   30

Definition at line 58 of file autopilot.h.

Referenced by auto_calc_target_score(), and auto_gun_event().

#define AUTO_GUN_MAX_TARGETS   100

Definition at line 57 of file autopilot.h.

#define AUTO_GUN_PHYSICAL_RANGE_MIN   3.0

Definition at line 61 of file autopilot.h.

#define AUTO_GUN_TICK   1

Definition at line 55 of file autopilot.h.

#define AUTO_GUN_UPDATE_TICK   30

Definition at line 59 of file autopilot.h.

Referenced by auto_command_autogun(), auto_gun_event(), auto_init(), auto_radio_command_autogun(), and auto_radio_command_target().

#define AUTO_PROFILE_MAX_SIZE   30

Definition at line 66 of file autopilot.h.

Referenced by auto_newautopilot(), auto_update_profile_event(), load_autopilot_data(), and newfreemech().

#define AUTO_PROFILE_TICK   180

Definition at line 64 of file autopilot.h.

Referenced by auto_heartbeat().

#define AUTO_PSTART ( a,
mech   )     if (!Started(mech)) { auto_command_startup(a, mech); return; }

Definition at line 170 of file autopilot.h.

#define AUTO_ROAM_MAP   1

Definition at line 97 of file autopilot.h.

Referenced by auto_command_roam(), and auto_roam_generate_target_hex().

#define AUTO_ROAM_MAX_ITERATIONS   3

Definition at line 108 of file autopilot.h.

Referenced by auto_astar_roam_event(), and auto_roam_generate_target_hex().

#define AUTO_ROAM_MAX_MAP_DISTANCE   50

Definition at line 105 of file autopilot.h.

Referenced by auto_roam_generate_target_hex().

#define AUTO_ROAM_MAX_RADIUS   30

Definition at line 103 of file autopilot.h.

Referenced by auto_command_roam().

#define AUTO_ROAM_NEW_HEX_TICK   100

Definition at line 102 of file autopilot.h.

Referenced by auto_astar_roam_event().

#define AUTO_ROAM_SPOT   2

Definition at line 98 of file autopilot.h.

Referenced by auto_command_roam(), and auto_roam_generate_target_hex().

#define AUTO_ROAM_TICK   3

Definition at line 101 of file autopilot.h.

Referenced by auto_astar_roam_event(), and auto_command_roam().

#define AUTO_SENSOR_TICK   30

Definition at line 67 of file autopilot.h.

#define AUTOPILOT_ASSIGNED_TARGET   256

Definition at line 36 of file autopilot.h.

#define AUTOPILOT_AUTOGUN   1

Definition at line 28 of file autopilot.h.

Referenced by auto_pilot_on(), and auto_stop_pilot().

#define AUTOPILOT_CHASETARG   32

Definition at line 33 of file autopilot.h.

Referenced by auto_com_event().

#define AUTOPILOT_CHASETARG_UPDATE_TICK   30

Definition at line 50 of file autopilot.h.

Referenced by auto_init(), and auto_set_chasetarget_mode().

#define AUTOPILOT_FOLLOW_TICK   3

Definition at line 47 of file autopilot.h.

Referenced by auto_astar_follow_event(), auto_com_event(), auto_command_chasetarget(), and auto_dumbfollow_event().

#define AUTOPILOT_FOLLOW_UPDATE_TICK   10

Definition at line 48 of file autopilot.h.

Referenced by auto_astar_follow_event(), and auto_init().

#define AUTOPILOT_GOTO_TICK   3

Definition at line 41 of file autopilot.h.

Referenced by ai_check_path(), auto_astar_goto_event(), auto_com_event(), auto_dumbgoto_event(), and auto_goto_event().

#define AUTOPILOT_GUNZOMBIE   2

Definition at line 29 of file autopilot.h.

Referenced by auto_pilot_on(), and auto_stop_pilot().

#define AUTOPILOT_LEAVE_TICK   5

Definition at line 42 of file autopilot.h.

Referenced by auto_com_event(), and auto_leave_event().

#define AUTOPILOT_LSENS   16

Definition at line 32 of file autopilot.h.

Referenced by auto_radio_command_sensor(), and auto_sensor_event().

#define AUTOPILOT_MAX_ARGS   5

Definition at line 24 of file autopilot.h.

Referenced by auto_addcommand(), auto_command_autogun(), auto_destroy_command_node(), auto_get_command_arg(), auto_parse_command(), and auto_show_command().

#define AUTOPILOT_MEMORY   100

Definition at line 23 of file autopilot.h.

#define AUTOPILOT_NC_DELAY   1

Definition at line 39 of file autopilot.h.

Referenced by auto_astar_follow_event(), auto_astar_goto_event(), auto_astar_roam_event(), auto_com_event(), auto_command_roam(), auto_dumbfollow_event(), auto_dumbgoto_event(), auto_engage(), auto_enter_event(), auto_goto_event(), and auto_leave_event().

#define AUTOPILOT_PILZOMBIE   4

Definition at line 30 of file autopilot.h.

Referenced by auto_pilot_on(), and auto_stop_pilot().

#define AUTOPILOT_PURSUE_TICK   3

Definition at line 45 of file autopilot.h.

#define AUTOPILOT_ROAM   8

Definition at line 31 of file autopilot.h.

#define AUTOPILOT_STARTUP_TICK   STARTUP_TIME + AUTOPILOT_NC_DELAY

Definition at line 52 of file autopilot.h.

Referenced by auto_astar_follow_event(), auto_astar_goto_event(), auto_astar_roam_event(), auto_command_startup(), auto_dumbfollow_event(), auto_dumbgoto_event(), auto_enter_event(), and auto_leave_event().

#define AUTOPILOT_SWARMCHARGE   128

Definition at line 35 of file autopilot.h.

Referenced by auto_com_event().

#define AUTOPILOT_WAITFOE_TICK   4

Definition at line 44 of file autopilot.h.

Referenced by auto_com_event().

#define AUTOPILOT_WAS_CHASE_ON   64

Definition at line 34 of file autopilot.h.

#define CCLEN (  )     (1 + acom[a->commands[a->program_counter]].argcount)

Definition at line 148 of file autopilot.h.

Referenced by auto_com_event().

#define ChasingTarget (  )     ((a)->flags & AUTOPILOT_CHASETARG)

Definition at line 86 of file autopilot.h.

Referenced by auto_radio_command_leavebase(), auto_radio_command_pickup(), and auto_set_chasetarget_mode().

#define CheckHexBit ( array,
offset   )     (array[WhichByte(offset)] & (1 << WhichBit(offset)) ? 1 : 0)

Definition at line 194 of file autopilot.h.

Referenced by auto_astar_generate_path().

#define ClearHexBit ( array,
offset   ) 

Value:

do { array[offset >> 3] = \
        array[offset >> 3] & ~(1 << (offset & 7)); } while (0)

Definition at line 197 of file autopilot.h.

Referenced by auto_astar_generate_path().

#define DoStartGun (  ) 

Value:

do { \
        StartGun(a); \
        a->flags &= ~AUTOPILOT_GUNZOMBIE; \
    } while (0)

Definition at line 115 of file autopilot.h.

Referenced by auto_command_autogun(), auto_radio_command_autogun(), auto_radio_command_target(), and load_autopilot_data().

#define DoStopGun (  )     StopGun(a)

Definition at line 121 of file autopilot.h.

Referenced by auto_com_event(), auto_command_autogun(), auto_gun_event(), auto_radio_command_autogun(), auto_radio_command_target(), auto_sensor_event(), and load_autopilot_data().

#define ForgetChasingTarget (  )     (a)->flags &= ~(AUTOPILOT_WAS_CHASE_ON)

Definition at line 93 of file autopilot.h.

Referenced by auto_set_chasetarget_mode().

#define Gunning (  )     ((a)->flags & AUTOPILOT_AUTOGUN)

Definition at line 69 of file autopilot.h.

Referenced by auto_com_event(), auto_command_autogun(), auto_radio_command_autogun(), auto_radio_command_target(), and load_autopilot_data().

#define GVAL ( a,
 ) 

Value:

(((a->program_counter + (b)) < a->first_free) ? \
    a->commands[(a->program_counter+(b))] : -1)
Todo:
{Get rid of these}

Definition at line 144 of file autopilot.h.

Referenced by auto_com_event().

#define HexOffSet ( x,
y   )     (x * MAPY + y)

Definition at line 188 of file autopilot.h.

Referenced by auto_astar_generate_path().

#define HexOffSetNode ( node   )     (HexOffSet(node->x, node->y))

Definition at line 189 of file autopilot.h.

#define PG (  )     a->program_counter

Definition at line 151 of file autopilot.h.

Referenced by auto_com_event(), and auto_jump().

#define PilZombify (  )     do { a->flags |= AUTOPILOT_PILZOMBIE; } while (0)

Definition at line 126 of file autopilot.h.

Referenced by auto_com_event().

#define print_autogun_log ( autopilot,
args...   ) 

Definition at line 208 of file autopilot.h.

Referenced by auto_gun_event(), and auto_update_profile_event().

#define RememberChasingTarget (  )     (a)->flags |= AUTOPILOT_WAS_CHASE_ON

Definition at line 92 of file autopilot.h.

Referenced by auto_set_chasetarget_mode().

#define SetHexBit ( array,
offset   ) 

Value:

do { array[offset >> 3] = \
        array[offset >> 3] | (1 << (offset & 7)); } while (0)

Definition at line 195 of file autopilot.h.

Referenced by auto_astar_generate_path().

#define StartChasingTarget (  )     (a)->flags |= AUTOPILOT_CHASETARG

Definition at line 87 of file autopilot.h.

Referenced by auto_set_chasetarget_mode().

#define StartGun (  )     (a)->flags |= AUTOPILOT_AUTOGUN

Definition at line 70 of file autopilot.h.

#define StopChasingTarget (  )     (a)->flags &= ~(AUTOPILOT_CHASETARG)

Definition at line 88 of file autopilot.h.

Referenced by auto_radio_command_leavebase(), auto_radio_command_pickup(), and auto_set_chasetarget_mode().

#define StopGun (  )     (a)->flags &= ~(AUTOPILOT_AUTOGUN|AUTOPILOT_GUNZOMBIE)

Definition at line 71 of file autopilot.h.

Referenced by auto_update_profile_event().

#define UnassignTarget (  )     (a)->flags &= ~(AUTOPILOT_ASSIGNED_TARGET)

Definition at line 76 of file autopilot.h.

Referenced by auto_command_autogun(), auto_gun_event(), auto_radio_command_autogun(), and auto_radio_command_target().

#define UnZombify (  ) 

Value:

do { if (a->flags & AUTOPILOT_GUNZOMBIE) { StartGun(a);\
        a->flags &= ~AUTOPILOT_GUNZOMBIE; } } while (0)

Definition at line 129 of file autopilot.h.

#define UnZombifyAuto (  ) 

Value:

do { if (Gunning(a)) UnZombify(a); if (a->flags & AUTOPILOT_PILZOMBIE) { \
        a->flags &= ~AUTOPILOT_PILZOMBIE ;\
        AUTOEVENT(a, EVENT_AUTOCOM, auto_com_event, 1, 0); } } while (0)

Definition at line 133 of file autopilot.h.

#define UnZombifyMech ( mech   ) 

Value:

do { AUTO *au; if (MechAuto(mech) > 0 && \
        (au=FindObjectsData(MechAuto(mech)))) UnZombifyAuto(au); } while (0)

Definition at line 138 of file autopilot.h.

Referenced by mech_Rsetmapindex(), mech_startup_event(), mech_udisembark(), and Sensor_DoWeSeeNow().

#define WasChasingTarget (  )     ((a)->flags & AUTOPILOT_WAS_CHASE_ON)

Definition at line 91 of file autopilot.h.

Referenced by auto_set_chasetarget_mode().

#define WhichBit ( hex_offset   )     ((hex_offset) & 7)

Definition at line 192 of file autopilot.h.

#define WhichByte ( hex_offset   )     ((hex_offset) >> 3)

Definition at line 191 of file autopilot.h.

#define Zombify (  )     do { a->flags |= AUTOPILOT_GUNZOMBIE; StopGun(a); } while (0)

Definition at line 123 of file autopilot.h.

Referenced by auto_gun_event(), and auto_sensor_event().


Typedef Documentation

typedef struct astar_node_t astar_node

typedef struct command_node_t command_node

typedef struct profile_node_t profile_node

typedef struct target_node_t target_node

typedef struct weapon_node_t weapon_node


Enumeration Type Documentation

anonymous enum

Enumerator:
GOAL_CHASETARGET 
GOAL_DUMBFOLLOW 
GOAL_DUMBGOTO 
GOAL_ENTERBASE 
GOAL_FOLLOW 
GOAL_GOTO 
GOAL_LEAVEBASE 
GOAL_OLDGOTO 
GOAL_ROAM 
GOAL_WAIT 
COMMAND_ATTACKLEG 
COMMAND_AUTOGUN 
COMMAND_CHASEMODE 
COMMAND_CMODE 
COMMAND_DROPOFF 
COMMAND_EMBARK 
COMMAND_ENTERBAY 
COMMAND_JUMP 
COMMAND_LOAD 
COMMAND_PICKUP 
COMMAND_REPORT 
COMMAND_ROAMMODE 
COMMAND_SHUTDOWN 
COMMAND_SPEED 
COMMAND_STARTUP 
COMMAND_STOPGUN 
COMMAND_SWARM 
COMMAND_SWARMMODE 
COMMAND_UDISEMBARK 
COMMAND_UNLOAD 
AUTO_NUM_COMMANDS 

Definition at line 329 of file autopilot.h.

00329      {
00330     GOAL_CHASETARGET,   /* An extension of follow for chasetarget */
00331     GOAL_DUMBFOLLOW,
00332     GOAL_DUMBGOTO,
00333     GOAL_ENTERBASE,     /* Revamp of enterbase so it keeps trying */
00334     GOAL_FOLLOW,        /* Uses the new Astar system */
00335     GOAL_GOTO,          /* Uses the new Astar system */ 
00336     GOAL_LEAVEBASE,
00337     GOAL_OLDGOTO,       /* Old implementation of goto */
00338     GOAL_ROAM,          /* New version using Astar */
00339     GOAL_WAIT,          /* unimplemented */
00340 
00341     COMMAND_ATTACKLEG,  /* unimplemented */
00342     COMMAND_AUTOGUN,    /* New version that has 3 options 'on', 'off' and 'target dbref' */
00343     COMMAND_CHASEMODE,  /* unimplemented */
00344     COMMAND_CMODE,      /* unimplemented */
00345     COMMAND_DROPOFF, 
00346     COMMAND_EMBARK,
00347     COMMAND_ENTERBAY,   /* unimplemented */
00348     COMMAND_JUMP,       /* unimplemented */
00349     COMMAND_LOAD,       /* unimplemented */
00350     COMMAND_PICKUP,
00351     COMMAND_REPORT,     /* unimplemented */
00352     COMMAND_ROAMMODE,   /* unimplemented */
00353     COMMAND_SHUTDOWN,
00354     COMMAND_SPEED,
00355     COMMAND_STARTUP,
00356     COMMAND_STOPGUN,    /* unimplemented */
00357     COMMAND_SWARM,      /* unimplemented */
00358     COMMAND_SWARMMODE,  /* unimplemented */
00359     COMMAND_UDISEMBARK,
00360     COMMAND_UNLOAD,     /* unimplemented */
00361     AUTO_NUM_COMMANDS
00362 };


Function Documentation

void auto_addcommand ( dbref  player,
void *  data,
char *  buffer 
)

Definition at line 449 of file autopilot_core.c.

References acom, command_node_t::ai_command_function, ACOM::ai_command_function, command_node_t::argcount, ACOM::argcount, args, command_node_t::args, auto_create_command_node(), auto_show_command(), AUTOPILOT_MAX_ARGS, command_node_t::command_enum, ACOM::command_enum, AUTO::commands, dllist_create_node(), dllist_insert_end(), DOCHECK, first_parseattribute(), ACOM::name, name, notify, notify_printf(), and proper_explodearguments().

Referenced by auto_com_event(), auto_radio_command_dfollow(), auto_radio_command_dgoto(), auto_radio_command_dropoff(), auto_radio_command_embark(), auto_radio_command_enterbase(), auto_radio_command_follow(), auto_radio_command_goto(), auto_radio_command_leavebase(), auto_radio_command_ogoto(), and auto_radio_command_pickup().

00450 {
00451 
00452         AUTO *autopilot = (AUTO *) data;
00453         char *args[AUTOPILOT_MAX_ARGS]; /* args[0] is the command the rest are 
00454                                                                            args for the command */
00455         char *command;                          /* temp string to get the name of the command */
00456         int argc;
00457         int i, j;
00458 
00459         command_node *temp_command_node;
00460         dllist_node *temp_dllist_node;
00461 
00462         /* Clear the Args */
00463         memset(args, 0, sizeof(char *) * AUTOPILOT_MAX_ARGS);
00464 
00465         command = first_parseattribute(buffer);
00466 
00467         /* Look at the buffer and try and get the command */
00468         for(i = 0; acom[i].name; i++) {
00469                 if((!strncmp(command, acom[i].name, strlen(command))) &&
00470                    (!strncmp(acom[i].name, command, strlen(acom[i].name))))
00471                         break;
00472         }
00473 
00474         /* Free the command string we dont need it anymore */
00475         free(command);
00476 
00477         /* Make sure its a valid command */
00478         DOCHECK(!acom[i].name, "Invalid Command!");
00479 
00480         /* Get the arguments for the command */
00481         if(acom[i].argcount > 0) {
00482 
00483                 /* Parse the buffer for commands
00484                  * Its argcount + 1 because we are parsing the command + its
00485                  * arguments */
00486                 argc = proper_explodearguments(buffer, args, acom[i].argcount + 1);
00487 
00488                 if(argc != acom[i].argcount + 1) {
00489 
00490                         /* Free the args before we quit */
00491                         for(j = 0; j < AUTOPILOT_MAX_ARGS; j++) {
00492                                 if(args[j])
00493                                         free(args[j]);
00494                         }
00495                         notify(player, "Not the proper number of arguments!");
00496                         return;
00497 
00498                 }
00499 
00500         } else {
00501 
00502                 /* Copy the command to the first arg */
00503                 args[0] = strdup(acom[i].name);
00504 
00505         }
00506 
00507         /* Build the command node */
00508         temp_command_node = auto_create_command_node();
00509 
00510         for(j = 0; j < AUTOPILOT_MAX_ARGS; j++) {
00511                 if(args[j])
00512                         temp_command_node->args[j] = args[j];
00513         }
00514 
00515         temp_command_node->argcount = acom[i].argcount;
00516         temp_command_node->command_enum = acom[i].command_enum;
00517         temp_command_node->ai_command_function = acom[i].ai_command_function;
00518 
00519         /* Add the command to the list */
00520         temp_dllist_node = dllist_create_node(temp_command_node);
00521         dllist_insert_end(autopilot->commands, temp_dllist_node);
00522 
00523         /* Let the player know it worked */
00524         notify_printf(player, "Command Added: %s",
00525                                   auto_show_command(temp_command_node));
00526 
00527 }

void auto_astar_follow_event ( MUXEVENT muxevent  ) 

Definition at line 1563 of file autopilot_commands.c.

References ai_set_speed(), AUTO::astar_path, auto_astar_follow_event(), auto_astar_generate_path(), auto_command_startup(), auto_destroy_astar_path(), auto_get_command_arg(), auto_get_command_enum(), auto_goto_next_command(), AUTOEVENT, AUTOPILOT_FOLLOW_TICK, AUTOPILOT_FOLLOW_UPDATE_TICK, AUTOPILOT_NC_DELAY, AUTOPILOT_STARTUP_TICK, CLASS_MECH, CountDestroyedLegs(), my_event_type::data, my_event_type::data2, Destroyed, dllist_get_node(), dllist_remove_node_at_pos(), dllist_size(), EVENT_AUTOFOLLOW, Fallen, figure_out_range_and_bearing(), FindXY(), AUTO::follow_update_tick, getMap(), getMech(), GOAL_CHASETARGET, GOAL_FOLLOW, IsAuto(), IsMech, Location, AUTO::mapindex, MECH::mapindex, MBUF_SIZE, mech_stand(), MechFacing, MechFX, MechFY, MechSpeed, MechType, MechX, MechY, AUTO::mymech, AUTO::mymechnum, MECH::mynum, AUTO::mynum, AUTO::ofsx, AUTO::ofsy, Readnum, RealCoordToMapCoord(), SendAI, slow_down_if_neccessary(), speed_up_if_neccessary(), Standing, Started, Starting, update_wanted_heading(), x, astar_node_t::x, y, and astar_node_t::y.

Referenced by auto_astar_follow_event(), auto_com_event(), and auto_command_chasetarget().

01564 {
01565 
01566         AUTO *autopilot = (AUTO *) muxevent->data;
01567         MECH *mech = autopilot->mymech;
01568         MECH *target;
01569         MAP *map;
01570 
01571         dbref target_dbref;
01572 
01573         float range;
01574         float fx, fy;
01575         short x, y;
01576         int bearing;
01577         int destroy_path = (int) muxevent->data2;
01578 
01579         char *argument;
01580         astar_node *temp_astar_node;
01581 
01582         char error_buf[MBUF_SIZE];
01583 
01584         if(!IsMech(mech->mynum) || !IsAuto(autopilot->mynum))
01585                 return;
01586 
01587         /* Are we in the mech we're supposed to be in */
01588         if(Location(autopilot->mynum) != autopilot->mymechnum)
01589                 return;
01590 
01591         /* Our mech is destroyed */
01592         if(Destroyed(mech))
01593                 return;
01594 
01595         /* Check to make sure the first command in the queue is this one */
01596         switch (auto_get_command_enum(autopilot, 1)) {
01597 
01598         case GOAL_FOLLOW:
01599                 break;
01600         case GOAL_CHASETARGET:
01601                 break;
01602         default:
01603                 return;
01604         }
01605 
01606         /* Get the Map */
01607         if(!(map = getMap(autopilot->mapindex))) {
01608 
01609                 /* Bad Map */
01610                 snprintf(error_buf, MBUF_SIZE, "Internal AI Error - Attempting to"
01611                                  " follow with AI #%d but AI is not on a valid"
01612                                  " Map (#%d).", autopilot->mynum, autopilot->mapindex);
01613                 SendAI(error_buf);
01614 
01615                 auto_goto_next_command(autopilot, AUTOPILOT_NC_DELAY);
01616                 return;
01617 
01618         }
01619 
01620         /* Make sure mech is started and standing */
01621         if(!Started(mech)) {
01622 
01623                 /* Startup */
01624                 if(!Starting(mech))
01625                         auto_command_startup(autopilot, mech);
01626 
01627                 /* Run this command after startup */
01628                 AUTOEVENT(autopilot, EVENT_AUTOFOLLOW, auto_astar_follow_event,
01629                                   AUTOPILOT_STARTUP_TICK, destroy_path);
01630                 return;
01631         }
01632 
01633         /* Ok not standing so lets do that first */
01634         if(MechType(mech) == CLASS_MECH && Fallen(mech) &&
01635            !(CountDestroyedLegs(mech) > 0)) {
01636 
01637                 if(!Standing(mech))
01638                         mech_stand(autopilot->mynum, mech, "");
01639 
01640                 /* Ok lets run this command again */
01641                 AUTOEVENT(autopilot, EVENT_AUTOFOLLOW, auto_astar_follow_event,
01642                                   AUTOPILOT_NC_DELAY, destroy_path);
01643                 return;
01644         }
01645 
01648         /* Get the only argument - dbref of target */
01649         if(!(argument = auto_get_command_arg(autopilot, 1, 1))) {
01650 
01651                 /* Ok bad argument - means the command is messed up
01652                  * so should go to next one */
01653                 snprintf(error_buf, MBUF_SIZE, "Internal AI Error - AI #%d attempting"
01654                                  " to follow target but was unable to - bad argument - going"
01655                                  " to next command", autopilot->mynum);
01656                 SendAI(error_buf);
01657                 auto_goto_next_command(autopilot, AUTOPILOT_NC_DELAY);
01658                 return;
01659         }
01660 
01661         /* See if its a valid number */
01662         if(Readnum(target_dbref, argument)) {
01663 
01664                 snprintf(error_buf, MBUF_SIZE, "Internal AI Error - AI #%d attempting"
01665                                  " to follow target but was unable to - bad argument '%s' - going"
01666                                  " to next command", autopilot->mynum, argument);
01667                 SendAI(error_buf);
01668                 free(argument);
01669                 auto_goto_next_command(autopilot, AUTOPILOT_NC_DELAY);
01670                 return;
01671         }
01672         free(argument);
01673 
01674         /* Get the target */
01675         if(!(target = getMech(target_dbref))) {
01676 
01677                 /* Bad Target */
01678                 snprintf(error_buf, MBUF_SIZE, "Internal AI Error - Attempting to"
01679                                  " follow unit #%d with AI #%d but its not a valid unit.",
01680                                  target_dbref, autopilot->mynum);
01681                 SendAI(error_buf);
01682 
01683                 ai_set_speed(mech, autopilot, 0);
01684                 auto_goto_next_command(autopilot, AUTOPILOT_NC_DELAY);
01685                 return;
01686         }
01687 
01688         /* Is the target destroyed or we not even on the same map */
01689         if(Destroyed(target) || (target->mapindex != mech->mapindex)) {
01690 
01691                 snprintf(error_buf, MBUF_SIZE, "Internal AI Error - Attempting to"
01692                                  " follow unit #%d with AI #%d but it is either dead or"
01693                                  " not on the same map.", target_dbref, autopilot->mynum);
01694                 SendAI(error_buf);
01695 
01696                 ai_set_speed(mech, autopilot, 0);
01697                 auto_goto_next_command(autopilot, AUTOPILOT_NC_DELAY);
01698                 return;
01699         }
01700 
01701         /* Generate the target hex - since this can be altered by position command */
01702         FindXY(MechFX(target), MechFY(target),
01703                    MechFacing(target) + autopilot->ofsx, autopilot->ofsy, &fx, &fy);
01704 
01705         RealCoordToMapCoord(&x, &y, fx, fy);
01706 
01707         /* Make sure the hex is sane - if not set the target hex to the target's
01708          * hex */
01709         if(x < 0 || y < 0 || x >= map->map_width || y >= map->map_height) {
01710 
01711                 /* Reset the hex to the Target's current hex */
01712                 x = MechX(target);
01713                 y = MechY(target);
01714 
01715         }
01716 
01717         /* Are we in the target hex and the target isn't moving ? */
01718         if((MechX(mech) == x) && (MechY(mech) == y) && (MechSpeed(target) < 0.5)) {
01719 
01720                 /* Ok go into holding pattern */
01721                 ai_set_speed(mech, autopilot, 0.0);
01722 
01723                 /* Destroy the path so we can force the path to be generated if the
01724                  * target moves */
01725                 if(autopilot->astar_path) {
01726                         auto_destroy_astar_path(autopilot);
01727                 }
01728 
01729                 AUTOEVENT(autopilot, EVENT_AUTOFOLLOW, auto_astar_follow_event,
01730                                   AUTOPILOT_FOLLOW_TICK, 0);
01731                 return;
01732         }
01733 
01734         /* Destroy the path if we need to - this typically happens
01735          * if its the first run of the event */
01736         if(destroy_path) {
01737                 auto_destroy_astar_path(autopilot);
01738         }
01739 
01740         /* Do we need to generate the path - only switch paths if we don't have
01741          * one or if the ticker has gone high enough */
01742         if(!(autopilot->astar_path) ||
01743            autopilot->follow_update_tick >= AUTOPILOT_FOLLOW_UPDATE_TICK) {
01744 
01745                 /* Target hex is not target's hex */
01746                 if((x != MechX(mech)) || (y != MechY(mech))) {
01747 
01748                         /* Try and generate path with target hex */
01749                         if(!(auto_astar_generate_path(autopilot, mech, x, y))) {
01750 
01751                                 /* Didn't work so reset the x,y coords to target's hex
01752                                  * and try again */
01753                                 x = MechX(target);
01754                                 y = MechY(target);
01755 
01756                                 /* This is how we try again - reset the ticker and
01757                                  * it will try again */
01758                                 autopilot->follow_update_tick = AUTOPILOT_FOLLOW_UPDATE_TICK;
01759 
01760                         } else {
01761 
01762                                 /* Reset the ticker - found path */
01763                                 autopilot->follow_update_tick = 0;
01764 
01765                         }
01766 
01767                         if((autopilot->follow_update_tick != 0) &&
01768                            !(auto_astar_generate_path(autopilot, mech, x, y))) {
01769 
01770                                 /* Major failure - No path found */
01771                                 snprintf(error_buf, MBUF_SIZE,
01772                                                  "Internal AI Error - Attempting to"
01773                                                  " generate an astar path for AI #%d to hex %d,%d to follow"
01774                                                  " unit #%d, but was unable to.", autopilot->mynum, x,
01775                                                  y, target_dbref);
01776                                 SendAI(error_buf);
01777 
01780                                 ai_set_speed(mech, autopilot, 0);
01781                                 auto_goto_next_command(autopilot, AUTOPILOT_NC_DELAY);
01782                                 return;
01783 
01784                         } else {
01785 
01786                                 /* Path found */
01787                                 autopilot->follow_update_tick = 0;
01788                         }
01789 
01790                 } else {
01791 
01792                         /* Ok same hex so try and generate path */
01793                         if(!(auto_astar_generate_path(autopilot, mech, x, y))) {
01794 
01795                                 /* Couldn't find a path for some reason */
01796                                 snprintf(error_buf, MBUF_SIZE,
01797                                                  "Internal AI Error - Attempting to"
01798                                                  " generate an astar path for AI #%d to hex %d,%d to follow"
01799                                                  " unit #%d, but was unable to.", autopilot->mynum, x,
01800                                                  y, target_dbref);
01801                                 SendAI(error_buf);
01802 
01805                                 ai_set_speed(mech, autopilot, 0);
01806                                 auto_goto_next_command(autopilot, AUTOPILOT_NC_DELAY);
01807                                 return;
01808 
01809                         } else {
01810 
01811                                 /* Zero the ticker */
01812                                 autopilot->follow_update_tick = 0;
01813 
01814                         }
01815 
01816                 }
01817 
01818         }
01819 
01820         /* Make sure list is ok */
01821         if(!(autopilot->astar_path) || (dllist_size(autopilot->astar_path) <= 0)) {
01822 
01823                 snprintf(error_buf, MBUF_SIZE,
01824                                  "Internal AI Error - Attempting to follow"
01825                                  " Astar path for AI #%d - but the path is not there",
01826                                  autopilot->mynum);
01827                 SendAI(error_buf);
01828 
01829                 /* Destroy List */
01830                 auto_destroy_astar_path(autopilot);
01831                 ai_set_speed(mech, autopilot, 0);
01832                 auto_goto_next_command(autopilot, AUTOPILOT_NC_DELAY);
01833                 return;
01834 
01835         }
01836 
01837         /* Get the current hex target */
01838         temp_astar_node =
01839                 (astar_node *) dllist_get_node(autopilot->astar_path, 1);
01840 
01841         if(!(temp_astar_node)) {
01842 
01843                 snprintf(error_buf, MBUF_SIZE,
01844                                  "Internal AI Error - Attemping to follow"
01845                                  " Astar path for AI #%d - but the current astar node does not"
01846                                  " exist", autopilot->mynum);
01847                 SendAI(error_buf);
01848 
01849                 /* Destroy List */
01850                 auto_destroy_astar_path(autopilot);
01851                 ai_set_speed(mech, autopilot, 0);
01852                 auto_goto_next_command(autopilot, AUTOPILOT_NC_DELAY);
01853                 return;
01854 
01855         }
01856 
01857         /* Are we in the current target hex */
01858         if((MechX(mech) == temp_astar_node->x) &&
01859            (MechY(mech) == temp_astar_node->y)) {
01860 
01861                 /* Is this the last hex */
01862                 if(dllist_size(autopilot->astar_path) == 1) {
01863 
01864                         /* Done! */
01865                         ai_set_speed(mech, autopilot, 0);
01866                         auto_destroy_astar_path(autopilot);
01867 
01868                         /* Re-Run Follow */
01869                         AUTOEVENT(autopilot, EVENT_AUTOFOLLOW, auto_astar_follow_event,
01870                                           AUTOPILOT_FOLLOW_TICK, 0);
01871                         return;
01872 
01873                 } else {
01874 
01875                         /* Delete the node and goto the next one */
01876                         temp_astar_node =
01877                                 (astar_node *) dllist_remove_node_at_pos(autopilot->
01878                                                                                                                  astar_path, 1);
01879                         free(temp_astar_node);
01880 
01881                         /* Call this event again */
01882                         AUTOEVENT(autopilot, EVENT_AUTOFOLLOW, auto_astar_follow_event,
01883                                           AUTOPILOT_FOLLOW_TICK, 0);
01884                         return;
01885 
01886                 }
01887 
01888         }
01889 
01890         /* Set our current goal - not the end goal tho - unless this is
01891          * the end hex but whatever */
01892         x = temp_astar_node->x;
01893         y = temp_astar_node->y;
01894 
01895         /* Move towards our next hex */
01896         figure_out_range_and_bearing(mech, x, y, &range, &bearing);
01897         speed_up_if_neccessary(autopilot, mech, x, y, bearing);
01898         slow_down_if_neccessary(autopilot, mech, range, bearing, x, y);
01899         update_wanted_heading(autopilot, mech, bearing);
01900 
01901         /* Increase Tick */
01902         autopilot->follow_update_tick++;
01903 
01904         AUTOEVENT(autopilot, EVENT_AUTOFOLLOW, auto_astar_follow_event,
01905                           AUTOPILOT_FOLLOW_TICK, 0);
01906 
01907 }

int auto_astar_generate_path ( AUTO autopilot,
MECH mech,
short  end_x,
short  end_y 
)

Definition at line 994 of file autopilot_ai.c.

References astar_compare(), AUTO::astar_path, astar_release(), auto_create_astar_node(), auto_destroy_astar_path(), CheckHexBit, CLASS_MECH, CLASS_VEH_GROUND, ClearHexBit, dllist_create_list(), dllist_create_node(), dllist_insert_beginning(), Elevation, astar_node_t::f_score, FindHexRange(), FindXY(), astar_node_t::g_score, getMap(), GetTerrain, astar_node_t::h_score, HEAVY_FOREST, astar_node_t::hexoffset, HexOffSet, HIGHWATER, LIGHT_FOREST, MAP::map_height, MAP::map_width, MapCoordToRealCoord(), AUTO::mapindex, MAPX, MAPY, MBUF_SIZE, MechMove, MechSpecials2, MechType, MechX, MechY, MOUNTAINS, MOVE_HOVER, MOVE_TRACK, AUTO::mynum, rb_delete(), rb_destroy(), rb_exists(), rb_find(), rb_init(), rb_insert(), rb_release(), rb_search(), rb_size(), RealCoordToMapCoord(), ROUGH, SEARCH_FIRST, SetHexBit, WATER, WATERPROOF_TECH, astar_node_t::x, astar_node_t::x_parent, astar_node_t::y, and astar_node_t::y_parent.

Referenced by auto_astar_follow_event(), auto_astar_goto_event(), and auto_astar_roam_event().

00996 {
00997         MAP *map = getMap(autopilot->mapindex);
00998         int found_path = 0;
00999 
01000         /* Our bit arrays */
01001         unsigned char closed_list_bitfield[(MAPX * MAPY) / 8];
01002         unsigned char open_list_bitfield[(MAPX * MAPY) / 8];
01003 
01004         float x1, y1, x2, y2;           /* Floating point vars for real cords */
01005         short map_x1, map_y1, map_x2, map_y2;   /* The actual map 'hexes' */
01006         int i;
01007         int child_g_score, child_h_score;       /* the score values for the child hexes */
01008         int hexoffset;                          /* temp int to pass around as the hexoffset */
01009 
01010         /* Our lists using Hag's rbtree */
01011         /* Using two rbtree's to store the open_list so we can sort two
01012          * different ways */
01013         rbtree open_list_by_score;      /* open list sorted by score */
01014         rbtree open_list_by_xy; /* open list sorted by hexoffset */
01015         rbtree closed_list;             /* closed list sorted by hexoffset */
01016 
01017         /* Helper node for the final path */
01018         dllist_node *astar_path_node;
01019 
01020         /* Our astar_node helpers */
01021         astar_node *temp_astar_node;
01022         astar_node *parent_astar_node;
01023 
01024 #ifdef DEBUG_ASTAR
01025         /* Log File */
01026         FILE *logfile;
01027         char log_msg[MBUF_SIZE];
01028 
01029         /* Open the logfile */
01030         logfile = fopen("astar.log", "a");
01031 
01032         /* Write first message */
01033         snprintf(log_msg, MBUF_SIZE,
01034                          "\nStarting ASTAR Path finding for AI #%d from "
01035                          "%d, %d to %d, %d\n", autopilot->mynum, MechX(mech), MechY(mech),
01036                          end_x, end_y);
01037         fprintf(logfile, "%s", log_msg);
01038 #endif
01039 
01040         /* Zero the bitfields */
01041         memset(closed_list_bitfield, 0, sizeof(closed_list_bitfield));
01042         memset(open_list_bitfield, 0, sizeof(open_list_bitfield));
01043 
01044         /* Setup the trees */
01045         open_list_by_score = rb_init((void *)astar_compare, NULL);
01046         open_list_by_xy = rb_init((void *)astar_compare, NULL);
01047         closed_list = rb_init((void *)astar_compare, NULL);
01048 
01049         /* Setup the path */
01050         /* Destroy any existing path first */
01051         auto_destroy_astar_path(autopilot);
01052         autopilot->astar_path = dllist_create_list();
01053 
01054         /* Setup the start hex */
01055         temp_astar_node =
01056                 auto_create_astar_node(MechX(mech), MechY(mech), -1, -1, 0, 0);
01057 
01058         if(temp_astar_node == NULL) {
01061 #ifdef DEBUG_ASTAR
01062                 /* Write Log Message */
01063                 snprintf(log_msg, MBUF_SIZE,
01064                                  "AI ERROR - Unable to malloc astar node for " "hex %d, %d\n",
01065                                  MechX(mech), MechY(mech));
01066                 fprintf(logfile, "%s", log_msg);
01067 #endif
01068 
01069         }
01070 
01071         /* Add start hex to open list */
01072         rb_insert(open_list_by_score, (void *) temp_astar_node->f_score,
01073                           temp_astar_node);
01074         rb_insert(open_list_by_xy, (void *) temp_astar_node->hexoffset,
01075                           temp_astar_node);
01076         SetHexBit(open_list_bitfield, temp_astar_node->hexoffset);
01077 
01078 #ifdef DEBUG_ASTAR
01079         /* Log it */
01080         snprintf(log_msg, MBUF_SIZE, "Added hex %d, %d (%d %d) to open list\n",
01081                          temp_astar_node->x, temp_astar_node->y, temp_astar_node->g_score,
01082                          temp_astar_node->h_score);
01083         fprintf(logfile, "%s", log_msg);
01084 #endif
01085 
01086         /* Now loop till we find path */
01087         while (!found_path) {
01088 
01089                 /* Check to make sure there is still stuff in the open list
01090                  * if not, means we couldn't find a path so quit */
01091                 if(rb_size(open_list_by_score) == 0) {
01092                         break;
01093                 }
01094 
01095                 /* Get lowest cost node, then remove it from the open list */
01096                 parent_astar_node = (astar_node *) rb_search(open_list_by_score,
01097                                                                                                          SEARCH_FIRST, NULL);
01098 
01099                 rb_delete(open_list_by_score, (void *) parent_astar_node->f_score);
01100                 rb_delete(open_list_by_xy, (void *) parent_astar_node->hexoffset);
01101                 ClearHexBit(open_list_bitfield, parent_astar_node->hexoffset);
01102 
01103 #ifdef DEBUG_ASTAR
01104                 /* Log it */
01105                 snprintf(log_msg, MBUF_SIZE, "Removed hex %d, %d (%d %d) from open "
01106                                  "list - lowest cost node\n",
01107                                  parent_astar_node->x, parent_astar_node->y,
01108                                  parent_astar_node->g_score, parent_astar_node->h_score);
01109                 fprintf(logfile, "%s", log_msg);
01110 #endif
01111 
01112                 /* Add it to the closed list */
01113                 rb_insert(closed_list, (void *) parent_astar_node->hexoffset,
01114                                   parent_astar_node);
01115                 SetHexBit(closed_list_bitfield, parent_astar_node->hexoffset);
01116 
01117 #ifdef DEBUG_ASTAR
01118                 /* Log it */
01119                 snprintf(log_msg, MBUF_SIZE, "Added hex %d, %d (%d %d) to closed list"
01120                                  " - lowest cost node\n",
01121                                  parent_astar_node->x, parent_astar_node->y,
01122                                  parent_astar_node->g_score, parent_astar_node->h_score);
01123                 fprintf(logfile, "%s", log_msg);
01124 #endif
01125 
01126                 /* Now we check to see if we added the end hex to the closed list.
01127                  * When this happens it means we are done */
01128                 if(CheckHexBit(closed_list_bitfield, HexOffSet(end_x, end_y))) {
01129                         found_path = 1;
01130 
01131 #ifdef DEBUG_ASTAR
01132                         fprintf(logfile, "Found path for the AI\n");
01133 #endif
01134 
01135                         break;
01136                 }
01137 
01138                 /* Update open list */
01139                 /* Loop through the hexes around current hex and see if we can add
01140                  * them to the open list */
01141 
01142                 /* Set the parent hex of the new nodes */
01143                 map_x1 = parent_astar_node->x;
01144                 map_y1 = parent_astar_node->y;
01145 
01146                 /* Going around clockwise direction */
01147                 for(i = 0; i < 360; i += 60) {
01148 
01149                         /* Map coord to Real */
01150                         MapCoordToRealCoord(map_x1, map_y1, &x1, &y1);
01151 
01152                         /* Calc new hex */
01153                         FindXY(x1, y1, i, 1.0, &x2, &y2);
01154 
01155                         /* Real coord to Map */
01156                         RealCoordToMapCoord(&map_x2, &map_y2, x2, y2);
01157 
01158                         /* Make sure the hex is sane */
01159                         if(map_x2 < 0 || map_y2 < 0 ||
01160                            map_x2 >= map->map_width || map_y2 >= map->map_height)
01161                                 continue;
01162 
01163                         /* Generate hexoffset for the child node */
01164                         hexoffset = HexOffSet(map_x2, map_y2);
01165 
01166                         /* Check to see if its in the closed list 
01167                          * if so just ignore it */
01168                         if(CheckHexBit(closed_list_bitfield, hexoffset))
01169                                 continue;
01170 
01171                         /* Check to see if we can enter it */
01172                         if((MechType(mech) == CLASS_MECH) &&
01173                            (abs(Elevation(map, map_x1, map_y1)
01174                                         - Elevation(map, map_x2, map_y2)) > 2))
01175                                 continue;
01176 
01177                         if((MechType(mech) == CLASS_VEH_GROUND) &&
01178                            (abs(Elevation(map, map_x1, map_y1)
01179                                         - Elevation(map, map_x2, map_y2)) > 1))
01180                                 continue;
01181 
01182                         /* Score the hex */
01183                         /* Right now just assume movement cost from parent to child hex is
01184                          * the same (so 100) no matter which dir we go*/
01186                         child_g_score = 100;
01187 
01188                         /* Now add the g score from the parent */
01189                         child_g_score += parent_astar_node->g_score;
01190 
01191                         /* Next get range */
01192                         /* Using a varient of the Manhattan method since its perfectly
01193                          * logical for us to go diagonally
01194                          *
01195                          * Basicly just going to get the range,
01196                          * and multiply by 100 */
01199                         /* Get the end hex in real coords, using the old variables 
01200                          * to store the values */
01201                         MapCoordToRealCoord(end_x, end_y, &x1, &y1);
01202 
01203                         /* Re-using the x2 and y2 values we calc'd for the child hex 
01204                          * to find the range between the child hex and end hex */
01205                         child_h_score = 100 * FindHexRange(x2, y2, x1, y1);
01206 
01207                         /* Now add in some modifiers for terrain */
01208                         switch (GetTerrain(map, map_x2, map_y2)) {
01209                         case LIGHT_FOREST:
01210 
01211                                 /* Don't bother trying to enter a light forest 
01212                                  * hex unless we can */
01213                                 if((MechType(mech) == CLASS_VEH_GROUND) &&
01214                                    (MechMove(mech) != MOVE_TRACK))
01215                                         continue;
01216 
01217                                 child_g_score += 50;
01218                                 break;
01219                         case ROUGH:
01220                                 child_g_score += 50;
01221                                 break;
01222                         case HEAVY_FOREST:
01223 
01224                                 /* Don't bother trying to enter a heavy forest
01225                                  * hex unless we can */
01226                                 if(MechType(mech) == CLASS_VEH_GROUND)
01227                                         continue;
01228 
01229                                 child_g_score += 100;
01230                                 break;
01231                         case MOUNTAINS:
01232                                 child_g_score += 100;
01233                                 break;
01234                         case WATER:
01235 
01236                                 /* Don't bother trying to enter a water hex
01237                                  * unless we can */
01238                                 if((MechType(mech) == CLASS_VEH_GROUND) &&
01239                                    (MechMove(mech) != MOVE_HOVER) && !(MechSpecials2(mech) & WATERPROOF_TECH))
01240                                         continue;
01241 
01242                                 /* We really don't want them trying to enter water */
01243                                 child_g_score += 200;
01244                                 break;
01245                         case HIGHWATER:
01246 
01247                                 /* Don't bother trying to enter a water hex
01248                                  * unless we can */
01249                                 if((MechType(mech) == CLASS_VEH_GROUND) &&
01250                                    (MechMove(mech) != MOVE_HOVER) && !(MechSpecials2(mech) & WATERPROOF_TECH))
01251                                         continue;
01252 
01253                                 /* We really don't want them trying to enter water */
01254                                 child_g_score += 200;
01255                                 break;
01256                         default:
01257                                 break;
01258                         }
01259 
01260                         /* Is it already on the openlist */
01261                         if(CheckHexBit(open_list_bitfield, hexoffset)) {
01262 
01263                                 /* Ok need to compare the scores and if necessary recalc
01264                                  * and change stuff */
01265 
01266                                 /* Get the node off the open_list */
01267                                 temp_astar_node = (astar_node *) rb_find(open_list_by_xy,
01268                                                                                                                  (void *) hexoffset);
01269 
01270                                 /* Now compare the 'g_scores' to determine shortest path */
01271                                 /* If g_score is lower, this means better path 
01272                                  * from the current parent node */
01273                                 if(child_g_score < temp_astar_node->g_score) {
01274 
01275                                         /* Remove from open list */
01276                                         rb_delete(open_list_by_score,
01277                                                           (void *) temp_astar_node->f_score);
01278                                         rb_delete(open_list_by_xy,
01279                                                           (void *) temp_astar_node->hexoffset);
01280                                         ClearHexBit(open_list_bitfield,
01281                                                                 temp_astar_node->hexoffset);
01282 
01283 #ifdef DEBUG_ASTAR
01284                                         /* Log it */
01285                                         snprintf(log_msg, MBUF_SIZE,
01286                                                          "Removed hex %d, %d (%d %d) from "
01287                                                          "open list - score recal\n", temp_astar_node->x,
01288                                                          temp_astar_node->y, temp_astar_node->g_score,
01289                                                          temp_astar_node->h_score);
01290                                         fprintf(logfile, "%s", log_msg);
01291 #endif
01292 
01293                                         /* Recalc score */
01294                                         /* H-Score should be the same since the hex doesn't move */
01295                                         temp_astar_node->g_score = child_g_score;
01296                                         temp_astar_node->f_score = temp_astar_node->g_score +
01297                                                 temp_astar_node->h_score;
01298 
01299                                         /* Change parent hex */
01300                                         temp_astar_node->x_parent = map_x1;
01301                                         temp_astar_node->y_parent = map_y1;
01302 
01303                                         /* Will re-add the node below */
01304 
01305                                 } else {
01306 
01307                                         /* Don't need to do anything so we can skip 
01308                                          * to the next node */
01309                                         continue;
01310 
01311                                 }
01312 
01313                         } else {
01314 
01315                                 /* Node isn't on the open list so we have to create it */
01316                                 temp_astar_node =
01317                                         auto_create_astar_node(map_x2, map_y2, map_x1, map_y1,
01318                                                                                    child_g_score, child_h_score);
01319 
01320                                 if(temp_astar_node == NULL) {
01323 #ifdef DEBUG_ASTAR
01324                                         /* Log it */
01325                                         snprintf(log_msg, MBUF_SIZE,
01326                                                          "AI ERROR - Unable to malloc astar"
01327                                                          " node for hex %d, %d\n", map_x2, map_y2);
01328                                         fprintf(logfile, "%s", log_msg);
01329 #endif
01330 
01331                                 }
01332 
01333                         }
01334 
01335                         /* Now add (or re-add) the node to the open list */
01336 
01337                         /* Hack to check to make sure its score is not already on the open
01338                          * list. This slightly skews the results towards nodes found earlier
01339                          * then those found later */
01340                         while (1) {
01341 
01342                                 if(rb_exists
01343                                    (open_list_by_score, (void *) temp_astar_node->f_score)) {
01344                                         temp_astar_node->f_score++;
01345 
01346 #ifdef DEBUG_ASTAR
01347                                         fprintf(logfile, "Adjusting score for hex %d, %d - same"
01348                                                         " fscore already exists\n",
01349                                                         temp_astar_node->x, temp_astar_node->y);
01350 #endif
01351 
01352                                 } else {
01353                                         break;
01354                                 }
01355 
01356                         }
01357                         rb_insert(open_list_by_score, (void *) temp_astar_node->f_score,
01358                                           temp_astar_node);
01359                         rb_insert(open_list_by_xy, (void *) temp_astar_node->hexoffset,
01360                                           temp_astar_node);
01361                         SetHexBit(open_list_bitfield, temp_astar_node->hexoffset);
01362 
01363 #ifdef DEBUG_ASTAR
01364                         /* Log it */
01365                         snprintf(log_msg, MBUF_SIZE,
01366                                          "Added hex %d, %d (%d %d) to open list\n",
01367                                          temp_astar_node->x, temp_astar_node->y,
01368                                          temp_astar_node->g_score, temp_astar_node->h_score);
01369                         fprintf(logfile, "%s", log_msg);
01370 #endif
01371 
01372                 }                                               /* End of looking for hexes next to us */
01373 
01374         }                                                       /* End of looking for path */
01375 
01376         /* We Done lets go */
01377 
01378         /* Lets first see if we found a path */
01379         if(found_path) {
01380 
01381 #ifdef DEBUG_ASTAR
01382                 /* Log Message */
01383                 fprintf(logfile, "Building Path from closed list for AI\n");
01384 #endif
01385 
01386                 /* Found a path so we need to go through the closed list
01387                  * and generate it */
01388 
01389                 /* Get the end hex, find its parent hex and work back to
01390                  * start hex while building list */
01391 
01392                 /* Get end hex from closed list */
01393                 hexoffset = HexOffSet(end_x, end_y);
01394                 temp_astar_node = rb_find(closed_list, (void *) hexoffset);
01395 
01396                 /* Add end hex to path list */
01397                 astar_path_node = dllist_create_node(temp_astar_node);
01398                 dllist_insert_beginning(autopilot->astar_path, astar_path_node);
01399 
01400 #ifdef DEBUG_ASTAR
01401                 /* Log it */
01402                 fprintf(logfile, "Added hex %d, %d to path list\n",
01403                                 temp_astar_node->x, temp_astar_node->y);
01404 #endif
01405 
01406                 /* Remove it from closed list */
01407                 rb_delete(closed_list, (void *) temp_astar_node->hexoffset);
01408 
01409 #ifdef DEBUG_ASTAR
01410                 /* Log it */
01411                 fprintf(logfile,
01412                                 "Removed hex %d, %d from closed list - path list work\n",
01413                                 temp_astar_node->x, temp_astar_node->y);
01414 #endif
01415 
01416                 /* Check if the end hex is the start hex */
01417                 if(!(temp_astar_node->x == MechX(mech) &&
01418                          temp_astar_node->y == MechY(mech))) {
01419 
01420                         /* Its not so lets loop through the closed list
01421                          * building the path */
01422 
01423                         /* Loop */
01424                         while (1) {
01425 
01426                                 /* Get Parent Node Offset */
01427                                 hexoffset = HexOffSet(temp_astar_node->x_parent,
01428                                                                           temp_astar_node->y_parent);
01429 
01433                                 /* Get Parent Node from closed list */
01434                                 parent_astar_node = rb_find(closed_list, (void *) hexoffset);
01435 
01436                                 /* Check if start hex */
01437                                 /* If start hex quit */
01438                                 if(parent_astar_node->x == MechX(mech) &&
01439                                    parent_astar_node->y == MechY(mech)) {
01440                                         break;
01441                                 }
01442 
01443                                 /* Add to path list */
01444                                 astar_path_node = dllist_create_node(parent_astar_node);
01445                                 dllist_insert_beginning(autopilot->astar_path,
01446                                                                                 astar_path_node);
01447 
01448 #ifdef DEBUG_ASTAR
01449                                 /* Log it */
01450                                 fprintf(logfile, "Added hex %d, %d to path list\n",
01451                                                 parent_astar_node->x, parent_astar_node->y);
01452 #endif
01453 
01454                                 /* Remove from closed list */
01455                                 rb_delete(closed_list, (void *) parent_astar_node->hexoffset);
01456 
01457 #ifdef DEBUG_ASTAR
01458                                 /* Log it */
01459                                 fprintf(logfile,
01460                                                 "Removed hex %d, %d from closed list - path list work\n",
01461                                                 parent_astar_node->x, parent_astar_node->y);
01462 #endif
01463 
01464                                 /* Make parent new child */
01465                                 temp_astar_node = parent_astar_node;
01466 
01467                         }                                       /* End of while loop */
01468 
01469                 }
01470 
01471                 /* Done with the path its cleanup time */
01472 
01473         }
01474 
01475         /* Make sure we destroy all the objects we dont need any more */
01476 
01477 #ifdef DEBUG_ASTAR
01478         /* Log Message */
01479         fprintf(logfile, "Destorying the AI lists\n");
01480 #endif
01481 
01482         /* Destroy the open lists */
01483         rb_release(open_list_by_score, (void *)astar_release, NULL);
01484         rb_destroy(open_list_by_xy);
01485 
01486         /* Destroy the closed list */
01487         rb_release(closed_list, (void *)astar_release, NULL);
01488 
01489 #ifdef DEBUG_ASTAR
01490         /* Close Log file */
01491         fclose(logfile);
01492 #endif
01493 
01494         /* End */
01495         if(found_path) {
01496                 return 1;
01497         } else {
01498                 return 0;
01499         }
01500 
01501 }

void auto_astar_goto_event ( MUXEVENT muxevent  ) 

Definition at line 1313 of file autopilot_commands.c.

References ai_set_speed(), AUTO::astar_path, auto_astar_generate_path(), auto_astar_goto_event(), auto_command_startup(), auto_destroy_astar_path(), auto_get_command_arg(), auto_get_command_enum(), auto_goto_next_command(), AUTOEVENT, AUTOPILOT_GOTO_TICK, AUTOPILOT_NC_DELAY, AUTOPILOT_STARTUP_TICK, CLASS_MECH, CountDestroyedLegs(), my_event_type::data, my_event_type::data2, Destroyed, dllist_get_node(), dllist_remove_node_at_pos(), dllist_size(), EVENT_AUTOGOTO, Fallen, figure_out_range_and_bearing(), getMap(), GOAL_GOTO, IsAuto(), IsMech, Location, AUTO::mapindex, MBUF_SIZE, mech_stand(), MechType, MechX, MechY, AUTO::mymech, AUTO::mymechnum, MECH::mynum, AUTO::mynum, Readnum, SendAI, slow_down_if_neccessary(), speed_up_if_neccessary(), Standing, Started, Starting, update_wanted_heading(), astar_node_t::x, and astar_node_t::y.

Referenced by auto_astar_goto_event(), and auto_com_event().

01314 {
01315 
01316         AUTO *autopilot = (AUTO *) muxevent->data;
01317         int tx, ty;
01318         MECH *mech = autopilot->mymech;
01319         MAP *map;
01320         float range;
01321         int bearing;
01322 
01323         int generate_path = (int) muxevent->data2;
01324 
01325         char *argument;
01326         astar_node *temp_astar_node;
01327 
01328         char error_buf[MBUF_SIZE];
01329 
01330         /* Make sure the mech is a mech and the autopilot is an autopilot */
01331         if(!IsMech(mech->mynum) || !IsAuto(autopilot->mynum))
01332                 return;
01333 
01334         /* Are we in the mech we're supposed to be in */
01335         if(Location(autopilot->mynum) != autopilot->mymechnum)
01336                 return;
01337 
01338         /* Our mech is destroyed */
01339         if(Destroyed(mech))
01340                 return;
01341 
01342         /* Check to make sure the first command in the queue is this one */
01343         if(auto_get_command_enum(autopilot, 1) != GOAL_GOTO)
01344                 return;
01345 
01346         /* Get the Map */
01347         if(!(map = getMap(autopilot->mapindex))) {
01348 
01349                 /* Bad Map */
01350                 snprintf(error_buf, MBUF_SIZE, "Internal AI Error - Attempting to"
01351                                  " goto with AI #%d but AI is not on a valid"
01352                                  " Map (#%d).", autopilot->mynum, autopilot->mapindex);
01353                 SendAI(error_buf);
01354 
01355                 auto_goto_next_command(autopilot, AUTOPILOT_NC_DELAY);
01356                 return;
01357 
01358         }
01359 
01360         /* Make sure mech is started and standing */
01361         if(!Started(mech)) {
01362 
01363                 /* Startup */
01364                 if(!Starting(mech))
01365                         auto_command_startup(autopilot, mech);
01366 
01367                 /* Run this command after startup */
01368                 AUTOEVENT(autopilot, EVENT_AUTOGOTO, auto_astar_goto_event,
01369                                   AUTOPILOT_STARTUP_TICK, generate_path);
01370                 return;
01371         }
01372 
01373         /* Ok not standing so lets do that first */
01374         if(MechType(mech) == CLASS_MECH && Fallen(mech) &&
01375            !(CountDestroyedLegs(mech) > 0)) {
01376 
01377                 if(!Standing(mech))
01378                         mech_stand(autopilot->mynum, mech, "");
01379 
01380                 /* Ok lets run this command again */
01381                 AUTOEVENT(autopilot, EVENT_AUTOGOTO, auto_astar_goto_event,
01382                                   AUTOPILOT_NC_DELAY, generate_path);
01383                 return;
01384         }
01385 
01388         /* Do we need to generate the path */
01389         if(generate_path) {
01390 
01391                 /* Get the first argument - x coord */
01392                 if(!(argument = auto_get_command_arg(autopilot, 1, 1))) {
01393 
01394                         /* Ok bad argument - means the command is messed up
01395                          * so should go to next one */
01396                         snprintf(error_buf, MBUF_SIZE, "Internal AI Error - Attempting to"
01397                                          " generate an astar path for AI #%d to hex %d,%d but was"
01398                                          " unable to - bad first argument - going to next command",
01399                                          autopilot->mynum, tx, ty);
01400                         SendAI(error_buf);
01401                         auto_goto_next_command(autopilot, AUTOPILOT_NC_DELAY);
01402                         return;
01403                 }
01404 
01405                 /* Now change it into a number and make sure its valid */
01406                 if(Readnum(tx, argument)) {
01407 
01408                         snprintf(error_buf, MBUF_SIZE, "Internal AI Error - Attempting to"
01409                                          " generate an astar path for AI #%d to hex %d,%d but was"
01410                                          " unable to - bad first argument '%s' - going to next command",
01411                                          autopilot->mynum, tx, ty, argument);
01412                         SendAI(error_buf);
01413 
01414                         free(argument);
01415                         auto_goto_next_command(autopilot, AUTOPILOT_NC_DELAY);
01416                         return;
01417                 }
01418                 free(argument);
01419 
01420                 /* Get the second argument - y coord */
01421                 if(!(argument = auto_get_command_arg(autopilot, 1, 2))) {
01422 
01423                         /* Ok bad argument - either means the command is messed up
01424                          * so should go to next one */
01425                         snprintf(error_buf, MBUF_SIZE, "Internal AI Error - Attempting to"
01426                                          " generate an astar path for AI #%d to hex %d,%d but was"
01427                                          " unable to - bad second argument - going to next command",
01428                                          autopilot->mynum, tx, ty);
01429                         SendAI(error_buf);
01430                         auto_goto_next_command(autopilot, AUTOPILOT_NC_DELAY);
01431                         return;
01432                 }
01433 
01434                 /* Read second argument into a number and make sure its ok */
01435                 if(Readnum(ty, argument)) {
01436 
01437                         snprintf(error_buf, MBUF_SIZE, "Internal AI Error - Attempting to"
01438                                          " generate an astar path for AI #%d to hex %d,%d but was"
01439                                          " unable to - bad second argument '%s' - going to next command",
01440                                          autopilot->mynum, tx, ty, argument);
01441                         SendAI(error_buf);
01442 
01443                         free(argument);
01444                         auto_goto_next_command(autopilot, AUTOPILOT_NC_DELAY);
01445                         return;
01446                 }
01447                 free(argument);
01448 
01449         /* Boundaries */
01450         if (tx < 0 || ty < 0 || tx >= map->map_width || ty >= map->map_width) {
01451 
01452             /* Bad location to go to */
01453             snprintf(error_buf, MBUF_SIZE, "Internal AI Error - Attempting to"
01454                     " generate an astar path for AI #%d to bad hex"
01455                     " (%d, %d)", autopilot->mynum, tx, ty);
01456             SendAI(error_buf);
01457             auto_goto_next_command(autopilot, AUTOPILOT_NC_DELAY);
01458             return;
01459         }
01460 
01461                 /* Look for a path */
01462                 if(!(auto_astar_generate_path(autopilot, mech, tx, ty))) {
01463 
01464                         /* Couldn't find a path for some reason */
01465                         snprintf(error_buf, MBUF_SIZE, "Internal AI Error - Attempting to"
01466                                          " generate an astar path for AI #%d to hex %d,%d but was"
01467                                          " unable to", autopilot->mynum, tx, ty);
01468                         SendAI(error_buf);
01469 
01472                         auto_goto_next_command(autopilot, AUTOPILOT_NC_DELAY);
01473                         return;
01474 
01475                 }
01476 
01477         }
01478 
01479         /* Make sure list is ok */
01480         if(!(autopilot->astar_path) || (dllist_size(autopilot->astar_path) <= 0)) {
01481 
01482                 snprintf(error_buf, MBUF_SIZE,
01483                                  "Internal AI Error - Attempting to follow"
01484                                  " Astar path for AI #%d - but the path is not there",
01485                                  autopilot->mynum);
01486                 SendAI(error_buf);
01487 
01488                 auto_destroy_astar_path(autopilot);
01489                 auto_goto_next_command(autopilot, AUTOPILOT_NC_DELAY);
01490                 return;
01491 
01492         }
01493 
01494         /* Get the current hex target */
01495         temp_astar_node =
01496                 (astar_node *) dllist_get_node(autopilot->astar_path, 1);
01497 
01498         if(!(temp_astar_node)) {
01499 
01500                 snprintf(error_buf, MBUF_SIZE,
01501                                  "Internal AI Error - Attemping to follow"
01502                                  " Astar path for AI #%d - but the current astar node does not"
01503                                  " exist", autopilot->mynum);
01504                 SendAI(error_buf);
01505 
01506                 auto_destroy_astar_path(autopilot);
01507                 auto_goto_next_command(autopilot, AUTOPILOT_NC_DELAY);
01508                 return;
01509 
01510         }
01511 
01512         /* Are we in the current target hex */
01513         if((MechX(mech) == temp_astar_node->x) &&
01514            (MechY(mech) == temp_astar_node->y)) {
01515 
01516                 /* Is this the last hex */
01517                 if(dllist_size(autopilot->astar_path) == 1) {
01518 
01519                         /* Done! */
01520                         ai_set_speed(mech, autopilot, 0);
01521 
01522                         /* Destroy the path and goto the next command */
01523                         auto_destroy_astar_path(autopilot);
01524                         auto_goto_next_command(autopilot, AUTOPILOT_NC_DELAY);
01525                         return;
01526 
01527                 } else {
01528 
01529                         /* Delete the node and goto the next one */
01530                         temp_astar_node =
01531                                 (astar_node *) dllist_remove_node_at_pos(autopilot->
01532                                                                                                                  astar_path, 1);
01533                         free(temp_astar_node);
01534 
01535                         /* Call this event again */
01536                         AUTOEVENT(autopilot, EVENT_AUTOGOTO, auto_astar_goto_event,
01537                                           AUTOPILOT_GOTO_TICK, 0);
01538                         return;
01539 
01540                 }
01541 
01542         }
01543 
01544         /* Set our current goal - not the end goal tho - unless this is
01545          * the end hex but whatever */
01546         tx = temp_astar_node->x;
01547         ty = temp_astar_node->y;
01548 
01549         /* Move towards our next hex */
01550         figure_out_range_and_bearing(mech, tx, ty, &range, &bearing);
01551         speed_up_if_neccessary(autopilot, mech, tx, ty, bearing);
01552         slow_down_if_neccessary(autopilot, mech, range, bearing, tx, ty);
01553         update_wanted_heading(autopilot, mech, bearing);
01554 
01555         AUTOEVENT(autopilot, EVENT_AUTOGOTO, auto_astar_goto_event,
01556                           AUTOPILOT_GOTO_TICK, 0);
01557 
01558 }

void auto_astar_roam_event ( MUXEVENT muxevent  ) 

Definition at line 2674 of file autopilot_commands.c.

References ai_set_speed(), AUTO::astar_path, auto_astar_generate_path(), auto_astar_roam_event(), auto_command_startup(), auto_destroy_astar_path(), auto_get_command_enum(), auto_goto_next_command(), auto_roam_generate_target_hex(), AUTO_ROAM_MAX_ITERATIONS, AUTO_ROAM_NEW_HEX_TICK, AUTO_ROAM_TICK, AUTOEVENT, AUTOPILOT_NC_DELAY, AUTOPILOT_STARTUP_TICK, CLASS_MECH, CountDestroyedLegs(), my_event_type::data, my_event_type::data2, Destroyed, dllist_get_node(), dllist_remove_node_at_pos(), dllist_size(), EVENT_AUTO_ROAM, Fallen, figure_out_range_and_bearing(), getMap(), GOAL_ROAM, IsAuto(), IsMech, Location, AUTO::mapindex, MBUF_SIZE, mech_stand(), MechType, MechX, MechY, AUTO::mymech, AUTO::mymechnum, MECH::mynum, AUTO::mynum, AUTO::roam_update_tick, SendAI, slow_down_if_neccessary(), speed_up_if_neccessary(), Standing, Started, Starting, update_wanted_heading(), astar_node_t::x, and astar_node_t::y.

Referenced by auto_astar_roam_event(), and auto_command_roam().

02675 {
02676 
02677         AUTO *autopilot = (AUTO *) muxevent->data;
02678         int tx, ty;
02679         MECH *mech = autopilot->mymech;
02680         MAP *map;
02681         float range;
02682         int bearing;
02683         int roam_hex_attempt;
02684         int generate_path = (int) muxevent->data2;
02685 
02686         astar_node *temp_astar_node;
02687 
02688         char error_buf[MBUF_SIZE];
02689 
02690         /* Make sure the mech is a mech and the autopilot is an autopilot */
02691         if(!IsMech(mech->mynum) || !IsAuto(autopilot->mynum))
02692                 return;
02693 
02694         /* Are we in the mech we're supposed to be in */
02695         if(Location(autopilot->mynum) != autopilot->mymechnum)
02696                 return;
02697 
02698         /* Our mech is destroyed */
02699         if(Destroyed(mech))
02700                 return;
02701 
02702         /* Check to make sure the first command in the queue is this one */
02703         if(auto_get_command_enum(autopilot, 1) != GOAL_ROAM)
02704                 return;
02705 
02706         /* Get the Map */
02707         if(!(map = getMap(autopilot->mapindex))) {
02708 
02709                 /* Bad Map */
02710                 snprintf(error_buf, MBUF_SIZE, "Internal AI Error - Attempting to"
02711                                  " roam with AI #%d but AI is not on a valid"
02712                                  " Map (#%d).", autopilot->mynum, autopilot->mapindex);
02713                 SendAI(error_buf);
02714 
02715                 auto_goto_next_command(autopilot, AUTOPILOT_NC_DELAY);
02716                 return;
02717 
02718         }
02719 
02720         /* Make sure mech is started and standing */
02721         if(!Started(mech)) {
02722 
02723                 /* Startup */
02724                 if(!Starting(mech))
02725                         auto_command_startup(autopilot, mech);
02726 
02727                 /* Run this command after startup */
02728                 AUTOEVENT(autopilot, EVENT_AUTO_ROAM, auto_astar_roam_event,
02729                                   AUTOPILOT_STARTUP_TICK, generate_path);
02730                 return;
02731         }
02732 
02733         /* Ok not standing so lets do that first */
02734         if(MechType(mech) == CLASS_MECH && Fallen(mech) &&
02735            !(CountDestroyedLegs(mech) > 0)) {
02736 
02737                 if(!Standing(mech))
02738                         mech_stand(autopilot->mynum, mech, "");
02739 
02740                 /* Ok lets run this command again */
02741                 AUTOEVENT(autopilot, EVENT_AUTO_ROAM, auto_astar_roam_event,
02742                                   AUTOPILOT_NC_DELAY, generate_path);
02743                 return;
02744         }
02745 
02748         /* Do we need to generate a target hex */
02749         if(generate_path || autopilot->roam_update_tick >= AUTO_ROAM_NEW_HEX_TICK) {
02750 
02751                 /* Reset counter */
02752                 roam_hex_attempt = 0;
02753 
02754                 while (roam_hex_attempt < AUTO_ROAM_MAX_ITERATIONS) {
02755 
02756                         /* Generate Target Hex and then try and generate path to it */
02757 
02758                         /* Target hex */
02759                         auto_roam_generate_target_hex(autopilot, mech, map,
02760                                                                                   roam_hex_attempt);
02761 
02762                         /* Path */
02763                         if((autopilot->roam_target_hex_x != -1) &&
02764                            (autopilot->roam_target_hex_y != -1) &&
02765                            auto_astar_generate_path(autopilot, mech,
02766                                                                                 autopilot->roam_target_hex_x,
02767                                                                                 autopilot->roam_target_hex_y)) {
02768 
02769                                 /* Found a path */
02770                                 break;
02771 
02772                         }
02773 
02774                         roam_hex_attempt++;
02775 
02776                 }                                               /* End of looking for target hex */
02777 
02778                 /* Check the path */
02779                 if(!(autopilot->astar_path)
02780                    || (dllist_size(autopilot->astar_path) <= 0)) {
02781 
02782                         /* Put Roam to bed and try again */
02783                         AUTOEVENT(autopilot, EVENT_AUTO_ROAM, auto_astar_roam_event,
02784                                           AUTO_ROAM_TICK, 1);
02785                         return;
02786                 }
02787 
02788                 /* Reset the Roam ticker */
02789                 autopilot->roam_update_tick = 0;
02790 
02791         }
02792 
02793         /* Make sure list is ok */
02794         if(!(autopilot->astar_path) || (dllist_size(autopilot->astar_path) <= 0)) {
02795 
02796                 snprintf(error_buf, MBUF_SIZE,
02797                                  "Internal AI Error - Attempting to roam"
02798                                  " Astar path for AI #%d - but the path is not there",
02799                                  autopilot->mynum);
02800                 SendAI(error_buf);
02801 
02802                 auto_destroy_astar_path(autopilot);
02803                 auto_goto_next_command(autopilot, AUTOPILOT_NC_DELAY);
02804                 return;
02805 
02806         }
02807 
02808         /* Move along the path */
02809 
02810         /* Get the current hex target */
02811         temp_astar_node =
02812                 (astar_node *) dllist_get_node(autopilot->astar_path, 1);
02813 
02814         if(!(temp_astar_node)) {
02815 
02816                 snprintf(error_buf, MBUF_SIZE, "Internal AI Error - Attemping to roam"
02817                                  " Astar path for AI #%d - but the current astar node does not"
02818                                  " exist", autopilot->mynum);
02819                 SendAI(error_buf);
02820 
02821                 auto_destroy_astar_path(autopilot);
02822                 auto_goto_next_command(autopilot, AUTOPILOT_NC_DELAY);
02823                 return;
02824 
02825         }
02826 
02827         /* Are we in the current target hex */
02828         if((MechX(mech) == temp_astar_node->x) &&
02829            (MechY(mech) == temp_astar_node->y)) {
02830 
02831                 /* Is this the last hex */
02832                 if(dllist_size(autopilot->astar_path) == 1) {
02833 
02834                         /* Done! */
02835                         ai_set_speed(mech, autopilot, 0);
02836 
02837                         /* Destroy the path and run roam again */
02838                         auto_destroy_astar_path(autopilot);
02839                         AUTOEVENT(autopilot, EVENT_AUTO_ROAM, auto_astar_roam_event,
02840                                           AUTO_ROAM_TICK, 1);
02841                         return;
02842 
02843                 } else {
02844 
02845                         /* Delete the node and goto the next one */
02846                         temp_astar_node =
02847                                 (astar_node *) dllist_remove_node_at_pos(autopilot->
02848                                                                                                                  astar_path, 1);
02849                         free(temp_astar_node);
02850 
02851                         /* Update the tick counter */
02852                         autopilot->roam_update_tick++;
02853 
02854                         /* Call this event again */
02855                         AUTOEVENT(autopilot, EVENT_AUTO_ROAM, auto_astar_roam_event,
02856                                           AUTO_ROAM_TICK, 0);
02857                         return;
02858 
02859                 }
02860 
02861         }
02862 
02863         /* Set our current goal - not the end goal tho - unless this is
02864          * the end hex but whatever */
02865         tx = temp_astar_node->x;
02866         ty = temp_astar_node->y;
02867 
02868         /* Move towards our next hex */
02869         figure_out_range_and_bearing(mech, tx, ty, &range, &bearing);
02870         speed_up_if_neccessary(autopilot, mech, tx, ty, bearing);
02871         slow_down_if_neccessary(autopilot, mech, range, bearing, tx, ty);
02872         update_wanted_heading(autopilot, mech, bearing);
02873 
02874         /* Update the tick counter */
02875         autopilot->roam_update_tick++;
02876 
02877         /* Cycle it again */
02878         AUTOEVENT(autopilot, EVENT_AUTO_ROAM, auto_astar_roam_event,
02879                           AUTO_ROAM_TICK, 0);
02880 }

void auto_cal_mapindex ( MECH mech  ) 

Todo:
{Possibly move this to autopilot_core.c}

Definition at line 207 of file autopilot_commands.c.

References auto_get_command_enum(), FindObjectsData(), GOAL_ENTERBASE, GOAL_LEAVEBASE, Good_obj, Location, AUTO::mapindex, MECH::mapindex, MBUF_SIZE, MechAuto, MECH::mynum, and SendError.

Referenced by Leave_Hangar(), and mech_enter_event().

00208 {
00209 
00210         AUTO *autopilot;
00211         char error_buf[MBUF_SIZE];
00212 
00213         if(!mech) {
00214                 SendError("Null pointer catch in auto_cal_mapindex");
00215                 return;
00216         }
00217 
00218         if(MechAuto(mech) > 0) {
00219                 if(!(autopilot = FindObjectsData(MechAuto(mech))) ||
00220                    !Good_obj(MechAuto(mech)) ||
00221                    Location(MechAuto(mech)) != mech->mynum) {
00222                         snprintf(error_buf, MBUF_SIZE,
00223                                          "Mech #%d thinks it has the Autopilot #%d on it"
00224                                          " but FindObj breaks", mech->mynum, MechAuto(mech));
00225                         SendError(error_buf);
00226                         MechAuto(mech) = -1;
00227                 } else {
00228 
00229                         /* Check here if the AI is either entering or leaving a base
00230                          * so it doesn't reset the mapindex which the specific commands
00231                          * need */
00232                         switch (auto_get_command_enum(autopilot, 1)) {
00233 
00234                         case GOAL_LEAVEBASE:
00235                                 break;
00236                         case GOAL_ENTERBASE:
00237                                 break;
00238                         default:
00239                                 autopilot->mapindex = mech->mapindex;
00240                         }
00241 
00242                 }
00243         }
00244         return;
00245 }

void auto_com_event ( MUXEVENT muxevent  ) 

Definition at line 696 of file autopilot_commands.c.

References ADVANCE_PG, auto_addcommand(), auto_astar_follow_event(), auto_astar_goto_event(), AUTO_CHECKS, auto_com_event(), auto_command_autogun(), auto_command_chasetarget(), auto_command_dropoff(), auto_command_embark(), auto_command_pickup(), auto_command_roam(), auto_command_shutdown(), auto_command_speed(), auto_command_startup(), auto_command_udisembark(), auto_dumbfollow_event(), auto_dumbgoto_event(), auto_enter_event(), auto_get_command_enum(), auto_goto_event(), auto_goto_next_command(), AUTO_GSTART, auto_leave_event(), auto_valid_progline(), AUTOEVENT, AUTOPILOT_CHASETARG, AUTOPILOT_FOLLOW_TICK, AUTOPILOT_GOTO_TICK, AUTOPILOT_LEAVE_TICK, autopilot_load_cargo(), AUTOPILOT_NC_DELAY, AUTOPILOT_SWARMCHARGE, AUTOPILOT_WAITFOE_TICK, CCLEN, CLASS_BSUIT, COMMAND_ATTACKLEG, COMMAND_AUTOGUN, COMMAND_CHASEMODE, COMMAND_CMODE, COMMAND_DROPOFF, COMMAND_EMBARK, COMMAND_ENTERBAY, COMMAND_JUMP, COMMAND_LOAD, COMMAND_PICKUP, COMMAND_ROAMMODE, COMMAND_SHUTDOWN, COMMAND_SPEED, COMMAND_STARTUP, COMMAND_STOPGUN, COMMAND_SWARM, COMMAND_SWARMMODE, COMMAND_UDISEMBARK, COMMAND_UNLOAD, my_event_type::data, DoStopGun, EVENT_AUTOCOM, EVENT_AUTOENTERBASE, EVENT_AUTOFOLLOW, EVENT_AUTOGOTO, EVENT_AUTOLEAVE, FindObjectsData(), AUTO::flags, getMech(), GOAL_CHASETARGET, GOAL_DUMBFOLLOW, GOAL_DUMBGOTO, GOAL_ENTERBASE, GOAL_FOLLOW, GOAL_GOTO, GOAL_LEAVEBASE, GOAL_OLDGOTO, GOAL_ROAM, GOAL_WAIT, GOD, Gunning, GVAL, IsAuto(), IsMech, MECH::mapindex, AUTO::mapindex, MAX, mech_enterbay(), mech_unloadcargo(), MechIDS(), MechNumSeen, MechType, AUTO::mymech, MECH::mynum, AUTO::mynum, PG, PilZombify, PSTART, SBUF_SIZE, SendAI, and tprintf().

Referenced by auto_com_event(), and auto_engage().

00697 {
00698 
00699         AUTO *autopilot = (AUTO *) muxevent->data;
00700         MECH *mech = autopilot->mymech;
00701         MECH *tempmech;
00702         char buf[SBUF_SIZE];
00703         int i, j, t;
00704 
00705         command_node *command;
00706 
00707         /* No mech and/or no AI */
00708         if(!IsMech(mech->mynum) || !IsAuto(autopilot->mynum))
00709                 return;
00710 
00711         /* Make sure the map exists */
00712         if(!(FindObjectsData(mech->mapindex))) {
00713                 autopilot->mapindex = mech->mapindex;
00714                 PilZombify(autopilot);
00715                 /*
00716                    if (GVAL(a, 0) != COMMAND_UDISEMBARK && GVAL(a, 0) != GOAL_WAIT)
00717                    return;
00718                  */
00719                 if(auto_get_command_enum(autopilot, 1) != COMMAND_UDISEMBARK)
00720                         return;
00721         }
00722 
00723         /* Set the MAP on the AI */
00724         if(autopilot->mapindex < 0)
00725                 autopilot->mapindex = mech->mapindex;
00726 
00727         /* Basic Checks */
00728         AUTO_CHECKS(autopilot);
00729 
00730         /* Get the enum value for the FIRST command */
00731         switch (auto_get_command_enum(autopilot, 1)) {
00732 
00733                 /* First check the various GOALs then the COMMANDs */
00734         case GOAL_CHASETARGET:
00735                 auto_command_chasetarget(autopilot);
00736                 return;
00737         case GOAL_DUMBGOTO:
00738                 AUTOEVENT(autopilot, EVENT_AUTOGOTO, auto_dumbgoto_event,
00739                                   AUTOPILOT_GOTO_TICK, 0);
00740                 return;
00741         case GOAL_DUMBFOLLOW:
00742                 AUTOEVENT(autopilot, EVENT_AUTOFOLLOW, auto_dumbfollow_event,
00743                                   AUTOPILOT_FOLLOW_TICK, 0);
00744                 return;
00745 
00746         case GOAL_ENTERBASE:
00747                 AUTOEVENT(autopilot, EVENT_AUTOENTERBASE, auto_enter_event,
00748                                   AUTOPILOT_NC_DELAY, 1);
00749                 return;
00750 
00751         case GOAL_FOLLOW:
00752                 AUTOEVENT(autopilot, EVENT_AUTOFOLLOW, auto_astar_follow_event,
00753                                   AUTOPILOT_FOLLOW_TICK, 1);
00754                 return;
00755 
00756         case GOAL_GOTO:
00757                 AUTOEVENT(autopilot, EVENT_AUTOGOTO, auto_astar_goto_event,
00758                                   AUTOPILOT_GOTO_TICK, 1);
00759                 return;
00760 
00761         case GOAL_LEAVEBASE:
00762                 AUTOEVENT(autopilot, EVENT_AUTOLEAVE, auto_leave_event,
00763                                   AUTOPILOT_LEAVE_TICK, 1);
00764                 return;
00765 
00766         case GOAL_OLDGOTO:
00767                 AUTO_GSTART(autopilot, mech);
00768                 AUTOEVENT(autopilot, EVENT_AUTOGOTO, auto_goto_event,
00769                                   AUTOPILOT_GOTO_TICK, 0);
00770                 return;
00771 
00772         case GOAL_ROAM:
00773                 auto_command_roam(autopilot, mech);
00774                 return;
00775 
00776 #if 0
00777         case GOAL_WAIT:
00778                 i = GVAL(a, 1);
00779                 j = GVAL(a, 2);
00780                 if(!i) {
00781                         PG(a) += CCLEN(a);
00782                         AUTOEVENT(a, EVENT_AUTOCOM, auto_com_event, MAX(1, j), 0);
00783                 } else {
00784                         if(i == 1) {
00785                                 if(MechNumSeen(mech)) {
00786                                         ADVANCE_PG(a);
00787                                 } else {
00788                                         AUTOEVENT(a, EVENT_AUTOCOM, auto_com_event,
00789                                                           AUTOPILOT_WAITFOE_TICK, 0);
00790                                 }
00791                         } else {
00792                                 ADVANCE_PG(a);
00793                         }
00794                 }
00795                 return;
00796 #endif
00797 #if 0
00798         case COMMAND_ATTACKLEG:
00799                 if(!(tempmech = getMech(GVAL(a, 1)))) {
00800                         SendAI(tprintf("AIAttacklegError #%d", GVAL(a, 1)));
00801                         //ADVANCE_PG(a);
00802                         auto_goto_next_command(a);
00803                         return;
00804                 }
00805                 strcpy(buf, MechIDS(tempmech, 1));
00806                 autopilot_attackleg(mech, buf);
00807                 //ADVANCE_PG(a);
00808                 auto_goto_next_command(a);
00809                 return;
00810 #endif
00811 
00812         case COMMAND_AUTOGUN:
00813                 auto_command_autogun(autopilot, mech);
00814                 auto_goto_next_command(autopilot, AUTOPILOT_NC_DELAY);
00815                 break;
00816 
00817 #if 0
00818         case COMMAND_CHASEMODE:
00819                 if(GVAL(a, 1))
00820                         a->flags |= AUTOPILOT_CHASETARG;
00821                 else
00822                         a->flags &= ~AUTOPILOT_CHASETARG;
00823                 //ADVANCE_PG(a);
00824                 auto_goto_next_command(a);
00825                 return;
00826 #endif
00827 #if 0
00828         case COMMAND_CMODE:
00829                 i = GVAL(a, 1);
00830                 j = GVAL(a, 2);
00831                 autopilot_cmode(a, mech, i, j);
00832                 //ADVANCE_PG(a);
00833                 auto_goto_next_command(a);
00834                 return;
00835 #endif
00836 
00837         case COMMAND_DROPOFF:
00838                 auto_command_dropoff(mech);
00839                 auto_goto_next_command(autopilot, AUTOPILOT_NC_DELAY);
00840                 return;
00841 
00842         case COMMAND_EMBARK:
00843                 auto_command_embark(autopilot, mech);
00844                 auto_goto_next_command(autopilot, AUTOPILOT_NC_DELAY);
00845                 return;
00846 
00847 #if 0
00848         case COMMAND_ENTERBAY:
00849                 PSTART(a, mech);
00850                 mech_enterbay(GOD, mech, my2string(""));
00851                 //ADVANCE_PG(a);
00852                 auto_goto_next_command(a);
00853                 return;
00854 #endif
00855 #if 0
00856         case COMMAND_JUMP:
00857                 if(auto_valid_progline(a, GVAL(a, 1))) {
00858                         PG(a) = GVAL(a, 1);
00859                         AUTOEVENT(a, EVENT_AUTOCOM, auto_com_event,
00860                                           AUTOPILOT_NC_DELAY, 0);
00861                 } else {
00862                         ADVANCE_PG(a);
00863                 }
00864                 return;
00865 #endif
00866 #if 0
00867         case COMMAND_LOAD:
00868 /*          mech_loadcargo(GOD, mech, "50"); */
00869                 autopilot_load_cargo(GOD, mech, 50);
00870                 //ADVANCE_PG(a);
00871                 auto_goto_next_command(a);
00872                 break;
00873 #endif
00874         case COMMAND_PICKUP:
00875                 auto_command_pickup(autopilot, mech);
00876                 auto_goto_next_command(autopilot, AUTOPILOT_NC_DELAY);
00877                 return;
00878 #if 0
00879         case COMMAND_ROAMMODE:
00880                 t = a->flags;
00881                 if(GVAL(a, 1)) {
00882                         a->flags |= AUTOPILOT_ROAMMODE;
00883                         if(!(t & AUTOPILOT_ROAMMODE)) {
00884                                 if(MechType(mech) == CLASS_BSUIT)
00885                                         a->flags |= AUTOPILOT_SWARMCHARGE;
00886                                 auto_addcommand(a->mynum, a, tprintf("roam 0 0"));
00887                         }
00888                 } else {
00889                         a->flags &= ~AUTOPILOT_ROAMMODE;
00890                 }
00891                 //ADVANCE_PG(a);
00892                 auto_goto_next_command(a);
00893                 return;
00894 #endif
00895         case COMMAND_SHUTDOWN:
00896                 auto_command_shutdown(autopilot, mech);
00897                 auto_goto_next_command(autopilot, AUTOPILOT_NC_DELAY);
00898                 return;
00899 
00900         case COMMAND_SPEED:
00901                 auto_command_speed(autopilot);
00902                 auto_goto_next_command(autopilot, AUTOPILOT_NC_DELAY);
00903                 return;
00904 
00905         case COMMAND_STARTUP:
00906                 auto_command_startup(autopilot, mech);
00907                 return;
00908 #if 0
00909         case COMMAND_STOPGUN:
00910                 if(Gunning(a))
00911                         DoStopGun(a);
00912                 //ADVANCE_PG(a);
00913                 auto_goto_next_command(a);
00914                 break;
00915 #endif
00916 #if 0
00917         case COMMAND_SWARM:
00918                 if(!(tempmech = getMech(GVAL(a, 1)))) {
00919                         SendAI(tprintf("AISwarmError #%d", GVAL(a, 1)));
00920                         //ADVANCE_PG(a);
00921                         auto_goto_next_command(a);
00922                         return;
00923                 }
00924                 strcpy(buf, MechIDS(tempmech, 1));
00925                 autopilot_swarm(mech, buf);
00926                 //ADVANCE_PG(a);
00927                 auto_goto_next_command(a);
00928                 return;
00929 #endif
00930 #if 0
00931         case COMMAND_SWARMMODE:
00932                 if(MechType(mech) != CLASS_BSUIT) {
00933                         //ADVANCE_PG(a);
00934                         auto_goto_next_command(a);
00935                         return;
00936                 }
00937                 if(GVAL(a, 1))
00938                         a->flags |= AUTOPILOT_SWARMCHARGE;
00939                 else
00940                         a->flags &= ~AUTOPILOT_SWARMCHARGE;
00941                 //ADVANCE_PG(a);
00942                 auto_goto_next_command(a);
00943                 return;
00944 #endif
00945 
00946         case COMMAND_UDISEMBARK:
00947                 auto_command_udisembark(mech);
00948                 auto_goto_next_command(autopilot, AUTOPILOT_NC_DELAY);
00949                 return;
00950 
00951 #if 0
00952         case COMMAND_UNLOAD:
00953                 mech_unloadcargo(GOD, mech, my2string(" * 9999"));
00954                 //ADVANCE_PG(a);
00955                 auto_goto_next_command(a);
00956                 break;
00957 #endif
00958         }
00959 }

void auto_command_dropoff ( MECH mech  ) 

Definition at line 566 of file autopilot_commands.c.

References GOD, and mech_dropoff().

Referenced by auto_com_event().

00567 {
00568         mech_dropoff(GOD, mech, NULL);
00569 }

void auto_command_pickup ( AUTO autopilot,
MECH mech 
)

Definition at line 522 of file autopilot_commands.c.

References auto_get_command_arg(), getMech(), GOD, MBUF_SIZE, mech_pickup(), MechIDS(), AUTO::mynum, Readnum, SBUF_SIZE, and SendAI.

Referenced by auto_com_event().

00523 {
00524 
00525         char *argument;
00526         int target;
00527         char error_buf[MBUF_SIZE];
00528         char buf[SBUF_SIZE];
00529         MECH *tempmech;
00530 
00533         /* Read in the argument */
00534         argument = auto_get_command_arg(autopilot, 1, 1);
00535         if(Readnum(target, argument)) {
00536 
00537                 snprintf(error_buf, MBUF_SIZE, "AI Error - AI #%d given bad"
00538                                  " argument for pickup command", autopilot->mynum);
00539                 SendAI(error_buf);
00540                 free(argument);
00541                 return;
00542 
00543         }
00544         free(argument);
00545 
00546         /* Check the target */
00547         if(!(tempmech = getMech(target))) {
00548                 snprintf(error_buf, MBUF_SIZE, "AI Error - AI #%d unable to pickup"
00549                                  " unit #%d", autopilot->mynum, target);
00550                 SendAI(error_buf);
00551                 return;
00552         }
00553 
00554         /* Now try and pick it up */
00555         strcpy(buf, MechIDS(tempmech, 1));
00556         mech_pickup(GOD, mech, buf);
00557 
00561 }

void auto_command_roam ( AUTO autopilot,
MECH mech 
)

Definition at line 2371 of file autopilot_commands.c.

References args, auto_astar_roam_event(), auto_get_command_arg(), auto_goto_next_command(), AUTO_ROAM_MAP, AUTO_ROAM_MAX_RADIUS, AUTO_ROAM_SPOT, AUTO_ROAM_TICK, AUTOEVENT, AUTOPILOT_NC_DELAY, EVENT_AUTO_ROAM, getMap(), MAP::map_height, MAP::map_width, AUTO::mapindex, MBUF_SIZE, AUTO::mynum, proper_explodearguments(), Readnum, AUTO::roam_anchor_distance, AUTO::roam_anchor_hex_x, AUTO::roam_anchor_hex_y, AUTO::roam_type, and SendAI.

Referenced by auto_com_event().

02372 {
02373 
02374         char *argument;
02375         char error_buf[MBUF_SIZE];
02376         char *args[4];
02377         int argc;
02378         int i;
02379         int anchor_hex_x;
02380         int anchor_hex_y;
02381         int anchor_distance;
02382 
02383         MAP *map;
02384 
02385         /* Read in the argument */
02386         argument = auto_get_command_arg(autopilot, 1, 1);
02387 
02388         /* Parse the argument */
02389         argc = proper_explodearguments(argument, args, 4);
02390 
02391         /* Free the argument */
02392         free(argument);
02393 
02394         /* Now we check to see how many arguments it found */
02395         if(argc == 1) {
02396 
02397                 /* Wander the map aimlessly */
02398                 if(strcmp(args[0], "map") == 0) {
02399 
02400                         /* Set flags */
02401                         autopilot->roam_type = AUTO_ROAM_MAP;
02402 
02403                         /* Fire off event */
02404                         AUTOEVENT(autopilot, EVENT_AUTO_ROAM, auto_astar_roam_event,
02405                                           AUTO_ROAM_TICK, 1);
02406 
02407                 } else {
02408 
02409                         /* Invalid command */
02410                         snprintf(error_buf, MBUF_SIZE, "AI Error - AI #%d given bad"
02411                                          " argument for roam command", autopilot->mynum);
02412                         SendAI(error_buf);
02413 
02414                         auto_goto_next_command(autopilot, AUTOPILOT_NC_DELAY);
02415 
02416                 }
02417 
02418         } else if(argc == 4) {
02419 
02420                 /* Stay within a certain radius */
02421                 if(strcmp(args[0], "radius") == 0) {
02422 
02423                         /* Need to grab distance and start hex */
02424                         if(Readnum(anchor_hex_x, args[1])) {
02425 
02426                                 snprintf(error_buf, MBUF_SIZE, "AI Error - AI #%d given bad"
02427                                                  " argument (anchor_hex_x) for roam command",
02428                                                  autopilot->mynum);
02429                                 SendAI(error_buf);
02430 
02431                                 auto_goto_next_command(autopilot, AUTOPILOT_NC_DELAY);
02432 
02433                                 /* Free Args */
02434                                 for(i = 0; i < 4; i++) {
02435                                         if(args[i])
02436                                                 free(args[i]);
02437                                 }
02438 
02439                                 return;
02440                         }
02441 
02442                         if(Readnum(anchor_hex_y, args[2])) {
02443 
02444                                 snprintf(error_buf, MBUF_SIZE, "AI Error - AI #%d given bad"
02445                                                  " argument (anchor_hex_y) for roam command",
02446                                                  autopilot->mynum);
02447                                 SendAI(error_buf);
02448 
02449                                 auto_goto_next_command(autopilot, AUTOPILOT_NC_DELAY);
02450 
02451                                 /* Free Args */
02452                                 for(i = 0; i < 4; i++) {
02453                                         if(args[i])
02454                                                 free(args[i]);
02455                                 }
02456 
02457                                 return;
02458                         }
02459 
02460                         /* Need to grab distance and start hex */
02461                         if(Readnum(anchor_distance, args[3])) {
02462 
02463                                 snprintf(error_buf, MBUF_SIZE, "AI Error - AI #%d given bad"
02464                                                  " argument (anchor_distance) for roam command",
02465                                                  autopilot->mynum);
02466                                 SendAI(error_buf);
02467 
02468                                 auto_goto_next_command(autopilot, AUTOPILOT_NC_DELAY);
02469 
02470                                 /* Free Args */
02471                                 for(i = 0; i < 4; i++) {
02472                                         if(args[i])
02473                                                 free(args[i]);
02474                                 }
02475 
02476                                 return;
02477                         }
02478 
02479                         /* Make sure values are sane */
02480 
02481                         /* Get the Map */
02482                         if(!(map = getMap(autopilot->mapindex))) {
02483 
02484                                 /* Bad Map */
02485                                 snprintf(error_buf, MBUF_SIZE,
02486                                                  "Internal AI Error - Attempting to"
02487                                                  " roam with AI #%d but AI is not on a valid"
02488                                                  " Map (#%d).", autopilot->mynum,
02489                                                  autopilot->mapindex);
02490                                 SendAI(error_buf);
02491 
02492                                 auto_goto_next_command(autopilot, AUTOPILOT_NC_DELAY);
02493 
02494                                 /* Free Args */
02495                                 for(i = 0; i < 4; i++) {
02496                                         if(args[i])
02497                                                 free(args[i]);
02498                                 }
02499 
02500                                 return;
02501 
02502                         }
02503 
02504                         /* Check to make sure the hexes are inside the map and the distance
02505                          * is not beyond our limit */
02506                         if(anchor_hex_x < 0 || anchor_hex_y < 0 ||
02507                            anchor_hex_x >= map->map_width ||
02508                            anchor_hex_y >= map->map_height ||
02509                            anchor_distance > AUTO_ROAM_MAX_RADIUS) {
02510 
02511                                 snprintf(error_buf, MBUF_SIZE, "AI Error - AI #%d given bad"
02512                                                  " argument (bad anchor hex or bad anchor distance)"
02513                                                  " %d,%d : %d hexes for roam command",
02514                                                  autopilot->mynum, anchor_hex_x, anchor_hex_y,
02515                                                  anchor_distance);
02516                                 SendAI(error_buf);
02517 
02518                                 auto_goto_next_command(autopilot, AUTOPILOT_NC_DELAY);
02519 
02520                                 /* Free Args */
02521                                 for(i = 0; i < 4; i++) {
02522                                         if(args[i])
02523                                                 free(args[i]);
02524                                 }
02525 
02526                                 return;
02527                         }
02528 
02529                         /* Set values */
02530                         autopilot->roam_type = AUTO_ROAM_SPOT;
02531                         autopilot->roam_anchor_hex_x = anchor_hex_x;
02532                         autopilot->roam_anchor_hex_y = anchor_hex_y;
02533                         autopilot->roam_anchor_distance = anchor_distance;
02534 
02535                         /* Fire off event */
02536                         AUTOEVENT(autopilot, EVENT_AUTO_ROAM, auto_astar_roam_event,
02537                                           AUTO_ROAM_TICK, 1);
02538 
02539                 } else {
02540 
02541                         /* Invalid command */
02542                         snprintf(error_buf, MBUF_SIZE, "AI Error - AI #%d given bad"
02543                                          " argument for roam command", autopilot->mynum);
02544                         SendAI(error_buf);
02545 
02546                         auto_goto_next_command(autopilot, AUTOPILOT_NC_DELAY);
02547 
02548                 }
02549 
02550         } else {
02551 
02552                 /* Invalid command */
02553                 snprintf(error_buf, MBUF_SIZE, "AI Error - AI #%d given bad"
02554                                  " argument for roam command", autopilot->mynum);
02555                 SendAI(error_buf);
02556 
02557                 auto_goto_next_command(autopilot, AUTOPILOT_NC_DELAY);
02558 
02559         }
02560 
02561         /* Free Args */
02562         for(i = 0; i < 4; i++) {
02563                 if(args[i])
02564                         free(args[i]);
02565         }
02566 
02567 }

void auto_command_shutdown ( AUTO autopilot,
MECH mech 
)

Definition at line 130 of file autopilot_commands.c.

References mech_shutdown(), AUTO::mynum, and Started.

Referenced by auto_com_event().

00131 {
00132 
00133         if(!Started(mech))
00134                 return;
00135 
00136         mech_shutdown(autopilot->mynum, mech, "");
00137 
00138 }

void auto_command_speed ( AUTO autopilot  ) 

Definition at line 574 of file autopilot_commands.c.

References auto_get_command_arg(), MBUF_SIZE, AUTO::mynum, Readnum, SendAI, and AUTO::speed.

Referenced by auto_com_event().

00575 {
00576 
00577         char *argument;
00578         unsigned short speed;
00579         char error_buf[MBUF_SIZE];
00580 
00581         /* Read in the argument */
00582         argument = auto_get_command_arg(autopilot, 1, 1);
00583         if(Readnum(speed, argument)) {
00584 
00585                 snprintf(error_buf, MBUF_SIZE, "AI Error - AI #%d given bad"
00586                                  " argument for speed command", autopilot->mynum);
00587                 SendAI(error_buf);
00588                 free(argument);
00589                 return;
00590 
00591         }
00592         free(argument);
00593 
00594         /* Make sure its a valid speed value */
00595         if(speed < 1 || speed > 100) {
00596 
00597                 snprintf(error_buf, MBUF_SIZE, "AI Error - AI #%d given bad"
00598                                  " argument for speed command - out side of the range",
00599                                  autopilot->mynum);
00600                 SendAI(error_buf);
00601                 return;
00602 
00603         }
00604 
00605         /* Now set it */
00606         autopilot->speed = speed;
00607 
00608 }

void auto_command_startup ( AUTO autopilot,
MECH mech 
)

Definition at line 114 of file autopilot_commands.c.

References auto_goto_next_command(), AUTOPILOT_STARTUP_TICK, mech_startup(), AUTO::mynum, Started, and Starting.

Referenced by auto_astar_follow_event(), auto_astar_goto_event(), auto_astar_roam_event(), auto_com_event(), auto_dumbfollow_event(), auto_dumbgoto_event(), auto_enter_event(), and auto_leave_event().

00115 {
00116 
00117         if(Started(mech))
00118                 return;
00119 
00120         if(!Starting(mech)) {
00121                 mech_startup(autopilot->mynum, mech, "");
00122                 auto_goto_next_command(autopilot, AUTOPILOT_STARTUP_TICK);
00123         }
00124 
00125 }

void auto_delcommand ( dbref  player,
void *  data,
char *  buffer 
)

Definition at line 326 of file autopilot_core.c.

References auto_destroy_command_node(), AUTO::commands, dllist_head(), dllist_remove(), dllist_remove_node_at_pos(), dllist_size(), MBUF_SIZE, AUTO::mynum, notify, notify_printf(), Readnum, and SendAI.

Referenced by auto_radio_command_reset().

00327 {
00328 
00329         int p, i;
00330         AUTO *autopilot = (AUTO *) data;
00331         int remove_all_commands = 0;
00332         command_node *temp_command_node;
00333         char error_buf[MBUF_SIZE];
00334 
00335         /* Make sure they specified an argument */
00336         if(!*buffer) {
00337                 notify(player, "No argument used : Usage delcommand [num]\n");
00338                 notify_printf(player, "Must be within the range"
00339                                           " 1 to %d or -1 for all\n",
00340                                           dllist_size(autopilot->commands));
00341                 return;
00342         }
00343 
00344         /* Make sure its a number */
00345         if(Readnum(p, buffer)) {
00346                 notify_printf(player, "Invalid Argument : Must be within the range"
00347                                           " 1 to %d or -1 for all\n",
00348                                           dllist_size(autopilot->commands));
00349                 return;
00350         }
00351 
00352         /* Check if its a valid command position
00353          * If its -1 means remove all */
00354         if(p == -1) {
00355                 remove_all_commands = 1;
00356         } else if((p > dllist_size(autopilot->commands)) || (p < 1)) {
00357                 notify_printf(player, "Invalid Argument : Must be within the range"
00358                                           " 1 to %d or -1 for all\n",
00359                                           dllist_size(autopilot->commands));
00360                 return;
00361         }
00362 
00366         /* Now remove the node(s) */
00367         if(!remove_all_commands) {
00368 
00369                 /* Remove the node at pos */
00370                 temp_command_node =
00371                         (command_node *) dllist_remove_node_at_pos(autopilot->commands,
00372                                                                                                            p);
00373 
00374                 if(!temp_command_node) {
00375                         snprintf(error_buf, MBUF_SIZE,
00376                                          "Internal AI Error: Trying to remove"
00377                                          " Command #%d from AI #%d but the command node doesn't exist\n",
00378                                          p, autopilot->mynum);
00379                         SendAI(error_buf);
00380                 }
00381 
00382                 /* Destroy the command_node */
00383                 auto_destroy_command_node(temp_command_node);
00384 
00385                 notify_printf(player, "Command #%d Successfully Removed\n", p);
00386 
00387         } else {
00388 
00389                 /* Remove ALL the commands */
00390                 while (dllist_size(autopilot->commands)) {
00391 
00392                         /* Remove the first node on the list and get the data
00393                          * from it */
00394                         temp_command_node =
00395                                 (command_node *) dllist_remove(autopilot->commands,
00396                                                                                            dllist_head(autopilot->
00397                                                                                                                    commands));
00398 
00399                         /* Make sure the command node exists */
00400                         if(!temp_command_node) {
00401 
00402                                 snprintf(error_buf, MBUF_SIZE,
00403                                                  "Internal AI Error: Trying to remove"
00404                                                  " the first command from AI #%d but the command node doesn't exist\n",
00405                                                  autopilot->mynum);
00406                                 SendAI(error_buf);
00407 
00408                         } else {
00409 
00410                                 /* Destroy the command node */
00411                                 auto_destroy_command_node(temp_command_node);
00412 
00413                         }
00414 
00415                 }
00416 
00417                 notify(player, "All the commands have been removed.\n");
00418 
00419         }
00420 
00421 }

void auto_destroy_astar_path ( AUTO autopilot  ) 

Definition at line 1535 of file autopilot_ai.c.

References AUTO::astar_path, dllist_destroy_list(), dllist_remove_node_at_pos(), and dllist_size().

Referenced by auto_astar_follow_event(), auto_astar_generate_path(), auto_astar_goto_event(), auto_astar_roam_event(), auto_newautopilot(), and newfreemech().

01536 {
01537 
01538         astar_node *temp_astar_node;
01539 
01540         /* Make sure there is a path if not quit */
01541         if(!(autopilot->astar_path))
01542                 return;
01543 
01544         /* There is a path lets kill it */
01545         if(dllist_size(autopilot->astar_path) > 0) {
01546 
01547                 while (dllist_size(autopilot->astar_path)) {
01548                         temp_astar_node =
01549                                 dllist_remove_node_at_pos(autopilot->astar_path, 1);
01550                         free(temp_astar_node);
01551                 }
01552 
01553         }
01554 
01555         /* Finally destroying the path */
01556         dllist_destroy_list(autopilot->astar_path);
01557         autopilot->astar_path = NULL;
01558 
01559 }

void auto_destroy_command_node ( command_node node  ) 

Definition at line 57 of file autopilot_core.c.

References command_node_t::args, and AUTOPILOT_MAX_ARGS.

Referenced by auto_delcommand(), auto_goto_next_command(), auto_newautopilot(), and newfreemech().

00058 {
00059 
00060         int i;
00061 
00062         /* Free the args */
00063         for(i = 0; i < AUTOPILOT_MAX_ARGS; i++) {
00064                 if(node->args[i]) {
00065                         free(node->args[i]);
00066                         node->args[i] = NULL;
00067                 }
00068         }
00069 
00070         /* Free the node */
00071         free(node);
00072 
00073         return;
00074 
00075 }

void auto_destroy_weaplist ( AUTO autopilot  ) 

Definition at line 383 of file autopilot_autogun.c.

References auto_destroy_weapon_node(), dllist_destroy_list(), dllist_remove_node_at_pos(), dllist_size(), and AUTO::weaplist.

Referenced by auto_newautopilot(), and newfreemech().

00384 {
00385 
00386         weapon_node *temp_weapon_node;
00387 
00388         /* Check to make sure there is a weapon list */
00389         if(!(autopilot->weaplist))
00390                 return;
00391 
00392         /* There is a weapon list - lets kill it */
00393         if(dllist_size(autopilot->weaplist) > 0) {
00394 
00395                 while (dllist_size(autopilot->weaplist)) {
00396                         temp_weapon_node =
00397                                 (weapon_node *) dllist_remove_node_at_pos(autopilot->weaplist,
00398                                                                                                                   1);
00399                         auto_destroy_weapon_node(temp_weapon_node);
00400                 }
00401 
00402         }
00403 
00404         /* Finally destroying the list */
00405         dllist_destroy_list(autopilot->weaplist);
00406         autopilot->weaplist = NULL;
00407 
00408 }

void auto_disengage ( dbref  player,
void *  data,
char *  buffer 
)

Definition at line 722 of file autopilot_core.c.

References auto_pilot_on(), auto_stop_pilot(), DOCHECK, and notify.

Referenced by auto_radio_command_reset().

00723 {
00724 
00725         AUTO *autopilot = (AUTO *) data;
00726 
00727         DOCHECK(!auto_pilot_on(autopilot),
00728                         "The autopilot's already offline! You have to engage it first.");
00729 
00730         auto_stop_pilot(autopilot);
00731         notify(player, "Autopilot has been disengaged.");
00732 
00733         return;
00734 
00735 }

void auto_dumbfollow_event ( MUXEVENT muxevent  ) 

Definition at line 1942 of file autopilot_commands.c.

References auto_command_startup(), auto_dumbfollow_event(), auto_get_command_arg(), auto_get_command_enum(), auto_goto_next_command(), AUTOEVENT, AUTOPILOT_FOLLOW_TICK, AUTOPILOT_NC_DELAY, AUTOPILOT_STARTUP_TICK, CLASS_MECH, CountDestroyedLegs(), my_event_type::data, Destroyed, EVENT_AUTOFOLLOW, Fallen, figure_out_range_and_bearing(), getMap(), getMech(), GOAL_DUMBFOLLOW, IsAuto(), IsMech, Location, AUTO::mapindex, MBUF_SIZE, mech_heading(), mech_speed(), mech_stand(), MechDesiredFacing, MechFacing, MechSpeed, MechType, MechX, MechY, MP1, AUTO::mymech, AUTO::mymechnum, MECH::mynum, AUTO::mynum, AUTO::ofsx, AUTO::ofsy, Readnum, SBUF_SIZE, SendAI, slow_down_if_neccessary(), speed_up_if_neccessary(), Standing, Started, Starting, TWOPIOVER360, update_wanted_heading(), x, and y.

Referenced by auto_com_event(), and auto_dumbfollow_event().

01943 {
01944 
01945         AUTO *autopilot = (AUTO *) muxevent->data;
01946         int tx, ty, x, y;
01947         int h;
01948         MECH *leader;
01949         MECH *mech = autopilot->mymech;
01950         MAP *map;
01951         float range;
01952         int bearing;
01953 
01954         char *argument;
01955         int target;
01956 
01957         char error_buf[MBUF_SIZE];
01958         char buffer[SBUF_SIZE];
01959 
01960         /* Making sure the mech is a mech and the autopilot is an autopilot */
01961         if(!IsMech(mech->mynum) || !IsAuto(autopilot->mynum))
01962                 return;
01963 
01964         /* Are we in the mech we're supposed to be in */
01965         if(Location(autopilot->mynum) != autopilot->mymechnum)
01966                 return;
01967 
01968         /* Our mech is destroyed */
01969         if(Destroyed(mech))
01970                 return;
01971 
01972         /* Check to make sure the first command in the queue is this one */
01973         if(auto_get_command_enum(autopilot, 1) != GOAL_DUMBFOLLOW)
01974                 return;
01975 
01976         /* Get the Map */
01977         if(!(map = getMap(autopilot->mapindex))) {
01978 
01979                 /* Bad Map */
01980                 snprintf(error_buf, MBUF_SIZE, "Internal AI Error - Attempting to"
01981                                  " follow [dumbly] with AI #%d but AI is not on a valid"
01982                                  " Map (#%d).", autopilot->mynum, autopilot->mapindex);
01983                 SendAI(error_buf);
01984 
01985                 auto_goto_next_command(autopilot, AUTOPILOT_NC_DELAY);
01986                 return;
01987 
01988         }
01989 
01990         /* Make sure mech is started and standing */
01991         if(!Started(mech)) {
01992 
01993                 /* Startup */
01994                 if(!Starting(mech))
01995                         auto_command_startup(autopilot, mech);
01996 
01997                 /* Run this command after startup */
01998                 AUTOEVENT(autopilot, EVENT_AUTOFOLLOW, auto_dumbfollow_event,
01999                                   AUTOPILOT_STARTUP_TICK, 0);
02000                 return;
02001         }
02002 
02003         /* Make sure the mech is standing before going on */
02004         if(MechType(mech) == CLASS_MECH && Fallen(mech) &&
02005            !(CountDestroyedLegs(mech) > 0)) {
02006 
02007                 if(!Standing(mech))
02008                         mech_stand(autopilot->mynum, mech, "");
02009 
02010                 /* Ok lets run this command again */
02011                 AUTOEVENT(autopilot, EVENT_AUTOFOLLOW, auto_dumbfollow_event,
02012                                   AUTOPILOT_NC_DELAY, 0);
02013                 return;
02014         }
02015 
02018         /* Get the target */
02019         if(!(argument = auto_get_command_arg(autopilot, 1, 1))) {
02020 
02021                 /* Ok bad argument - means the command is messed up
02022                  * so should go to next one */
02023                 snprintf(error_buf, MBUF_SIZE, "Internal AI Error - AI #%d attempting"
02024                                  " to follow target [dumbly] but was unable to - bad argument - going"
02025                                  " to next command", autopilot->mynum);
02026                 SendAI(error_buf);
02027                 auto_goto_next_command(autopilot, AUTOPILOT_NC_DELAY);
02028                 return;
02029         }
02030 
02031         /* Try and read the value */
02032         if(Readnum(target, argument)) {
02033 
02034                 /* Not proper number so skip command goto next */
02035                 snprintf(error_buf, MBUF_SIZE, "Internal AI Error - AI #%d attempting"
02036                                  " to follow target [dumbly] but was unable to - bad argument '%s' - going"
02037                                  " to next command", autopilot->mynum, argument);
02038                 SendAI(error_buf);
02039                 free(argument);
02040                 auto_goto_next_command(autopilot, AUTOPILOT_NC_DELAY);
02041                 return;
02042 
02043         }
02044         free(argument);
02045 
02046         /* Make sure its a valid target */
02047         if(!(leader = getMech(target)) || Destroyed(leader)) {
02048 
02049                 /* For some reason, leader is missing(?) */
02050                 snprintf(error_buf, MBUF_SIZE, "Internal AI Error - AI #%d attempting"
02051                                  " to follow target [dumbly] but was unable to - bad or dead target -"
02052                                  " going to next command", autopilot->mynum);
02053                 SendAI(error_buf);
02054                 auto_goto_next_command(autopilot, AUTOPILOT_NC_DELAY);
02055                 return;
02056         }
02057 
02058         h = MechDesiredFacing(leader);
02059         x = autopilot->ofsy * cos(TWOPIOVER360 * (270.0 + (h + autopilot->ofsx)));
02060         y = autopilot->ofsy * sin(TWOPIOVER360 * (270.0 + (h + autopilot->ofsx)));
02061         tx = MechX(leader) + x;
02062         ty = MechY(leader) + y;
02063 
02064         if(MechX(mech) == tx && MechY(mech) == ty) {
02065 
02066                 /* Do ugly stuff */
02067                 /* For now, try to match speed (if any) and heading (if any) of the
02068                    leader */
02069                 if(MechSpeed(leader) > 1 || MechSpeed(leader) < -1 ||
02070                    MechSpeed(mech) > 1 || MechSpeed(mech) < -1) {
02071 
02072                         if(MechDesiredFacing(mech) != MechFacing(leader)) {
02073                                 snprintf(buffer, SBUF_SIZE, "%d", MechFacing(leader));
02074                                 mech_heading(autopilot->mynum, mech, buffer);
02075                         }
02076 
02077                         if(MechSpeed(mech) != MechSpeed(leader)) {
02078                                 snprintf(buffer, SBUF_SIZE, "%.2f", MechSpeed(leader));
02079                                 mech_speed(autopilot->mynum, mech, buffer);
02080                         }
02081                 }
02082 
02083                 AUTOEVENT(autopilot, EVENT_AUTOFOLLOW, auto_dumbfollow_event,
02084                                   AUTOPILOT_FOLLOW_TICK, 0);
02085                 return;
02086         }
02087 
02088         figure_out_range_and_bearing(mech, tx, ty, &range, &bearing);
02089         speed_up_if_neccessary(autopilot, mech, tx, ty, -1);
02090 
02091         if(MechSpeed(leader) < MP1)
02092                 slow_down_if_neccessary(autopilot, mech, range + 1, bearing, tx, ty);
02093 
02094         update_wanted_heading(autopilot, mech, bearing);
02095 
02096         AUTOEVENT(autopilot, EVENT_AUTOFOLLOW, auto_dumbfollow_event,
02097                           AUTOPILOT_FOLLOW_TICK, 0);
02098 }

void auto_dumbgoto_event ( MUXEVENT muxevent  ) 

Definition at line 1163 of file autopilot_commands.c.

References ai_set_speed(), auto_command_startup(), auto_dumbgoto_event(), auto_get_command_arg(), auto_get_command_enum(), auto_goto_next_command(), AUTOEVENT, AUTOPILOT_GOTO_TICK, AUTOPILOT_NC_DELAY, AUTOPILOT_STARTUP_TICK, CLASS_MECH, CountDestroyedLegs(), my_event_type::data, Destroyed, EVENT_AUTOGOTO, Fallen, figure_out_range_and_bearing(), getMap(), GOAL_DUMBGOTO, IsAuto(), IsMech, Location, AUTO::mapindex, MBUF_SIZE, mech_stand(), MechSpeed, MechType, MechX, MechY, AUTO::mymech, AUTO::mymechnum, MECH::mynum, AUTO::mynum, Readnum, SendAI, slow_down_if_neccessary(), speed_up_if_neccessary(), Standing, Started, Starting, and update_wanted_heading().

Referenced by auto_com_event(), and auto_dumbgoto_event().

01164 {
01165 
01166         AUTO *autopilot = (AUTO *) muxevent->data;
01167         int tx, ty;
01168         MECH *mech = autopilot->mymech;
01169         MAP *map;
01170         float range;
01171         int bearing;
01172 
01173         char *argument;
01174         char error_buf[MBUF_SIZE];
01175 
01176         if(!IsMech(mech->mynum) || !IsAuto(autopilot->mynum))
01177                 return;
01178 
01179         /* Are we in the mech we're supposed to be in */
01180         if(Location(autopilot->mynum) != autopilot->mymechnum)
01181                 return;
01182 
01183         /* Our mech is destroyed */
01184         if(Destroyed(mech))
01185                 return;
01186 
01187         /* Check to make sure the first command in the queue is this one */
01188         if(auto_get_command_enum(autopilot, 1) != GOAL_DUMBGOTO)
01189                 return;
01190 
01191         /* Get the Map */
01192         if(!(map = getMap(autopilot->mapindex))) {
01193 
01194                 /* Bad Map */
01195                 snprintf(error_buf, MBUF_SIZE, "Internal AI Error - Attempting to"
01196                                  " goto [dumbly] with AI #%d but AI is not on a valid"
01197                                  " Map (#%d).", autopilot->mynum, autopilot->mapindex);
01198                 SendAI(error_buf);
01199 
01200                 auto_goto_next_command(autopilot, AUTOPILOT_NC_DELAY);
01201                 return;
01202 
01203         }
01204 
01205         /* Make sure mech is started */
01206         if(!Started(mech)) {
01207 
01208                 /* Startup */
01209                 if(!Starting(mech))
01210                         auto_command_startup(autopilot, mech);
01211 
01212                 /* Run this command after startup */
01213                 AUTOEVENT(autopilot, EVENT_AUTOGOTO, auto_dumbgoto_event,
01214                                   AUTOPILOT_STARTUP_TICK, 0);
01215                 return;
01216         }
01217 
01218         /* Ok not standing so lets do that first */
01219         if(MechType(mech) == CLASS_MECH && Fallen(mech) &&
01220            !(CountDestroyedLegs(mech) > 0)) {
01221 
01222                 if(!Standing(mech))
01223                         mech_stand(autopilot->mynum, mech, "");
01224 
01225                 /* Ok lets run this command again */
01226                 AUTOEVENT(autopilot, EVENT_AUTOGOTO, auto_dumbgoto_event,
01227                                   AUTOPILOT_NC_DELAY, 0);
01228                 return;
01229         }
01230 
01233         /* Get the first argument - x coord */
01234         if(!(argument = auto_get_command_arg(autopilot, 1, 1))) {
01235 
01236                 /* Ok bad argument - means the command is messed up
01237                  * so should go to next one */
01238                 snprintf(error_buf, MBUF_SIZE, "Internal AI Error - Attempting to"
01239                                  " goto [dumbly] with AI #%d but was unable to - bad"
01240                                  " first argument - going to next command", autopilot->mynum);
01241                 SendAI(error_buf);
01242                 auto_goto_next_command(autopilot, AUTOPILOT_NC_DELAY);
01243                 return;
01244         }
01245 
01246         /* Read in the argument */
01247         if(Readnum(tx, argument)) {
01248 
01249                 snprintf(error_buf, MBUF_SIZE, "Internal AI Error - Attempting to"
01250                                  " goto [dumbly] with AI #%d but was unable to - bad"
01251                                  " first argument '%s' - going to next command",
01252                                  autopilot->mynum, argument);
01253                 SendAI(error_buf);
01254                 free(argument);
01255                 auto_goto_next_command(autopilot, AUTOPILOT_NC_DELAY);
01256                 return;
01257         }
01258         free(argument);
01259 
01260         /* Get the first argument - y coord */
01261         if(!(argument = auto_get_command_arg(autopilot, 1, 2))) {
01262 
01263                 /* Ok bad argument - means the command is messed up
01264                  * so should go to next one */
01265                 snprintf(error_buf, MBUF_SIZE, "Internal AI Error - Attempting to"
01266                                  " goto [dumbly] with AI #%d but was unable to - bad"
01267                                  " second argument - going to next command",
01268                                  autopilot->mynum);
01269                 SendAI(error_buf);
01270                 auto_goto_next_command(autopilot, AUTOPILOT_NC_DELAY);
01271                 return;
01272         }
01273 
01274         /* Read in the argument */
01275         if(Readnum(ty, argument)) {
01276 
01277                 snprintf(error_buf, MBUF_SIZE, "Internal AI Error - Attempting to"
01278                                  " goto [dumbly] with AI #%d but was unable to - bad"
01279                                  " second argument '%s' - going to next command",
01280                                  autopilot->mynum, argument);
01281                 SendAI(error_buf);
01282                 free(argument);
01283                 auto_goto_next_command(autopilot, AUTOPILOT_NC_DELAY);
01284                 return;
01285         }
01286         free(argument);
01287 
01288         /* If we're at the target hex - stop */
01289         if(MechX(mech) == tx && MechY(mech) == ty && abs(MechSpeed(mech)) < 0.5) {
01290 
01291                 /* We've reached this goal! Time for next one. */
01292                 ai_set_speed(mech, autopilot, 0);
01293 
01294                 auto_goto_next_command(autopilot, AUTOPILOT_NC_DELAY);
01295                 return;
01296         }
01297 
01298         /* Make our way to the goal */
01299         figure_out_range_and_bearing(mech, tx, ty, &range, &bearing);
01300         speed_up_if_neccessary(autopilot, mech, tx, ty, bearing);
01301         slow_down_if_neccessary(autopilot, mech, range, bearing, tx, ty);
01302         update_wanted_heading(autopilot, mech, bearing);
01303         AUTOEVENT(autopilot, EVENT_AUTOGOTO, auto_dumbgoto_event,
01304                           AUTOPILOT_GOTO_TICK, 0);
01305 }

void auto_engage ( dbref  player,
void *  data,
char *  buffer 
)

Definition at line 689 of file autopilot_core.c.

References auto_com_event(), auto_init(), auto_pilot_on(), auto_set_comtitle(), AUTOEVENT, AUTOPILOT_NC_DELAY, DOCHECK, EVENT_AUTOCOM, getMech(), Location, AUTO::mapindex, MECH::mapindex, MechAuto, AUTO::mymech, AUTO::mymechnum, AUTO::mynum, and notify.

Referenced by auto_radio_command_dfollow(), auto_radio_command_dgoto(), auto_radio_command_dropoff(), auto_radio_command_embark(), auto_radio_command_enterbase(), auto_radio_command_follow(), auto_radio_command_goto(), auto_radio_command_heading(), auto_radio_command_leavebase(), auto_radio_command_ogoto(), auto_radio_command_pickup(), auto_radio_command_reset(), and auto_radio_command_stop().

00690 {
00691 
00692         AUTO *autopilot = (AUTO *) data;
00693         MECH *mech;
00694 
00695         autopilot->mymech = mech =
00696                 getMech((autopilot->mymechnum = Location(autopilot->mynum)));
00697         DOCHECK(!autopilot, "Internal error! - Bad AI object!");
00698         DOCHECK(!mech, "Error: The autopilot isn't inside a 'mech!");
00699         DOCHECK(auto_pilot_on(autopilot),
00700                         "The autopilot's already online! You have to disengage it first.");
00701 
00702         if(MechAuto(mech) <= 0)
00703                 auto_init(autopilot, mech);
00704         MechAuto(mech) = autopilot->mynum;
00705 
00706         if(MechAuto(mech) > 0)
00707                 auto_set_comtitle(autopilot, mech);
00708 
00709         autopilot->mapindex = mech->mapindex;
00710 
00711         notify(player, "Engaging autopilot...");
00712         AUTOEVENT(autopilot, EVENT_AUTOCOM, auto_com_event, AUTOPILOT_NC_DELAY,
00713                           0);
00714 
00715         return;
00716 
00717 }

void auto_enter_event ( MUXEVENT muxevent  ) 

Definition at line 2221 of file autopilot_commands.c.

References ai_set_speed(), auto_command_startup(), auto_enter_event(), auto_get_command_arg(), auto_get_command_enum(), auto_goto_next_command(), AUTOEVENT, AUTOPILOT_NC_DELAY, AUTOPILOT_STARTUP_TICK, CLASS_MECH, CountDestroyedLegs(), my_event_type::data, my_event_type::data2, Destroyed, EnteringHangar, EVENT_AUTOENTERBASE, Fallen, find_entrance_by_xy(), getMap(), GOAL_ENTERBASE, GOD, IsAuto(), IsMech, Location, AUTO::mapindex, MECH::mapindex, MBUF_SIZE, mech_enterbase(), mech_stand(), MechDesiredSpeed, MechSpeed, MechType, MechX, MechY, AUTO::mymech, AUTO::mymechnum, MECH::mynum, AUTO::mynum, SendAI, Standing, Started, and Starting.

Referenced by auto_com_event(), and auto_enter_event().

02222 {
02223 
02224         AUTO *autopilot = (AUTO *) muxevent->data;
02225         MECH *mech = autopilot->mymech;
02226         MAP *map;
02227         mapobj *map_object;
02228         int num;
02229         int reset_mapindex = (int) muxevent->data2;
02230 
02231         char *argument;
02232         char dir[2];
02233         char error_buf[MBUF_SIZE];
02234 
02235         if(!IsMech(mech->mynum) || !IsAuto(autopilot->mynum))
02236                 return;
02237 
02238         /* Are we in the mech we're supposed to be in */
02239         if(Location(autopilot->mynum) != autopilot->mymechnum)
02240                 return;
02241 
02242         /* Our mech is destroyed */
02243         if(Destroyed(mech))
02244                 return;
02245 
02246         /* Check to make sure the first command in the queue is this one */
02247         if(auto_get_command_enum(autopilot, 1) != GOAL_ENTERBASE)
02248                 return;
02249 
02250         /* Get the Map */
02251         if(!(map = getMap(autopilot->mapindex))) {
02252 
02253                 /* Bad Map */
02254                 snprintf(error_buf, MBUF_SIZE, "Internal AI Error - Attempting to"
02255                                  " enterbase with AI #%d but AI is not on a valid"
02256                                  " Map (#%d).", autopilot->mynum, autopilot->mapindex);
02257                 SendAI(error_buf);
02258 
02259                 auto_goto_next_command(autopilot, AUTOPILOT_NC_DELAY);
02260                 return;
02261 
02262         }
02263 
02264         /* Is there anything even to enter here */
02265         if(!(map_object = find_entrance_by_xy(map, MechX(mech), MechY(mech)))) {
02266 
02267                 /* Nothing in this hex */
02268                 snprintf(error_buf, MBUF_SIZE, "Internal AI Error - Attempting to"
02269                                  " enterbase with AI #%d but there is nothing at %d, %d"
02270                                  " to enter", autopilot->mynum, MechX(mech), MechY(mech));
02271                 SendAI(error_buf);
02272                 auto_goto_next_command(autopilot, AUTOPILOT_NC_DELAY);
02273                 return;
02274         }
02275 
02276         /* Reset the mapindex if this is the first run of the event */
02277         if(reset_mapindex) {
02278                 autopilot->mapindex = mech->mapindex;
02279         }
02280 
02281         /* Make sure mech is started */
02282         if(!Started(mech)) {
02283 
02284                 /* Startup */
02285                 if(!Starting(mech))
02286                         auto_command_startup(autopilot, mech);
02287 
02288                 /* Run this command after startup */
02289                 AUTOEVENT(autopilot, EVENT_AUTOENTERBASE,
02290                                   auto_enter_event, AUTOPILOT_STARTUP_TICK, 0);
02291                 return;
02292         }
02293 
02294         /* Ok not standing so lets do that first */
02295         if(MechType(mech) == CLASS_MECH && Fallen(mech) &&
02296            !(CountDestroyedLegs(mech) > 0)) {
02297 
02298                 if(!Standing(mech))
02299                         mech_stand(autopilot->mynum, mech, "");
02300 
02301                 /* Ok lets run this command again */
02302                 AUTOEVENT(autopilot, EVENT_AUTOENTERBASE,
02303                                   auto_enter_event, AUTOPILOT_NC_DELAY, 0);
02304                 return;
02305         }
02306 
02307         /* Get enter direction */
02308         if(!(argument = auto_get_command_arg(autopilot, 1, 1))) {
02309 
02310                 /* Ok bad argument - means the command is messed up
02311                  * so should go to next one */
02312                 snprintf(error_buf, MBUF_SIZE, "Internal AI Error - Attempting to"
02313                                  " enterbase with AI #%d but was given bad argument -"
02314                                  " going to next command", autopilot->mynum);
02315                 SendAI(error_buf);
02316                 auto_goto_next_command(autopilot, AUTOPILOT_NC_DELAY);
02317                 return;
02318         }
02319 
02320         /* Check the first letter of the 'only' argument
02321          * this tells us what direction to enter */
02322         switch (argument[0]) {
02323 
02324         case 'n':
02325         case 'N':
02326                 strcpy(dir, "n");
02327                 break;
02328         case 's':
02329         case 'S':
02330                 strcpy(dir, "s");
02331                 break;
02332         case 'w':
02333         case 'W':
02334                 strcpy(dir, "w");
02335                 break;
02336         case 'e':
02337         case 'E':
02338                 strcpy(dir, "e");
02339                 break;
02340         default:
02341                 strcpy(dir, "");
02342 
02343         }
02344         free(argument);
02345 
02346         /* New map so we're done */
02347         if(mech->mapindex != autopilot->mapindex) {
02348 
02349                 autopilot->mapindex = mech->mapindex;
02350                 auto_goto_next_command(autopilot, AUTOPILOT_NC_DELAY);
02351                 return;
02352         }
02353 
02354         if(MechDesiredSpeed(mech) != 0.0)
02355                 ai_set_speed(mech, autopilot, 0);
02356 
02357         if((MechSpeed(mech) == 0.0) && !EnteringHangar(mech)) {
02358                 mech_enterbase(GOD, mech, dir);
02359         }
02360 
02361         /* Run this event again if we're not in yet */
02362         AUTOEVENT(autopilot, EVENT_AUTOENTERBASE, auto_enter_event,
02363                           AUTOPILOT_NC_DELAY, 0);
02364 }

void auto_eventstats ( dbref  player,
void *  data,
char *  buffer 
)

Definition at line 578 of file autopilot_core.c.

References FIRST_AUTO_EVENT, LAST_AUTO_EVENT, muxevent_count_type_data(), muxevent_names, notify, notify_printf(), and total.

00579 {
00580 
00581         AUTO *autopilot = (AUTO *) data;
00582         int i, j, total;
00583 
00584         notify(player, "Events by type: ");
00585         notify(player, "-------------------------------");
00586 
00587         total = 0;
00588 
00589         for(i = FIRST_AUTO_EVENT; i <= LAST_AUTO_EVENT; i++) {
00590 
00591                 if((j = muxevent_count_type_data(i, (void *) autopilot))) {
00592                         notify_printf(player, "%-20s%d", muxevent_names[i], j);
00593                         total += j;
00594                 }
00595 
00596         }
00597 
00598         if(total) {
00599                 notify(player, "-------------------------------");
00600                 notify_printf(player, "%d total", total);
00601         }
00602 
00603 }

char* auto_get_command_arg ( AUTO autopilot,
int  command_number,
int  arg_number 
)

Definition at line 777 of file autopilot_core.c.

References command_node_t::args, AUTOPILOT_MAX_ARGS, AUTO::commands, dllist_get_node(), dllist_size(), MBUF_SIZE, AUTO::mynum, SendAI, and strndup().

Referenced by auto_astar_follow_event(), auto_astar_goto_event(), auto_command_autogun(), auto_command_embark(), auto_command_pickup(), auto_command_roam(), auto_command_speed(), auto_dumbfollow_event(), auto_dumbgoto_event(), auto_enter_event(), auto_goto_event(), and auto_leave_event().

00779 {
00780 
00781         char *argument;
00782         command_node *temp_command_node;
00783         char error_buf[MBUF_SIZE];
00784 
00785         if(command_number > dllist_size(autopilot->commands)) {
00786                 snprintf(error_buf, MBUF_SIZE, "Internal AI Error: Trying to "
00787                                  "access Command #%d for AI #%d but it doesn't exist",
00788                                  command_number, autopilot->mynum);
00789                 SendAI(error_buf);
00790                 return NULL;
00791         }
00792 
00793         if(arg_number >= AUTOPILOT_MAX_ARGS) {
00794                 snprintf(error_buf, MBUF_SIZE, "Internal AI Error: Trying to "
00795                                  "access Arg #%d for AI #%d Command #%d but its greater"
00796                                  " then AUTOPILOT_MAX_ARGS (%d)",
00797                                  arg_number, autopilot->mynum, command_number,
00798                                  AUTOPILOT_MAX_ARGS);
00799                 SendAI(error_buf);
00800                 return NULL;
00801         }
00802 
00803         temp_command_node = (command_node *) dllist_get_node(autopilot->commands,
00804                                                                                                                  command_number);
00805 
00808         if(!temp_command_node->args[arg_number]) {
00809                 snprintf(error_buf, MBUF_SIZE, "Internal AI Error: Trying to "
00810                                  "access Arg #%d for AI #%d Command #%d but it doesn't exist",
00811                                  autopilot->mynum, arg_number, command_number);
00812                 SendAI(error_buf);
00813                 return NULL;
00814         }
00815 
00816         argument = strndup(temp_command_node->args[arg_number], MBUF_SIZE);
00817 
00818         return argument;
00819 
00820 }

int auto_get_command_enum ( AUTO autopilot,
int  command_number 
)

Definition at line 826 of file autopilot_core.c.

References AUTO_NUM_COMMANDS, command_node_t::command_enum, AUTO::commands, dllist_get_node(), dllist_size(), MBUF_SIZE, AUTO::mynum, and SendAI.

Referenced by auto_astar_follow_event(), auto_astar_goto_event(), auto_astar_roam_event(), auto_cal_mapindex(), auto_com_event(), auto_dumbfollow_event(), auto_dumbgoto_event(), auto_enter_event(), and auto_leave_event().

00827 {
00828 
00829         int command_enum;
00830         command_node *temp_command_node;
00831         char error_buf[MBUF_SIZE];
00832 
00833         /* Make sure there are commands */
00834         if(dllist_size(autopilot->commands) <= 0) {
00835                 return -1;
00836         }
00837 
00838         if(command_number <= 0) {
00839                 snprintf(error_buf, MBUF_SIZE, "Internal AI Error: Trying to "
00840                                  "access a command (%d) for AI #%d that can't be on a list",
00841                                  command_number, autopilot->mynum);
00842                 SendAI(error_buf);
00843                 return -1;
00844         }
00845 
00846         /* Make sure the command is on the list */
00847         if(command_number > dllist_size(autopilot->commands)) {
00848                 snprintf(error_buf, MBUF_SIZE, "Internal AI Error: Trying to "
00849                                  "access Command #%d for AI #%d but it doesn't exist",
00850                                  autopilot->mynum, command_number);
00851                 SendAI(error_buf);
00852                 return -1;
00853         }
00854 
00855         temp_command_node = (command_node *) dllist_get_node(autopilot->commands,
00856                                                                                                                  command_number);
00857 
00860         command_enum = temp_command_node->command_enum;
00861 
00862         /* If its a bad enum value we have a problem */
00863         if((command_enum >= AUTO_NUM_COMMANDS) || (command_enum < 0)) {
00864                 snprintf(error_buf, MBUF_SIZE, "Internal AI Error: Command ENUM for"
00865                                  " AI #%d Command Number #%d doesn't exist\n",
00866                                  autopilot->mynum, command_number);
00867                 SendAI(error_buf);
00868                 return -1;
00869         }
00870 
00871         return command_enum;
00872 
00873 }

void auto_goto_next_command ( AUTO autopilot,
int  time 
)

Definition at line 740 of file autopilot_core.c.

References AUTO_COM, auto_destroy_command_node(), AUTO::commands, dllist_head(), dllist_remove(), dllist_size(), MBUF_SIZE, AUTO::mynum, and SendAI.

Referenced by auto_astar_follow_event(), auto_astar_goto_event(), auto_astar_roam_event(), auto_com_event(), auto_command_roam(), auto_command_startup(), auto_dumbfollow_event(), auto_dumbgoto_event(), auto_enter_event(), auto_goto_event(), and auto_leave_event().

00741 {
00742 
00743         command_node *temp_command_node;
00744         char error_buf[MBUF_SIZE];
00745 
00746         if(dllist_size(autopilot->commands) < 0) {
00747                 snprintf(error_buf, MBUF_SIZE, "Internal AI Error: Trying to remove"
00748                                  " the first command from AI #%d but the command list is empty\n",
00749                                  autopilot->mynum);
00750                 SendAI(error_buf);
00751                 return;
00752         }
00753 
00754         temp_command_node = (command_node *) dllist_remove(autopilot->commands,
00755                                                                                                            dllist_head(autopilot->
00756                                                                                                                                    commands));
00757 
00758         if(!temp_command_node) {
00759                 snprintf(error_buf, MBUF_SIZE, "Internal AI Error: Trying to remove"
00760                                  " the first command from AI #%d but the command node doesn't exist\n",
00761                                  autopilot->mynum);
00762                 SendAI(error_buf);
00763                 return;
00764         }
00765 
00766         auto_destroy_command_node(temp_command_node);
00767 
00768         /* Fire off the AUTO_COM event */
00769         AUTO_COM(autopilot, time);
00770 
00771 }

void auto_gun_event ( AUTO AUTOPILOT  ) 

Definition at line 905 of file autopilot_autogun.c.

References AssignedTarget, auto_calc_target_score(), auto_create_target_node(), auto_generic_compare(), AUTO_GUN_MAX_RANGE, AUTO_GUN_UPDATE_TICK, auto_targets_callback(), Destroyed, DoStopGun, FindHexRange(), getMap(), getMech(), IsAuto(), IsMech, LBUF_SIZE, MECH::mapindex, MECH::mapnumber, MechFX, MechFY, AUTO::mymech, MECH::mynum, AUTO::mynum, OODing, print_autogun_log, rb_destroy(), rb_exists(), rb_init(), rb_insert(), rb_search(), rb_size(), rb_walk(), SEARCH_LAST, Started, AUTO::target, AUTO::target_score, AUTO::target_threshold, AUTO::target_update_tick, UnassignTarget, WALK_INORDER, AUTO::weaplist, x, y, and Zombify.

Referenced by auto_heartbeat().

00906 {
00907         MECH *mech = (MECH *) autopilot->mymech;        /* Its Mech */
00908         MAP *map;                                       /* The current Map */
00909         MECH *target;                           /* Our current target */
00910         MECH *physical_target;          /* Our physical target */
00911         rbtree targets;                     /* all the targets we're looking at */
00912         target_node *temp_target_node;  /* temp target node struct */
00913         weapon_node *temp_weapon_node;  /* temp weapon node struct */
00914 
00915         char buffer[LBUF_SIZE];         /* General use buffer */
00916 
00917         int target_score;                       /* variable to store temp score */
00918         int threshold_score;            /* The score to beat to switch targets */
00919 
00920         /* Stuff for Physical attacks */
00921         int elevation_diff;                     /* Whats the elevation difference between
00922                                                                    the target and the mech */
00923         int what_arc;                           /* What arc is the target in */
00924         int new_arc;                            /* What arc now that we've twisted
00925                                                                    our torso */
00926         int relative_bearing;           /* Int to figure out which part of
00927                                                                    the rear arc hes in */
00928         int is_section_destroyed[4];    /* Array of the different possible
00929                                                                            sections that could be destroyed */
00930         int section_hasbusyweap[4];     /* Array to show if a section has a
00931                                                                    cycling weapon in it */
00932         int rleg_bth, lleg_bth;         /* To help us decide which leg to kick
00933                                                                    with */
00934         int is_rarm_ready, is_larm_ready;       /* To help us decide which arms to
00935                                                                                    punch with */
00936 
00937         /* Stuff for Weapon Attacks */
00938         int accumulate_heat;            /* How much heat we're building up */
00939         int i, j;
00940 
00941         float range;                            /* General variable for range */
00942         float maxspeed;                         /* So we know how fast our guy is going */
00943 
00944         /* For use with chase targ */
00945         short x, y;
00946         float fx, fy;
00947         char do_chasetarget;            /* Flag should we do chasetarget
00948                                                                    based on certain conditions */
00949 
00950         /* Basic checks */
00951         if(!mech || !autopilot)
00952                 return;
00953 
00954         if(!IsMech(mech->mynum) || !IsAuto(autopilot->mynum))
00955                 return;
00956 
00957         /* Ok our mech is dead we're done */
00958         if(Destroyed(mech)) {
00959                 DoStopGun(autopilot);
00960                 return;
00961         }
00962 
00964         if(!Started(mech)) {
00965                 Zombify(autopilot);
00966                 return;
00967         }
00968 
00969         /* Not on map - so lets calm down */
00970         if(!(map = getMap(mech->mapindex))) {
00971                 Zombify(autopilot);
00972                 return;
00973         }
00974 
00975         /* Log it */
00976         print_autogun_log(autopilot, "Autogun Event Started");
00977 
00978         /* check for a gun profile. */
00979     if(autopilot->weaplist == NULL) {
00980                 print_autogun_log(autopilot, "Autogun Event Finished");
00981                 return;
00982         }
00983 
00984         /* OODing so don't shoot any guns */
00985         if(OODing(mech)) {
00986                 /* Log It */
00987                 print_autogun_log(autopilot, "Autogun Event Finished");
00988                 return;
00989         }
00990 
00991         /* First check to make sure we have a valid current target */
00992         if(autopilot->target > -1) {
00993 
00994                 if(!(target = getMech(autopilot->target))) {
00995 
00996                         /* ok its not a valid target reset */
00997                         autopilot->target = -1;
00998                         autopilot->target_score = 0;
00999 
01000                 } else if(Destroyed(target) || (target->mapindex != mech->mapindex)) {
01001 
01002                         /* Target is either dead or not on the map anymore */
01003                         autopilot->target = -1;
01004                         autopilot->target_score = 0;
01005 
01006                 } else {
01007 
01008                         /* Will keep on an assigned target even if its to far
01009                          * away */
01010 
01011                         /* Get range from mech to current target */
01012                         range = FindHexRange(MechFX(mech), MechFY(mech),
01013                                                                  MechFX(target), MechFY(target));
01014 
01015                         if((range >= (float) AUTO_GUN_MAX_RANGE) &&
01016                            !AssignedTarget(autopilot)) {
01017 
01018                                 /* Target is to far away */
01019                                 autopilot->target = -1;
01020                                 autopilot->target_score = 0;
01021 
01022                         }
01023 
01024                 }
01025 
01026         }
01027 
01028         /* Were we given a target and its no longer there? */
01029         if(AssignedTarget(autopilot) && autopilot->target == -1) {
01030 
01031                 /* Ok we had an assigned target but its gone now */
01032                 UnassignTarget(autopilot);
01033 
01035         }
01036 
01037         /* Do we need to look for a new target */
01038         if(autopilot->target == -1 ||
01039            (autopilot->target_update_tick >= AUTO_GUN_UPDATE_TICK &&
01040                 !AssignedTarget(autopilot))) {
01041 
01042                 /* Ok looking for a new target */
01043 
01044                 /* Log It */
01045                 print_autogun_log(autopilot, "Autogun - Looking for new target");
01046 
01047                 /* Reset the update ticker */
01048                 autopilot->target_update_tick = 0;
01049 
01050                 /* Setup the rbtree */
01051                 targets = rb_init(&auto_generic_compare, NULL);
01052 
01053                 /* Cycle through possible targets and pick something to shoot */
01054                 for(i = 0; i < map->first_free; i++) {
01055 
01056                         /* Make sure its on the right map */
01057                         if(i != mech->mapnumber && (j = map->mechsOnMap[i]) > 0) {
01058 
01059                                 /* Is it a valid unit ? */
01060                                 if(!(target = getMech(j)))
01061                                         continue;
01062 
01063                                 /* Score the target */
01064                                 target_score =
01065                                         auto_calc_target_score(autopilot, mech, target, map);
01066 
01067                                 /* Log It */
01068                                 print_autogun_log(autopilot,
01069                                                                   "Autogun - Possible target #%d with score %d",
01070                                                                   target->mynum, target_score);
01071 
01072                                 /* If target has a score add it to rbtree */
01073                                 if(target_score > 0) {
01074 
01075                                         /* Create target node and fill with proper values */
01076                                         temp_target_node = auto_create_target_node(target_score,
01077                                                                                                                            target->mynum);
01078 
01081                                         /* Add it to list but first make sure it doesn't overlap
01082                                          * with a current score */
01083                                         while (1) {
01084 
01085                                                 if(rb_exists
01086                                                    (targets, &temp_target_node->target_score)) {
01087                                                         temp_target_node->target_score++;
01088                                                 } else {
01089                                                         break;
01090                                                 }
01091 
01092                                         }
01093 
01094                                         /* Add it */
01095                                         rb_insert(targets, &temp_target_node->target_score,
01096                                                           temp_target_node);
01097 
01098                                 }
01099 
01100                                 /* Check to see if its our current target */
01101                                 if(autopilot->target == target->mynum) {
01102 
01103                                         /* Save the new score */
01104                                         autopilot->target_score = target_score;
01105 
01106                                 }
01107 
01108                         }
01109 
01110                 }                                               /* End of for loop */
01111 
01112                 /* Check to see if we couldn't find ANY targets within range,
01113                  * if not, cycle autogun and set the update tick to 20, so we
01114                  * check again in 10 seconds */
01115                 if(!(rb_size(targets) > 0)) {
01116 
01117                         /* Have the AI look for a new target 10 seconds from now */
01120                         autopilot->target = -1;
01121                         autopilot->target_score = 0;
01122                         autopilot->target_update_tick = 0;
01123 
01124                         /* Don't need the target list any more so lets destroy it */
01125                         rb_walk(targets, WALK_INORDER, &auto_targets_callback, NULL);
01126                         rb_destroy(targets);
01127 
01128             /* Log It */
01129                         print_autogun_log(autopilot, "Autogun in idle mode");
01130                         print_autogun_log(autopilot, "Autogun Event Finished");
01131                         return;
01132                 }
01133 
01134                 /* Now if we have a current target, compare it to best target from
01135                  * the new list.  If better then threshold, lock new target, else
01136                  * stay on target */
01137 
01138                 /* Best target */
01139                 temp_target_node =
01140                         (target_node *) rb_search(targets, SEARCH_LAST, NULL);
01141 
01142                 /* Log It */
01143                 print_autogun_log(autopilot,
01144                                                   "Autogun - Best target #%d with score %d",
01145                                                   temp_target_node->target_dbref,
01146                                                   temp_target_node->target_score);
01147                 print_autogun_log(autopilot,
01148                                                   "Autogun - Current target #%d with score %d",
01149                                                   autopilot->target, autopilot->target_score);
01150 
01151                 if(autopilot->target > -1 && autopilot->target_score > 0) {
01152 
01153                         /* Check to see if its our current target */
01154                         if(autopilot->target != temp_target_node->target_dbref) {
01155 
01156                                 /* Calc the threshold score to beat */
01157                                 threshold_score =
01158                                         ((100.0 +
01159                                           (float) autopilot->target_threshold) / 100.0) *
01160                                         autopilot->target_score;
01161 
01162                                 if(temp_target_node->target_score > threshold_score) {
01163 
01164                                         /* Change targets */
01165                                         autopilot->target = temp_target_node->target_dbref;
01166                                         autopilot->target_score = temp_target_node->target_score;
01167 
01168                                         print_autogun_log(autopilot, "Switching Target to #%d",
01169                                                                           autopilot->target);
01170 
01171                                 }
01172 
01173                                 /* Else: Don't switch targets */
01174 
01175                         }
01176 
01177                         /* Else: Don't need to swtich targets */
01178 
01179                 } else {
01180 
01181                         /* Don't have a good current target so lock this one */
01182                         autopilot->target = temp_target_node->target_dbref;
01183                         autopilot->target_score = temp_target_node->target_score;
01184 
01185                 }                                               /* End of choosing new target */
01186 
01187                 /* Don't need the target list any more so lets destroy it */
01188                 rb_walk(targets, WALK_INORDER, &auto_targets_callback, NULL);
01189                 rb_destroy(targets);
01190 
01191         } else {
01192 
01193                 /* Ok didn't need to look for a new target so update the ticker */
01194                 autopilot->target_update_tick++;
01195 
01196         }
01197 
01198         /* End of picking a new target */
01199 
01200         /* Log It */
01201         print_autogun_log(autopilot, "Autogun - Current target #%d with score %d",
01202                                           autopilot->target, autopilot->target_score);
01203 
01204         /* Setup the current target */
01205         if(!(target = getMech(autopilot->target))) {
01206 
01207                 /* There were no valid targets so
01208                  * rerun autogun */
01209 
01210                 /* Reset the AI */
01211                 autopilot->target = -1;
01212                 autopilot->target_score = 0;
01213 
01214         /* Log It */
01215                 print_autogun_log(autopilot, "Autogun - No valid current targets");
01216                 print_autogun_log(autopilot, "Autogun Event Finished");
01217                 return;
01218 
01219         }
01220 
01221         /* Check to see if we need to (re)lock our target */
01222         if(MechTarget(mech) != autopilot->target) {
01223 
01224                 /* Lock Him */
01225                 snprintf(buffer, LBUF_SIZE, "%c%c", MechID(target)[0],
01226                                  MechID(target)[1]);
01227                 mech_settarget(autopilot->mynum, mech, buffer);
01228 
01229                 /* Log It */
01230                 print_autogun_log(autopilot, "Autogun - Locking target #%d",
01231                                                   autopilot->target);
01232 
01233         }
01234 
01235         /* Update autosensor */
01236 
01237         /* Now lets get physical */
01238 
01239         /* Log It */
01240         print_autogun_log(autopilot, "Autogun - Start Physical Attack Stage");
01241 
01242         /* Get range from mech to current target */
01243         range =
01244                 FindHexRange(MechFX(mech), MechFY(mech), MechFX(target),
01245                                          MechFY(target));
01246 
01247         /* First check our range to our target, if within range attack it, else
01248          * check to see if its outside our range threshold and if so pick a target
01249          * close and attack that */
01250 
01252         if(range < 1.0) {
01253 
01254                 /* We're beating on our main target */
01255                 physical_target = target;
01256 
01257         } else if(range > AUTO_GUN_PHYSICAL_RANGE_MIN) {
01258 
01259                 /* Try and find a target */
01260 
01261                 physical_target = NULL;
01262 
01263                 /* Cycle through possible targets and pick something to beat on */
01264                 for(i = 0; i < map->first_free; i++) {
01265 
01266                         /* Make sure its on the right map */
01267                         if(i != mech->mapnumber && (j = map->mechsOnMap[i]) > 0) {
01268 
01269                                 /* Is it a valid unit ? */
01270                                 if(!(target = getMech(j)))
01271                                         continue;
01272 
01273                                 if(Destroyed(target))
01274                                         continue;
01275 
01276                                 if(MechStatus(target) & COMBAT_SAFE)
01277                                         continue;
01278 
01279                                 if(MechTeam(target) == MechTeam(mech))
01280                                         continue;
01281 
01282                                 /* Check its range */
01283                                 range = FindHexRange(MechFX(mech), MechFY(mech),
01284                                                                          MechFX(target), MechFY(target));
01285 
01286                                 /* Just go for first one , can always add scoring later */
01287                                 if(range < 1.0) {
01288                                         physical_target = target;
01289                                         break;
01290                                 }
01291 
01292                         }
01293 
01294                 }
01295 
01296         } else {
01297 
01298                 /* Our target is close so dont try and physically attack anyone */
01299                 physical_target = NULL;
01300 
01301         }
01302 
01303         /* Now nail it with a physical attack but only if we see it */
01304         if(physical_target &&
01305            (MechToMech_LOSFlag(map, mech, physical_target) & MECHLOSFLAG_SEEN)) {
01306 
01307                 /* Log It */
01308                 print_autogun_log(autopilot,
01309                                                   "Autogun - Attempting physical attack against"
01310                                                   " target #%d", physical_target->mynum);
01311 
01312                 /* Calculate elevation difference */
01313                 elevation_diff = MechZ(mech) - MechZ(target);
01314 
01315                 /* Are we a biped Mech */
01316                 if((MechType(mech) == CLASS_MECH) && (MechMove(mech) == MOVE_BIPED)) {
01317 
01318                         /* Center the torso */
01319                         MechStatus(mech) &= ~(TORSO_RIGHT | TORSO_LEFT);
01320 
01321                         if(MechSpecials(mech) & FLIPABLE_ARMS) {
01322 
01323                                 /* Center the arms if need be */
01324                                 MechStatus(mech) &= ~(FLIPPED_ARMS);
01325                         }
01326 
01327                         /* Find direction of bad guy */
01328                         what_arc =
01329                                 InWeaponArc(mech, MechFX(physical_target),
01330                                                         MechFY(physical_target));
01331 
01332                         /* Rotate if we need to */
01333                         if(what_arc & LSIDEARC) {
01334 
01335                                 /* Rotate Left */
01336                                 MechStatus(mech) |= TORSO_LEFT;
01337 
01338                         } else if(what_arc & RSIDEARC) {
01339 
01340                                 /* Rotate Right */
01341                                 MechStatus(mech) |= TORSO_RIGHT;
01342 
01343                         } else if(what_arc & REARARC) {
01344 
01345                                 /* Find out if it would be better to
01346                                  * rotate left or right */
01347                                 relative_bearing =
01348                                         MechFacing(mech) - FindBearing(MechFX(mech), MechFY(mech),
01349                                                                                                    MechFX(physical_target),
01350                                                                                                    MechFY(physical_target));
01351 
01352                                 if(relative_bearing > 120 && relative_bearing < 180) {
01353 
01354                                         /* Rotate Right */
01355                                         MechStatus(mech) |= TORSO_RIGHT;
01356 
01357                                 } else if(relative_bearing > 180 && relative_bearing < 240) {
01358 
01359                                         /* Rotate Left */
01360                                         MechStatus(mech) |= TORSO_LEFT;
01361 
01362                                 }
01363 
01364                                 /* ELSE: Hes directly behind us so we can't do anything */
01365 
01366                         }
01367 
01368                         /* Calculate the new arc */
01369                         new_arc =
01370                                 InWeaponArc(mech, MechFX(physical_target),
01371                                                         MechFY(physical_target));
01372 
01373                         /* Check to see what sections are destroyed */
01374                         memset(is_section_destroyed, 0, sizeof(is_section_destroyed));
01375                         is_section_destroyed[0] = SectIsDestroyed(mech, RARM);
01376                         is_section_destroyed[1] = SectIsDestroyed(mech, LARM);
01377                         is_section_destroyed[2] = SectIsDestroyed(mech, RLEG);
01378                         is_section_destroyed[3] = SectIsDestroyed(mech, LLEG);
01379 
01380                         /* Check to see if the sections have a busy weapon */
01381                         memset(section_hasbusyweap, 0, sizeof(section_hasbusyweap));
01382                         section_hasbusyweap[0] = SectHasBusyWeap(mech, RARM);
01383                         section_hasbusyweap[1] = SectHasBusyWeap(mech, LARM);
01384                         section_hasbusyweap[2] = SectHasBusyWeap(mech, RLEG);
01385                         section_hasbusyweap[3] = SectHasBusyWeap(mech, LLEG);
01386 
01387                         /* Try weapon physical attacks */
01388 
01389                         /* Right Arm */
01390                         if(!is_section_destroyed[0] && !section_hasbusyweap[0] &&
01391                            !AnyLimbsRecycling(mech) && ((new_arc & FORWARDARC) ||
01392                                                                                         (new_arc & RSIDEARC)) &&
01393                            (elevation_diff == 0 || elevation_diff == -1)) {
01394 
01395                                 snprintf(buffer, LBUF_SIZE, "r %c%c",
01396                                                  MechID(target)[0], MechID(target)[1]);
01397 
01398                                 if(have_axe(mech, RARM))
01399                                         mech_axe(autopilot->mynum, mech, buffer);
01400                                 /* else if (have_mace(mech, RARM)) */
01402                                 else if(have_sword(mech, RARM))
01403                                         mech_sword(autopilot->mynum, mech, buffer);
01404 
01405                         }
01406 
01407                         /* Left Arm */
01408                         if(!is_section_destroyed[1] && !section_hasbusyweap[1] &&
01409                            !AnyLimbsRecycling(mech) && ((new_arc & FORWARDARC) ||
01410                                                                                         (new_arc & LSIDEARC)) &&
01411                            (elevation_diff == 0 || elevation_diff == -1)) {
01412 
01413                                 snprintf(buffer, LBUF_SIZE, "l %c%c",
01414                                                  MechID(target)[0], MechID(target)[1]);
01415 
01416                                 if(have_axe(mech, LARM))
01417                                         mech_axe(autopilot->mynum, mech, buffer);
01418                                 /* else if (have_mace(mech, RARM)) */
01420                                 else if(have_sword(mech, LARM))
01421                                         mech_sword(autopilot->mynum, mech, buffer);
01422 
01423                         }
01424 
01425                         /* Try and kick but only if we got two legs, one of them
01426                          * doesn't have a cycling weapon and the target is in the
01427                          * front arc */
01428                         if((!section_hasbusyweap[2] || !section_hasbusyweap[3]) &&
01429                            !is_section_destroyed[2] && !is_section_destroyed[3] &&
01430                            (what_arc & FORWARDARC) && !AnyLimbsRecycling(mech) &&
01431                            (elevation_diff == 0 || elevation_diff == 1)) {
01432 
01433                                 rleg_bth = 0;
01434                                 lleg_bth = 0;
01435 
01436                                 /* Check the RLEG for any crits or weaps cycling */
01437                                 if(!section_hasbusyweap[2]) {
01438                                         if(!OkayCritSectS(RLEG, 0, SHOULDER_OR_HIP))
01439                                                 rleg_bth += 3;
01440                                         if(!OkayCritSectS(RLEG, 1, UPPER_ACTUATOR))
01441                                                 rleg_bth++;
01442                                         if(!OkayCritSectS(RLEG, 2, LOWER_ACTUATOR))
01443                                                 rleg_bth++;
01444                                         if(!OkayCritSectS(RLEG, 3, HAND_OR_FOOT_ACTUATOR))
01445                                                 rleg_bth++;
01446                                 } else {
01447                                         rleg_bth = 99;
01448                                 }
01449 
01450                                 /* Check the LLEG for any crits or weaps cycling */
01451                                 if(!section_hasbusyweap[3]) {
01452                                         if(!OkayCritSectS(LLEG, 0, SHOULDER_OR_HIP))
01453                                                 lleg_bth += 3;
01454                                         if(!OkayCritSectS(LLEG, 1, UPPER_ACTUATOR))
01455                                                 lleg_bth++;
01456                                         if(!OkayCritSectS(LLEG, 2, LOWER_ACTUATOR))
01457                                                 lleg_bth++;
01458                                         if(!OkayCritSectS(LLEG, 3, HAND_OR_FOOT_ACTUATOR))
01459                                                 lleg_bth++;
01460                                 } else {
01461                                         rleg_bth = 99;
01462                                 }
01463 
01464                                 /* Now kick depending on which one would be better 
01465                                  * to kick with */
01466                                 if(rleg_bth <= lleg_bth) {
01467                                         snprintf(buffer, LBUF_SIZE, "r %c%c",
01468                                                          MechID(physical_target)[0],
01469                                                          MechID(physical_target)[1]);
01470                                 } else {
01471                                         snprintf(buffer, LBUF_SIZE, "l %c%c",
01472                                                          MechID(physical_target)[0],
01473                                                          MechID(physical_target)[1]);
01474                                 }
01475                                 mech_kick(autopilot->mynum, mech, buffer);
01476                         }
01477 
01478                         /* Finally try to punch */
01479                         if(((!is_section_destroyed[0] && !section_hasbusyweap[0]) ||
01480                                 (!is_section_destroyed[1] && !section_hasbusyweap[1]))
01481                            && !AnyLimbsRecycling(mech) &&
01482                            (elevation_diff == 0 || elevation_diff == -1)) {
01483 
01484                                 is_rarm_ready = 0;
01485                                 is_larm_ready = 0;
01486 
01487                                 if(!is_section_destroyed[0] &&
01488                                    !section_hasbusyweap[0] &&
01489                                    ((new_arc & FORWARDARC) || (new_arc & RSIDEARC))) {
01490 
01491                                         /* We can use the right arm */
01492                                         is_rarm_ready = 1;
01493                                 }
01494 
01495                                 if(!is_section_destroyed[1] &&
01496                                    !section_hasbusyweap[1] &&
01497                                    ((new_arc & FORWARDARC) || (new_arc & LSIDEARC))) {
01498 
01499                                         /* We can use the left arm */
01500                                         is_larm_ready = 1;
01501                                 }
01502 
01503                                 if(is_rarm_ready == 1 && is_larm_ready == 1) {
01504                                         snprintf(buffer, LBUF_SIZE, "b %c%c",
01505                                                          MechID(target)[0], MechID(target)[1]);
01506                                 } else if(is_rarm_ready == 1) {
01507                                         snprintf(buffer, LBUF_SIZE, "r %c%c",
01508                                                          MechID(target)[0], MechID(target)[1]);
01509                                 } else {
01510                                         snprintf(buffer, LBUF_SIZE, "l %c%c",
01511                                                          MechID(target)[0], MechID(target)[1]);
01512                                 }
01513 
01514                                 /* Now punch */
01515                                 mech_punch(autopilot->mynum, mech, buffer);
01516 
01517                         }
01518 
01519                 } else if((MechType(mech) == CLASS_MECH) &&
01520                                   (MechMove(mech) == MOVE_QUAD)) {
01521 
01522                         /* Quad Mech - Right now only supporting kicking front style for quad */
01523                         /* Remember, the RARM becomes the Front RLEG and the LARM becomes the
01524                          * Front LLEG */
01525 
01526                         /* Find direction of bad guy */
01527                         what_arc =
01528                                 InWeaponArc(mech, MechFX(physical_target),
01529                                                         MechFY(physical_target));
01530 
01531                         /* Check to see what sections are destroyed */
01532                         memset(is_section_destroyed, 0, sizeof(is_section_destroyed));
01533                         is_section_destroyed[0] = SectIsDestroyed(mech, RARM);
01534                         is_section_destroyed[1] = SectIsDestroyed(mech, LARM);
01535                         is_section_destroyed[2] = SectIsDestroyed(mech, RLEG);
01536                         is_section_destroyed[3] = SectIsDestroyed(mech, LLEG);
01537 
01538                         /* Check to see if the sections have a busy weapon */
01539                         memset(section_hasbusyweap, 0, sizeof(section_hasbusyweap));
01540                         section_hasbusyweap[0] = SectHasBusyWeap(mech, RARM);
01541                         section_hasbusyweap[1] = SectHasBusyWeap(mech, LARM);
01542                         //section_hasbusyweap[2] = SectHasBusyWeap(mech, RLEG);
01543                         //section_hasbusyweap[3] = SectHasBusyWeap(mech, LLEG);
01544 
01545                         /* Try and kick but only if we got two legs, one of them
01546                          * doesn't have a cycling weapon and the target is in the
01547                          * front arc */
01548                         if((!section_hasbusyweap[0] || !section_hasbusyweap[0]) &&
01549                            !is_section_destroyed[0] && !is_section_destroyed[1] &&
01550                            !is_section_destroyed[2] && !is_section_destroyed[3] &&
01551                            (what_arc & FORWARDARC) && !AnyLimbsRecycling(mech) &&
01552                            (elevation_diff == 0 || elevation_diff == 1)) {
01553 
01554                                 rleg_bth = 0;
01555                                 lleg_bth = 0;
01556 
01557                                 /* Check the Front Right Leg for any crits or weaps cycling */
01558                                 if(!section_hasbusyweap[0]) {
01559                                         if(!OkayCritSectS(RARM, 0, SHOULDER_OR_HIP))
01560                                                 rleg_bth += 3;
01561                                         if(!OkayCritSectS(RARM, 1, UPPER_ACTUATOR))
01562                                                 rleg_bth++;
01563                                         if(!OkayCritSectS(RARM, 2, LOWER_ACTUATOR))
01564                                                 rleg_bth++;
01565                                         if(!OkayCritSectS(RARM, 3, HAND_OR_FOOT_ACTUATOR))
01566                                                 rleg_bth++;
01567                                 } else {
01568                                         rleg_bth = 99;
01569                                 }
01570 
01571                                 /* Check the Front Left Leg for any crits or weaps cycling */
01572                                 if(!section_hasbusyweap[1]) {
01573                                         if(!OkayCritSectS(LARM, 0, SHOULDER_OR_HIP))
01574                                                 lleg_bth += 3;
01575                                         if(!OkayCritSectS(LARM, 1, UPPER_ACTUATOR))
01576                                                 lleg_bth++;
01577                                         if(!OkayCritSectS(LARM, 2, LOWER_ACTUATOR))
01578                                                 lleg_bth++;
01579                                         if(!OkayCritSectS(LARM, 3, HAND_OR_FOOT_ACTUATOR))
01580                                                 lleg_bth++;
01581                                 } else {
01582                                         rleg_bth = 99;
01583                                 }
01584 
01585                                 /* Now kick depending on which one would be better 
01586                                  * to kick with */
01587                                 if(rleg_bth <= lleg_bth) {
01588                                         snprintf(buffer, LBUF_SIZE, "r %c%c",
01589                                                          MechID(physical_target)[0],
01590                                                          MechID(physical_target)[1]);
01591                                 } else {
01592                                         snprintf(buffer, LBUF_SIZE, "l %c%c",
01593                                                          MechID(physical_target)[0],
01594                                                          MechID(physical_target)[1]);
01595                                 }
01596                                 mech_kick(autopilot->mynum, mech, buffer);
01597                         }
01598 
01599                 } else if(MechType(mech) == CLASS_BSUIT) {
01600 
01601                         /* Are we a BSuit */
01602 
01603                 } else {
01604 
01605                         /* Eventually add code here maybe for other physical attacks for
01606                          * tanks perhaps */
01607 
01608                 }
01609 
01610         }
01611 
01612         /* End of physical attack */
01613         /* Log It */
01614         print_autogun_log(autopilot, "Autogun - End Physical Attack Stage");
01615 
01616         /* Now we mow down our target */
01617 
01618         /* Get our current target */
01619         /* Check to make sure we didn't kill it with physical attack
01620          * or something */
01621         if(!(target = getMech(autopilot->target))) {
01622 
01623                 /* There were no valid targets so
01624                  * rerun autogun */
01625 
01626                 /* Reset the AI */
01627                 autopilot->target = -1;
01628                 autopilot->target_score = 0;
01629 
01630         /* Log It */
01631                 print_autogun_log(autopilot, "Autogun - No valid current target");
01632                 print_autogun_log(autopilot, "Autogun Event Finished");
01633                 return;
01634 
01635         } else if(Destroyed(target) || (target->mapindex != mech->mapindex)) {
01636 
01637                 /* Target is either dead or not on the map anymore */
01638                 autopilot->target = -1;
01639                 autopilot->target_score = 0;
01640 
01641         /* Log it */
01642                 print_autogun_log(autopilot, "Autogun - Target Gone");
01643                 print_autogun_log(autopilot, "Autogun Event Finished");
01644                 return;
01645         }
01646 
01647         /* Log It */
01648         print_autogun_log(autopilot, "Autogun - Starting Weapon Attack Phase");
01649 
01650         /* Get range from mech to current target */
01651         range = FindHexRange(MechFX(mech), MechFY(mech),
01652                                                  MechFX(target), MechFY(target));
01653 
01654         /* This probably unnecessary but since it doesn't
01655          * take much to calc range it should be ok for
01656          * testing for now */
01657         if((range >= (float) AUTO_GUN_MAX_RANGE) && !AssignedTarget(autopilot)) {
01658 
01659                 /* Target is to far - reset */
01660                 autopilot->target = -1;
01661                 autopilot->target_score = 0;
01662 
01663 
01664                 /* Log it */
01665                 print_autogun_log(autopilot, "Autogun - Target out of range");
01666                 print_autogun_log(autopilot, "Autogun Event Finished");
01667                 return;
01668         }
01669 
01670         /* Cycle through Guns while watching the heat */
01671         if((range < (float) AUTO_GUN_MAX_RANGE)
01672            && autopilot->profile[(int) range]) {
01673 
01674                 /* Ok we got weapons lets use them */
01675 
01676                 /* Reset heat counter to current heat */
01677                 accumulate_heat = MechWeapHeat(mech);
01678 
01679                 /* If the unit is moving need to account for the heat of that as well */
01680                 if((MechType(mech) == CLASS_MECH) && (fabs(MechSpeed(mech)) > 0.0)) {
01681 
01682                         maxspeed = MMaxSpeed(mech);
01683                         if(IsRunning(MechDesiredSpeed(mech), maxspeed))
01684                                 accumulate_heat += 2;
01685                         else
01686                                 accumulate_heat += 1;
01687                 }
01688 
01689                 /* Get first weapon */
01690                 temp_weapon_node =
01691                         (weapon_node *) rb_search(autopilot->profile[(int) range],
01692                                                                           SEARCH_LAST, NULL);
01693 
01694                 while (temp_weapon_node) {
01695 
01696                         /* Check to see if the weapon even works */
01697                         if(WeaponIsNonfunctional(mech, temp_weapon_node->section,
01698                                                                          temp_weapon_node->critical,
01699                                                                          GetWeaponCrits(mech,
01700                                                                                                         Weapon2I
01701                                                                                                         (temp_weapon_node->
01702                                                                                                          weapon_db_number))) >
01703                            0) {
01704 
01705                                 /* Weapon Doesn't work so go to next one */
01706                                 temp_weapon_node =
01707                                         (weapon_node *) rb_search(autopilot->profile[(int) range],
01708                                                                                           SEARCH_PREV,
01709                                                                                           &temp_weapon_node->
01710                                                                                           range_scores[(int) range]);
01711 
01712                                 continue;
01713                         }
01714 
01715                         /* Check to see if its cycling */
01716                         if(WpnIsRecycling
01717                            (mech, temp_weapon_node->section,
01718                                 temp_weapon_node->critical)) {
01719 
01720                                 /* Go to the next one */
01721                                 temp_weapon_node =
01722                                         (weapon_node *) rb_search(autopilot->profile[(int) range],
01723                                                                                           SEARCH_PREV,
01724                                                                                           &temp_weapon_node->
01725                                                                                           range_scores[(int) range]);
01726 
01727                                 continue;
01728                         }
01729 
01730                         if(IsAMS(temp_weapon_node->weapon_db_number)) {
01731 
01732                                 /* Ok its an AMS so go to next weapon */
01733                                 temp_weapon_node =
01734                                         (weapon_node *) rb_search(autopilot->profile[(int) range],
01735                                                                                           SEARCH_PREV,
01736                                                                                           &temp_weapon_node->
01737                                                                                           range_scores[(int) range]);
01738                                 continue;
01739                         }
01740 
01741                         /* Check heat levels, since the heat isn't updated untill we're done
01742                          * we have to manage the heat ourselves */
01744                         if((MechType(mech) == CLASS_MECH) && (((float) accumulate_heat +
01745                                                                                                    (float)
01746                                                                                                    MechWeapons
01747                                                                                                    [temp_weapon_node->
01748                                                                                                         weapon_db_number].heat -
01749                                                                                                    (float)
01750                                                                                                    MechMinusHeat(mech)) >
01751                                                                                                   AUTO_GUN_MAX_HEAT)) {
01752 
01753                                 /* Would make ourselves to hot to fire this gun */
01754                                 temp_weapon_node =
01755                                         (weapon_node *) rb_search(autopilot->profile[(int) range],
01756                                                                                           SEARCH_PREV,
01757                                                                                           &temp_weapon_node->
01758                                                                                           range_scores[(int) range]);
01759 
01760                                 continue;
01761                         }
01762 
01763                         /* Ok passed the checks now setup the arcs and see if we can fire it */
01764 
01765                         /* Ok the rest depends on what type of unit we driving */
01766                         if((MechType(mech) == CLASS_MECH) &&
01767                            (MechMove(mech) == MOVE_BIPED)) {
01768 
01769                                 /* Center ourself and get target arc */
01770                                 MechStatus(mech) &= ~(TORSO_RIGHT | TORSO_LEFT);
01771                                 if(MechSpecials(mech) & FLIPABLE_ARMS) {
01772 
01773                                         /* Center the arms if need be */
01774                                         MechStatus(mech) &= ~(FLIPPED_ARMS);
01775                                 }
01776 
01777                                 /* Get Target Arc */
01778                                 what_arc = InWeaponArc(mech, MechFX(target), MechFY(target));
01779 
01780                                 /* Now go through the various arcs and see if we
01781                                  * need to flip arm or rotorso or something */
01782                                 if(what_arc & REARARC) {
01783 
01784                                         if(temp_weapon_node->section == LARM ||
01785                                            temp_weapon_node->section == RARM) {
01786 
01787                                                 /* First see if we can flip arms */
01788                                                 if(MechSpecials(mech) & FLIPABLE_ARMS) {
01789 
01790                                                         /* Flip the arms */
01791                                                         MechStatus(mech) |= FLIPPED_ARMS;
01792 
01793                                                 } else {
01794 
01795                                                         /* Now see if we can rotatorso */
01796 
01797                                                         /* Find out if it would be better to
01798                                                          * rotate left or right */
01799                                                         relative_bearing = MechFacing(mech) -
01800                                                                 FindBearing(MechFX(mech), MechFY(mech),
01801                                                                                         MechFX(target), MechFY(target));
01802 
01803                                                         if(relative_bearing > 120
01804                                                            && relative_bearing < 180
01805                                                            && temp_weapon_node->section == RARM) {
01806 
01807                                                                 /* Rotate Right */
01808                                                                 MechStatus(mech) |= TORSO_RIGHT;
01809 
01810                                                         } else if(relative_bearing > 180
01811                                                                           && relative_bearing < 240
01812                                                                           && temp_weapon_node->section == LARM) {
01813 
01814                                                                 /* Rotate Left */
01815                                                                 MechStatus(mech) |= TORSO_LEFT;
01816 
01817                                                         } else {
01818 
01819                                                                 /* Can't do anything so go to next weapon */
01820                                                                 temp_weapon_node =
01821                                                                         (weapon_node *) rb_search(autopilot->
01822                                                                                                                           profile[(int)
01823                                                                                                                                           range],
01824                                                                                                                           SEARCH_PREV,
01825                                                                                                                           &temp_weapon_node->
01826                                                                                                                           range_scores[(int) range]);
01827 
01828                                                                 continue;
01829 
01830                                                         }
01831 
01832                                                 }
01833 
01834                                         } else
01835                                                 if(!
01836                                                    (GetPartFireMode
01837                                                         (mech, temp_weapon_node->section,
01838                                                          temp_weapon_node->critical) & REAR_MOUNT)) {
01839 
01840                                                 /* Weapon is forward torso or leg mounted weapon
01841                                                  * so no way to shoot with */
01842                                                 temp_weapon_node =
01843                                                         (weapon_node *) rb_search(autopilot->
01844                                                                                                           profile[(int) range],
01845                                                                                                           SEARCH_PREV,
01846                                                                                                           &temp_weapon_node->
01847                                                                                                           range_scores[(int)
01848                                                                                                                                    range]);
01849 
01850                                                 continue;
01851 
01852                                         }
01853 
01854                                         /* ELSE: Weapon is rear mounted so don't need to 
01855                                          * do anything */
01856 
01857                                 } else if(what_arc & LSIDEARC) {
01858 
01859                                         if(temp_weapon_node->section == RLEG ||
01860                                            temp_weapon_node->section == LLEG) {
01861 
01862                                                 /* No way can we hit him with leg mounted
01863                                                  * weapons so lets go to next one */
01864                                                 temp_weapon_node =
01865                                                         (weapon_node *) rb_search(autopilot->
01866                                                                                                           profile[(int) range],
01867                                                                                                           SEARCH_PREV,
01868                                                                                                           &temp_weapon_node->
01869                                                                                                           range_scores[(int)
01870                                                                                                                                    range]);
01871 
01872                                                 continue;
01873 
01874                                         }
01875 
01876                                         /* Rotate torso left */
01877                                         MechStatus(mech) |= TORSO_LEFT;
01878 
01879                                 } else if(what_arc & RSIDEARC) {
01880 
01881                                         if(temp_weapon_node->section == RLEG ||
01882                                            temp_weapon_node->section == LLEG) {
01883 
01884                                                 /* No way can we hit him with leg mounted
01885                                                  * weapons so lets go to next one */
01886                                                 temp_weapon_node =
01887                                                         (weapon_node *) rb_search(autopilot->
01888                                                                                                           profile[(int) range],
01889                                                                                                           SEARCH_PREV,
01890                                                                                                           &temp_weapon_node->
01891                                                                                                           range_scores[(int)
01892                                                                                                                                    range]);
01893 
01894                                                 continue;
01895 
01896                                         }
01897 
01898                                         /* Rotate torso right */
01899                                         MechStatus(mech) |= TORSO_RIGHT;
01900 
01901                                 } else {
01902 
01903                                         if(GetPartFireMode(mech, temp_weapon_node->section,
01904                                                                            temp_weapon_node->
01905                                                                            critical) & REAR_MOUNT) {
01906 
01907                                                 /* No way can we hit the guy with a rear
01908                                                  * gun so lets go to next one */
01909                                                 temp_weapon_node =
01910                                                         (weapon_node *) rb_search(autopilot->
01911                                                                                                           profile[(int) range],
01912                                                                                                           SEARCH_PREV,
01913                                                                                                           &temp_weapon_node->
01914                                                                                                           range_scores[(int)
01915                                                                                                                                    range]);
01916 
01917                                                 continue;
01918 
01919                                         }
01920 
01921                                 }
01922 
01923                         } else if((MechType(mech) == CLASS_MECH) &&
01924                                           (MechMove(mech) == MOVE_QUAD)) {
01925 
01926                                 /* Get Target Arc */
01927                                 what_arc = InWeaponArc(mech, MechFX(target), MechFY(target));
01928 
01929                                 if(what_arc & REARARC) {
01930 
01931                                         if(!(GetPartFireMode(mech, temp_weapon_node->section,
01932                                                                                  temp_weapon_node->
01933                                                                                  critical) & REAR_MOUNT)) {
01934 
01935                                                 /* Weapon is not rear mounted so skip it and
01936                                                  * go to the next weapon */
01937                                                 temp_weapon_node =
01938                                                         (weapon_node *) rb_search(autopilot->
01939                                                                                                           profile[(int) range],
01940                                                                                                           SEARCH_PREV,
01941                                                                                                           &temp_weapon_node->
01942                                                                                                           range_scores[(int)
01943                                                                                                                                    range]);
01944 
01945                                                 continue;
01946 
01947                                         }
01948 
01949                                 } else if(what_arc & FORWARDARC) {
01950 
01951                                         if(GetPartFireMode(mech, temp_weapon_node->section,
01952                                                                            temp_weapon_node->
01953                                                                            critical) & REAR_MOUNT) {
01954 
01955                                                 /* Weapon is rear mounted so skip it and
01956                                                  * go to the next weapon */
01957                                                 temp_weapon_node =
01958                                                         (weapon_node *) rb_search(autopilot->
01959                                                                                                           profile[(int) range],
01960                                                                                                           SEARCH_PREV,
01961                                                                                                           &temp_weapon_node->
01962                                                                                                           range_scores[(int)
01963                                                                                                                                    range]);
01964 
01965                                                 continue;
01966 
01967                                         }
01968 
01969                                 } else {
01970 
01971                                         /* The attacker is in a zone we can't possibly
01972                                          * shoot into, so just go to next weapon */
01973                                         temp_weapon_node =
01974                                                 (weapon_node *) rb_search(autopilot->
01975                                                                                                   profile[(int) range],
01976                                                                                                   SEARCH_PREV,
01977                                                                                                   &temp_weapon_node->
01978                                                                                                   range_scores[(int) range]);
01979 
01980                                         continue;
01981 
01982                                 }
01983 
01984                         } else if((MechType(mech) == CLASS_VEH_GROUND) ||
01985                                           (MechType(mech) == CLASS_VEH_NAVAL)) {
01986 
01987                                 /* Get Target Arc */
01988                                 what_arc = InWeaponArc(mech, MechFX(target), MechFY(target));
01989 
01990                                 /* Check if turret exists and weapon is there */
01991                                 if(GetSectInt(mech, TURRET)
01992                                    && temp_weapon_node->section == TURRET) {
01993 
01994                                         /* Rotate Turret and nail the guy */
01995                                         if(!(MechTankCritStatus(mech) & TURRET_JAMMED) &&
01996                                            !(MechTankCritStatus(mech) & TURRET_LOCKED) &&
01997                                            (AcceptableDegree
01998                                                 (MechTurretFacing(mech) + MechFacing(mech)) !=
01999                                                 FindBearing(MechFX(mech), MechFY(mech),
02000                                                                         MechFX(target), MechFY(target)))) {
02001 
02002                                                 snprintf(buffer, LBUF_SIZE, "%d",
02003                                                                  FindBearing(MechFX(mech), MechFY(mech),
02004                                                                                          MechFX(target), MechFY(target)));
02005                                                 mech_turret(autopilot->mynum, mech, buffer);
02006                                         }
02007 
02008                                 } else {
02009 
02010                                         /* Check if in arc of weapon */
02011                                         if(!IsInWeaponArc(mech, MechFX(target), MechFY(target),
02012                                                                           temp_weapon_node->section,
02013                                                                           temp_weapon_node->critical)) {
02014 
02015                                                 /* Not in the arc so lets go to the next weapon */
02016                                                 temp_weapon_node =
02017                                                         (weapon_node *) rb_search(autopilot->
02018                                                                                                           profile[(int) range],
02019                                                                                                           SEARCH_PREV,
02020                                                                                                           &temp_weapon_node->
02021                                                                                                           range_scores[(int)
02022                                                                                                                                    range]);
02023 
02024                                                 continue;
02025 
02026                                         }
02027 
02028                                 }
02029 
02030                         } else {
02031 
02032                                 /* We're either an aero, ds, bsuit, mechwarrior or vtol
02033                                  *
02034                                  * Still need to add code for them */
02035 
02036                         }
02037 
02038                         /* Done moving around, fire the weapon */
02039                         snprintf(buffer, LBUF_SIZE, "%d",
02040                                          temp_weapon_node->weapon_number);
02041                         mech_fireweapon(autopilot->mynum, mech, buffer);
02042 
02043                         /* Log It */
02044                         print_autogun_log(autopilot, "Autogun - Fired Weapon #%d "
02045                                                           "at target #%d",
02046                                                           temp_weapon_node->weapon_number,
02047                                                           autopilot->target);
02048 
02049                         /* Ok check to see if weapon was fired if so account for the
02050                          * heat */
02051                         if(WpnIsRecycling
02052                            (mech, temp_weapon_node->section,
02053                                 temp_weapon_node->critical)) {
02054                                 accumulate_heat +=
02055                                         MechWeapons[temp_weapon_node->weapon_db_number].heat;
02056                         }
02057 
02058                         /* Ok go to the next weapon */
02059                         temp_weapon_node =
02060                                 (weapon_node *) rb_search(autopilot->profile[(int) range],
02061                                                                                   SEARCH_PREV,
02062                                                                                   &temp_weapon_node->
02063                                                                                   range_scores[(int) range]);
02064 
02065                 }                                               /* End of cycling through weapons */
02066 
02067         }
02068 
02069         /* Log It */
02070         print_autogun_log(autopilot, "Autogun - End Weapon Attack Phase");
02071 
02072         /* Setup chasetarg 
02073          * 
02074          * Since chasetarget uses follow but we don't want follow getting
02075          * messed up if its following a normal target.  We define our own
02076          * follow (basicly its follow but with the command name chasetarget */
02077 
02078         /* Get the first command, if its chasetarget or there is no command
02079          * check to see if we need to update chasetarget, otherwise means
02080          * AI is doing something else important so don't try to chase
02081          * anything */
02082 
02083         if(ChasingTarget(autopilot)) {
02084 
02085                 /* Reset the flag */
02086                 do_chasetarget = 0;
02087 
02088                 /* Get the first command's enum and check it */
02089                 switch (auto_get_command_enum(autopilot, 1)) {
02090 
02091                 case GOAL_CHASETARGET:
02092 
02093                         /* Ok its our command so we can change it */
02094                         do_chasetarget = 1;
02095                         break;
02096 
02097                 case -1:
02098 
02099                         /* No current commands so we can do our chasetarget */
02100                         do_chasetarget = 1;
02101                         break;
02102 
02103                         /* ALl the other stuff we don't want to mess with */
02104                 default:
02105 
02106                         /* Reset the chase values */
02107                         autopilot->chase_target = -10;
02108                         autopilot->chasetarg_update_tick =
02109                                 AUTOPILOT_CHASETARG_UPDATE_TICK;
02110                         autopilot->follow_update_tick = AUTOPILOT_FOLLOW_UPDATE_TICK;
02111                         break;
02112 
02113                 }
02114 
02115                 /* Check the flag */
02116                 if(do_chasetarget) {
02117 
02118                         /* Ok lets chase the guy */
02119 
02120                         /* First see if we need to update */
02121                         if((autopilot->target != autopilot->chase_target) ||
02122                            (autopilot->chasetarg_update_tick >=
02123                                 AUTOPILOT_CHASETARG_UPDATE_TICK)) {
02124 
02125                                 /* Tell the AI to follow its target */
02126                                 /* Basicly remove all the commands, add in
02127                                  * autogun and follow and engage */
02128 
02129                                 /* Let the AI know we chasing this guy */
02130                                 autopilot->chase_target = autopilot->target;
02131 
02132                                 /* Reset the tickers */
02133                                 autopilot->chasetarg_update_tick = 0;
02134                                 autopilot->follow_update_tick = AUTOPILOT_FOLLOW_UPDATE_TICK;
02135 
02136                                 /* Reset the AI */
02137                                 auto_disengage(autopilot->mynum, autopilot, "");
02138                                 auto_delcommand(autopilot->mynum, autopilot, "-1");
02139 
02140                                 /* Add in autogun and follow and engage */
02141                                 if(AssignedTarget(autopilot) && autopilot->target != -1) {
02142                                         snprintf(buffer, LBUF_SIZE, "autogun target %d",
02143                                                          autopilot->target);
02144                                 } else {
02145                                         snprintf(buffer, LBUF_SIZE, "autogun on");
02146                                 }
02147 
02148                                 auto_addcommand(autopilot->mynum, autopilot, buffer);
02149                                 snprintf(buffer, LBUF_SIZE, "chasetarget %d",
02150                                                  autopilot->target);
02151                                 auto_addcommand(autopilot->mynum, autopilot, buffer);
02152                                 auto_engage(autopilot->mynum, autopilot, "");
02153 
02154                                 /* Log it */
02155                                 print_autogun_log(autopilot, "Autogun Event Finished");
02156 
02157                                 return;
02158 
02159                         } else {
02160 
02161                                 /* Update the ticker */
02162                                 autopilot->chasetarg_update_tick++;
02163 
02164                                 /* Check to see if we need to turn to face the guy by
02165                                  * generating our target hex and seeing if we are in that
02166                                  * hex then face the bad guy */
02167                                 if((target = getMech(autopilot->target)) &&
02168                                    (!Destroyed(target)
02169                                         && (target->mapindex == mech->mapindex))) {
02170 
02171                                         /* Generate the target hex */
02174                                         FindXY(MechFX(target), MechFY(target),
02175                                                    MechFacing(target) + autopilot->ofsx,
02176                                                    autopilot->ofsy, &fx, &fy);
02177 
02178                                         RealCoordToMapCoord(&x, &y, fx, fy);
02179 
02180                                         /* Make sure the hex is sane */
02181                                         if(x < 0 || y < 0 || x >= map->map_width
02182                                            || y >= map->map_height) {
02183 
02184                                                 /* Bad Target Hex */
02185 
02186                                                 /* Reset the hex to the Target's current hex */
02187                                                 x = MechX(target);
02188                                                 y = MechY(target);
02189 
02190                                         }
02191 
02192                                         /* Are we in the target hex and is the target not moving */
02193                                         if((MechX(mech) == x) && (MechY(mech) == y)
02194                                            && (MechSpeed(target) < 0.5)) {
02195 
02196                                                 /* Get his bearing and face him */
02197                                                 MapCoordToRealCoord(x, y, &fx, &fy);
02198 
02199                                                 /* If we're not facing him, turn towards him */
02200                                                 if(MechDesiredFacing(mech) !=
02201                                                    FindBearing(MechFX(mech), MechFY(mech), fx, fy)) {
02202 
02203                                                         snprintf(buffer, LBUF_SIZE, "%d",
02204                                                                          FindBearing(MechFX(mech), MechFY(mech),
02205                                                                                                  fx, fy));
02206                                                         mech_heading(autopilot->mynum, mech, buffer);
02207 
02208                                                 }
02209                                                 /* Turn towards him */
02210                                         }
02211                                         /* Is he moving and are we in target hex */
02212                                 }
02213                                 /* Do we need to turn towards him */
02214                         }                                       /* Do we need to update */
02215 
02216                 }
02217                 /* Do we run chasetarget */
02218         }
02219 
02220         /* Is chasetarget on */
02221         /* Make sure multiple instances of autogun aren't running */
02222 
02223         /* Log it */
02224         print_autogun_log(autopilot, "Autogun Event Finished");
02225 
02226         /* The End */
02227 }

void auto_init ( AUTO autopilot,
MECH mech 
)

Todo:
{Make this smarter and check some of these}

Definition at line 659 of file autopilot_core.c.

References AUTO::auto_cdist, AUTO::auto_cmode, AUTO::auto_fweight, AUTO::auto_goweight, AUTO_GUN_UPDATE_TICK, AUTO::auto_nervous, AUTOPILOT_CHASETARG_UPDATE_TICK, AUTOPILOT_FOLLOW_UPDATE_TICK, AUTO::chase_target, AUTO::chasetarg_update_tick, AUTO::flags, AUTO::follow_update_tick, AUTO::ofsx, AUTO::ofsy, AUTO::speed, AUTO::target, AUTO::target_score, AUTO::target_threshold, and AUTO::target_update_tick.

Referenced by auto_engage(), and auto_radio_command_reset().

00660 {
00661 
00662         autopilot->ofsx = 0;            /* Positional - angle */
00663         autopilot->ofsy = 0;            /* Positional - distance */
00664         autopilot->auto_cmode = 1;      /* CHARGE! */
00665         autopilot->auto_cdist = 2;      /* Attempt to avoid kicking distance */
00666         autopilot->auto_nervous = 0;
00667         autopilot->auto_goweight = 44;  /* We're mainly concentrating on fighting */
00668         autopilot->auto_fweight = 55;
00669         autopilot->speed = 100;         /* Reset to full speed */
00670         autopilot->flags = 0;
00671 
00672         /* Target Stuff */
00673         autopilot->target = -2;
00674         autopilot->target_score = 0;
00675         autopilot->target_threshold = 50;
00676         autopilot->target_update_tick = AUTO_GUN_UPDATE_TICK;
00677 
00678         /* Follow & Chase target stuff */
00679         autopilot->chase_target = -10;
00680         autopilot->chasetarg_update_tick = AUTOPILOT_CHASETARG_UPDATE_TICK;
00681         autopilot->follow_update_tick = AUTOPILOT_FOLLOW_UPDATE_TICK;
00682 
00683 }

void auto_leave_event ( MUXEVENT muxevent  ) 

Definition at line 2103 of file autopilot_commands.c.

References ai_set_speed(), auto_command_startup(), auto_get_command_arg(), auto_get_command_enum(), auto_goto_next_command(), auto_leave_event(), AUTOEVENT, AUTOPILOT_LEAVE_TICK, AUTOPILOT_NC_DELAY, AUTOPILOT_STARTUP_TICK, CLASS_MECH, CountDestroyedLegs(), my_event_type::data, my_event_type::data2, Destroyed, EVENT_AUTOLEAVE, Fallen, getMap(), GOAL_LEAVEBASE, IsAuto(), IsMech, Location, AUTO::mapindex, MECH::mapindex, MBUF_SIZE, mech_stand(), MechType, AUTO::mymech, AUTO::mymechnum, MECH::mynum, AUTO::mynum, Readnum, SendAI, speed_up_if_neccessary(), Standing, Started, Starting, and update_wanted_heading().

Referenced by auto_com_event(), and auto_leave_event().

02104 {
02105 
02106         AUTO *autopilot = (AUTO *) muxevent->data;
02107         MECH *mech = autopilot->mymech;
02108         MAP *map;
02109 
02110         int dir;
02111         int reset_mapindex = (int) muxevent->data2;
02112         char *argument;
02113         char error_buf[MBUF_SIZE];
02114 
02115         if(!IsMech(mech->mynum) || !IsAuto(autopilot->mynum))
02116                 return;
02117 
02118         /* Are we in the mech we're supposed to be in */
02119         if(Location(autopilot->mynum) != autopilot->mymechnum)
02120                 return;
02121 
02122         /* Our mech is destroyed */
02123         if(Destroyed(mech))
02124                 return;
02125 
02126         /* Check to make sure the first command in the queue is this one */
02127         if(auto_get_command_enum(autopilot, 1) != GOAL_LEAVEBASE)
02128                 return;
02129 
02130         /* Get the Map */
02131         if(!(map = getMap(autopilot->mapindex))) {
02132 
02133                 /* Bad Map */
02134                 snprintf(error_buf, MBUF_SIZE, "Internal AI Error - Attempting to"
02135                                  " leavebase with AI #%d but AI is not on a valid"
02136                                  " Map (#%d).", autopilot->mynum, autopilot->mapindex);
02137                 SendAI(error_buf);
02138 
02139                 auto_goto_next_command(autopilot, AUTOPILOT_NC_DELAY);
02140                 return;
02141 
02142         }
02143 
02144         /* Make sure mech is started */
02145         if(!Started(mech)) {
02146 
02147                 /* Startup */
02148                 if(!Starting(mech))
02149                         auto_command_startup(autopilot, mech);
02150 
02151                 /* Run this command after startup */
02152                 AUTOEVENT(autopilot, EVENT_AUTOLEAVE, auto_leave_event,
02153                                   AUTOPILOT_STARTUP_TICK, reset_mapindex);
02154                 return;
02155         }
02156 
02157         /* Ok not standing so lets do that first */
02158         if(MechType(mech) == CLASS_MECH && Fallen(mech) &&
02159            !(CountDestroyedLegs(mech) > 0)) {
02160 
02161                 if(!Standing(mech))
02162                         mech_stand(autopilot->mynum, mech, "");
02163 
02164                 /* Ok lets run this command again */
02165                 AUTOEVENT(autopilot, EVENT_AUTOLEAVE, auto_leave_event,
02166                                   AUTOPILOT_NC_DELAY, reset_mapindex);
02167                 return;
02168         }
02169 
02172         /* Do we need to reset the mapindex value ? */
02173         if(reset_mapindex) {
02174                 autopilot->mapindex = mech->mapindex;
02175         }
02176 
02177         /* Get the argument - direction */
02178         if(!(argument = auto_get_command_arg(autopilot, 1, 1))) {
02179 
02180                 /* Ok bad argument - means the command is messed up
02181                  * so should go to next one */
02182                 snprintf(error_buf, MBUF_SIZE, "Internal AI Error - Attempting to"
02183                                  " leavebase with AI #%d but was given bad argument"
02184                                  " defaulting to direction = 0", autopilot->mynum);
02185                 SendAI(error_buf);
02186 
02187                 dir = 0;
02188 
02189         } else if(Readnum(dir, argument)) {
02190 
02191                 snprintf(error_buf, MBUF_SIZE, "Internal AI Error - Attempting to"
02192                                  " leavebase with AI #%d but was given bad argument '%s'"
02193                                  " defaulting to direction = 0", autopilot->mynum, argument);
02194                 SendAI(error_buf);
02195 
02196                 dir = 0;
02197 
02198         }
02199         free(argument);
02200 
02201         if(mech->mapindex != autopilot->mapindex) {
02202 
02203                 /* We're elsewhere, pal! */
02204                 autopilot->mapindex = mech->mapindex;
02205                 ai_set_speed(mech, autopilot, 0);
02206                 auto_goto_next_command(autopilot, AUTOPILOT_NC_DELAY);
02207                 return;
02208         }
02209 
02210         /* Still not out yet so keep trying */
02211         speed_up_if_neccessary(autopilot, mech, -1, -1, dir);
02212         update_wanted_heading(autopilot, mech, dir);
02213         AUTOEVENT(autopilot, EVENT_AUTOLEAVE, auto_leave_event,
02214                           AUTOPILOT_LEAVE_TICK, 0);
02215 }

void auto_listcommands ( dbref  player,
void *  data,
char *  buffer 
)

Definition at line 532 of file autopilot_core.c.

References addline, auto_show_command(), c, AUTO::commands, dllist_get_node(), dllist_size(), AUTO::flags, KillCoolMenu(), Location, AUTO::mapindex, MBUF_SIZE, AUTO::mymechnum, AUTO::mynum, Name(), ShowCoolMenu(), AUTO::speed, and vsi.

00533 {
00534 
00535         AUTO *autopilot = (AUTO *) data;
00536         coolmenu *c = NULL;
00537         char buf[MBUF_SIZE];
00538         int i, count = 0;
00539 
00540         addline();
00541 
00542         snprintf(buf, MBUF_SIZE, "Autopilot data for %s", Name(autopilot->mynum));
00543         vsi(buf);
00544 
00545         snprintf(buf, MBUF_SIZE, "Controling unit %s",
00546                          Name(Location(autopilot->mynum)));
00547         vsi(buf);
00548 
00549         addline();
00550 
00551         snprintf(buf, MBUF_SIZE, "MyRef: #%d  MechRef: #%d  MapIndex: #%d  "
00552                          "FSpeed: %d %% (Flag:%d)", autopilot->mynum,
00553                          autopilot->mymechnum, autopilot->mapindex, autopilot->speed,
00554                          autopilot->flags);
00555         vsi(buf);
00556 
00557         addline();
00558 
00559         if(dllist_size(autopilot->commands)) {
00560 
00561                 for(i = 1; i <= dllist_size(autopilot->commands); i++) {
00562                         snprintf(buf, MBUF_SIZE, "#%-3d %s", i,
00563                                          auto_show_command((command_node *)
00564                                                                            dllist_get_node(autopilot->commands,
00565                                                                                                            i)));
00566                         vsi(buf);
00567                 }
00568 
00569         } else {
00570                 vsi("No commands have been queued to date.");
00571         }
00572 
00573         addline();
00574         ShowCoolMenu(player, c);
00575         KillCoolMenu(c);
00576 }

void auto_load_commands ( FILE *  file,
AUTO autopilot 
)

Definition at line 211 of file autopilot_core.c.

References AI_COMMAND_DLLIST_END, AI_COMMAND_DLLIST_START, auto_read_command_node(), CHELO, AUTO::commands, dllist_create_list(), dllist_create_node(), dllist_insert_end(), and AUTO::mynum.

00212 {
00213 
00214         int i;                                          /* Our Counter */
00215         unsigned char tmpb;                     /* Our temp int we use when reading */
00216         unsigned int size;                      /* The size of our command list */
00217 
00218         dllist_node *temp_dllist_node;
00219         command_node *temp_command_node;
00220 
00221         /* Alloc a dllist to the AI for commands */
00222         autopilot->commands = dllist_create_list();
00223 
00224         /* If we can't even read the file don't bother
00225          * with the rest */
00226         if(feof(file))
00227                 return;
00228 
00229         /* Loop for the beginning tag */
00230         fread(&tmpb, 1, 1, file);
00231         if(tmpb != AI_COMMAND_DLLIST_START) {
00232                 fprintf(stderr, "Unable to locate START for reading data"
00233                                 " for AI #%d\n", autopilot->mynum);
00234                 fflush(stderr);
00235                 exit(1);
00236         }
00237 
00238         /* Read in size of dllist */
00239         CHELO(&size, sizeof(size), 1, file);
00240 
00241         /* if size is bigger then zero means we have to read
00242          * in some command nodes */
00243         if(size > 0) {
00244 
00245                 /* Loop through the list and add the nodes */
00246                 for(i = 1; i <= size; i++) {
00247 
00248                         temp_command_node = auto_read_command_node(file);
00249                         temp_dllist_node = dllist_create_node(temp_command_node);
00250                         dllist_insert_end(autopilot->commands, temp_dllist_node);
00251 
00252                 }
00253 
00254         }
00255 
00256         /* Look for the end tag */
00257         fread(&tmpb, 1, 1, file);
00258         if(tmpb != AI_COMMAND_DLLIST_END) {
00259                 fprintf(stderr, "Unable to locate END for reading data"
00260                                 " for AI #%d\n", autopilot->mynum);
00261                 fflush(stderr);
00262                 exit(1);
00263         }
00264 
00265         return;
00266 
00267 }

void auto_newautopilot ( dbref  key,
void **  data,
int  selector 
)

Definition at line 882 of file autopilot_core.c.

References AUTO::astar_path, auto_destroy_astar_path(), auto_destroy_command_node(), auto_destroy_weaplist(), AUTO_PROFILE_MAX_SIZE, auto_stop_pilot(), AUTO::commands, dllist_create_list(), dllist_destroy_list(), dllist_head(), dllist_remove(), dllist_size(), getMech(), MechAuto, AUTO::mymechnum, AUTO::mynum, AUTO::profile, rb_destroy(), SPECIAL_ALLOC, SPECIAL_FREE, AUTO::speed, and AUTO::weaplist.

00883 {
00884 
00885         AUTO *autopilot = *data;
00886         MECH *mech;
00887         command_node *temp;
00888         int i;
00889 
00890         switch (selector) {
00891         case SPECIAL_ALLOC:
00892 
00893                 /* Allocate the command list */
00894                 autopilot->commands = dllist_create_list();
00895 
00896                 /* Make sure certain things are set NULL */
00897                 autopilot->astar_path = NULL;
00898                 autopilot->weaplist = NULL;
00899 
00900                 for(i = 0; i < AUTO_PROFILE_MAX_SIZE; i++) {
00901                         autopilot->profile[i] = NULL;
00902                 }
00903 
00904                 /* And some things not set null */
00905                 autopilot->speed = 100;
00906 
00907                 break;
00908 
00909         case SPECIAL_FREE:
00910 
00911                 /* Make sure the AI is stopped */
00912                 auto_stop_pilot(autopilot);
00913 
00914                 /* Go through the list and remove any leftover nodes */
00915                 while (dllist_size(autopilot->commands)) {
00916 
00917                         /* Remove the first node on the list and get the data
00918                          * from it */
00919                         temp = (command_node *) dllist_remove(autopilot->commands,
00920                                                                                                   dllist_head(autopilot->
00921                                                                                                                           commands));
00922 
00923                         /* Destroy the command node */
00924                         auto_destroy_command_node(temp);
00925 
00926                 }
00927 
00928                 /* Destroy the list */
00929                 dllist_destroy_list(autopilot->commands);
00930                 autopilot->commands = NULL;
00931 
00932                 /* Destroy any astar path list thats on the AI */
00933                 auto_destroy_astar_path(autopilot);
00934 
00935                 /* Destroy profile array */
00936                 for(i = 0; i < AUTO_PROFILE_MAX_SIZE; i++) {
00937                         if(autopilot->profile[i]) {
00938                                 rb_destroy(autopilot->profile[i]);
00939                         }
00940                         autopilot->profile[i] = NULL;
00941                 }
00942 
00943                 /* Destroy weaponlist */
00944                 auto_destroy_weaplist(autopilot);
00945 
00946                 /* Finally reset the AI value on its unit if
00947                  * it needs to */
00948                 if((mech = getMech(autopilot->mymechnum))) {
00949 
00950                         /* Just incase another AI has taken over */
00951                         if(MechAuto(mech) == autopilot->mynum) {
00952                                 MechAuto(mech) = -1;
00953                         }
00954 
00955                 }
00956 
00957                 break;
00958 
00959         }
00960 
00961 }

void auto_parse_command ( AUTO autopilot,
MECH mech,
int  chn,
char *  buffer 
)

Definition at line 1232 of file autopilot_radio.c.

References args, auto_cmds, auto_reply(), AUTOPILOT_MAX_ARGS, Destroyed, LBUF_SIZE, MechID, name, Number, proper_explodearguments(), sho, and silent.

Referenced by sendchannelstuff().

01233 {
01234 
01235         int argc, cmd;
01236         char *args[2];
01237         char *command_args[AUTOPILOT_MAX_ARGS];
01238         char mech_id[3];
01239         char message[LBUF_SIZE];
01240         char reply[LBUF_SIZE];
01241         int i;
01242 
01243         /* Basic checks */
01244         if(!autopilot || !mech)
01245                 return;
01246         if(Destroyed(mech))
01247                 return;
01248 
01249         /* Get the args - just need the first one */
01250         if(proper_explodearguments(buffer, args, 2) < 2) {
01251                 /* free args */
01252                 for(i = 0; i < 2; i++) {
01253                         if(args[i])
01254                                 free(args[i]);
01255                 }
01256                 return;
01257         }
01258 
01259         /* Check to see if the command was given to this AI */
01260         if(strcmp(args[0], "all")) {
01261                 mech_id[0] = MechID(mech)[0];
01262                 mech_id[1] = MechID(mech)[1];
01263                 mech_id[2] = '\0';
01264 
01265                 if(strcasecmp(mech_id, args[0])) {
01266                         /* free args */
01267                         for(i = 0; i < 2; i++) {
01268                                 if(args[i])
01269                                         free(args[i]);
01270                         }
01271                         return;
01272                 }
01273 
01274         }
01275 
01276         /* Parse the command */
01277         cmd = -1;
01278         argc = proper_explodearguments(args[1], command_args, AUTOPILOT_MAX_ARGS);
01279 
01280         /* Loop through the various possible commands looking for ours */
01281         for(i = 0; auto_cmds[i].sho; i++) {
01282                 if(!strncmp
01283                    (auto_cmds[i].sho, command_args[0], strlen(auto_cmds[i].sho)))
01284                         if(!strncmp
01285                            (auto_cmds[i].name, command_args[0],
01286                                 strlen(command_args[0]))) {
01287                                 if(argc == (auto_cmds[i].args + 1)) {
01288                                         cmd = i;
01289                                         break;
01290                                 }
01291                         }
01292         }
01293 
01294         /* Did we find a command */
01295         if(cmd < 0) {
01296 
01297                 snprintf(message, LBUF_SIZE, "Unable to comprehend the command.");
01298                 auto_reply(mech, message);
01299 
01300                 /* free args */
01301                 for(i = 0; i < 2; i++) {
01302                         if(args[i])
01303                                 free(args[i]);
01304                 }
01305                 for(i = 0; i < AUTOPILOT_MAX_ARGS; i++) {
01306                         if(command_args[i])
01307                                 free(command_args[i]);
01308                 }
01309                 return;
01310 
01311         }
01312 
01313         /* Zero the buffer */
01314         memset(message, 0, sizeof(message));
01315         memset(reply, 0, sizeof(reply));
01316 
01317         /* Call the radio command function */
01318         (*(auto_cmds[cmd].fun)) (autopilot, mech, command_args, argc, message);
01319 
01320         /* If its a silent command there is no reply */
01321         if(auto_cmds[cmd].silent) {
01322 
01323                 /* Free args and exit */
01324                 for(i = 0; i < 2; i++) {
01325                         if(args[i])
01326                                 free(args[i]);
01327                 }
01328                 for(i = 0; i < AUTOPILOT_MAX_ARGS; i++) {
01329                         if(command_args[i])
01330                                 free(command_args[i]);
01331                 }
01332                 return;
01333 
01334         }
01335 
01336         /* Check to see if a message was returned */
01337         if(*message) {
01338 
01339                 /* Check if there was an error message
01340                  * otherwise add a front and back to the message */
01341                 if(message[0] == '!') {
01342                         snprintf(reply, LBUF_SIZE, "ERROR: %s!", message + 1);
01343                 } else {
01344 
01345                         switch (Number(0, 20)) {
01346                         case 0:
01347                         case 1:
01348                         case 2:
01349                         case 4:
01350                                 snprintf(reply, LBUF_SIZE, "%s%s%s", "Affirmative, ",
01351                                                  message, ".");
01352                                 break;
01353                         case 5:
01354                                 snprintf(reply, LBUF_SIZE, "%s%s%s", "Nod, ", message, ".");
01355                                 break;
01356                         case 6:
01357                                 snprintf(reply, LBUF_SIZE, "%s%s%s", "Fine, ", message, ".");
01358                                 break;
01359                         case 7:
01360                                 snprintf(reply, LBUF_SIZE, "%s%s%s", "Aye aye, Captain, ",
01361                                                  message, "!");
01362                                 break;
01363                         case 8:
01364                         case 9:
01365                         case 10:
01366                                 snprintf(reply, LBUF_SIZE, "%s%s%s", "Da, boss, ",
01367                                                  message, "!");
01368                                 break;
01369                         case 11:
01370                         case 12:
01371                                 snprintf(reply, LBUF_SIZE, "%s%s%s", "Ok, ", message, ".");
01372                                 break;
01373                         case 13:
01374                                 snprintf(reply, LBUF_SIZE, "%s%s%s", "Okay, okay, ",
01375                                                  message, ", happy now?");
01376                                 break;
01377                         case 14:
01378                                 snprintf(reply, LBUF_SIZE, "%s%s%s", "Okidoki, ",
01379                                                  message, "!");
01380                                 break;
01381                         case 15:
01382                         case 16:
01383                         case 17:
01384                                 snprintf(reply, LBUF_SIZE, "%s%s%s", "Aye, ", message, ".");
01385                                 break;
01386                         default:
01387                                 snprintf(reply, LBUF_SIZE, "%s%s%s", "Roger, Roger, ",
01388                                                  message, ".");
01389                                 break;
01390                         }                                       /* End of switch */
01391 
01392                 }
01393 
01394                 auto_reply(mech, reply);
01395 
01396         } else if(!auto_cmds[cmd].silent) {
01397 
01398                 /* Command isn't silent but it didn't return a message */
01399                 snprintf(reply, LBUF_SIZE, "Ok.");
01400                 auto_reply(mech, reply);
01401 
01402         }
01403 
01404         /* free args */
01405         for(i = 0; i < 2; i++) {
01406                 if(args[i])
01407                         free(args[i]);
01408         }
01409         for(i = 0; i < AUTOPILOT_MAX_ARGS; i++) {
01410                 if(command_args[i])
01411                         free(command_args[i]);
01412         }
01413 
01414 }

void auto_radio_command_autogun ( AUTO autopilot,
MECH mech,
char **  args,
int  argc,
char *  mesg 
)

Definition at line 141 of file autopilot_radio.c.

References AssignedTarget, AUTO_GUN_UPDATE_TICK, DoStartGun, DoStopGun, Gunning, LBUF_SIZE, Readnum, AUTO::target, AUTO::target_score, AUTO::target_threshold, AUTO::target_update_tick, and UnassignTarget.

00143 {
00144 
00145         int threshold;
00146 
00147         if(strcmp(args[1], "on") == 0) {
00148 
00149                 autopilot->target = -1;
00150                 autopilot->target_score = 0;
00151                 autopilot->target_update_tick = AUTO_GUN_UPDATE_TICK;
00152 
00153                 /* Reset the Assigned target flag */
00154                 if(AssignedTarget(autopilot)) {
00155                         UnassignTarget(autopilot);
00156                 }
00157 
00158                 if(Gunning(autopilot)) {
00159                         DoStopGun(autopilot);
00160                 }
00161                 DoStartGun(autopilot);
00162 
00163                 snprintf(mesg, LBUF_SIZE, "shooting at whatever I want");
00164                 return;
00165 
00166         } else if(strcmp(args[1], "off") == 0) {
00167 
00168                 /* Reset the AI */
00169                 autopilot->target = -2;
00170                 autopilot->target_score = 0;
00171                 autopilot->target_update_tick = 0;
00172 
00173                 /* Reset this flag since we don't want to be shooting anything */
00174                 if(AssignedTarget(autopilot)) {
00175                         UnassignTarget(autopilot);
00176                 }
00177 
00178                 if(Gunning(autopilot))
00179                         DoStopGun(autopilot);
00180 
00181                 snprintf(mesg, LBUF_SIZE, "powering down weapons");
00182                 return;
00183 
00184         } else if(strcmp(args[1], "threshold") == 0) {
00185 
00186                 /* Ok user specifying a threshold" */
00187                 /* Right now we're only going to allow them to specify a value
00188                  * between 0 and 100 - basicly how much percentage wise over
00189                  * the current value does the new target have to be to switch */
00190                 if(argc == 3 && !Readnum(threshold, args[2]) &&
00191                    threshold >= 0 && threshold <= 100) {
00192 
00193                         /* Set the new threshold value */
00194                         autopilot->target_threshold = threshold;
00195 
00196                         snprintf(mesg, LBUF_SIZE, "new threshold set to %d%%", threshold);
00197                         return;
00198 
00199                 } else {
00200 
00201                         /* Bad value for threshold */
00202                         snprintf(mesg, LBUF_SIZE, "!Invalid value used with threshold: "
00203                                          "Usage autogun threshold [0-100]");
00204                         return;
00205 
00206                 }
00207 
00208         }
00209 
00210         snprintf(mesg, LBUF_SIZE, "!Invalid Input for autogun:"
00211                          " use 'on' or 'off'");
00212 
00213 }

void auto_radio_command_chasetarg ( AUTO autopilot,
MECH mech,
char **  args,
int  argc,
char *  mesg 
)

Definition at line 218 of file autopilot_radio.c.

References AUTO_CHASETARGET_OFF, AUTO_CHASETARGET_ON, auto_set_chasetarget_mode(), and LBUF_SIZE.

00220 {
00221 
00222         if(strcmp(args[1], "on") == 0) {
00223 
00224                 auto_set_chasetarget_mode(autopilot, AUTO_CHASETARGET_ON);
00225                 snprintf(mesg, LBUF_SIZE, "Chase Target Mode is Activated");
00226                 return;
00227 
00228         } else if(strcmp(args[1], "off") == 0) {
00229 
00230                 auto_set_chasetarget_mode(autopilot, AUTO_CHASETARGET_OFF);
00231                 snprintf(mesg, LBUF_SIZE, "Chase Target Mode is Deactivated");
00232                 return;
00233         }
00234         snprintf(mesg, LBUF_SIZE,
00235                          "!Invalid Input for chasetarg: use 'on' or 'off'");
00236 
00237 }

void auto_radio_command_dfollow ( AUTO autopilot,
MECH mech,
char **  args,
int  argc,
char *  mesg 
)

Definition at line 242 of file autopilot_radio.c.

References auto_addcommand(), auto_engage(), Clear, FindTargetDBREFFromMapNumber(), LBUF_SIZE, AUTO::mynum, AUTO::ofsx, AUTO::ofsy, and SBUF_SIZE.

00244 {
00245 
00246         dbref targetref;
00247         char buffer[SBUF_SIZE];
00248 
00249         targetref = FindTargetDBREFFromMapNumber(mech, args[1]);
00250         if(targetref <= 0) {
00251                 snprintf(mesg, LBUF_SIZE, "!Invalid target to follow");
00252                 return;
00253         }
00254 
00255         Clear(autopilot);
00256 
00257         snprintf(buffer, SBUF_SIZE, "dumbfollow %d", targetref);
00258         auto_addcommand(autopilot->mynum, autopilot, buffer);
00259         auto_engage(autopilot->mynum, autopilot, "");
00260         snprintf(mesg, LBUF_SIZE, "following %s [dumbly] (%d degrees, %d away)",
00261                          args[1], autopilot->ofsx, autopilot->ofsy);
00262 }

void auto_radio_command_dgoto ( AUTO autopilot,
MECH mech,
char **  args,
int  argc,
char *  mesg 
)

Definition at line 267 of file autopilot_radio.c.

References auto_addcommand(), auto_engage(), Clear, LBUF_SIZE, AUTO::mynum, Readnum, SBUF_SIZE, x, and y.

00269 {
00270 
00271         int x, y;
00272         char buffer[SBUF_SIZE];
00273 
00274         if(Readnum(x, args[1])) {
00275                 snprintf(mesg, LBUF_SIZE, "!First number not an integer");
00276                 return;
00277         }
00278         if(Readnum(y, args[2])) {
00279                 snprintf(mesg, LBUF_SIZE, "!First number not an integer");
00280                 return;
00281         }
00282 
00283         Clear(autopilot);
00284 
00285         snprintf(buffer, SBUF_SIZE, "dumbgoto %d %d", x, y);
00286         auto_addcommand(autopilot->mynum, autopilot, buffer);
00287         auto_engage(autopilot->mynum, autopilot, "");
00288         snprintf(mesg, LBUF_SIZE, "going [dumbly] to %d,%d", x, y);
00289 
00290 }

void auto_radio_command_dropoff ( AUTO autopilot,
MECH mech,
char **  args,
int  argc,
char *  mesg 
)

Definition at line 295 of file autopilot_radio.c.

References auto_addcommand(), auto_engage(), Clear, LBUF_SIZE, AUTO::mynum, and SBUF_SIZE.

00297 {
00298 
00299         char buffer[SBUF_SIZE];
00300 
00301         Clear(autopilot);
00302 
00303         snprintf(buffer, SBUF_SIZE, "dropoff");
00304         auto_addcommand(autopilot->mynum, autopilot, buffer);
00305         auto_engage(autopilot->mynum, autopilot, "");
00306         snprintf(mesg, LBUF_SIZE, "dropping off");
00307 
00308 }

void auto_radio_command_embark ( AUTO autopilot,
MECH mech,
char **  args,
int  argc,
char *  mesg 
)

Definition at line 313 of file autopilot_radio.c.

References auto_addcommand(), auto_engage(), Clear, FindTargetDBREFFromMapNumber(), LBUF_SIZE, AUTO::mynum, and SBUF_SIZE.

00315 {
00316 
00317         dbref targetref;
00318         char buffer[SBUF_SIZE];
00319 
00320         targetref = FindTargetDBREFFromMapNumber(mech, args[1]);
00321         if(targetref <= 0) {
00322                 snprintf(mesg, LBUF_SIZE, "!Invalid target to embark");
00323                 return;
00324         }
00325 
00326         Clear(autopilot);
00327         snprintf(buffer, SBUF_SIZE, "embark %d", targetref);
00328         auto_addcommand(autopilot->mynum, autopilot, buffer);
00329         auto_engage(autopilot->mynum, autopilot, "");
00330         snprintf(mesg, LBUF_SIZE, "embarking %s", args[1]);
00331         return;
00332 
00333 }

void auto_radio_command_enterbase ( AUTO autopilot,
MECH mech,
char **  args,
int  argc,
char *  mesg 
)

Definition at line 338 of file autopilot_radio.c.

References auto_addcommand(), auto_engage(), Clear, LBUF_SIZE, AUTO::mynum, and SBUF_SIZE.

00340 {
00341 
00342         char buffer[SBUF_SIZE];
00343 
00344         if(argc - 1) {
00345                 snprintf(buffer, SBUF_SIZE, "enterbase %s", args[1]);
00346                 snprintf(mesg, LBUF_SIZE, "entering base (%s side)", args[1]);
00347         } else {
00348                 strncpy(buffer, "enterbase n", SBUF_SIZE);
00349                 snprintf(mesg, LBUF_SIZE, "entering base");
00350         }
00351 
00352         Clear(autopilot);
00353         auto_addcommand(autopilot->mynum, autopilot, buffer);
00354         auto_engage(autopilot->mynum, autopilot, "");
00355 
00356 }

void auto_radio_command_follow ( AUTO autopilot,
MECH mech,
char **  args,
int  argc,
char *  mesg 
)

Definition at line 361 of file autopilot_radio.c.

References auto_addcommand(), auto_engage(), Clear, FindTargetDBREFFromMapNumber(), LBUF_SIZE, AUTO::mynum, AUTO::ofsx, AUTO::ofsy, and SBUF_SIZE.

00363 {
00364 
00365         char buffer[SBUF_SIZE];
00366         dbref targetref;
00367 
00368         targetref = FindTargetDBREFFromMapNumber(mech, args[1]);
00369         if(targetref <= 0) {
00370                 snprintf(mesg, LBUF_SIZE, "!Invalid target to follow");
00371                 return;
00372         }
00373 
00374         Clear(autopilot);
00375 
00376         snprintf(buffer, SBUF_SIZE, "follow %d", targetref);
00377         auto_addcommand(autopilot->mynum, autopilot, buffer);
00378         auto_engage(autopilot->mynum, autopilot, "");
00379         snprintf(mesg, LBUF_SIZE, "following %s (%d degrees, %d away)", args[1],
00380                          autopilot->ofsx, autopilot->ofsy);
00381 
00382 }

void auto_radio_command_goto ( AUTO autopilot,
MECH mech,
char **  args,
int  argc,
char *  mesg 
)

Definition at line 387 of file autopilot_radio.c.

References auto_addcommand(), auto_engage(), Clear, getMap(), LBUF_SIZE, MAP::map_height, MAP::map_width, MECH::mapindex, MechX, MechY, AUTO::mynum, Readnum, SBUF_SIZE, x, and y.

00389 {
00390 
00391         int x, y;
00392         char buffer[SBUF_SIZE];
00393     MAP *map;
00394 
00395         if(Readnum(x, args[1])) {
00396                 snprintf(mesg, LBUF_SIZE, "!First number not integer");
00397                 return;
00398         }
00399         if(Readnum(y, args[2])) {
00400                 snprintf(mesg, LBUF_SIZE, "!Second number not integer");
00401                 return;
00402         }
00403 
00404         if(MechX(mech) == x && MechY(mech) == y) {
00405                 snprintf(mesg, LBUF_SIZE, "!Already in that hex");
00406                 return;
00407         }
00408 
00409     map = getMap(mech->mapindex);
00410 
00411     if (x < 0 || y < 0 || x >= map->map_width || y >= map->map_height) {
00412         snprintf(mesg, LBUF_SIZE, "!Bad hex to travel to");
00413         return;
00414     }
00415 
00416         Clear(autopilot);
00417 
00418         snprintf(buffer, SBUF_SIZE, "goto %d %d", x, y);
00419         auto_addcommand(autopilot->mynum, autopilot, buffer);
00420         auto_engage(autopilot->mynum, autopilot, "");
00421         snprintf(mesg, LBUF_SIZE, "going to %d,%d", x, y);
00422 
00423 }

void auto_radio_command_heading ( AUTO autopilot,
MECH mech,
char **  args,
int  argc,
char *  mesg 
)

Definition at line 428 of file autopilot_radio.c.

References auto_engage(), Clear, LBUF_SIZE, mech_heading(), mech_speed(), AUTO::mynum, Readnum, and SBUF_SIZE.

00430 {
00431 
00432         int heading;
00433         char buffer[SBUF_SIZE];
00434 
00435         if(Readnum(heading, args[1])) {
00436                 snprintf(mesg, LBUF_SIZE, "!Number not integer");
00437                 return;
00438         }
00439 
00440         Clear(autopilot);
00441         auto_engage(autopilot->mynum, autopilot, "");
00442         snprintf(buffer, SBUF_SIZE, "%d", heading);
00443         mech_heading(autopilot->mynum, mech, buffer);
00444         strcpy(buffer, "0");
00445         mech_speed(autopilot->mynum, mech, buffer);
00446         snprintf(buffer, LBUF_SIZE, "stopped and heading changed to %d", heading);
00447 
00448 }

void auto_radio_command_help ( AUTO autopilot,
MECH mech,
char **  args,
int  argc,
char *  mesg 
)

Definition at line 453 of file autopilot_radio.c.

References auto_cmds, auto_reply(), LBUF_SIZE, and name.

00455 {
00456 
00457         int i;
00458 
00461         snprintf(mesg, LBUF_SIZE, "The following commands are possible:");
00462 
00463         for(i = 0; auto_cmds[i].name; i++) {
00464                 if(i > 0 && !strcmp(auto_cmds[i].name, auto_cmds[i - 1].name))
00465                         continue;
00466                 strncat(mesg, " ", LBUF_SIZE);
00467                 strncat(mesg, auto_cmds[i].name, LBUF_SIZE);
00468         }
00469 
00470         auto_reply(mech, mesg);
00471 
00472 }

void auto_radio_command_hide ( AUTO autopilot,
MECH mech,
char **  args,
int  argc,
char *  mesg 
)

Definition at line 477 of file autopilot_radio.c.

References bsuit_hide(), BUILDING, CLASS_BSUIT, CLASS_MW, HasCamo, HEAVY_FOREST, LBUF_SIZE, LIGHT_FOREST, MechRTerrain, MechType, MOUNTAINS, AUTO::mynum, and ROUGH.

00479 {
00480 
00481         if((HasCamo(mech)) ?
00482            0 : MechType(mech) != CLASS_BSUIT && MechType(mech) != CLASS_MW) {
00483                 snprintf(mesg, LBUF_SIZE,
00484                                  "!Last I checked I was kind of big for that");
00485                 return;
00486         }
00487 
00488         if(!(MechRTerrain(mech) == HEAVY_FOREST ||
00489                  MechRTerrain(mech) == LIGHT_FOREST ||
00490                  MechRTerrain(mech) == ROUGH ||
00491                  MechRTerrain(mech) == MOUNTAINS ||
00492                  (MechType(mech) == CLASS_BSUIT ? MechRTerrain(mech) ==
00493                   BUILDING : 0))) {
00494                 snprintf(mesg, LBUF_SIZE, "!Invalid Terrain");
00495                 return;
00496         }
00497 
00498         bsuit_hide(autopilot->mynum, mech, "");
00499         snprintf(mesg, LBUF_SIZE, "Begining to hide");
00500 
00501 }

void auto_radio_command_jumpjet ( AUTO autopilot,
MECH mech,
char **  args,
int  argc,
char *  mesg 
)

Definition at line 507 of file autopilot_radio.c.

References FindTargetDBREFFromMapNumber(), LBUF_SIZE, mech_jump(), MechJumpSpeed, AUTO::mynum, Readnum, and SBUF_SIZE.

00509 {
00510 
00511         dbref target;
00512         char buffer[SBUF_SIZE];
00513         int bear, rng;
00514 
00515         if(!abs(MechJumpSpeed(mech))) {
00516                 snprintf(mesg, LBUF_SIZE, "!I don't do hiphop and jump around");
00517                 return;
00518         }
00519 
00520         if((argc - 1) == 1) {
00521                 if((target = FindTargetDBREFFromMapNumber(mech, args[1])) <= 0) {
00522                         snprintf(mesg, LBUF_SIZE, "!Unable to see such a target");
00523                         return;
00524                 }
00525                 strcpy(buffer, args[1]);
00526                 mech_jump(autopilot->mynum, mech, buffer);
00527                 snprintf(mesg, LBUF_SIZE, "jumping on [%s]", args[1]);
00528                 return;
00529         } else {
00530                 if(Readnum(bear, args[1])) {
00531                         snprintf(mesg, LBUF_SIZE, "!Invalid bearing");
00532                         return;
00533                 }
00534                 if(Readnum(rng, args[2])) {
00535                         snprintf(mesg, LBUF_SIZE, "!Invalid range");
00536                         return;
00537                 }
00538                 snprintf(buffer, SBUF_SIZE, "%s %s", args[1], args[2]);
00539                 mech_jump(autopilot->mynum, mech, buffer);
00540                 snprintf(mesg, LBUF_SIZE, "jump %s degrees %s hexes", args[1],
00541                                  args[2]);
00542                 return;
00543         }
00544 }

void auto_radio_command_leavebase ( AUTO autopilot,
MECH mech,
char **  args,
int  argc,
char *  mesg 
)

Definition at line 549 of file autopilot_radio.c.

References auto_addcommand(), auto_engage(), ChasingTarget, Clear, LBUF_SIZE, AUTO::mynum, Readnum, SBUF_SIZE, and StopChasingTarget.

00551 {
00552 
00553         char buffer[SBUF_SIZE];
00554         int direction;
00555 
00556         if(Readnum(direction, args[1])) {
00557                 snprintf(mesg, LBUF_SIZE, "!Invalid value for direction");
00558                 return;
00559         }
00560 
00561         /* Make sure chasetarget doesn't interfere with this */
00562         if(ChasingTarget(autopilot)) {
00563                 StopChasingTarget(autopilot);
00564         }
00565 
00566         Clear(autopilot);
00567 
00568         snprintf(buffer, SBUF_SIZE, "leavebase %d", direction);
00569         auto_addcommand(autopilot->mynum, autopilot, buffer);
00570         auto_engage(autopilot->mynum, autopilot, "");
00571         snprintf(mesg, LBUF_SIZE, "leaving base at %d heading", direction);
00572 
00573 }

void auto_radio_command_ogoto ( AUTO autopilot,
MECH mech,
char **  args,
int  argc,
char *  mesg 
)

Definition at line 578 of file autopilot_radio.c.

References auto_addcommand(), auto_engage(), Clear, LBUF_SIZE, AUTO::mynum, Readnum, SBUF_SIZE, x, and y.

00580 {
00581 
00582         int x, y;
00583         char buffer[SBUF_SIZE];
00584 
00585         if(Readnum(x, args[1])) {
00586                 snprintf(mesg, LBUF_SIZE, "!First number not integer");
00587                 return;
00588         }
00589         if(Readnum(y, args[2])) {
00590                 snprintf(mesg, LBUF_SIZE, "!Second number not integer");
00591                 return;
00592         }
00593 
00594         Clear(autopilot);
00595 
00596         snprintf(buffer, SBUF_SIZE, "oldgoto %d %d", x, y);
00597         auto_addcommand(autopilot->mynum, autopilot, buffer);
00598         auto_engage(autopilot->mynum, autopilot, "");
00599         snprintf(mesg, LBUF_SIZE, "going [old version] to %d,%d", x, y);
00600 
00601 }

void auto_radio_command_pickup ( AUTO autopilot,
MECH mech,
char **  args,
int  argc,
char *  mesg 
)

Definition at line 606 of file autopilot_radio.c.

References auto_addcommand(), auto_engage(), ChasingTarget, Clear, FindTargetDBREFFromMapNumber(), LBUF_SIZE, AUTO::mynum, SBUF_SIZE, and StopChasingTarget.

00608 {
00609 
00610         dbref targetref;
00611         char buffer[SBUF_SIZE];
00612 
00613         targetref = FindTargetDBREFFromMapNumber(mech, args[1]);
00614         if(targetref <= 0) {
00615                 snprintf(mesg, LBUF_SIZE, "!Invalid target to pickup");
00616                 return;
00617         }
00618 
00619         /* Make sure chasetarget doesn't interfere with this */
00620         if(ChasingTarget(autopilot)) {
00621                 StopChasingTarget(autopilot);
00622         }
00623 
00624         Clear(autopilot);
00625 
00626         snprintf(buffer, SBUF_SIZE, "pickup %d", targetref);
00627         auto_addcommand(autopilot->mynum, autopilot, buffer);
00628         auto_engage(autopilot->mynum, autopilot, "");
00629         snprintf(mesg, LBUF_SIZE, "picking up %s", args[1]);
00630 
00631 }

void auto_radio_command_position ( AUTO autopilot,
MECH mech,
char **  args,
int  argc,
char *  mesg 
)

Definition at line 637 of file autopilot_radio.c.

References LBUF_SIZE, AUTO::ofsx, AUTO::ofsy, Readnum, x, and y.

00639 {
00640 
00641         int x, y;
00642 
00645         if(Readnum(x, args[1])) {
00646                 snprintf(mesg, LBUF_SIZE, "!Invalid first int");
00647                 return;
00648         }
00649         if(Readnum(y, args[2])) {
00650                 snprintf(mesg, LBUF_SIZE, "!Invalide second int");
00651                 return;
00652         }
00653 
00654         autopilot->ofsx = x;
00655         autopilot->ofsy = y;
00656         snprintf(mesg, LBUF_SIZE, "following %d degrees, %d away", x, y);
00657 
00658 }

void auto_radio_command_prone ( AUTO autopilot,
MECH mech,
char **  args,
int  argc,
char *  mesg 
)

Definition at line 663 of file autopilot_radio.c.

References LBUF_SIZE, mech_drop(), and AUTO::mynum.

00665 {
00666 
00667         mech_drop(autopilot->mynum, mech, "");
00668         snprintf(mesg, LBUF_SIZE, "hitting the deck");
00669 
00670 }

void auto_radio_command_report ( AUTO autopilot,
MECH mech,
char **  args,
int  argc,
char *  mesg 
)

Todo:
{Add something that tells more info then this}

Definition at line 676 of file autopilot_radio.c.

References auto_reply(), Fallen, FaMechRange, getMech(), GetMechToMechID(), InLineOfSight(), IsRunning, Jumping, LBUF_SIZE, MBUF_SIZE, MechFacing, MechSpeed, MechTarget, MechX, MechY, and MMaxSpeed.

00678 {
00679 
00680         char buffer[MBUF_SIZE];
00681         MECH *target;
00682 
00683         /* Is the AI moving or something */
00684         if(Jumping(mech))
00685                 strcpy(buffer, "Jumping");
00686         else if(Fallen(mech))
00687                 strcpy(buffer, "Prone");
00688         else if(IsRunning(MechSpeed(mech), MMaxSpeed(mech)))
00689                 strcpy(buffer, "Running");
00690         else if(MechSpeed(mech) > 1.0)
00691                 strcpy(buffer, "Walking");
00692         else
00693                 strcpy(buffer, "Standing");
00694 
00695         snprintf(mesg, LBUF_SIZE, "%s at %d, %d", buffer, MechX(mech),
00696                          MechY(mech));
00697 
00698         /* Which way is the AI going */
00699         if(MechSpeed(mech) > 1.0) {
00700                 snprintf(buffer, MBUF_SIZE, ", headed %d speed %.2f",
00701                                  MechFacing(mech), MechSpeed(mech));
00702                 strncat(mesg, buffer, LBUF_SIZE);
00703         } else {
00704                 snprintf(buffer, MBUF_SIZE, ", headed %d", MechFacing(mech));
00705                 strncat(mesg, buffer, LBUF_SIZE);
00706         }
00707 
00708         /* Is the AI targeting something */
00709         if(MechTarget(mech) != -1) {
00710                 target = getMech(MechTarget(mech));
00711 
00712                 if(target) {
00713                         snprintf(buffer, MBUF_SIZE, ", targeting %s %s",
00714                                          GetMechToMechID(mech, target),
00715                                          InLineOfSight(mech, target, MechX(target),
00716                                                                    MechY(target), FaMechRange(mech, target)) ?
00717                                          "" : "(not in LOS)");
00718                         strncat(mesg, buffer, LBUF_SIZE);
00719                 }
00720         }
00721 
00722         /* Send the mesg to the reply system, this is a silent command */
00723         auto_reply(mech, mesg);
00724 
00725 }

void auto_radio_command_reset ( AUTO autopilot,
MECH mech,
char **  args,
int  argc,
char *  mesg 
)

Definition at line 730 of file autopilot_radio.c.

References auto_delcommand(), auto_disengage(), auto_engage(), auto_init(), LBUF_SIZE, AUTO::mynum, and SBUF_SIZE.

00732 {
00733 
00734         char buffer[SBUF_SIZE];
00735 
00736         auto_disengage(autopilot->mynum, autopilot, "");
00737         auto_delcommand(autopilot->mynum, autopilot, "-1");
00738         auto_init(autopilot, mech);
00739         auto_engage(autopilot->mynum, autopilot, "");
00740         snprintf(mesg, LBUF_SIZE, "all internal events and flags reset!");
00741 
00742 }

void auto_radio_command_sensor ( AUTO autopilot,
MECH mech,
char **  args,
int  argc,
char *  mesg 
)

Definition at line 748 of file autopilot_radio.c.

References AUTOPILOT_LSENS, EVENT_AUTO_SENSOR, AUTO::flags, LBUF_SIZE, mech_sensor(), muxevent_remove_type_data(), AUTO::mynum, and SBUF_SIZE.

00750 {
00751 
00752         char buf[SBUF_SIZE];
00753 
00754         /* Make sure no sensor event running */
00755         muxevent_remove_type_data(EVENT_AUTO_SENSOR, autopilot);
00756 
00757         if((argc - 1) == 2) {
00758 
00759                 /* Set the user specified sensors */
00760                 snprintf(buf, SBUF_SIZE, "%s %s", args[1], args[2]);
00761                 mech_sensor(autopilot->mynum, mech, buf);
00762                 autopilot->flags |= AUTOPILOT_LSENS;
00763                 snprintf(mesg, LBUF_SIZE, "updated my sensors");
00764                 return;
00765 
00766         }
00767 
00768         /* Let AI decide */
00769         autopilot->flags &= ~AUTOPILOT_LSENS;
00770         snprintf(mesg, LBUF_SIZE, "using my own judgement with sensors");
00771         return;
00772 
00773 }

void auto_radio_command_shutdown ( AUTO autopilot,
MECH mech,
char **  args,
int  argc,
char *  mesg 
)

Definition at line 778 of file autopilot_radio.c.

References LBUF_SIZE, mech_shutdown(), and AUTO::mynum.

00780 {
00781 
00782         mech_shutdown(autopilot->mynum, mech, "");
00783         snprintf(mesg, LBUF_SIZE, "shutting down");
00784 
00785 }

void auto_radio_command_speed ( AUTO autopilot,
MECH mech,
char **  args,
int  argc,
char *  mesg 
)

Definition at line 790 of file autopilot_radio.c.

References LBUF_SIZE, Readnum, and AUTO::speed.

00792 {
00793 
00794         int speed = 100;
00795 
00796         if(Readnum(speed, args[1])) {
00797                 snprintf(mesg, LBUF_SIZE, "!Invalid value - not a number");
00798                 return;
00799         }
00800 
00801         if(speed < 1 || speed > 100) {
00802                 snprintf(mesg, LBUF_SIZE, "!Invalid speed");
00803                 return;
00804         }
00805 
00806         autopilot->speed = speed;
00807         snprintf(mesg, LBUF_SIZE, "setting speed to %d %%", speed);
00808 
00809 }

void auto_radio_command_stand ( AUTO autopilot,
MECH mech,
char **  args,
int  argc,
char *  mesg 
)

Definition at line 814 of file autopilot_radio.c.

References LBUF_SIZE, mech_stand(), and AUTO::mynum.

00816 {
00817 
00818         mech_stand(autopilot->mynum, mech, "");
00819         snprintf(mesg, LBUF_SIZE, "standing up");
00820 
00821 }

void auto_radio_command_startup ( AUTO autopilot,
MECH mech,
char **  args,
int  argc,
char *  mesg 
)

Definition at line 826 of file autopilot_radio.c.

References LBUF_SIZE, mech_startup(), and AUTO::mynum.

00828 {
00829 
00830         if(argc > 1) {
00831                 if(!strncasecmp(args[1], "override", strlen(args[1]))) {
00832                         mech_startup(autopilot->mynum, mech, "override");
00833                         snprintf(mesg, LBUF_SIZE, "emergency override startup triggered");
00834                         return;
00835                 }
00836         }
00837 
00838         mech_startup(autopilot->mynum, mech, "");
00839         snprintf(mesg, LBUF_SIZE, "starting up");
00840 
00841 }

void auto_radio_command_stop ( AUTO autopilot,
MECH mech,
char **  args,
int  argc,
char *  mesg 
)

Definition at line 846 of file autopilot_radio.c.

References AUTO_CHASETARGET_OFF, auto_engage(), auto_set_chasetarget_mode(), Clear, LBUF_SIZE, mech_speed(), AUTO::mynum, and SBUF_SIZE.

00848 {
00849 
00850         char buffer[SBUF_SIZE];
00851 
00852         strcpy(buffer, "0");
00853 
00854         /* Turn chasetarget off */
00855         auto_set_chasetarget_mode(autopilot, AUTO_CHASETARGET_OFF);
00856 
00857         Clear(autopilot);
00858 
00859         auto_engage(autopilot->mynum, autopilot, "");
00860         mech_speed(autopilot->mynum, mech, buffer);
00861         snprintf(mesg, LBUF_SIZE, "halting");
00862 
00863 }

void auto_radio_command_sweight ( AUTO autopilot,
MECH mech,
char **  args,
int  argc,
char *  mesg 
)

Definition at line 868 of file autopilot_radio.c.

References AUTO::auto_fweight, AUTO::auto_goweight, LBUF_SIZE, MAX, Readnum, x, and y.

00870 {
00871 
00872         int x, y;
00873 
00874         if(Readnum(x, args[1])) {
00875                 snprintf(mesg, LBUF_SIZE, "!Invalid first int");
00876                 return;
00877         }
00878         if(Readnum(y, args[2])) {
00879                 snprintf(mesg, LBUF_SIZE, "!Invalide second int");
00880                 return;
00881         }
00882         x = MAX(1, x);
00883         y = MAX(1, y);
00884         autopilot->auto_goweight = x;
00885         autopilot->auto_fweight = y;
00886         snprintf(mesg, LBUF_SIZE, "sweight'ed to %d:%d. (go:fight)", x, y);
00887         return;
00888 
00889 }

void auto_radio_command_target ( AUTO autopilot,
MECH mech,
char **  args,
int  argc,
char *  mesg 
)

Definition at line 894 of file autopilot_radio.c.

References AssignedTarget, AssignTarget, AUTO_GUN_UPDATE_TICK, DoStartGun, DoStopGun, FindTargetDBREFFromMapNumber(), Gunning, LBUF_SIZE, AUTO::target, AUTO::target_score, AUTO::target_update_tick, and UnassignTarget.

00896 {
00897 
00898         dbref targetref;
00899 
00900         if(!strcmp(args[1], "-")) {
00901 
00902                 /* Basicly doing the same as 'autogun on' */
00903                 autopilot->target = -1;
00904                 autopilot->target_score = 0;
00905                 autopilot->target_update_tick = AUTO_GUN_UPDATE_TICK;
00906 
00907                 if(AssignedTarget(autopilot)) {
00908                         UnassignTarget(autopilot);
00909                 }
00910 
00911                 if(Gunning(autopilot)) {
00912                         DoStopGun(autopilot);
00913                 }
00914                 DoStartGun(autopilot);
00915 
00916                 snprintf(mesg, LBUF_SIZE, "shooting at whatever I want");
00917                 return;
00918 
00919         } else {
00920 
00921                 targetref = FindTargetDBREFFromMapNumber(mech, args[1]);
00922                 if(targetref <= 0) {
00923                         snprintf(mesg, LBUF_SIZE, "!Unable to see such a target");
00924                         return;
00925                 }
00926 
00927         }
00928 
00929         autopilot->target = targetref;
00930         autopilot->target_score = 0;
00931         autopilot->target_update_tick = 0;
00932 
00933         /* Let the AI know its an assigned target */
00934         if(!AssignedTarget(autopilot)) {
00935                 AssignTarget(autopilot);
00936         }
00937 
00938         if(Gunning(autopilot)) {
00939                 DoStopGun(autopilot);
00940         }
00941         DoStartGun(autopilot);
00942 
00943         snprintf(mesg, LBUF_SIZE, "aiming for [%s] (and ignoring everyone else)",
00944                          args[1]);
00945 
00946 }

void auto_reply ( MECH mech,
char *  buf 
)

Definition at line 1196 of file autopilot_radio.c.

Referenced by auto_parse_command(), auto_radio_command_help(), auto_radio_command_report(), mech_radio(), mech_scan(), and sendAIM().

01197 {
01198 
01199         char *reply;
01200 
01201         /* No zero freq messages */
01202         if(!mech->freq[0])
01203                 return;
01204 
01205         /* Make sure there is an autopilot */
01206         if(MechAuto(mech) <= 0)
01207                 return;
01208 
01209         /* Make sure valid objects */
01210         if(!(FindObjectsData(MechAuto(mech))) ||
01211            !Good_obj(MechAuto(mech)) || Location(MechAuto(mech)) != mech->mynum) {
01212                 MechAuto(mech) = -1;
01213                 return;
01214         }
01215 
01216         /* Copy the buffer */
01217         reply = strdup(buf);
01218 
01219         if(reply) {
01220                 MECHEVENT(mech, EVENT_AUTO_REPLY, auto_reply_event, Number(1, 2),
01221                                   reply);
01222         } else {
01223                 SendAI
01224                         ("Interal AI Error: Attempting to radio reply but unable to copy string");
01225         }
01226 
01227 }

void auto_reply_event ( MUXEVENT muxevent  ) 

Definition at line 1172 of file autopilot_radio.c.

References my_event_type::data, my_event_type::data2, getMap(), IsMech, MECH::mapindex, MECH::mynum, and sendchannelstuff().

Referenced by auto_reply().

01173 {
01174 
01175         MECH *mech = (MECH *) muxevent->data;
01176         char *buf = (char *) muxevent->data2;
01177         MAP *map;
01178 
01179         /* Make sure its a mech */
01180         if(!IsMech(mech->mynum)) {
01181                 free(buf);
01182                 return;
01183         }
01184 
01185         /* If valid object */
01186         if(mech)
01187                 if((map = (getMap(mech->mapindex))))
01188                         sendchannelstuff(mech, 0, buf);
01189 
01190         free(buf);
01191 }

void auto_save_commands ( FILE *  file,
AUTO autopilot 
)

Definition at line 172 of file autopilot_core.c.

References AI_COMMAND_DLLIST_END, AI_COMMAND_DLLIST_START, auto_write_command_node(), CHESA, AUTO::commands, dllist_get_node(), dllist_size(), and outbyte.

Referenced by save_autopilot_data().

00173 {
00174 
00175         int i;                                          /* Our Counter */
00176         unsigned char tmpb;                     /* Our temp int we use when writing */
00177         unsigned int size;                      /* The size of our command list */
00178 
00179         command_node *temp_command_node;
00180 
00181         /* Print the Start Code */
00182         outbyte(AI_COMMAND_DLLIST_START);
00183 
00184         /* Write the size of our list */
00185         size = dllist_size(autopilot->commands);
00186         CHESA(&size, sizeof(size), 1, file);
00187 
00188         /* Check the size of the list, if there are commands save them */
00189         if(dllist_size(autopilot->commands) > 0) {
00190 
00191                 /* Ok there stuff here so lets write it */
00192                 for(i = 1; i <= dllist_size(autopilot->commands); i++) {
00193                         temp_command_node =
00194                                 (command_node *) dllist_get_node(autopilot->commands, i);
00195                         auto_write_command_node(file, temp_command_node);
00196                 }
00197 
00198         }
00199 
00200         /* Print the Stop Code */
00201         outbyte(AI_COMMAND_DLLIST_END);
00202 
00203         return;
00204 
00205 }

void auto_sensor_event ( AUTO autopilot  ) 

Todo:
{Improve this so it knows more about the terrain}

Definition at line 152 of file autopilot_autogun.c.

References AUTOPILOT_LSENS, BEAGLE_DESTROYED, BEAGLE_PROBE_TECH, BLOODHOUND_DESTROYED, BLOODHOUND_PROBE_TECH, BOUNDED(), statedata::db_top, Destroyed, DoStopGun, dprintk, FaMechRange, AUTO::flags, FlyingT, getMap(), getMech(), HeatFactor(), IsAuto(), IsMech, Landed, MECH::mapindex, MAP::maplight, MAP::mapvis, MarkForLOSUpdate(), mech_notify(), MECHALL, MechCritStatus, MechSensor, MechSpecials, MechSpecials2, MechTarget, MechTons, mudstate, AUTO::mymech, AUTO::mymechnum, AUTO::mynum, MECH::mynum, PrefVisSens(), SearchLightInRange(), SENSOR_BAP, SENSOR_BHAP, SENSOR_EM, SENSOR_IR, SENSOR_RA, SENSOR_VIS, Started, and Zombify.

Referenced by auto_heartbeat().

00153 {
00154         MECH *target = NULL;
00155         MAP *map;
00156         char buf[16];
00157         int wanted_s[2];
00158         int rvis;
00159         int slite, prefvis;
00160         float trng;
00161         int set = 0;
00162 
00163         if((autopilot->mymechnum > mudstate.db_top) || (autopilot->mymechnum < 0 )) {
00164                 dprintk("mymechnum is bad!");
00165                 return;
00166         }
00167         if((autopilot->mynum > mudstate.db_top) || (autopilot->mynum < 0 )) {
00168                 dprintk("mynum is bad!");
00169                 return;
00170         }
00171                          
00172         
00173         MECH *mech = (MECH *) autopilot->mymech;
00174         
00175         /* Make sure its a MECH Xcode Object and the AI is
00176          * an AUTOPILOT Xcode Object */
00177         /* Basic checks */
00178         if(!mech) {
00179                 dprintk("mech is bad!");
00180                 return;
00181         }
00182         if(!autopilot) {
00183                 dprintk("ai is bad!");
00184                 return;
00185         }
00186                         
00187         if(!IsMech(mech->mynum) || !IsAuto(autopilot->mynum))
00188                 return;
00189 
00190         /* Mech is dead so stop trying to shoot things */
00191         if(Destroyed(mech)) {
00192                 DoStopGun(autopilot);
00193                 return;
00194         }
00195 
00196         /* Mech isn't started */
00197         if(!Started(mech)) {
00198                 Zombify(autopilot);
00199                 return;
00200         }
00201 
00202         /* The mech is using user defined sensors so don't try
00203          * and change them */
00204         if(autopilot->flags & AUTOPILOT_LSENS)
00205                 return;
00206 
00207         /* Get the map */
00208         if(!(map = getMap(mech->mapindex))) {
00209 
00210                 /* Bad Map */
00211                 Zombify(autopilot);
00212                 return;
00213         }
00214         
00215         /* Get the target if there is one */
00216         if(MechTarget(mech) > 0)
00217                 target = getMech(MechTarget(mech));
00218 
00219         /* Checks to see if there is slite, and what types of vis
00220          * and which visual sensor (V or L) to use */
00221         slite = (map->mapvis != 2 ? SearchLightInRange(mech, map) : 0);
00222         rvis = (map->maplight ? (map->mapvis) : (map->mapvis * (slite ? 1 : 3)));
00223         prefvis = PrefVisSens(mech, map, slite, target);
00224 
00225         /* Is there a target */
00226         if(target) {
00227 
00228                 /* Range to target */
00229                 trng = FaMechRange(mech, target);
00230 
00231                 /* Actually not gonna bother with this */
00232                 /* If the target is running hot and is close switch to IR */
00233                 if(!set && HeatFactor(target) > 35 && (int) trng < 15) {
00234                         //wanted_s[0] = SENSOR_IR;
00235                         //wanted_s[1] = ((MechTons(target) >= 60) ? SENSOR_EM : prefvis);
00236                         //set++;
00237                 }
00238 
00239                 /* If the target is BIG and close enough, use EM */
00240                 if(!set && MechTons(target) >= 60 && (int) trng <= 20) {
00241                         wanted_s[0] = SENSOR_EM;
00242                         wanted_s[1] = SENSOR_IR;
00243                         set++;
00244                 }
00245 
00246                 /* If the target is flying switch to Radar */
00247                 if(!set && !Landed(target) && FlyingT(target)) {
00248                         wanted_s[0] = SENSOR_RA;
00249                         wanted_s[1] = prefvis;
00250                         set++;
00251                 }
00252 
00253                 /* If the target is really close and the unit has BAP, use it */
00254                 if(!set && (int) trng <= 4 && MechSpecials(mech) & BEAGLE_PROBE_TECH
00255                    && !(MechCritStatus(mech) & BEAGLE_DESTROYED)) {
00256                         wanted_s[0] = SENSOR_BAP;
00257                         wanted_s[1] = SENSOR_BAP;
00258                         set++;
00259                 }
00260 
00261                 /* If the target is really close and the unit has Bloodhound, use it */
00262                 if(!set && (int) trng <= 8
00263                    && MechSpecials2(mech) & BLOODHOUND_PROBE_TECH
00264                    && !(MechCritStatus(mech) & BLOODHOUND_DESTROYED)) {
00265                         wanted_s[0] = SENSOR_BHAP;
00266                         wanted_s[1] = SENSOR_BHAP;
00267                         set++;
00268                 }
00269 
00270                 /* Didn't stop at any of the others so use selected visual sensors */
00271                 if(!set) {
00272                         wanted_s[0] = prefvis;
00273                         wanted_s[1] = (rvis <= 15 ? SENSOR_EM : prefvis);
00274                         set++;
00275                 }
00276 
00277         }
00278 
00279         /* Ok no target and no sensors set yet so lets go for defaults */
00280         if(!set) {
00281                 if(rvis <= 15) {
00282                         /* Vis is less then or equal to 15 so go to E I for longer range */
00283                         wanted_s[0] = SENSOR_EM;
00284                         wanted_s[1] = SENSOR_IR;
00285                 } else {
00286                         /* Ok lets go with default visual sensors */
00287                         wanted_s[0] = prefvis;
00288                         wanted_s[1] = prefvis;
00289                 }
00290         }
00291 
00292         /* Check to make sure valid sensors are selected and then set them */
00293         if(wanted_s[0] >= SENSOR_VIS && wanted_s[0] <= SENSOR_BHAP &&
00294            wanted_s[1] >= SENSOR_VIS && wanted_s[1] <= SENSOR_BHAP &&
00295            (MechSensor(mech)[0] != wanted_s[0]
00296                 || MechSensor(mech)[1] != wanted_s[1])) {
00297 
00298                 wanted_s[0] = BOUNDED(SENSOR_VIS, wanted_s[0], SENSOR_BHAP);
00299                 wanted_s[1] = BOUNDED(SENSOR_VIS, wanted_s[1], SENSOR_BHAP);
00300 
00301                 MechSensor(mech)[0] = wanted_s[0];
00302                 MechSensor(mech)[1] = wanted_s[1];
00303                 mech_notify(mech, MECHALL, "As your sensors change, your lock clears.");
00304                 MechTarget(mech) = -1;
00305                 MarkForLOSUpdate(mech);
00306         }
00307 }

void auto_set_chasetarget_mode ( AUTO autopilot,
int  mode 
)

Definition at line 254 of file autopilot_commands.c.

References AUTO_CHASETARGET_OFF, AUTO_CHASETARGET_ON, AUTO_CHASETARGET_REMEMBER, AUTO_CHASETARGET_SAVE, AUTOPILOT_CHASETARG_UPDATE_TICK, ChasingTarget, ForgetChasingTarget, RememberChasingTarget, StartChasingTarget, StopChasingTarget, and WasChasingTarget.

Referenced by auto_radio_command_chasetarg(), and auto_radio_command_stop().

00255 {
00256 
00257         /* Depending on the mode we do different things */
00258         switch (mode) {
00259 
00260         case AUTO_CHASETARGET_ON:
00261 
00262                 /* Start Chasing */
00263                 if(!ChasingTarget(autopilot))
00264                         StartChasingTarget(autopilot);
00265 
00266                 /* Reset this flag because we don't need it set */
00267                 if(WasChasingTarget(autopilot))
00268                         ForgetChasingTarget(autopilot);
00269 
00270                 /* Flags to reset */
00271                 autopilot->chase_target = -10;
00272                 autopilot->chasetarg_update_tick = AUTOPILOT_CHASETARG_UPDATE_TICK;
00273 
00274                 break;
00275 
00276         case AUTO_CHASETARGET_OFF:
00277 
00278                 /* Stop Chasing */
00279                 if(ChasingTarget(autopilot))
00280                         StopChasingTarget(autopilot);
00281 
00282                 /* Reset this flag because we don't need it set */
00283                 if(WasChasingTarget(autopilot))
00284                         ForgetChasingTarget(autopilot);
00285 
00286                 break;
00287 
00288         case AUTO_CHASETARGET_REMEMBER:
00289 
00290                 /* If we we had chasetarget on - turn it back on */
00291                 if(WasChasingTarget(autopilot)) {
00292 
00293                         /* Start chasing */
00294                         if(!ChasingTarget(autopilot))
00295                                 StartChasingTarget(autopilot);
00296 
00297                         /* Reset the values */
00298                         autopilot->chase_target = -10;
00299                         autopilot->chasetarg_update_tick =
00300                                 AUTOPILOT_CHASETARG_UPDATE_TICK;
00301 
00302                         /* Unset the flag because we don't need it now */
00303                         ForgetChasingTarget(autopilot);
00304 
00305                 }
00306 
00307                 break;
00308 
00309         case AUTO_CHASETARGET_SAVE:
00310 
00311                 /* If we are chasing a target turn this off 
00312                  * but save it */
00313                 if(ChasingTarget(autopilot)) {
00314 
00315                         StopChasingTarget(autopilot);
00316                         RememberChasingTarget(autopilot);
00317 
00318                 }
00319 
00320                 break;
00321 
00322         }
00323 
00324 }

void auto_set_comtitle ( AUTO autopilot,
MECH mech 
)

Definition at line 645 of file autopilot_core.c.

References LBUF_SIZE, mech_set_channeltitle(), MechIDS(), MechType_Ref, and AUTO::mynum.

Referenced by auto_engage().

00646 {
00647 
00648         char buf[LBUF_SIZE];
00649 
00650         snprintf(buf, LBUF_SIZE, "a=%s/%s", MechType_Ref(mech), MechIDS(mech, 1));
00651         mech_set_channeltitle(autopilot->mynum, mech, buf);
00652 
00653 }

void auto_update_profile_event ( AUTO autopilot  ) 

Definition at line 542 of file autopilot_autogun.c.

References AUTO_PROFILE_MAX_SIZE, statedata::db_top, Destroyed, dprintk, IsAuto(), IsMech, MAX_WEAPS_SECTION, mudstate, AUTO::mymech, AUTO::mymechnum, MECH::mynum, AUTO::mynum, print_autogun_log, AUTO::profile, rb_destroy(), and StopGun.

Referenced by auto_heartbeat().

00542                                                 {
00543         MECH *mech = (MECH *) autopilot->mymech;
00544 
00545         weapon_node *temp_weapon_node;
00546         dllist_node *temp_dllist_node;
00547 
00548         int section;
00549         int weapon_count_section;
00550         unsigned char weaparray[MAX_WEAPS_SECTION];
00551         unsigned char weapdata[MAX_WEAPS_SECTION];
00552         int critical[MAX_WEAPS_SECTION];
00553 
00554         int range;
00555 
00556         int weapon_count;
00557         int weapon_number;
00558 
00559         /* Basic checks */
00560         /* some accounting checks. try to prevent some race stuff */
00561 
00562         if((autopilot->mymechnum > mudstate.db_top) || (autopilot->mymechnum < 1 )) {
00563                 /* most commonly, the mech is a bad memory space.
00564                  * lets not try to access it
00565                  */
00566                 dprintk("ap mymechnum is bad");
00567                 StopGun(autopilot);
00568                 return;
00569         }
00570 
00571         if(!mech) {
00572                 dprintk("mech is bad!");
00573                 return;
00574         }
00575         if(!autopilot) {
00576                 dprintk("ai is bad!");
00577                 return;
00578         }
00579         if(!IsMech(mech->mynum) || !IsAuto(autopilot->mynum))
00580                 return;
00581 
00582         /* Ok our mech is dead we're done */
00583         if(Destroyed(mech)) {
00584                 return;
00585         }
00586     
00587         /* Log Message */
00588         print_autogun_log(autopilot, "Profiling Unit #%d", mech->mynum);
00589 
00590         /* Destroy the arrays first, don't worry about the weap
00591          * structures because we can clear them with the ddlist
00592          * weaplist */
00593 
00594         /* Zero the array of rbtree stuff */
00595         for(range = 0; range < AUTO_PROFILE_MAX_SIZE; range++) {
00596 
00597                 if(autopilot->profile[range]) {
00598 
00599                         /* Destroy rbtree */
00600                         rb_destroy(autopilot->profile[range]);
00601                 }
00602                 autopilot->profile[range] = NULL;
00603         }
00604 
00605         /* Check to see if the weaplist exists */
00606         if(autopilot->weaplist != NULL) {
00607 
00608                 /* Destroy the list */
00609                 auto_destroy_weaplist(autopilot);
00610         }
00611 
00612         /* List doesn't exist so lets build it */
00613         autopilot->weaplist = dllist_create_list();
00614 
00615         /* Reset the AI's max range value for its mech */
00616         autopilot->mech_max_range = 0;
00617 
00618         /* Set our counter */
00619         weapon_count = -1;
00620 
00621         /* Now loop through the weapons building a list */
00622         for(section = 0; section < NUM_SECTIONS; section++) {
00623 
00624                 /* Find all the weapons for a given section */
00625                 weapon_count_section = FindWeapons(mech, section,
00626                                                                                    weaparray, weapdata, critical);
00627 
00628                 /* No weapons here */
00629                 if(weapon_count_section <= 0)
00630                         continue;
00631 
00632                 /* loop through the possible weapons */
00633                 for(weapon_number = 0; weapon_number < weapon_count_section;
00634                         weapon_number++) {
00635 
00636                         /* Count it even if its not a valid weapon like AMS */
00637                         /* This is so when we go to fire the weapon we know
00638                          * which one to send in the command */
00639                         weapon_count++;
00640 
00641                         if(IsAMS(weaparray[weapon_number]))
00642                                 continue;
00643 
00644                         /* Does it work? */
00645                         if(WeaponIsNonfunctional(mech, section, critical[weapon_number],
00646                                                                          GetWeaponCrits(mech,
00647                                                                                                         Weapon2I(weaparray
00648                                                                                                                          [weapon_number])))
00649                            > 0)
00650                                 continue;
00651 
00652                         /* Ok made it this far, lets add it to our list */
00653                         temp_weapon_node = auto_create_weapon_node(weapon_count,
00654                                                                                                            weaparray
00655                                                                                                            [weapon_number],
00656                                                                                                            section,
00657                                                                                                            critical
00658                                                                                                            [weapon_number]);
00659 
00660                         temp_dllist_node = dllist_create_node(temp_weapon_node);
00661                         dllist_insert_end(autopilot->weaplist, temp_dllist_node);
00662 
00663                         /* Check the max range */
00664                         if(autopilot->mech_max_range <
00665                            MechWeapons[weaparray[weapon_number]].longrange) {
00666                                 autopilot->mech_max_range =
00667                                         MechWeapons[weaparray[weapon_number]].longrange;
00668                         }
00669 
00670                 }
00671 
00672         }
00673 
00674         /* Now build the profile array, basicly loop through 
00675          * all the current avail weapons, get its max range,
00676          * then loop through ranges and for each range add it
00677          * to profile */
00678 
00679         /* Our counter */
00680         weapon_number = 1;
00681 
00682         while (weapon_number <= dllist_size(autopilot->weaplist)) {
00683 
00684                 /* Get the weapon */
00685                 temp_weapon_node =
00686                         (weapon_node *) dllist_get_node(autopilot->weaplist,
00687                                                                                         weapon_number);
00688 
00689                 for(range = 0; range <
00690                         MechWeapons[temp_weapon_node->weapon_db_number].longrange;
00691                         range++) {
00692 
00693                         /* Out side the the range of AI's profile system */
00694                         if(range >= AUTO_PROFILE_MAX_SIZE) {
00695                                 break;
00696                         }
00697 
00698                         /* Score the weapon */
00699                         temp_weapon_node->range_scores[range] =
00700                                 auto_calc_weapon_score(temp_weapon_node->weapon_db_number,
00701                                                                            range);
00702 
00703                         /* If rbtree for this range doesn't exist, create it */
00704                         if(autopilot->profile[range] == NULL) {
00705                                 autopilot->profile[range] =
00706                                         rb_init(&auto_generic_compare, NULL);
00707                         }
00708 
00709                         /* Check to see if the score exists in the tree
00710                          * if so alter it slightly so we don't have
00711                          * overlaping keys */
00712                         while (1) {
00713 
00714                                 if(rb_exists(autopilot->profile[range],
00715                                                          &temp_weapon_node->range_scores[range])) {
00716                                         temp_weapon_node->range_scores[range]++;
00717                                 } else {
00718                                         break;
00719                                 }
00720 
00721                         }
00722 
00723                         /* Add it to tree */
00724                         rb_insert(autopilot->profile[range],
00725                                           &temp_weapon_node->range_scores[range],
00726                                           temp_weapon_node);
00727 
00728                 }
00729 
00730                 /* Increment */
00731                 weapon_number++;
00732 
00733         }
00734 
00735         /* Log Message */
00736         print_autogun_log(autopilot, "Finished Profiling");
00737 
00738 }

int PrefVisSens ( MECH mech,
MAP map,
int  slite,
MECH target 
)

Definition at line 124 of file autopilot_autogun.c.

References MAP::maplight, MechCritStatus, MechStatus, SENSOR_LA, SENSOR_VIS, SLITE_LIT, and SLITE_ON.

Referenced by auto_sensor_event().

00125 {
00126 
00127         /* No map or mech so use default till we get put somewhere */
00128         if(!mech || !map)
00129                 return SENSOR_VIS;
00130 
00131         /* Ok the AI is lit or using slite so use V */
00132         if(MechStatus(mech) & SLITE_ON || MechCritStatus(mech) & SLITE_LIT)
00133                 return SENSOR_VIS;
00134 
00135         /* The target is lit so use V */
00136         if(target && MechCritStatus(target) & SLITE_LIT)
00137                 return SENSOR_VIS;
00138 
00139         /* Ok if its night/dawn/dusk and theres no slite use L */
00140         if(map->maplight <= 1 && slite != 3 && slite != 5)
00141                 return SENSOR_LA;
00142 
00143         /* Default sensor */
00144         return SENSOR_VIS;
00145 }

int SearchLightInRange ( MECH mech,
MAP map 
)

Todo:
{ Add more code to the sensor system so the AI can be more aware of its terrain }

Definition at line 54 of file autopilot_autogun.c.

References FaMechRange, FindObjectsData(), MAP::first_free, FORWARDARC, InWeaponArc(), LITE_RANGE, MechCritStatus, MechFX, MechFY, MECHLOSFLAG_BLOCK, MAP::mechsOnMap, MechSpecials, MechStatus, SLITE_DEST, SLITE_ON, and SLITE_TECH.

Referenced by auto_sensor_event().

00055 {
00056 
00057         MECH *target;
00058         int i;
00059 
00060         /* Make sure theres a valid mech or map */
00061         if(!mech || !map)
00062                 return 0;
00063 
00064         /* Loop through all the units on the map */
00065         for(i = 0; i < map->first_free; i++) {
00066 
00067                 /* No units on the map */
00068                 if(!(target = FindObjectsData(map->mechsOnMap[i])))
00069                         continue;
00070 
00071                 /* The unit doesn't have slite on */
00072                 if(!(MechSpecials(target) & SLITE_TECH)
00073                    || MechCritStatus(mech) & SLITE_DEST)
00074                         continue;
00075 
00076                 /* Is the mech close enough to be affected by the slite */
00077                 if(FaMechRange(target, mech) < LITE_RANGE) {
00078 
00079                         /* Returning true, but let's differentiate also between being in-arc. */
00080                         if((MechStatus(target) & SLITE_ON) &&
00081                            InWeaponArc(target, MechFX(mech), MechFY(mech)) & FORWARDARC) {
00082 
00083                                 /* Make sure its in los */
00084                                 if(!
00085                                    (map->
00086                                         LOSinfo[target->mapnumber][mech->
00087                                                                                            mapnumber] &
00088                                         MECHLOSFLAG_BLOCK))
00089 
00090                                         /* Slite on and, arced, and LoS to you */
00091                                         return 3;
00092                                 else
00093                                         /* Slite on, arced, but LoS blocked */
00094                                         return 4;
00095 
00096                         } else if(!MechStatus(target) & SLITE_ON &&
00097                                           InWeaponArc(target, MechFX(mech),
00098                                                                   MechFY(mech)) & FORWARDARC) {
00099 
00100                                 if(!
00101                                    (map->
00102                                         LOSinfo[target->mapnumber][mech->
00103                                                                                            mapnumber] &
00104                                         MECHLOSFLAG_BLOCK))
00105 
00106                                         /* Slite off, arced, and LoS to you */
00107                                         return 5;
00108 
00109                                 else
00110                                         /* Slite off, arced, and LoS blocked */
00111                                         return 6;
00112                         }
00113 
00114                         /* Slite is in range of you, but apparently not arced on you. 
00115                          * Return tells wether on or off */
00116                         return (MechStatus(target) & SLITE_ON ? 1 : 2);
00117                 }
00118 
00119         }
00120         return 0;
00121 }


Generated on Mon May 28 04:25:32 2007 for BattletechMUX by  doxygen 1.4.7