src/hcode/btech/p.mech.los.h File Reference

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

Go to the source code of this file.

Functions

float ActualElevation (MAP *map, int x, int y, MECH *mech)
int CalculateLOSFlag (MECH *mech, MECH *target, MAP *map, int x, int y, int ff, float hexRange)
int AddTerrainMod (MECH *mech, MECH *target, MAP *map, float hexRange, int wAmmoMode)
int InLineOfSight_NB (MECH *mech, MECH *target, int x, int y, float hexRange)
int InLineOfSight (MECH *mech, MECH *target, int x, int y, float hexRange)
void mech_losemit (dbref player, MECH *mech, char *buffer)


Function Documentation

float ActualElevation ( MAP map,
int  x,
int  y,
MECH mech 
)

Definition at line 35 of file mech.los.c.

References CLASS_DS, CLASS_MECH, Elevation, Fallen, IsDS, MechDugIn, MechMove, MechType, MechZ, and MOVE_NONE.

Referenced by CalculateLOSFlag().

00036 {
00037 
00038         if(!map)
00039                 return 0.0;
00040         if(!mech)
00041                 return (float) (Elevation(map, x, y) + 0.1);
00042         if(MechType(mech) == CLASS_MECH && !Fallen(mech))
00043                 return (float) MechZ(mech) + 1.5;
00044         else if(MechMove(mech) == MOVE_NONE)
00045                 return (float) MechZ(mech) + 1.5;
00046         else if(IsDS(mech))
00047                 return (float) MechZ(mech) + 2.5 + (MechType(mech) ==
00048                                                                                         CLASS_DS ? 0 : 2);
00049         if(MechDugIn(mech))
00050                 return (float) MechZ(mech) + 0.1;
00051         return (float) MechZ(mech) + 0.5;
00052 }

int AddTerrainMod ( MECH mech,
MECH target,
MAP map,
float  hexRange,
int  wAmmoMode 
)

Definition at line 282 of file mech.los.c.

References MECHLOSFLAG_PARTIAL, MechStatus, MechToMech_LOSFlag, PARTIAL_COVER, and Sensor_ToHitBonus().

Referenced by FindNormalBTH(), and FireSpot().

00284 {
00285         /* Possibly do a quickie check only */
00286         if(mech && target) {
00287                 if(MechToMech_LOSFlag(map, mech, target) & MECHLOSFLAG_PARTIAL)
00288                         MechStatus(target) |= PARTIAL_COVER;
00289                 else
00290                         MechStatus(target) &= ~PARTIAL_COVER;
00291 
00292                 return Sensor_ToHitBonus(mech, target,
00293                                                                  MechToMech_LOSFlag(map, mech, target),
00294                                                                  map->maplight, hexRange, wAmmoMode);
00295         }
00296         return 0;
00297 }

int CalculateLOSFlag ( MECH mech,
MECH target,
MAP map,
int  x,
int  y,
int  ff,
float  hexRange 
)

Definition at line 60 of file mech.los.c.

References AA_TECH, ActualElevation(), BOUNDED(), BRIDGE, CLASS_MECH, Elevation, Fallen, FIRE, GetRTerrain, GetTerrain, HEAVY_FOREST, HIGHWATER, ICE, InWater, IsWater, LIGHT_FOREST, MAP::map_height, MAP::map_width, MAP::maxvis, MECHLOSFLAG_BLOCK, MECHLOSFLAG_FIRE, MECHLOSFLAG_MNTN, MECHLOSFLAG_PARTIAL, MECHLOSFLAG_SEEC2, MECHLOSFLAG_SEEN, MECHLOSFLAG_SMOKE, MECHLOSFLAG_WATER, MECHLOSFLAG_WOOD, MECHLOSMAX_WATER, MECHLOSMAX_WOOD, MechMove, MechRTerrain, MechSpecials, MechType, MechX, MechY, MechZ, MOUNTAINS, MOVE_HOVER, SMOKE, TraceLOS(), WATER, WaterBeast, and lostrace_info::y.

