src/hcode/btech/autopilot_ai.c File Reference

#include <math.h>
#include "mech.h"
#include "autopilot.h"
#include "p.autopilot_command.h"
#include "p.mech.utils.h"
#include "p.map.obj.h"
#include "spath.h"
#include "p.mech.combat.h"
#include "p.glue.hcode.h"

Include dependency graph for autopilot_ai.c:

Go to the source code of this file.

Data Structures

struct  LOC

Defines

#define SCORE_MOD   100
#define SAFE_SCORE   SCORE_MOD * 1000
#define MIN_SAFE   8
#define NORM_SAFE   32
#define MAX_SIM_PATHS   40
#define MNORM_COUNT   37
#define CFAST_COUNT   9
#define Floodable(loc)   (!GetSectArmor(m,loc) || (!GetSectRArmor(m,loc) && GetSectORArmor(m,loc)))
#define FloodCheck(loc)   if (GetSectInt(m,loc)) if (Floodable(loc)) return 1;
#define MAGIC_NUM   -123456
#define U1(a, b)   if (a < b || a == MAGIC_NUM) a = b
#define U2(a, b)   if (a > b || a == MAGIC_NUM) a = b
#define FU(a, b, c, s)   ((b) == (c) ? 0 : (s) * ((a) - (b)) / ((c) - (b)))
#define UNREF(a, b, mod)   if (a != MAGIC_NUM && b != MAGIC_NUM) { int c = a, d = b; a = (c * (mod - 1) + d) / mod; b = (c + d * (mod - 1)) / mod; }

Enumerations

enum  { SP_OPT_NORM, SP_OPT_FASTER, SP_OPT_SLOWER, SP_OPT_C }

Functions

void sendAIM (AUTO *a, MECH *m, char *msg)
char * AI_Info (MECH *m, AUTO *a)
float terrain_speed (MECH *mech, float tempspeed, float maxspeed, int terrain, int elev)
static int ai_crash (MAP *map, MECH *m, LOC *l)
static void LOCInit (LOC *l, MECH *m)
int getEnemies (MECH *mech, MAP *map, int reset)
int getFriends (MECH *mech, MAP *map, int reset)
void ai_path_score (MECH *m, MAP *map, AUTO *a, int opts[][2], int num_o, int gotenemy, float dx, float dy, float delx, float dely, int *rl, int *bd, int *bscore)
int ai_max_speed (MECH *m, AUTO *a)
int ai_opponents (AUTO *a, MECH *m)
void ai_run_speed (MECH *mech, AUTO *a)
void ai_stop (MECH *mech, AUTO *a)
void ai_set_speed (MECH *mech, AUTO *a, float spd)
void ai_set_heading (MECH *mech, AUTO *a, int dir)
void ai_adjust_move (AUTO *a, MECH *m, char *text, int hmod, int smod, int b_score)
int ai_check_path (MECH *m, AUTO *a, float dx, float dy, float delx, float dely)
void ai_init (AUTO *a, MECH *m)
int artillery_round_flight_time (float fx, float fy, float tx, float ty)
static int mech_snipe_func (MECH *mech, dbref player, int index, int high)
void mech_snipe (dbref player, MECH *mech, char *buffer)
static astar_nodeauto_create_astar_node (short x, short y, short x_parent, short y_parent, short g_score, short h_score)
int astar_compare (int a, int b, void *arg)
void astar_release (void *key, void *data)
int auto_astar_generate_path (AUTO *autopilot, MECH *mech, short end_x, short end_y)
void astar_smooth_path (AUTO *autopilot)
void auto_destroy_astar_path (AUTO *autopilot)

Variables

int sp_opt [SP_OPT_C] = { 0, 1, -1 }
int move_norm_opt [MNORM_COUNT][2]
int combat_fast_opt [CFAST_COUNT][2]
static LOC enemy_l [MAX_MECHS_PER_MAP]
static MECHenemy_m [MAX_MECHS_PER_MAP]
static int enemy_o [MAX_MECHS_PER_MAP]
static int enemy_i [MAX_MECHS_PER_MAP]
static int enemy_c = 0
static LOC friend_l [MAX_MECHS_PER_MAP]
static MECHfriend_m [MAX_MECHS_PER_MAP]
static int friend_o [MAX_MECHS_PER_MAP]
static int friend_i [MAX_MECHS_PER_MAP]
static int friend_c = 0
static MECHtarget_mech


Define Documentation

#define CFAST_COUNT   9

Definition at line 94 of file autopilot_ai.c.

Referenced by ai_check_path().

#define Floodable ( loc   )     (!GetSectArmor(m,loc) || (!GetSectRArmor(m,loc) && GetSectORArmor(m,loc)))

#define FloodCheck ( loc   )     if (GetSectInt(m,loc)) if (Floodable(loc)) return 1;

Referenced by ai_crash().

#define FU ( a,
b,
c,
 )     ((b) == (c) ? 0 : (s) * ((a) - (b)) / ((c) - (b)))

Definition at line 406 of file autopilot_ai.c.

#define MAGIC_NUM   -123456

Definition at line 402 of file autopilot_ai.c.

Referenced by ai_check_path().

#define MAX_SIM_PATHS   40

Definition at line 36 of file autopilot_ai.c.

Referenced by ai_path_score().

#define MIN_SAFE   8

Definition at line 34 of file autopilot_ai.c.

Referenced by ai_check_path().

#define MNORM_COUNT   37

Definition at line 52 of file autopilot_ai.c.

Referenced by ai_check_path().

#define NORM_SAFE   32

Definition at line 35 of file autopilot_ai.c.

Referenced by ai_path_score().

#define SAFE_SCORE   SCORE_MOD * 1000

Definition at line 33 of file autopilot_ai.c.

Referenced by ai_check_path().

#define SCORE_MOD   100

Definition at line 32 of file autopilot_ai.c.

#define U1 ( a,
 )     if (a < b || a == MAGIC_NUM) a = b

Definition at line 404 of file autopilot_ai.c.

#define U2 ( a,
 )     if (a > b || a == MAGIC_NUM) a = b

Definition at line 405 of file autopilot_ai.c.

#define UNREF ( a,
b,
mod   )     if (a != MAGIC_NUM && b != MAGIC_NUM) { int c = a, d = b; a = (c * (mod - 1) + d) / mod; b = (c + d * (mod - 1)) / mod; }

Definition at line 783 of file autopilot_ai.c.

Referenced by ai_check_path().


Enumeration Type Documentation

anonymous enum

Enumerator:
SP_OPT_NORM 
SP_OPT_FASTER 
SP_OPT_SLOWER 
SP_OPT_C 

Definition at line 47 of file autopilot_ai.c.

00047      {
00048         SP_OPT_NORM, SP_OPT_FASTER, SP_OPT_SLOWER, SP_OPT_C
00049 };


Function Documentation

void ai_adjust_move ( AUTO a,
MECH m,
char *  text,
int  hmod,
int  smod,
int  b_score 
)

Definition at line 785 of file autopilot_ai.c.

