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) |
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 }
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 }
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 }
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 }
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 }