Referenced by InLineOfSight(), and update_LOSinfo().

00062 {
00063         int new_flag = (ff & (MECHLOSFLAG_SEEN)) + MECHLOSFLAG_SEEC2;
00064         int woods_count = 0;
00065         int water_count = 0;
00066         int height, i;
00067         int pos_x, pos_y;
00068         float pos_z, z_inc, end_z;
00069         int terrain;
00070         int dopartials = 0;
00071         int underwater, bothworlds, t_underwater, t_bothworlds;
00072         int uwatercount = 0, coordcount;
00073         lostrace_info *coords;
00074 
00075 #ifndef BT_PARTIAL
00076         float partial_z, p_z_inc;
00077 #endif
00078 
00079         /* A Hex target off the map? Don't bother */
00080         if(!target && ((x < 0 || y < 0 || x >= map->map_width ||
00081                                         y >= map->map_height)))
00082                 return new_flag + MECHLOSFLAG_BLOCK;
00083 
00084         /* Outside max sensor range in the worst case? Don't bother. */
00085         if(hexRange > (((MechSpecials(mech) & AA_TECH) || (target &&
00086                                                                                                            (MechSpecials(target) &
00087                                                                                                                 AA_TECH))) ? 180 :
00088                                    map->maxvis))
00089                 return new_flag + MECHLOSFLAG_BLOCK;
00090 
00091         /* We start at (MechX(mech), MechY(mech)) and wind up at (x,y) */
00092         pos_x = MechX(mech);
00093         pos_y = MechY(mech);
00094         pos_z = ActualElevation(map, pos_x, pos_y, mech);
00095         end_z = ActualElevation(map, x, y, target);
00096 
00097 /* Definition of 'both worlds': According to FASA, if a mech is half
00098    submerged, or a sub is surfaced, or any naval or hover is on top
00099    of the water, it can see in both the underwater and overwater 'worlds'.
00100    In other words, it'll never get a block from the water/air interface.
00101    Neither will anything get such a block against it. That's what the
00102    'both worlds' variables test for. */
00103 
00104         if(end_z > 10 && pos_z > 10)
00105                 return new_flag;
00106         bothworlds = IsWater(MechRTerrain(mech)) &&     /* Can we be in both worlds? */
00107                 (((MechType(mech) == CLASS_MECH) && (MechZ(mech) == -1)) ||
00108                  ((WaterBeast(mech)) && (MechZ(mech) == 0)) ||
00109                  ((MechMove(mech) == MOVE_HOVER) && (MechZ(mech) == 0)));
00110         underwater = InWater(mech) && (pos_z < 0.0);
00111 
00112         /* Ice hex targeting special case */
00113         if(!target && !underwater && GetRTerrain(map, x, y) == ICE)
00114                 end_z = 0.0;
00115 
00116         if(target) {
00117                 /* What about him? Both worlds? Or flat out underwater? */
00118                 t_bothworlds = IsWater(MechRTerrain(target)) &&
00119                         (((MechType(target) == CLASS_MECH) && (MechZ(target) == -1)) ||
00120                          ((WaterBeast(target)) && (MechZ(target) == 0)) ||
00121                          ((MechMove(target) == MOVE_HOVER) && (MechZ(target) == 0)));
00122 
00123                 t_underwater = InWater(target) && (end_z < 0.0);
00124         } else {
00125                 if(GetRTerrain(map, x, y) == ICE)
00126                         t_bothworlds = 1;
00127                 else
00128                         t_bothworlds = 0;
00129                 t_underwater = (end_z < 0.0);   /* Is the hex underwater? */
00130         }
00131 
00132         /* And now we look once more to make sure we aren't wasting our time */
00133         if(((underwater) && !(t_underwater)) ||
00134            ((t_underwater) && !(underwater))) {
00135                 return new_flag + MECHLOSFLAG_BLOCK;
00136         }
00137 
00138         /* Worth our time to mess with figuring partial cover? */
00139         if(target && mech)
00140                 dopartials = (MechType(target) == CLASS_MECH) && (!Fallen(target));
00141 
00142         /*Same hex is always LoS */
00143         if((x == pos_x) && (y == pos_y))
00144                 return new_flag;
00145 
00146         /* Special cases are out of the way, looks like we have to do actual work. */
00147         coordcount = TraceLOS(map, pos_x, pos_y, x, y, &coords);
00148         if(coordcount > 0) {
00149                 z_inc = (float) (end_z - pos_z) / coordcount;
00150         } else {
00151                 z_inc = 0;                              /* In theory, this should never happen. */
00152         }
00153 
00154 #ifndef BT_PARTIAL
00155         partial_z = 0;
00156         p_z_inc = (float) 1 / coordcount;
00157 #endif
00158 
00159         if(coordcount > 0) {            /* not in same hex ; in same hex, you see always */
00160                 for(i = 0; i < coordcount; i++) {
00161                         pos_z += z_inc;
00162 #ifndef BT_PARTIAL
00163                         partial_z += p_z_inc;
00164 #endif
00165                         if(coords[i].x < 0 || coords[i].x >= map->map_width ||
00166                            coords[i].y < 0 || coords[i].y >= map->map_height)
00167                                 continue;
00168                         /* Should be possible to see into water.. perhaps. But not
00169                            on vislight */
00170                         terrain = GetRTerrain(map, coords[i].x, coords[i].y);
00171                         /* get the current height */
00172                         height = Elevation(map, coords[i].x, coords[i].y);
00173 
00174 /* If you, persoanlly, are underwater, the only way you can see someone
00175    if if they are underwater or in both worlds AND your LoS passes thru
00176    nothing but water hexes AND your LoS doesn't go thru the sea floor */
00177                         if(underwater) {
00178 
00179 /* LoS hits sea floor */
00180                                 if(!(IsWater(terrain)) || (terrain != BRIDGE &&
00181                                                                                    height >= pos_z)) {
00182                                         new_flag |= MECHLOSFLAG_BLOCK;
00183                                         return new_flag;
00184                                 }
00185 
00186 /* LoS pops out of water, AND we're not tracing to half-submerged mech's head */
00187                                 if(!t_bothworlds && pos_z > 0.0) {
00188                                         new_flag |= MECHLOSFLAG_BLOCK;
00189                                         return new_flag;
00190                                 }
00191 
00192 /* uwatercount = # hexes LoS travel UNDERWATER */
00193                                 if(pos_z <= 0.0)
00194                                         uwatercount++;
00195                                 water_count++;
00196                         } else {                        /* Viewer is not underwater */
00197                                 /* keep track of how many wooded hexes we cross */
00198                                 if(pos_z < (height + 2)) {
00199                                         switch (GetTerrain(map, coords[i].x, coords[i].y)) {
00200                                         case SMOKE:
00201                                                 if(i < coordcount - 1)
00202                                                         new_flag |= MECHLOSFLAG_SMOKE;
00203                                                 break;
00204                                         case FIRE:
00205                                                 if(i < coordcount - 1)
00206                                                         new_flag |= MECHLOSFLAG_FIRE;
00207                                                 break;
00208                                         }
00209                                         switch (terrain) {
00210                                         case LIGHT_FOREST:
00211                                         case HEAVY_FOREST:
00212                                                 if(i < coordcount - 1)
00213                                                         woods_count += (terrain == LIGHT_FOREST) ? 1 : 2;
00214                                                 break;
00215                                         case HIGHWATER:
00216                                                 water_count++;
00217                                                 break;
00218                                         case ICE:
00219                                                 if(pos_z < -0.0) {
00220                                                         new_flag |= MECHLOSFLAG_BLOCK;
00221                                                         return new_flag;
00222                                                 }
00223                                                 water_count++;
00224                                                 break;
00225                                         case WATER:
00226 
00227 /* LoS goes INTO water and we're not tracing to a target in both worlds */
00228                                                 if(!bothworlds && (pos_z < 0.0)) {
00229                                                         new_flag |= MECHLOSFLAG_BLOCK;
00230                                                         return new_flag;
00231                                                 }
00232 
00233 /* Hexes in LoS that are phsyically underwater */
00234                                                 if(pos_z < 0.0)
00235                                                         uwatercount++;
00236                                                 water_count++;
00237                                                 break;
00238                                         case MOUNTAINS:
00239                                                 if(i < coordcount - 1)
00240                                                         new_flag |= MECHLOSFLAG_MNTN;
00241                                                 break;
00242                                         }
00243                                 }
00244                                 /* make this the new 'current hex' */
00245                                 if(height >= pos_z && terrain != BRIDGE) {
00246                                         new_flag |= MECHLOSFLAG_BLOCK;
00247                                         return new_flag;
00248                                 }
00249 #ifndef BT_PARTIAL
00250                                 else if(dopartials && height >= (pos_z - partial_z))
00251                                         new_flag |= MECHLOSFLAG_PARTIAL;
00252 #endif
00253                         }
00254                 }
00255         }
00256         /* Then, we check the hex before target hex */
00257 #ifdef BT_PARTIAL
00258         if(coordcount >= 2)
00259                 if(dopartials) {
00260                         if(MechZ(target) >= MechZ(mech) &&
00261                            (Elevation(map, coords[coordcount - 2].x,
00262                                                   coords[coordcount - 2].y) == (MechZ(target) + 1)))
00263                                 new_flag |= MECHLOSFLAG_PARTIAL;
00264                         if(MechZ(target) == -1 && MechRTerrain(target) == WATER)
00265                                 new_flag |= MECHLOSFLAG_PARTIAL;
00266                 }
00267 #endif
00268 
00269         water_count = BOUNDED(0, water_count, MECHLOSMAX_WATER - 1);
00270         woods_count = BOUNDED(0, woods_count, MECHLOSMAX_WOOD - 1);
00271         new_flag += MECHLOSFLAG_WOOD * woods_count;
00272         new_flag += MECHLOSFLAG_WATER * water_count;
00273 
00274 /* Block EM after 2, Vis/IR after 6 */
00275         if(uwatercount > 2)
00276                 new_flag |= MECHLOSFLAG_MNTN;
00277         if(uwatercount > 6)
00278                 new_flag |= MECHLOSFLAG_FIRE;
00279         return new_flag;
00280 }