References AI_Info(), ai_set_heading(), ai_set_speed(), MechDesiredFacing, MechDesiredSpeed, MMaxSpeed, MP1, SendAI, SP_OPT_FASTER, and SP_OPT_SLOWER.

Referenced by ai_check_path().

00787 {
00788         float ms;
00789 
00790         ai_set_heading(m, a, MechDesiredFacing(m) + hmod);
00791         switch (smod) {
00792         default:
00793                 SendAI("%s state: %s (hmod:%d) sc:%d", AI_Info(m, a), text, hmod,
00794                            b_score);
00795                 break;
00796         case SP_OPT_FASTER:
00797                 SendAI("%s state: %s+accelerating (hmod:%d) sc:%d", AI_Info(m, a),
00798                            text, hmod, b_score);
00799                 ms = MMaxSpeed(m);
00800                 ai_set_speed(m, a,
00801                                          (float) ((MechDesiredSpeed(m) <
00802                                                            MP1 ? MP1 : MechDesiredSpeed(m)) * 4.0 / 3.0));
00803                 break;
00804         case SP_OPT_SLOWER:
00805                 SendAI("%s state: %s+decelerating (hmod:%d) sc:%d", AI_Info(m, a),
00806                            text, hmod, b_score);
00807                 ms = MMaxSpeed(m);
00808                 ai_set_speed(m, a, (int) (MechDesiredSpeed(m) * 2.0 / 3.0));
00809                 break;
00810         }
00811 }

int ai_check_path ( MECH m,
AUTO a,
float  dx,
float  dy,
float  delx,
float  dely 
)

Definition at line 813 of file autopilot_ai.c.

References ai_adjust_move(), AI_Info(), ai_opponents(), ai_path_score(), ai_stop(), AUTO_GOET, AUTO_GOTT, AUTOPILOT_GOTO_TICK, AUTO::b_bsc, AUTO::b_dan, AUTO::b_msc, CFAST_COUNT, CLASS_MECH, combat_fast_opt, getEnemies(), getFriends(), getMap(), AUTO::last_upd, MAGIC_NUM, MECH::mapindex, MAX, MechType, MIN_SAFE, MNORM_COUNT, move_norm_opt, mudstate, muxevent_tick, statedata::now, SAFE_SCORE, SendAI, sendAIM(), UNREF, AUTO::w_bsc, AUTO::w_dan, and AUTO::w_msc.

Referenced by auto_goto_event().

00815 {
00816         int o;
00817         int b_len, bl, b, b_score;
00818         MAP *map = getMap(m->mapindex);
00819 
00820         o = ai_opponents(a, m);
00821         if(a->last_upd > mudstate.now || (mudstate.now - a->last_upd) > AUTO_GOET) {
00822                 if((muxevent_tick - a->last_upd) > AUTO_GOTT) {
00823                         a->b_msc = MAGIC_NUM;
00824                         a->w_msc = MAGIC_NUM;
00825                         a->b_bsc = MAGIC_NUM;
00826                         a->w_bsc = MAGIC_NUM;
00827                         a->b_dan = MAGIC_NUM;
00828                         a->b_dan = (40 + 20 * 29 + 100) * 30;   /* To stay focused */
00829                 } else {
00830                         /* Slight update ; Un-refine the goals somewhat */
00831                         UNREF(a->w_msc, a->b_msc, 3);
00832                         UNREF(a->w_bsc, a->b_bsc, 5);
00833                         UNREF(a->w_dan, a->b_dan, 8);
00834                         a->b_dan = MAX(a->b_dan, (40 + 20 * 29 + 100) * 30);    /* To stay focused */
00835                 }
00836                 a->last_upd = mudstate.now;
00837         }
00838         /* Got either opponents (nasty) or [possibly] blocked path (slightly nasty), i.e. 12sec */
00839         if(MechType(m) == CLASS_MECH)
00840                 getFriends(m, map, 0);
00841         if(o) {
00842                 getEnemies(m, map, 0);
00843                 if(!((muxevent_tick / AUTOPILOT_GOTO_TICK) % 4)) {      /* Just every fourth tick, i.e. 12sec */
00844                         /* Thorough check */
00845                         ai_path_score(m, map, a, move_norm_opt, MNORM_COUNT, 1, dx, dy,
00846                                                   delx, dely, &bl, &b, &b_score);
00847                         b_len = b_score / SAFE_SCORE;
00848                         if(b_len >= MIN_SAFE)
00849                                 ai_adjust_move(a, m, "combat(/twitchy)",
00850                                                            move_norm_opt[b][0], move_norm_opt[b][1],
00851                                                            b_score);
00852                 } else {
00853                         ai_path_score(m, map, a, combat_fast_opt, CFAST_COUNT, 1, dx,
00854                                                   dy, delx, dely, &bl, &b, &b_score);
00855                         b_len = b_score / SAFE_SCORE;
00856                         if(b_len >= MIN_SAFE)
00857                                 ai_adjust_move(a, m, "[f]combat(/twitchy)",
00858                                                            combat_fast_opt[b][0], combat_fast_opt[b][1],
00859                                                            b_score);
00860                 }
00861                 return 1;                               /* We want to keep fighting near foes */
00862         }
00863         if(!((muxevent_tick / AUTOPILOT_GOTO_TICK) % 4)) {      /* Just every fourth tick, i.e. 12sec */
00864                 /* Thorough check */
00865                 ai_path_score(m, map, a, move_norm_opt, MNORM_COUNT, 0, dx, dy,
00866                                           delx, dely, &bl, &b, &b_score);
00867                 b_len = b_score / SAFE_SCORE;
00868                 if(b_len >= MIN_SAFE)
00869                         ai_adjust_move(a, m, "moving", move_norm_opt[b][0],
00870                                                    move_norm_opt[b][1], b_score);
00871         } else {
00872                 ai_path_score(m, map, a, combat_fast_opt, CFAST_COUNT, 0, dx, dy,
00873                                           delx, dely, &bl, &b, &b_score);
00874                 b_len = b_score / SAFE_SCORE;
00875                 if(b_len >= MIN_SAFE)
00876                         ai_adjust_move(a, m, "[f]moving", combat_fast_opt[b][0],
00877                                                    combat_fast_opt[b][1], b_score);
00878         }
00879 
00880         if(b_len >= MIN_SAFE)
00881                 return 1;
00882 
00883         /* Slow down + stop - no sense in dying needlessly */
00884         ai_stop(m, a);
00885         SendAI("%s state: panic", AI_Info(m, a));
00886         sendAIM(a, m, "PANIC! Unable to comply with order.");
00887         return 0;
00888 }

static int ai_crash ( MAP map,
MECH m,
LOC l 
) [static]

Definition at line 126 of file autopilot_ai.c.

