#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 ADVANCE_PG | ( | a | ) | PG(a) += CCLEN(a); REDO(a,AUTOPILOT_NC_DELAY) |
Definition at line 166 of file autopilot.h.
Referenced by auto_com_event().
#define AssignedTarget | ( | a | ) | ((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 | ) | (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 |
#define AUTO_CHASETARGET_SAVE 4 |
#define AUTO_CHECKS | ( | a | ) |
Value:
Definition at line 157 of file autopilot.h.
Referenced by auto_com_event(), and auto_goto_event().
#define AUTO_COM | ( | a, | |||
n | ) | AUTOEVENT(a, EVENT_AUTOCOM, auto_com_event, (n), 0); |
#define AUTO_GOET 15 |
Definition at line 112 of file autopilot.h.
Referenced by ai_check_path().
#define AUTO_GOTT 240 |
#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 |
#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 |
#define AUTO_ROAM_MAX_RADIUS 30 |
#define AUTO_ROAM_NEW_HEX_TICK 100 |
#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 |
#define AUTOPILOT_CHASETARG 32 |
#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 |
#define AUTOPILOT_LEAVE_TICK 5 |
#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 |
#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 |
#define AUTOPILOT_WAITFOE_TICK 4 |
#define AUTOPILOT_WAS_CHASE_ON 64 |
Definition at line 34 of file autopilot.h.
#define CCLEN | ( | a | ) | (1 + acom[a->commands[a->program_counter]].argcount) |
#define ChasingTarget | ( | a | ) | ((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) |
#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 | ( | a | ) |
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 | ( | a | ) | 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 | ) | (a)->flags &= ~(AUTOPILOT_WAS_CHASE_ON) |
#define Gunning | ( | a | ) | ((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, | |||
b | ) |
Value:
(((a->program_counter + (b)) < a->first_free) ? \ a->commands[(a->program_counter+(b))] : -1)
Definition at line 144 of file autopilot.h.
Referenced by auto_com_event().
Definition at line 189 of file autopilot.h.
#define PG | ( | a | ) | a->program_counter |
#define PilZombify | ( | a | ) | do { a->flags |= AUTOPILOT_PILZOMBIE; } while (0) |
#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 | ) | (a)->flags |= AUTOPILOT_WAS_CHASE_ON |
#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 | ) | (a)->flags |= AUTOPILOT_CHASETARG |
#define StartGun | ( | a | ) | (a)->flags |= AUTOPILOT_AUTOGUN |
Definition at line 70 of file autopilot.h.
#define StopChasingTarget | ( | a | ) | (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 | ) | (a)->flags &= ~(AUTOPILOT_AUTOGUN|AUTOPILOT_GUNZOMBIE) |
#define UnassignTarget | ( | a | ) | (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 | ( | a | ) |
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 | ( | a | ) |
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 | ) | ((a)->flags & AUTOPILOT_WAS_CHASE_ON) |
#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 | ( | a | ) | 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 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 |
anonymous enum |
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 };
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 }
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 | ) |
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 | |||
) |
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 }
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 | ) |
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 }
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 }
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 }
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 }