int InLineOfSight ( MECH mech,
MECH target,
int  x,
int  y,
float  hexRange 
)

Definition at line 312 of file mech.los.c.

References CalculateLOSFlag(), CLAIRVOYANT, MAP::cloudbase, getMap(), InWeaponArc(), MAP::LOSinfo, MAP::map_height, MAP::map_width, MapCoordToRealCoord(), MECH::mapindex, MAP::maplight, MECH::mapnumber, MAP::mapvis, mech_notify(), MechCritStatus, MechFX, MechFY, MECHLOSFLAG_BLOCK, MECHLOSFLAG_SEEN, MECHLOSFLAG_SEESP, MECHLOSFLAG_SEESS, MECHPILOT, MechToMech_LOSFlag, MECH::mynum, SendError, Sensor_CanSee(), and tprintf().

Referenced by auto_radio_command_report(), DisplayTarget(), find_mech_in_hex(), findC3RangeWithNetwork(), FireSpot(), fun_btlosm2m(), InLineOfSight_NB(), mech_attachcables(), mech_bearing(), mech_c3_join_leave(), mech_c3i_join_leave(), mech_contacts(), mech_detachcables(), mech_embark(), mech_hide_event(), mech_jump(), mech_lock_event(), mech_pickup(), mech_radio(), mech_range(), mech_report(), mech_scan(), mech_settarget(), mech_spot(), mech_vector(), mech_view(), MechFireBroadcast(), MechLOSBroadcast(), MechLOSBroadcasti(), mechSeenByNetwork(), MechSeesHexF(), navigate_sketch_mechs(), parse_tacargs(), ScrambleInfraAndLiteAmp(), show_lrs_map(), showNetworkTargets(), and sketch_tac_mechs().