References ACCEL_MOD, BOUNDED(), confdata::btech_slowdown, CLASS_BSUIT, CLASS_MECH, CLASS_MW, CLASS_VEH_GROUND, LOC::dh, LOC::ds, LOC::e, Elevation, FindComponents(), FloodCheck, LOC::fx, LOC::fy, GetRTerrain, GYRO_DESTROYED, LOC::h, HEAVY_FOREST, HIGHWATER, is_aero, IsDS, Landed, LARM, LLEG, LOC::lx, LOC::ly, MAP::map_height, MAP::map_width, MAX, MechCritStatus, MechDesiredFacing, MechFacing, MechIsQuad, MechLateral, MechMove, MechType, MMaxSpeed, MOVE_FLY, MOVE_HOVER, MOVE_MOD, MOVE_TRACK, MOVE_VTOL, MOVE_WHEEL, MP1, MP_PER_KPH, mudconf, NUM_SECTIONS, RARM, RealCoordToMapCoord(), RLEG, LOC::s, LOC::t, terrain_speed(), WATER, LOC::x, and LOC::y.

Referenced by ai_path_score(), and mech_snipe_func().

00127 {
00128         float newx = 0.0, newy = 0.0;
00129         float tempspeed, maxspeed, acc;
00130         int offset;
00131         int normangle;
00132         int mw_mod = 1;
00133         int ch = 0;
00134 
00135         if(!map)
00136                 return 0;
00137 
00138         maxspeed = MMaxSpeed(m);
00139 
00140         /* UpdateHeading */
00141         if(l->h != l->dh && !(MechCritStatus(m) & GYRO_DESTROYED)) {
00142                 ch = 1;
00143                 if(is_aero(m))
00144                         maxspeed = maxspeed * ACCEL_MOD;
00145                 normangle = l->h - l->dh;
00146                 if(MechType(m) == CLASS_MW || MechType(m) == CLASS_BSUIT)
00147                         mw_mod = 60;
00148                 /* XXX Jumping */
00149                 if(fabs(l->s) < 1.0)
00150                         offset = 3 * maxspeed * MP_PER_KPH * mw_mod;
00151                 else {
00152                         offset = 2 * maxspeed * MP_PER_KPH * mw_mod;
00153                         if((abs(normangle) > offset) && (l->s > (maxspeed * 2 / 3)))
00154                                 offset -= offset / 2 * (3.0 * l->s / maxspeed - 2.0);
00155                 }
00156                 offset = offset * MOVE_MOD;
00157                 if(normangle < 0)
00158                         normangle += 360;
00159                 if(IsDS(m) && offset >= 10)
00160                         offset = 10;
00161                 if(normangle > 180) {
00162                         l->h += offset;
00163                         if(l->h >= 360)
00164                                 l->h -= 360;
00165                         normangle += offset;
00166                         if(normangle >= 360)
00167                                 l->h = l->dh;
00168                 } else {
00169                         l->h -= offset;
00170                         if(l->h < 0)
00171                                 l->h += 360;
00172                         normangle -= offset;
00173                         if(normangle < 0)
00174                                 l->h = l->dh;
00175                 }
00176 
00177         }
00178         /* UpdateSpeed */
00179         /* XXX MASC */
00180         /* XXX heat (_hard_ to track) */
00181         tempspeed = l->ds;
00182         if(MechType(m) != CLASS_MW && MechMove(m) != MOVE_VTOL &&
00183            (MechMove(m) != MOVE_FLY || Landed(m)))
00184                 tempspeed = terrain_speed(m, tempspeed, maxspeed, l->t, l->e);
00185         if(ch) {
00186                 if(mudconf.btech_slowdown == 2) {
00187                         int dif = MechFacing(m) - MechDesiredFacing(m);
00188 
00189                         if(dif < 0)
00190                                 dif = -dif;
00191                         if(dif > 180)
00192                                 dif = 360 - dif;
00193                         if(dif) {
00194                                 dif = (dif - 1) / 30 + 2;
00195                                 tempspeed = tempspeed * (10 - dif) / 10;
00196                         }
00197                 } else if(mudconf.btech_slowdown == 1) {
00198                         if(l->h != l->dh)
00199                                 tempspeed = tempspeed * 2.0 / 3.0;
00200                         else
00201                                 tempspeed = tempspeed * 3.0 / 4.0;
00202                 }
00203         }
00204         if(MechIsQuad(m) && MechLateral(m))
00205                 tempspeed -= MP1;
00206         if(tempspeed <= 0.0) {
00207                 tempspeed = 0.0;
00208         }
00209         if(l->ds < 0.)
00210                 tempspeed = -tempspeed;
00211         if(tempspeed != l->s) {
00212                 if(MechIsQuad(m))
00213                         acc = maxspeed / 10.;
00214                 else
00215                         acc = maxspeed / 20.;
00216                 if(tempspeed < l->s) {
00217                         /* Decelerating */
00218                         l->s -= acc;
00219                         if(tempspeed > l->s)
00220                                 l->s = tempspeed;
00221                 } else {
00222                         /* Accelerating */
00223                         l->s += acc;
00224                         if(tempspeed < l->s)
00225                                 l->s = tempspeed;
00226                 }
00227         }
00228         /* move_mech + NewHexEntered */
00229         /* XXX Jumping mechs [aeros,VTOLs] */
00230         /* XXX Non-mechs */
00231         /* XXX Quads */
00232         FindComponents(l->s * MOVE_MOD, l->h, &newx, &newy);
00233         l->fx += newx;
00234         l->fy += newy;
00235         l->lx = l->x;
00236         l->ly = l->y;
00237         RealCoordToMapCoord(&l->x, &l->y, l->fx, l->fy);
00238         /* Ensure we don't run off map */
00239         if(BOUNDED(0, l->x, map->map_width - 1) != l->x)
00240                 return 1;
00241         if(BOUNDED(0, l->y, map->map_height - 1) != l->y)
00242                 return 1;
00243         if(l->lx != l->x || l->ly != l->y) {
00244                 int oz = l->e;
00245 
00246                 /* Ensure if mech m can do transition auto_lx,auto_ly => auto_x,auto_y */
00247 
00248                 /* XXX Decent handling of terrain choosing and stuff */
00249                 switch (GetRTerrain(map, l->x, l->y)) {
00250                 case HEAVY_FOREST:
00251                         if(MechType(m) != CLASS_MECH)
00252                                 return 1;
00253                         break;
00254                 case WATER:
00255                         if(MechMove(m) == MOVE_TRACK || MechMove(m) == MOVE_WHEEL)
00256                                 return 1;
00257                         else {
00258                                 /* Check floodability for mechs */
00259                                 if(MechType(m) == CLASS_MECH) {
00260                                         int t = Elevation(map, l->x, l->y);
00261 
00262                                         if(t < 0) {
00263                                                 if(t == -1) {
00264                                                         /* Check feet */
00265 #define Floodable(loc) (!GetSectArmor(m,loc) || (!GetSectRArmor(m,loc) && GetSectORArmor(m,loc)))
00266 #define FloodCheck(loc) if (GetSectInt(m,loc)) if (Floodable(loc)) return 1;
00267                                                         FloodCheck(LLEG);
00268                                                         FloodCheck(RLEG);
00269                                                         if(MechIsQuad(m)) {
00270                                                                 FloodCheck(LARM);
00271                                                                 FloodCheck(RARM);
00272                                                         }
00273                                                 } else {
00274                                                         int i;
00275 
00276                                                         for(i = 0; i < NUM_SECTIONS; i++)
00277                                                                 FloodCheck(i);
00278                                                 }
00279                                         }
00280                                 }
00281                         }
00282                         break;
00283                 case HIGHWATER:
00284                         return 1;
00285                         break;
00286                 }
00287                 l->e = Elevation(map, l->x, l->y);
00288                 if(MechMove(m) == MOVE_HOVER)
00289                         l->e = MAX(0, l->e);
00290                 l->t = GetRTerrain(map, l->x, l->y);
00291                 if(MechType(m) == CLASS_MECH)
00292                         if((l->e - oz) > 2 || (oz - l->e) > 2)
00293                                 return 1;
00294                 /* XXX Check flooding etc, should avoid _that_ */
00295                 if(MechType(m) == CLASS_VEH_GROUND)
00296                         if((l->e - oz) > 1 || (oz - l->e) > 1)
00297                                 return 1;
00298 
00299         }
00300         return 0;
00301 }