00313 {
00314         MAP *map;
00315         float x1, y1;
00316         int arc;
00317         int losflag;
00318 
00319         map = getMap(mech->mapindex);
00320         if(!map) {
00321                 mech_notify(mech, MECHPILOT,
00322                                         "You are on an invalid map! Map index reset!");
00323                 SendError(tprintf("InLineOfSight:invalid map:Mech %d  Index %d",
00324                                                   mech->mynum, mech->mapindex));
00325                 mech->mapindex = -1;
00326                 return 0;
00327         }
00328         if(x < 0 || y < 0 || y >= map->map_height || x >= map->map_width) {
00329                 SendError(tprintf("x:%d y:%d out of bounds for #%d (LOS check)", x,
00330                                                   y, mech ? mech->mynum : -1));
00331         }
00332 
00333         /* Possibly do a quickie check only */
00334         if(MechCritStatus(mech) & CLAIRVOYANT)
00335                 return 1;
00336 
00337         if(target) {
00338                 x1 = MechFX(target);
00339                 y1 = MechFY(target);
00340         } else
00341                 MapCoordToRealCoord(x, y, &x1, &y1);
00342         arc = InWeaponArc(mech, x1, y1);
00343 
00344         if(mech && target) {
00345 #ifndef ADVANCED_LOS
00346                 losflag = MechToMech_LOSFlag(map, mech, target);
00347                 if(Sensor_CanSee(mech, target, &losflag, arc, hexRange, map->mapvis,
00348                                                  map->maplight, map->cloudbase)) {
00349                         map->LOSinfo[mech->mapnumber][target->mapnumber] |=
00350                                 (MECHLOSFLAG_SEEN | MECHLOSFLAG_SEESP | MECHLOSFLAG_SEESS);
00351                         return 1;
00352                 } else {
00353                         map->LOSinfo[mech->mapnumber][target->mapnumber] &=
00354                                 ~(MECHLOSFLAG_SEEN | MECHLOSFLAG_SEESP | MECHLOSFLAG_SEESS);
00355                         return 0;
00356                 }
00357 #else
00358                 if(MechToMech_LOSFlag(map, mech, target) & (MECHLOSFLAG_SEESP |
00359                                                                                                         MECHLOSFLAG_SEESS))
00360                         return MechToMech_LOSFlag(map, mech, target) &
00361                                 (MECHLOSFLAG_SEESP | MECHLOSFLAG_SEESS | MECHLOSFLAG_BLOCK);
00362 #endif
00363                 return 0;
00364         }
00365         losflag = CalculateLOSFlag(mech, NULL, map, x, y, 0, hexRange);
00366         return Sensor_CanSee(mech, NULL, &losflag, arc, hexRange, map->mapvis,
00367                                                  map->maplight, map->cloudbase);
00368 }

int InLineOfSight_NB ( MECH mech,
MECH target,
int  x,
int  y,
float  hexRange 
)

Definition at line 299 of file mech.los.c.

References InLineOfSight(), and MECHLOSFLAG_BLOCK.

Referenced by checkTAG(), FindBSuitTarget(), fun_bthexlos(), fun_btid2db(), fun_btlosm2m(), GetMechToMechID(), mech_charge(), mech_contacts(), mech_report(), mech_scan(), mech_tag(), mech_view(), mechSeenByNetwork(), PhysicalAttack(), showNetworkTargets(), and SwarmHitTarget().

00300 {
00301         int i;
00302 
00303         if(mech == target)
00304                 return 1;
00305 
00306         i = InLineOfSight(mech, target, x, y, hexRange);
00307         if(i & MECHLOSFLAG_BLOCK)
00308                 return 0;
00309         return i;
00310 }

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

Definition at line 370 of file mech.los.c.

References cch, MECH_USUALSP, MechLOSBroadcast(), and notify.

00371 {
00372         cch(MECH_USUALSP);
00373         MechLOSBroadcast(mech, buffer);
00374         notify(player, "Broadcast done.");
00375 }


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