char* AI_Info ( MECH m,
AUTO a 
)

Definition at line 115 of file autopilot_ai.c.

References MECH::mapindex, MBUF_SIZE, MECH::mynum, and AUTO::mynum.

Referenced by ai_adjust_move(), and ai_check_path().

00116 {
00117         static char buf[MBUF_SIZE];
00118 
00119         sprintf(buf, "Unit#%d on #%d [A#%d]:", m->mynum, m->mapindex, a->mynum);
00120         return buf;
00121 }

void ai_init ( AUTO a,
MECH m 
)

Definition at line 890 of file autopilot_ai.c.

References AUTO::auto_cdist, AUTO::auto_cmode, AUTO::auto_fweight, AUTO::auto_goweight, AUTO::auto_nervous, AUTO::flags, AUTO::speed, and AUTO::target.

00891 {
00892 
00893         /* XXX Analyze our unit type ; set basic combat tactic */
00894         a->auto_cmode = 1;                      /* CHARGE! */
00895         a->auto_cdist = 2;                      /* Attempt to avoid kicking distance */
00896         a->auto_nervous = 0;
00897         a->auto_goweight = 44;          /* We're mainly concentrating on fighting */
00898         a->auto_fweight = 55;
00899         a->speed = 100;                         /* Reset to full speed */
00900         a->flags = 0;
00901         a->target = -1;
00902 }

int ai_max_speed ( MECH m,
AUTO a 
)

Definition at line 692 of file autopilot_ai.c.

References MechDesiredSpeed, and MMaxSpeed.

Referenced by ai_run_speed().

00693 {
00694         float ms;
00695 
00696         if(MechDesiredSpeed(m) != (ms = MMaxSpeed(m)))
00697                 return 0;
00698         return 1;
00699 }

int ai_opponents ( AUTO a,
MECH m 
)

Definition at line 701 of file autopilot_ai.c.

References AUTO::auto_nervous, and MechNumSeen.

Referenced by ai_check_path().

00702 {
00703         if(a->auto_nervous) {
00704                 a->auto_nervous--;
00705                 return 1;
00706         }
00707         if(MechNumSeen(m))
00708                 a->auto_nervous = 30;   /* We'll stay frisky for awhile even if cons are lost for one reason or another */
00709         return MechNumSeen(m);
00710 }

void ai_path_score ( MECH m,
MAP map,
AUTO a,
int  opts[][2],
int  num_o,
int  gotenemy,
float  dx,
float  dy,
float  delx,
float  dely,
int *  rl,
int *  bd,
int *  bscore 
)

Definition at line 408 of file autopilot_ai.c.

References AcceptableDegree(), ai_crash(), AUTO::auto_cdist, AUTO::auto_cmode, BOUNDED(), BSIDE, CLASS_MECH, CLASS_VEH_GROUND, LOC::dh, LOC::ds, enemy_c, enemy_l, enemy_m, enemy_o, FindBearing(), FindXYRange(), friend_c, friend_l, friend_m, friend_o, FSIDE, GetSectArmor, GetSectOArmor, LOC::h, LOCInit(), LSIDE, MAX, MAX_SIM_PATHS, MechType, MIN, MMaxSpeed, MP1, MP2, MP4, MP6, MP9, MyHexDist(), NORM_SAFE, RSIDE, sp_opt, SP_OPT_FASTER, WATER, x, and y.

Referenced by ai_check_path().

00411 {
00412         int i, j, k, l, bearing;
00413         int sd, sc;
00414         LOC lo[MAX_SIM_PATHS];
00415         int dan[MAX_SIM_PATHS], tdan[MAX_SIM_PATHS], msc[MAX_SIM_PATHS],
00416                 bsc[MAX_SIM_PATHS];
00417         int out[MAX_SIM_PATHS], stack[MAX_SIM_PATHS], br[MAX_SIM_PATHS];
00418 
00419         for(i = 0; i < num_o; i++) {
00420                 msc[i] = 0;
00421                 bsc[i] = 0;
00422                 dan[i] = 0;
00423                 tdan[i] = 0;
00424                 out[i] = 0;
00425                 stack[i] = 0;
00426                 br[i] = 9999;
00427                 LOCInit(&lo[i], m);
00428                 lo[i].dh = AcceptableDegree(lo[i].dh + opts[i][0]);
00429                 sd = sp_opt[opts[i][1]];
00430                 if(sd) {
00431                         if(sd < 0) {
00432                                 lo[i].ds = lo[i].ds * 2.0 / 3.0;
00433                         } else if(sd == 1) {
00434                                 float ms = MMaxSpeed(m);
00435 
00436                                 lo[i].ds = (lo[i].ds < MP1 ? MP1 : lo[i].ds) * 4.0 / 3.0;
00437                                 if(lo[i].ds > ms)
00438                                         lo[i].ds = ms;
00439                         } else {
00440                                 float ms = MMaxSpeed(m);
00441 
00442                                 lo[i].ds = ms;
00443                         }
00444                 }
00445         }
00446         for(i = 0; i < NORM_SAFE; i++) {
00447                 dx += delx;
00448                 dy += dely;
00449                 for(k = 0; k < num_o; k++) {
00450                         if(out[k])
00451                                 continue;
00452                         if(ai_crash(map, m, &lo[k])) {  /* Simulate _one_ step */
00453                                 out[k] = i + 1;
00454                                 continue;
00455                         }
00456                         /* Base target-acquisition stuff */
00457                         if((l = FindXYRange(lo[k].fx, lo[k].fy, dx, dy)) < br[k])
00458                                 br[k] = l;
00459 
00460                         /* Generally speaking we're going to the point spesified */
00461                         msc[k] += 4 * (2 * (50 - br[k]) + (100 - l));
00462 
00463                         /* Heading change's inherently [slightly] evil */
00464                         if(lo[k].h != lo[k].dh)
00465                                 msc[k] -= 1;
00466 
00467                         /* Moving is a good thing */
00468                         if(lo[k].x != lo[k].lx || lo[k].y != lo[k].ly) {
00469                                 if(lo[k].t == WATER)
00470                                         msc[k] -= 5;
00471                                 msc[k] += 10;
00472                         }
00473                         /* Punish for not utilizing full speed (this is .. hm, flaky) */
00474                         if(opts[k][1] != SP_OPT_FASTER && MMaxSpeed(m) > 0.1) {
00475                                 sc = BOUNDED(0, 100 * lo[k].ds / MMaxSpeed(m), 100);
00476                                 msc[k] -= (100 - sc) / 30;      /* Basically, unused speed is bad */
00477                         }
00478                 }
00479                 if(MechType(m) == CLASS_MECH) {
00480                         /* Simulate friends */
00481                         for(j = 0; j < friend_c; j++) {
00482                                 if(friend_o[j])
00483                                         continue;
00484                                 if(ai_crash(map, friend_m[j], &friend_l[j]))
00485                                         friend_o[j] = 1;
00486                         }
00487                         for(k = 0; k < num_o; k++) {
00488                                 int sc = 0;
00489 
00490                                 if(out[k] || stack[k])
00491                                         continue;
00492                                 /* Meaning of stack: Someone moves _into_ the hex */
00493                                 for(j = 0; j < friend_c; j++)
00494                                         if(!friend_o[j])
00495                                                 if(lo[k].x == friend_l[j].x &&
00496                                                    lo[k].y == friend_l[j].y)
00497                                                         sc++;
00498                                 if(sc > 1) {    /* Possible stackage */
00499                                         int osc = sc;
00500 
00501                                         for(j = 0; j < friend_c; j++)
00502                                                 if(!friend_o[j])
00503                                                         if(lo[k].x == friend_l[j].x &&
00504                                                            lo[k].y == friend_l[j].y)
00505                                                                 if((lo[k].lx != lo[k].x ||
00506                                                                         lo[k].ly != lo[k].y) ||
00507                                                                    (friend_l[j].lx != friend_l[j].x ||
00508                                                                         friend_l[j].ly != friend_l[j].y))
00509                                                                         osc--;
00510                                         if(osc != sc)
00511                                                 stack[k] = i + 1;
00512                                 }
00513                                 if(gotenemy)
00514                                         tdan[k] = 0;
00515                         }
00516                 }
00517                 if(gotenemy) {
00518                         /* Update enemy locations as well */
00519                         for(j = 0; j < enemy_c; j++) {
00520                                 if(enemy_o[j])
00521                                         continue;
00522                                 if(ai_crash(map, enemy_m[j], &enemy_l[j]))
00523                                         enemy_o[j] = 1;
00524                                 for(k = 0; k < num_o; k++) {
00525                                         if(out[k])
00526                                                 continue;
00527                                         if((l = MyHexDist(lo[k].x, lo[k].y, enemy_l[j].x,
00528                                                                           enemy_l[j].y, 0)) >= 100)
00529                                                 continue;
00530                                         switch (a->auto_cmode) {
00531                                         case 0: /* Withdraw */
00532                                                 if(l > a->auto_cdist)
00533                                                         bsc[k] += 5 * a->auto_cdist + l - a->auto_cdist;
00534                                                 else
00535                                                         bsc[k] += 5 * l;
00536                                                 break;
00537                                         case 1: /* Score  = fulfilling goal (=> distance from cdist) */
00538                                                 if(l < a->auto_cdist)
00539                                                         bsc[k] -= 10 * (a->auto_cdist - l);     /* Not too close */
00540                                                 else
00541                                                         bsc[k] -= 2 * (l - a->auto_cdist);
00542                                                 break;
00543                                         case 2:
00544                                                 if(l < a->auto_cdist)
00545                                                         bsc[k] -= 2 * (a->auto_cdist - l);
00546                                                 else
00547                                                         bsc[k] -= 10 * (l - a->auto_cdist);
00548                                         }
00549                                         if(l > 28)
00550                                                 continue;
00551                                         /* Danger modifier ; it's _always_ dangerous to be close */
00552                                         tdan[k] += (40 - MIN(40, l));
00553                                         /* Arcs can be .. dangerous */
00554                                         if(MechType(m) == CLASS_MECH) {
00555                                                 bearing =
00556                                                         FindBearing(lo[k].fx, lo[k].fy, enemy_l[j].fx,
00557                                                                                 enemy_l[j].fy);
00558                                                 bearing = lo[k].h - bearing;
00559                                                 if(bearing < 0)
00560                                                         bearing += 360;
00561                                                 if(bearing >= 90 && bearing <= 270) {
00562                                                         /* Sides are moderately dangerous [potential rear arcs] */
00563                                                         tdan[k] += 5 * (29 - MIN(29, l));
00564                                                         if(bearing >= 120 && bearing <= 240) {
00565                                                                 /* Rear arc is VERY dangerous */
00566                                                                 tdan[k] += 20 * (29 - MIN(29, l));
00567                                                         }
00568                                                 }
00569                                         } else if(MechType(m) == CLASS_VEH_GROUND) {
00570                                                 bearing =
00571                                                         FindBearing(lo[k].fx, lo[k].fy, enemy_l[j].fx,
00572                                                                                 enemy_l[j].fy);
00573                                                 bearing = lo[k].h - bearing;
00574                                                 if(bearing < 0)
00575                                                         bearing += 360;
00576                                                 if(bearing >= 45 && bearing <= 315) {
00577                                                         if(bearing >= 135 && bearing <= 225) {
00578                                                                 /* Rear arc is VERY dangerous */
00579                                                                 tdan[k] +=
00580                                                                         10 * (29 - MIN(29,
00581                                                                                                    l)) * (100 -
00582                                                                                                                   100 *
00583                                                                                                                   GetSectArmor(m,
00584                                                                                                                                            BSIDE)
00585                                                                                                                   / MAX(1,
00586                                                                                                                                 GetSectOArmor
00587                                                                                                                                 (m,
00588                                                                                                                                  BSIDE))) /
00589                                                                         100;
00590                                                         } else if(bearing < 135) {
00591                                                                 /* right side */
00592                                                                 tdan[k] +=
00593                                                                         7 * (29 - MIN(29,
00594                                                                                                   l)) * (100 -
00595                                                                                                                  100 * GetSectArmor(m,
00596                                                                                                                                                         RSIDE)
00597                                                                                                                  / MAX(1,
00598                                                                                                                            GetSectOArmor
00599                                                                                                                            (m,
00600                                                                                                                                 RSIDE))) /
00601                                                                         100;
00602                                                         } else {
00603                                                                 tdan[k] +=
00604                                                                         7 * (29 - MIN(29,
00605                                                                                                   l)) * (100 -
00606                                                                                                                  100 * GetSectArmor(m,
00607                                                                                                                                                         LSIDE)
00608                                                                                                                  / MAX(1,
00609                                                                                                                            GetSectOArmor
00610                                                                                                                            (m,
00611                                                                                                                                 LSIDE))) /
00612                                                                         100;
00613                                                         }
00614                                                 } else
00615                                                         tdan[k] +=
00616                                                                 5 * (29 - MIN(29,
00617                                                                                           l)) * (100 -
00618                                                                                                          100 * GetSectArmor(m,
00619                                                                                                                                                 FSIDE)
00620                                                                                                          / MAX(1,
00621                                                                                                                    GetSectOArmor(m,
00622                                                                                                                                                  FSIDE)))
00623                                                                 / 100;
00624                                         }
00625                                 }
00626                                 for(k = 0; k < num_o; k++) {
00627                                         if(out[k])
00628                                                 continue;
00629                                         /* Dangerous to be far from buddy in fight */
00630                                         l = FindXYRange(lo[k].fx, lo[k].fy, dx, dy);
00631                                         if(gotenemy && (delx != 0.0 || dely != 0.0))
00632                                                 tdan[k] += MIN(100, l * l);
00633                                         if(enemy_c)
00634                                                 tdan[k] = tdan[k] / enemy_c;
00635                                         /* It's inherently dangerous to move slowly: */
00636                                         if(lo[k].s <= MP2)
00637                                                 tdan[k] += 400;
00638                                         else if(lo[k].s <= MP4)
00639                                                 tdan[k] += 300;
00640                                         else if(lo[k].s <= MP6)
00641                                                 tdan[k] += 200;
00642                                         else if(lo[k].s <= MP9)
00643                                                 tdan[k] += 100;
00644                                         dan[k] += tdan[k] * (NORM_SAFE - i) / (NORM_SAFE / 2);
00645                                 }
00646                         }
00647                 }
00648         }
00649         for(i = 0; i < num_o; i++) {
00650                 U2(a->w_msc, msc[i]);
00651                 U1(a->b_msc, msc[i]);
00652                 if(gotenemy) {
00653                         U2(a->w_bsc, bsc[i]);
00654                         U1(a->b_bsc, bsc[i]);
00655                         U2(a->w_dan, dan[i]);
00656                         U1(a->b_dan, dan[i]);
00657                 }
00658         }
00659         /* Now we have been.. calibrated */
00660         *bscore = 0;
00661         *bd = -1;
00662         /* Find best overall score */
00663         for(i = 0; i < num_o; i++) {
00664                 if(!out[i])
00665                         out[i] = NORM_SAFE + 1;
00666                 if(!stack[i])
00667                         stack[i] = out[i];
00668                 sc = (out[i] - (out[i] - stack[i]) / 2) * SAFE_SCORE + FU(msc[i],
00669                                                                                                                                   a->w_msc,
00670                                                                                                                                   a->b_msc,
00671                                                                                                                                   SCORE_MOD *
00672                                                                                                                                   a->
00673                                                                                                                                   auto_goweight);
00674                 if(gotenemy)
00675                         sc +=
00676                                 FU(bsc[i], a->w_bsc, a->b_bsc,
00677                                    SCORE_MOD * a->auto_fweight) - FU(dan[i], a->w_dan,
00678                                                                                                          a->b_dan,
00679                                                                                                          SCORE_MOD *
00680                                                                                                          (a->auto_fweight +
00681                                                                                                           a->auto_goweight));
00682                 if(sc > *bscore
00683                    || (*bd >= 0 && sc == *bscore
00684                            && sp_opt[opts[i][1]] > sp_opt[opts[*bd][1]])) {
00685                         *bscore = sc;
00686                         *bd = i;
00687                         *rl = out[i] - 1;
00688                 }
00689         }
00690 }

void ai_run_speed ( MECH mech,
AUTO a 
)

Definition at line 712 of file autopilot_ai.c.

References ai_max_speed(), mech_speed(), and AUTO::mynum.

00713 {
00714         /* Warp speed, cap'n! */
00715         char buf[128];
00716 
00717         if(!ai_max_speed(mech, a)) {
00718                 strcpy(buf, "run");
00719                 mech_speed(a->mynum, mech, buf);
00720         }
00721 }

void ai_set_heading ( MECH mech,
AUTO a,
int  dir 
)

Definition at line 773 of file autopilot_ai.c.

References mech_heading(), MechDesiredFacing, and AUTO::mynum.

Referenced by ai_adjust_move().

00774 {
00775         char buf[128];
00776 
00777         if(dir == MechDesiredFacing(mech))
00778                 return;
00779         sprintf(buf, "%d", dir);
00780         mech_heading(a->mynum, mech, buf);
00781 }

void ai_set_speed ( MECH mech,
AUTO a,
float  spd 
)

Definition at line 757 of file autopilot_ai.c.

References FBOUNDED(), mech_speed(), MechDesiredSpeed, MMaxSpeed, AUTO::mynum, SBUF_SIZE, and AUTO::speed.

Referenced by ai_adjust_move(), auto_astar_follow_event(), auto_astar_goto_event(), auto_astar_roam_event(), auto_dumbgoto_event(), auto_enter_event(), auto_goto_event(), auto_leave_event(), slow_down_if_neccessary(), and speed_up_if_neccessary().

00758 {
00759         char buf[SBUF_SIZE];
00760         float newspeed;
00761 
00762         if(!mech || !a)
00763                 return;
00764 
00765         newspeed = FBOUNDED(0, spd, ((MMaxSpeed(mech) * a->speed) / 100.0));
00766 
00767         if(MechDesiredSpeed(mech) != newspeed) {
00768                 sprintf(buf, "%f", newspeed);
00769                 mech_speed(a->mynum, mech, buf);
00770         }
00771 }

void ai_stop ( MECH mech,
AUTO a 
)

Definition at line 723 of file autopilot_ai.c.

References mech_speed(), MechDesiredSpeed, and AUTO::mynum.

Referenced by ai_check_path().

00724 {
00725         char buf[128];
00726 
00727         if(MechDesiredSpeed(mech) > 0.1) {
00728                 strcpy(buf, "stop");
00729                 mech_speed(a->mynum, mech, buf);
00730         }
00731 }

int artillery_round_flight_time ( float  fx,
float  fy,
float  tx,
float  ty 
)

Definition at line 81 of file artillery.c.

00082 {
00083         int delay = MAX(ARTILLERY_MINIMUM_FLIGHT,
00084                                         (FindHexRange(fx, fy, tx, ty) / ARTY_SPEED));
00085 
00086         /* XXX Different weapons, diff. speed? */
00087         return delay;
00088 }

int astar_compare ( int  a,
int  b,
void *  arg 
)

Definition at line 986 of file autopilot_ai.c.

Referenced by auto_astar_generate_path().

00987 {
00988         return a - b;
00989 }

void astar_release ( void *  key,
void *  data 
)

Definition at line 990 of file autopilot_ai.c.

Referenced by auto_astar_generate_path().

00991 {
00992         free(data);
00993 }

void astar_smooth_path ( AUTO autopilot  ) 

Definition at line 1506 of file autopilot_ai.c.

01507 {
01508 
01509         dllist_node *current, *next, *prev;
01510 
01511         float x1, y1, x2, y2;
01512         int degrees;
01513 
01514         /* Get the n node off the list */
01515 
01516         /* Get the n+1 node off the list */
01517 
01518         /* Get bearing from n to n+1 */
01519 
01520         /* Get n+2 node off list */
01521 
01522         /* Get bearing from n to n+2 node */
01523 
01524         /* Compare bearings */
01525         /* If in same direction as previous
01526          * don't need n+1 node */
01527 
01528         /* Keep looping till bearing doesn't match */
01529         /* Then reset n node to final node and continue */
01530 
01531         return;
01532 
01533 }

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

Definition at line 994 of file autopilot_ai.c.

References astar_compare(), AUTO::astar_path, astar_release(), auto_create_astar_node(), auto_destroy_astar_path(), CheckHexBit, CLASS_MECH, CLASS_VEH_GROUND, ClearHexBit, dllist_create_list(), dllist_create_node(), dllist_insert_beginning(), Elevation, astar_node_t::f_score, FindHexRange(), FindXY(), astar_node_t::g_score, getMap(), GetTerrain, astar_node_t::h_score, HEAVY_FOREST, HexOffSet, astar_node_t::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 }

static astar_node* auto_create_astar_node ( short  x,
short  y,
short  x_parent,
short  y_parent,
short  g_score,
short  h_score 
) [static]

Definition at line 956 of file autopilot_ai.c.

References astar_node_t::f_score, astar_node_t::g_score, astar_node_t::h_score, astar_node_t::hexoffset, MAPY, astar_node_t::x, astar_node_t::x_parent, astar_node_t::y, and astar_node_t::y_parent.

Referenced by auto_astar_generate_path().

00959 {
00960 
00961         astar_node *temp;
00962         temp = malloc(sizeof(astar_node));
00963         if(temp == NULL)
00964                 return NULL;
00965 
00966         memset(temp, 0, sizeof(astar_node));
00967 
00968         temp->x = x;
00969         temp->y = y;
00970         temp->x_parent = x_parent;
00971         temp->y_parent = y_parent;
00972         temp->g_score = g_score;
00973         temp->h_score = h_score;
00974         temp->f_score = g_score + h_score;
00975         temp->hexoffset = x * MAPY + y;
00976 
00977         return temp;
00978 
00979 }

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 }

int getEnemies ( MECH mech,
MAP map,
int  reset 
)

Definition at line 331 of file autopilot_ai.c.

References COMBAT_SAFE, Destroyed, enemy_c, enemy_i, enemy_l, enemy_m, enemy_o, FindObjectsData(), MAP::first_free, FlMechRange, LOCInit(), MAP::mechsOnMap, MechStatus, and MechTeam.

Referenced by ai_check_path().

00332 {
00333         MECH *tempMech;
00334         int i;
00335 
00336         if(reset) {
00337                 for(i = 0; i < enemy_c; i++) {
00338                         LOCInit(&enemy_l[i], enemy_m[i]);       /* Just reset location */
00339                         enemy_o[i] = 0;
00340                 }
00341                 return 0;
00342         }
00343         enemy_c = 0;
00344         for(i = 0; i < map->first_free; i++) {
00345                 tempMech = FindObjectsData(map->mechsOnMap[i]);
00346                 if(!tempMech)
00347                         continue;
00348                 if(Destroyed(tempMech))
00349                         continue;
00350                 if(MechStatus(tempMech) & COMBAT_SAFE)
00351                         continue;
00352                 if(MechTeam(tempMech) == MechTeam(mech))
00353                         continue;
00354                 if(FlMechRange(map, mech, tempMech) > 50.0)
00355                         continue;                       /* Inconsequential */
00356                 /* Something that is _possibly_ unnerving */
00357                 LOCInit(&enemy_l[enemy_c], tempMech);   /* Location */
00358                 enemy_m[enemy_c] = tempMech;    /* Mech data */
00359                 enemy_i[enemy_c++] = i;
00360         }
00361         return enemy_c;
00362 }

int getFriends ( MECH mech,
MAP map,
int  reset 
)

Definition at line 364 of file autopilot_ai.c.

References CLASS_MECH, Destroyed, FindObjectsData(), MAP::first_free, FlMechRange, friend_c, friend_i, friend_l, friend_m, friend_o, LOCInit(), MAP::mechsOnMap, MechTeam, and MechType.

Referenced by ai_check_path().

00365 {
00366         MECH *tempMech;
00367         int i;
00368 
00369         if(reset) {
00370                 for(i = 0; i < friend_c; i++) {
00371                         LOCInit(&friend_l[i], friend_m[i]);     /* Just reset location */
00372                         friend_o[i] = 0;
00373                 }
00374                 return 0;
00375         }
00376         friend_c = 0;
00377         for(i = 0; i < map->first_free; i++) {
00378                 tempMech = FindObjectsData(map->mechsOnMap[i]);
00379                 if(!tempMech)
00380                         continue;
00381                 if(Destroyed(tempMech))
00382                         continue;
00383                 if(MechTeam(tempMech) != MechTeam(mech))
00384                         continue;
00385                 if(MechType(tempMech) != CLASS_MECH)
00386                         continue;
00387                 if(FlMechRange(map, mech, tempMech) > 50.0)
00388                         continue;                       /* Inconsequential */
00389                 LOCInit(&friend_l[friend_c], tempMech); /* Location */
00390                 friend_m[friend_c] = tempMech;  /* Mech data */
00391                 friend_i[friend_c++] = i;
00392         }
00393         return friend_c;
00394 }

static void LOCInit ( LOC l,
MECH m 
) [static]

Definition at line 303 of file autopilot_ai.c.

References LOC::dh, LOC::ds, LOC::e, LOC::fx, LOC::fy, LOC::h, LOC::lx, LOC::ly, MechDesiredFacing, MechDesiredSpeed, MechElevation, MechFacing, MechFX, MechFY, MechRTerrain, MechSpeed, MechX, MechY, LOC::s, LOC::t, LOC::x, and LOC::y.

Referenced by ai_path_score(), getEnemies(), getFriends(), and mech_snipe_func().

00304 {
00305         l->fx = MechFX(m);
00306         l->fy = MechFY(m);
00307         l->e = MechElevation(m);
00308         l->h = MechFacing(m);
00309         l->dh = MechDesiredFacing(m);
00310         l->s = MechSpeed(m);
00311         l->t = MechRTerrain(m);
00312         l->ds = MechDesiredSpeed(m);
00313         l->x = MechX(m);
00314         l->y = MechY(m);
00315         l->lx = MechX(m);
00316         l->ly = MechY(m);
00317 }

void mech_snipe ( dbref  player,
MECH mech,
char *  buffer 
)

Definition at line 932 of file autopilot_ai.c.

References args, DOCHECK, FindTargetDBREFFromMapNumber(), getMech(), mech_parseattributes(), mech_snipe_func(), multi_weap_sel(), target_mech, and WizRoy.

00933 {
00934         char *args[3];
00935         dbref d;
00936 
00937         DOCHECK(!WizRoy(player), "Permission denied.");
00938         DOCHECK(mech_parseattributes(buffer, args, 3) != 2,
00939                         "Please supply target ID _and_ weapon(s) to use");
00940         DOCHECK((d =
00941                          FindTargetDBREFFromMapNumber(mech, args[0])) <= 0,
00942                         "Invalid target!");
00943         target_mech = getMech(d);
00944         multi_weap_sel(mech, player, args[1], 1, mech_snipe_func);
00945 
00946 }

static int mech_snipe_func ( MECH mech,
dbref  player,
int  index,
int  high 
) [static]

Definition at line 908 of file autopilot_ai.c.

References ai_crash(), artillery_round_flight_time(), LOC::fx, LOC::fy, getMap(), LOCInit(), MECH::mapindex, mech_fireweapon(), mech_settarget(), MechFX, MechFY, MechTargX, MechTargY, target_mech, tprintf(), LOC::x, and LOC::y.

Referenced by mech_snipe().

00909 {
00910         /* Simulate mech movements until flight_time <= now */
00911         int now = 0, crashed = 0;
00912         int flt_time;
00913         LOC t;
00914         MAP *map = getMap(mech->mapindex);
00915 
00916         LOCInit(&t, target_mech);
00917         while ((flt_time =
00918                         artillery_round_flight_time(MechFX(mech), MechFY(mech), t.fx,
00919                                                                                 t.fy)) > now) {
00920                 if(!crashed)
00921                         if(ai_crash(map, target_mech, &t))
00922                                 crashed = 1;
00923                 now++;
00924         }
00925         /* Fire at t.x, t.y */
00926         if(MechTargX(mech) != t.x || MechTargY(mech) != t.y)
00927                 mech_settarget(player, mech, tprintf("%d %d", t.x, t.y));
00928         mech_fireweapon(player, mech, tprintf("%d", index));
00929         return 0;
00930 }

void sendAIM ( AUTO a,
MECH m,
char *  msg 
)

Definition at line 109 of file autopilot_ai.c.

References auto_reply(), and SendAI.

Referenced by ai_check_path().

00110 {
00111         auto_reply(m, msg);
00112         SendAI(msg);
00113 }

float terrain_speed ( MECH mech,
float  tempspeed,
float  maxspeed,
int  terrain,
int  elev 
)

Definition at line 936 of file mech.update.c.

Referenced by ai_crash(), and UpdateSpeed().

00938 {
00939         switch (terrain) {
00940         case SNOW:
00941         case ROUGH:
00942                 DECREASE(MP1);
00943                 break;
00944         case MOUNTAINS:
00945                 DECREASE(MP2);
00946                 break;
00947         case LIGHT_FOREST:
00948                 if(MechType(mech) != CLASS_BSUIT)
00949                         DECREASE(MP1);
00950                 break;
00951         case HEAVY_FOREST:
00952                 if(MechType(mech) != CLASS_BSUIT)
00953                         DECREASE(MP2);
00954                 break;
00955         case BRIDGE:
00956         case ROAD:
00957                 /* Ground units (wheeled and tracked) get +1 MP moving on paved surface */
00958 #ifndef BT_MOVEMENT_MODES
00959                 if(MechMove(mech) == MOVE_TRACK || MechMove(mech) == MOVE_WHEEL)
00960 #else
00961                 if(!(MechStatus2(mech) & SPRINTING) &&
00962                    (MechMove(mech) == MOVE_TRACK || MechMove(mech) == MOVE_WHEEL))
00963 #endif
00964                         INCREASE_OLD(MP1);
00965         case ICE:
00966                 if(MechZ(mech) >= 0)
00967                         break;
00968                 /* FALLTHRU */
00969                 /* if he's under the ice/bridge, treat as water. */
00970         case WATER:
00971                 if(MechIsBiped(mech) || MechIsQuad(mech)) {
00972                         if(elev <= -2)
00973                                 DECREASE(MP3);
00974                         else if(elev == -1)
00975                                 DECREASE(MP1);
00976                 }
00977                 break;
00978         }
00979         return tempspeed;
00980 }


Variable Documentation

int combat_fast_opt[CFAST_COUNT][2]

Initial value:

 {
        {0, SP_OPT_FASTER},
        {0, SP_OPT_NORM},
        {0, SP_OPT_SLOWER},
        {-10, SP_OPT_NORM},
        {10, SP_OPT_NORM},
        {-30, SP_OPT_NORM},
        {30, SP_OPT_NORM},
        {-60, SP_OPT_NORM},
        {60, SP_OPT_NORM}
}

Definition at line 97 of file autopilot_ai.c.

Referenced by ai_check_path().

int enemy_c = 0 [static]

Definition at line 323 of file autopilot_ai.c.

Referenced by ai_path_score(), and getEnemies().

int enemy_i[MAX_MECHS_PER_MAP] [static]

Definition at line 322 of file autopilot_ai.c.

Referenced by getEnemies().

LOC enemy_l[MAX_MECHS_PER_MAP] [static]

Definition at line 319 of file autopilot_ai.c.

Referenced by ai_path_score(), and getEnemies().

MECH* enemy_m[MAX_MECHS_PER_MAP] [static]

Definition at line 320 of file autopilot_ai.c.

Referenced by ai_path_score(), and getEnemies().

int enemy_o[MAX_MECHS_PER_MAP] [static]

Definition at line 321 of file autopilot_ai.c.

Referenced by ai_path_score(), and getEnemies().

int friend_c = 0 [static]

Definition at line 329 of file autopilot_ai.c.

Referenced by ai_path_score(), and getFriends().

int friend_i[MAX_MECHS_PER_MAP] [static]

Definition at line 328 of file autopilot_ai.c.

Referenced by getFriends().

LOC friend_l[MAX_MECHS_PER_MAP] [static]

Definition at line 325 of file autopilot_ai.c.

Referenced by ai_path_score(), and getFriends().

MECH* friend_m[MAX_MECHS_PER_MAP] [static]

Definition at line 326 of file autopilot_ai.c.

Referenced by ai_path_score(), and getFriends().

int friend_o[MAX_MECHS_PER_MAP] [static]

Definition at line 327 of file autopilot_ai.c.

Referenced by ai_path_score(), and getFriends().

int move_norm_opt[MNORM_COUNT][2]

Definition at line 54 of file autopilot_ai.c.

Referenced by ai_check_path().

int sp_opt[SP_OPT_C] = { 0, 1, -1 }

Definition at line 50 of file autopilot_ai.c.

Referenced by ai_path_score().

MECH* target_mech [static]

Definition at line 904 of file autopilot_ai.c.

Referenced by display_mechpref(), mech_mechprefs(), mech_snipe(), and mech_snipe_func().


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