1 #include "Handle_Items.h"
2 #include "Isometric_Utils.h"
3 #include "Structure.h"
4 #include "TileDat.h"
5 #include "WorldDef.h"
6 #include "Render_Fun.h"
7 #include "RenderWorld.h"
8 #include "Dialogue_Control.h"
9 #include "Structure_Wrap.h"
10 #include "PathAI.h"
11 #include "Overhead.h"
12 #include "Smell.h"
13 #include "FOV.h"
14 #include "Rotting_Corpses.h"
15 #include "Keys.h"
16 #include "Random.h"
17 #include "Input.h"
18 #include "Exit_Grids.h"
19 #include "Environment.h"
20 #include "WorldMan.h"
21 #include "Fog_Of_War.h"
22 #include "StrategicMap.h"
23 #include "Boxing.h"
24 #include "OppList.h"
25 #include "Lighting.h"
26 #include "Soldier_Macros.h"
27
28 #ifdef _DEBUG
29 #include "Font.h"
30 #include "Font_Control.h"
31 #include "Timer_Control.h"
32 #include "Video.h"
33 #endif
34
35 #include <string_theory/format>
36
37 #include <algorithm>
38 #include <iterator>
39
40 /* view directions */
41 #define DLEFT 0
42 #define DRIGHT 1
43 #define UP 2
44 #define LEFT 3
45 #define RIGHT 4
46 #define NOVIEW 5
47 #define MAXVIEWPATHS 17
48 #define VIEWPATHLENGTH 13
49
50 UINT8 gubGridNoMarkers[ WORLD_MAX ];
51 UINT8 gubGridNoValue = 254;
52
53 #ifdef _DEBUG
54 UINT8 gubFOVDebugInfoInfo[ WORLD_MAX ];
55 #endif
56
57
58 UINT8 ViewPath[MAXVIEWPATHS][VIEWPATHLENGTH] = {
59 {NOVIEW, UP, UP, UP, UP, UP, UP, UP, UP, UP, UP, UP, UP },
60 {UP, UP, UP, UP, DRIGHT, UP, UP, UP, UP, UP, UP, UP, UP },
61 {UP, UP, UP, UP, DLEFT, UP, UP, UP, UP, UP, UP, UP, UP },
62 {UP, UP, DLEFT, UP, DLEFT, UP, UP, UP, UP, UP, UP, UP, UP },
63 {UP, UP, DRIGHT, UP, DRIGHT, UP, UP, UP, UP, UP, UP, UP, UP },
64 {UP, UP, DRIGHT, DRIGHT, DRIGHT, UP, UP, UP, UP, UP, UP, UP, UP },
65 {UP, UP, DLEFT, DLEFT, DLEFT, UP, UP, UP, UP, UP, UP, UP, UP },
66 {UP, RIGHT, UP, DRIGHT, DRIGHT, DRIGHT, UP, UP, UP, UP, UP, UP, UP },
67 {UP, LEFT, UP, DLEFT, DLEFT, DLEFT, UP, UP, UP, UP, UP, UP, UP },
68 {DLEFT, DLEFT, DLEFT, DLEFT, DLEFT, UP, UP, UP, UP, UP, UP, UP, UP },
69 {DRIGHT, DRIGHT, DRIGHT, DRIGHT, DRIGHT, UP, UP, UP, UP, UP, UP, UP, UP },
70 {RIGHT, DRIGHT, DRIGHT, DRIGHT, DRIGHT, DRIGHT, UP, UP, UP, UP, UP, UP, UP },
71 {LEFT, DLEFT, DLEFT, DLEFT, DLEFT, DLEFT, UP, UP, UP, UP, UP, UP, UP },
72 {DLEFT, LEFT, LEFT, UP, NOVIEW, NOVIEW, NOVIEW, NOVIEW, NOVIEW, NOVIEW, NOVIEW, NOVIEW, NOVIEW},
73 {LEFT, LEFT, LEFT, UP, LEFT, NOVIEW, NOVIEW, NOVIEW, NOVIEW, NOVIEW, NOVIEW, NOVIEW, NOVIEW},
74 {DRIGHT, RIGHT, RIGHT, UP, NOVIEW, NOVIEW, NOVIEW, NOVIEW, NOVIEW, NOVIEW, NOVIEW, NOVIEW, NOVIEW},
75 {RIGHT, RIGHT, RIGHT, UP, RIGHT, NOVIEW, NOVIEW, NOVIEW, NOVIEW, NOVIEW, NOVIEW, NOVIEW, NOVIEW}
76 };
77
78 UINT8 ViewPath2[MAXVIEWPATHS][VIEWPATHLENGTH]= {
79 {NOVIEW, UP, UP, UP, UP, UP, UP, NOVIEW, NOVIEW, NOVIEW, NOVIEW, NOVIEW, NOVIEW},
80 {UP, UP, DLEFT, UP, UP, UP, DLEFT, DRIGHT, NOVIEW, NOVIEW, NOVIEW, NOVIEW, NOVIEW},
81 {UP, UP, DLEFT, UP, UP, UP, DRIGHT, DLEFT, NOVIEW, NOVIEW, NOVIEW, NOVIEW, NOVIEW},
82 {UP, UP, DLEFT, UP, UP, DLEFT, DLEFT, UP, NOVIEW, NOVIEW, NOVIEW, NOVIEW, NOVIEW},
83 {UP, UP, DRIGHT, UP, UP, DRIGHT, DRIGHT, UP, NOVIEW, NOVIEW, NOVIEW, NOVIEW, NOVIEW},
84 {UP, DLEFT, UP, UP, DLEFT, DLEFT, DLEFT, UP, UP, UP, UP, UP, UP },
85 {UP, DRIGHT, UP, UP, DRIGHT, DRIGHT, DRIGHT, UP, UP, UP, UP, UP, UP },
86 {DLEFT, DLEFT, UP, UP, DLEFT, DLEFT, DLEFT, UP, UP, UP, UP, UP, UP },
87 {DRIGHT, DRIGHT, UP, UP, DRIGHT, DRIGHT, DRIGHT, UP, UP, UP, UP, UP, UP },
88 {DLEFT, DLEFT, UP, DLEFT, DLEFT, DLEFT, DLEFT, UP, UP, UP, UP, UP, UP },
89 {DRIGHT, DRIGHT, UP, DRIGHT, DRIGHT, DRIGHT, DRIGHT, UP, UP, UP, UP, UP, UP },
90 {DLEFT, DLEFT, DLEFT, DLEFT, DLEFT, DLEFT, DLEFT, UP, UP, UP, UP, UP, UP },
91 {DRIGHT, DRIGHT, DRIGHT, DRIGHT, DRIGHT, DRIGHT, DRIGHT, UP, UP, UP, UP, UP, UP },
92 {DLEFT, LEFT, DLEFT, NOVIEW, NOVIEW, NOVIEW, NOVIEW, NOVIEW, NOVIEW, NOVIEW, NOVIEW, NOVIEW, NOVIEW},
93 {DRIGHT, RIGHT, DRIGHT, NOVIEW, NOVIEW, NOVIEW, NOVIEW, NOVIEW, NOVIEW, NOVIEW, NOVIEW, NOVIEW, NOVIEW},
94 {LEFT, LEFT, DLEFT, NOVIEW, NOVIEW, NOVIEW, NOVIEW, NOVIEW, NOVIEW, NOVIEW, NOVIEW, NOVIEW, NOVIEW},
95 {RIGHT, RIGHT, DRIGHT, NOVIEW, NOVIEW, NOVIEW, NOVIEW, NOVIEW, NOVIEW, NOVIEW, NOVIEW, NOVIEW, NOVIEW}
96 };
97
98
BuildSightDir(UINT32 dir,UINT32 * One,UINT32 * Two,UINT32 * Three,UINT32 * Four,UINT32 * Five)99 static void BuildSightDir(UINT32 dir, UINT32* One, UINT32* Two, UINT32* Three, UINT32* Four, UINT32* Five)
100 {
101 switch(dir)
102 {
103 case NORTH:
104 *One = NORTHWEST;
105 *Two = NORTHEAST;
106 *Three = NORTH;
107 *Four = WEST;
108 *Five = EAST;
109 break;
110 case NORTHEAST:
111 *One = NORTH;
112 *Two = EAST;
113 *Three = NORTHEAST;
114 *Four = NORTHWEST;
115 *Five = SOUTHEAST;
116 break;
117 case EAST:
118 *One = NORTHEAST;
119 *Two = SOUTHEAST;
120 *Three = EAST;
121 *Four = NORTH;
122 *Five = SOUTH;
123 break;
124 case SOUTHEAST:
125 *One = EAST;
126 *Two = SOUTH;
127 *Three = SOUTHEAST;
128 *Four = NORTHEAST;
129 *Five = SOUTHWEST;
130 break;
131 case SOUTH:
132 *One = SOUTHEAST;
133 *Two = SOUTHWEST;
134 *Three = SOUTH;
135 *Four = EAST;
136 *Five = WEST;
137 break;
138 case SOUTHWEST:
139 *One = SOUTH;
140 *Two = WEST;
141 *Three = SOUTHWEST;
142 *Four = SOUTHEAST;
143 *Five = NORTHWEST;
144 break;
145 case WEST:
146 *One = SOUTHWEST;
147 *Two = NORTHWEST;
148 *Three = WEST;
149 *Four = SOUTH;
150 *Five = NORTH;
151 break;
152 case NORTHWEST:
153 *One = WEST;
154 *Two = NORTH;
155 *Three = NORTHWEST;
156 *Four = SOUTHWEST;
157 *Five = NORTHEAST;
158 break;
159 default:
160 break;
161 }
162 }
163
164 #define NUM_SLANT_ROOF_SLOTS 200
165
166 struct SLANT_ROOF_FOV_TYPE
167 {
168 INT16 sGridNo;
169 BOOLEAN fAllocated;
170 };
171
172 SLANT_ROOF_FOV_TYPE gSlantRoofData[ NUM_SLANT_ROOF_SLOTS ];
173 UINT32 guiNumSlantRoofs = 0;
174
GetFreeSlantRoof(void)175 static INT32 GetFreeSlantRoof(void)
176 {
177 UINT32 uiCount;
178
179 for(uiCount=0; uiCount < guiNumSlantRoofs; uiCount++)
180 {
181 if( gSlantRoofData[uiCount].fAllocated==FALSE )
182 return( (INT32)uiCount );
183 }
184
185 if( guiNumSlantRoofs < NUM_SLANT_ROOF_SLOTS )
186 return( (INT32) guiNumSlantRoofs++ );
187
188 return( -1 );
189 }
190
ClearSlantRoofs(void)191 void ClearSlantRoofs( void )
192 {
193 UINT32 uiCount;
194
195 for( uiCount = 0; uiCount < guiNumSlantRoofs; uiCount++ )
196 {
197 if( ( gSlantRoofData[uiCount].fAllocated ) )
198 {
199 gSlantRoofData[uiCount].fAllocated = FALSE;
200 }
201 }
202 guiNumSlantRoofs = 0;
203 }
204
FindSlantRoofSlot(INT16 sGridNo)205 static BOOLEAN FindSlantRoofSlot(INT16 sGridNo)
206 {
207 UINT32 uiCount;
208
209 for( uiCount = 0; uiCount < guiNumSlantRoofs; uiCount++ )
210 {
211 if( ( gSlantRoofData[uiCount].fAllocated ) )
212 {
213 if ( gSlantRoofData[uiCount].sGridNo == sGridNo )
214 {
215 return( TRUE );
216 }
217 }
218 }
219 return( FALSE );
220 }
221
AddSlantRoofFOVSlot(INT16 sGridNo)222 void AddSlantRoofFOVSlot( INT16 sGridNo )
223 {
224 INT32 iSlantRoofSlot;
225 SLANT_ROOF_FOV_TYPE *pSlantRoof;
226
227 // Check if this is a duplicate!
228 if ( FindSlantRoofSlot( sGridNo ) )
229 {
230 return;
231 }
232
233 iSlantRoofSlot = GetFreeSlantRoof( );
234
235 if ( iSlantRoofSlot != -1 )
236 {
237 pSlantRoof = &gSlantRoofData[ iSlantRoofSlot ];
238 pSlantRoof->sGridNo = sGridNo;
239 pSlantRoof->fAllocated = TRUE;
240 }
241 }
242
ExamineSlantRoofFOVSlots()243 void ExamineSlantRoofFOVSlots( )
244 {
245 UINT32 uiCount;
246
247 for( uiCount = 0; uiCount < guiNumSlantRoofs; uiCount++ )
248 {
249 if( ( gSlantRoofData[uiCount].fAllocated ) )
250 {
251 ExamineGridNoForSlantRoofExtraGraphic( gSlantRoofData[uiCount].sGridNo );
252 }
253 }
254 ClearSlantRoofs( );
255 }
256
257
RevealRoofsAndItems(SOLDIERTYPE * const pSoldier,const BOOLEAN fShowLocators)258 void RevealRoofsAndItems(SOLDIERTYPE* const pSoldier, const BOOLEAN fShowLocators)
259 {
260 const UINT8 ubLevel = pSoldier->bLevel;
261 STRUCTURE* pStructure, *pDummy;
262 UINT32 maincnt,markercnt,marker,tilesLeftToSee,cnt,prevmarker;
263 INT8 Blocking, markerDir;
264 INT8 nextDir = 0;
265 UINT8 dir,range,Path2;
266 UINT8 ubRoomNo;
267 UINT8 ubMovementCost;
268 BOOLEAN fTravelCostObs;
269 BOOLEAN fGoneThroughDoor = FALSE;
270 BOOLEAN fThroughWindow = FALSE;
271 BOOLEAN fItemsQuoteSaid = FALSE;
272 BOOLEAN fRevealItems = TRUE;
273 BOOLEAN fStopRevealingItemsAfterThisTile = FALSE;
274 INT8 bTallestStructureHeight;
275 INT32 iDoorGridNo;
276 INT8 bStructHeight;
277 INT8 bThroughWindowDirection = -1; // XXX HACK000E
278
279 if ( pSoldier->uiStatusFlags & SOLDIER_ENEMY )
280 {
281 //pSoldier->needToLookForItems = FALSE;
282 return;
283 }
284
285 if ( pSoldier->uiStatusFlags & SOLDIER_VEHICLE )
286 {
287 return;
288 }
289
290 // Return if this guy has no gridno, has bad life, etc
291 if( pSoldier->sGridNo == NOWHERE || !pSoldier->bInSector || pSoldier->bLife < OKLIFE )
292 {
293 return;
294 }
295
296 if (pSoldier->bBlindedCounter > 0)
297 {
298 return;
299 }
300 gubGridNoValue++;
301
302 if ( gubGridNoValue == 255 )
303 {
304 //Reset!
305 std::fill(std::begin(gubGridNoMarkers), std::end(gubGridNoMarkers), 0);
306 gubGridNoValue = 1;
307 }
308
309 // OK, look for doors
310 MercLooksForDoors(*pSoldier);
311
312 dir = pSoldier->bDirection;
313
314 // a gassed merc can only see 1 tile away due to blurred vision
315 if ( pSoldier->uiStatusFlags & SOLDIER_GASSED )
316 {
317 range = GASSED_VIEW_RANGE;
318 }
319 else
320 {
321 range = NORMAL_VIEW_RANGE;
322 // balance item viewing range between normal and the limit set by opplist-type functions -- CJC
323 range = (AdjustMaxSightRangeForEnvEffects(LightTrueLevel(pSoldier->sGridNo, pSoldier->bLevel), range) + range) / 2;
324 }
325
326 UINT32 Dir[6];
327 BuildSightDir(dir,&Dir[0],&Dir[1],&Dir[2],&Dir[3],&Dir[4]);
328 INT32 Inc[6];
329 for (cnt = 0; cnt < 5; cnt++)
330 Inc[cnt] = DirectionInc(Dir[cnt]);
331
332 // create gridno increment for NOVIEW - in other words, no increment!
333 Inc[5] = 0;
334 Dir[5] = pSoldier->bDirection;
335
336 if (dir % 2 == 1) /* even numbers use ViewPath2 */
337 Path2 = TRUE;
338 else
339 Path2 = FALSE;
340
341
342 // ATE: if in this special cercumstance... our guys are moving on their own...
343 // Stop sighting items
344 // IN the future, we may want to do something else here...
345 const BOOLEAN itemsToo = !(gTacticalStatus.uiFlags & OUR_MERCS_AUTO_MOVE);
346
347 for (maincnt = 0; maincnt < MAXVIEWPATHS; maincnt++)
348 {
349 marker = pSoldier->sGridNo;
350 Blocking = FALSE;
351 tilesLeftToSee = 99;
352 fRevealItems = TRUE;
353 fStopRevealingItemsAfterThisTile = FALSE;
354
355 #ifdef _DEBUG
356 if (_KeyDown(SDLK_NUMLOCKCLEAR))
357 {
358 std::fill(std::begin(gubFOVDebugInfoInfo), std::end(gubFOVDebugInfoInfo), 0);
359 SetRenderFlags( RENDER_FLAG_FULL );
360 RenderWorld( );
361 }
362 #endif
363
364 for (markercnt = 0; markercnt < range; markercnt++)
365 {
366 //fGoneThroughDoor = FALSE;
367 //fThroughWindow = FALSE;
368 prevmarker = marker;
369
370 nextDir = 99;
371 fTravelCostObs = FALSE;
372 if ( fStopRevealingItemsAfterThisTile )
373 {
374 fRevealItems = FALSE;
375 fStopRevealingItemsAfterThisTile = FALSE;
376 }
377 if (Path2)
378 {
379 markerDir = ViewPath2[maincnt][markercnt];
380 if (markercnt < 12)
381 nextDir = ViewPath2[maincnt][markercnt+1];
382 }
383 else
384 {
385 markerDir = ViewPath[maincnt][markercnt];
386 if (markercnt < 12)
387 nextDir = ViewPath[maincnt][markercnt+1];
388 }
389
390 // OK, check flags for going through door/window last tile
391 if ( fThroughWindow == 1 )
392 {
393 // ATE: Make sure we are going through the same direction!
394 // THis is to solve the drassen SAM problem with seeing through walls
395 if ( static_cast<INT8>(Dir[markerDir]) == bThroughWindowDirection)
396 {
397 fThroughWindow = 2;
398 }
399 else
400 {
401 fThroughWindow = 0;
402 }
403 }
404 else if ( fThroughWindow == 2 )
405 {
406 // We've overstayed our welcome - remove!
407 fThroughWindow = 0;
408 }
409
410 if ( fGoneThroughDoor == 1 )
411 {
412 fGoneThroughDoor = 2;
413 }
414 else if ( fGoneThroughDoor == 2 )
415 {
416 // We've overstayed our welcome - remove!
417 fGoneThroughDoor = 0;
418 }
419
420 //ATE CHECK FOR NOVIEW!
421 if ( nextDir == NOVIEW )
422 {
423 nextDir = 99;
424 }
425
426 marker = NewGridNo((INT16)marker,(INT16)Inc[markerDir]);
427
428 // End if this is a no view...
429 if ( markerDir == NOVIEW && markercnt != 0 )
430 {
431 break;
432 }
433
434 #ifdef _DEBUG
435 if (_KeyDown(SDLK_NUMLOCKCLEAR))
436 {
437 int cnt = GetJA2Clock( );
438
439 gubFOVDebugInfoInfo[ marker ] = (UINT8)markercnt;
440 RenderFOVDebug( );
441 SetFontAttributes(LARGEFONT1, FONT_MCOLOR_WHITE);
442 MPrint( 10, 10 , ST::format("{}", maincnt) );
443 //MPrint( 10, 20 , ST::format("{}", marker) );
444 //MPrint( 50, 20 , ST::format("{}", pSoldier->sGridNo) );
445 InvalidateScreen( );
446 RefreshScreen();
447 do
448 {}
449 while( ( GetJA2Clock( ) - cnt ) < 250 );
450 }
451 #endif
452
453 // Check if we can get to this gridno from our direction in
454 ubMovementCost = gubWorldMovementCosts[ marker ][ Dir[ markerDir ] ][ ubLevel ];
455
456 // ATE: Added: If our current sector is below ground, ignore any blocks!
457 if ( gfCaves && ubMovementCost != TRAVELCOST_CAVEWALL )
458 {
459 ubMovementCost = TRAVELCOST_FLAT;
460 }
461
462 if ( IS_TRAVELCOST_DOOR( ubMovementCost ) )
463 {
464 ubMovementCost = DoorTravelCost(pSoldier, marker, ubMovementCost, pSoldier->bTeam == OUR_TEAM, &iDoorGridNo);
465 pStructure = FindStructure( (INT16) iDoorGridNo, STRUCTURE_ANYDOOR );
466 if ( pStructure != NULL && pStructure->fFlags & STRUCTURE_TRANSPARENT)
467 {
468 // cell door or somehow otherwise transparent; allow merc to see through
469 ubMovementCost = TRAVELCOST_FLAT;
470 }
471 }
472
473 // If we have hit an obstacle, STOP HERE
474 if ( ubMovementCost >= TRAVELCOST_BLOCKED )
475 {
476 // We have an obstacle here...
477 // If it is bigger than a breadbox... err... taller than a man...
478 // Then stop path altogether
479 // otherwise just stop revealing items
480
481 // CJC: only do this when the direction is horizontal; easier and faster to check
482 // and the effect should still be good enough
483
484 if ( ubMovementCost == TRAVELCOST_WALL || ubMovementCost == TRAVELCOST_DOOR || ubMovementCost == TRAVELCOST_EXITGRID )
485 {
486 fTravelCostObs = TRUE;
487 fRevealItems = FALSE;
488 }
489 else
490 {
491 // walls are handled above, so the blocking object is guaranteed not to be a wall
492 bTallestStructureHeight = GetTallestStructureHeight( (INT16) marker, FALSE );
493 if (bTallestStructureHeight >= 3)
494 {
495 fTravelCostObs = TRUE;
496 fStopRevealingItemsAfterThisTile = TRUE;
497 }
498 else if ( bTallestStructureHeight != 0 )
499 {
500 // stop revealing items after this tile but keep going
501 fStopRevealingItemsAfterThisTile = TRUE;
502 }
503 }
504
505 if ( (Dir[markerDir] % 2) == 1 )
506 {
507 // diagonal
508 fTravelCostObs = TRUE;
509 // cheap hack... don't reveal items
510 fRevealItems = FALSE;
511 }
512 else
513 {
514 bTallestStructureHeight = GetTallestStructureHeight( (INT16) marker, FALSE );
515 if (bTallestStructureHeight >= 3)
516 {
517 fTravelCostObs = TRUE;
518 fStopRevealingItemsAfterThisTile = TRUE;
519 }
520 else if ( bTallestStructureHeight != 0 )
521 {
522 // stop revealing items after this tile but keep going
523 fStopRevealingItemsAfterThisTile = TRUE;
524 }
525 }
526 }
527
528 // Check if it's been done already!
529 if ( gubGridNoMarkers[ marker ] != gubGridNoValue )
530 {
531 // Mark gridno
532 gubGridNoMarkers[ marker ] = gubGridNoValue;
533
534 // check and see if the gridno changed
535 // if the gridno is the same, avoid redundancy and break
536 if (marker==prevmarker && markercnt != 0 )
537 {
538
539 }
540 else // it changed
541 {
542 // Skip others if we have gone through a door but are too far away....
543 if ( fGoneThroughDoor )
544 {
545 if (markercnt > 5 ) // Are we near the door?
546 {
547 break;
548 }
549 }
550 // DO MINE FINDING STUFF
551 // GET INDEX FOR ITEM HERE
552 // if there IS a direction after this one, nextdir WILL NOT be 99
553 if (nextDir != 99)
554 {
555 Blocking = GetBlockingStructureInfo( (INT16)marker, (INT8)Dir[ markerDir ], (INT8)Dir[ nextDir ], ubLevel, &bStructHeight, &pDummy, FALSE );
556 }
557 else
558 {
559 // no "next" direction, so pass in a NOWHERE so that
560 // "SpecialViewObstruction" will know not to take it UINT32o consideration
561 Blocking = GetBlockingStructureInfo( (INT16)marker, (INT8)Dir[markerDir], (INT8)30, ubLevel, &bStructHeight, &pDummy, FALSE );
562 }
563
564 if ( gfCaves )
565 {
566 Blocking = NOTHING_BLOCKING;
567 }
568
569 // CHECK FOR ROOMS
570 if ( Blocking == BLOCKING_TOPLEFT_WINDOW || Blocking == BLOCKING_TOPLEFT_OPEN_WINDOW )
571 {
572 // CHECK FACING DIRECTION!
573 if ( Dir[markerDir] == NORTH || Dir[markerDir] == SOUTH )
574 {
575 if (markercnt <= 1 ) // Are we right beside it?
576 {
577 fThroughWindow = TRUE;
578 bThroughWindowDirection = ( INT8 ) Dir[ markerDir ];
579 }
580 }
581 }
582 if ( Blocking == BLOCKING_TOPRIGHT_WINDOW || Blocking == BLOCKING_TOPRIGHT_OPEN_WINDOW )
583 {
584 // CHECK FACING DIRECTION!
585 if ( Dir[markerDir] == EAST || Dir[markerDir] == WEST )
586 {
587 if (markercnt <= 1 ) // Are we right beside it?
588 {
589 fThroughWindow = TRUE;
590 bThroughWindowDirection = ( INT8 ) Dir[ markerDir ];
591 }
592 }
593 }
594
595 if ( Blocking == BLOCKING_TOPLEFT_DOOR )
596 {
597 fGoneThroughDoor = TRUE;
598 }
599 if ( Blocking == BLOCKING_TOPRIGHT_DOOR )
600 {
601 fGoneThroughDoor = TRUE;
602 }
603
604 // ATE: If we hit this tile, find item always!
605 //if (Blocking < FULL_BLOCKING )
606 {
607 // Handle special things for our mercs, like uncovering roofs
608 // and revealing objects...
609 //gpSoldier->shad |= SEENBIT;
610
611 // NOTE: don't allow object viewing if gassed XXX
612
613 if (itemsToo && fRevealItems ) // && itemIndex < MAXOBJECTLIST)
614 {
615 // OK, look for corpses...
616 LookForAndMayCommentOnSeeingCorpse( pSoldier, (INT16)marker, ubLevel );
617
618 if (SetItemsVisibilityOn(marker, ubLevel, INVISIBLE, fShowLocators))
619 {
620 SetRenderFlags(RENDER_FLAG_FULL);
621
622 if ( fShowLocators )
623 {
624 // Set makred render flags
625 //gpWorldLevelData[marker].uiFlags|=MAPELEMENT_REDRAW;
626 //gpWorldLevelData[gusCurMousePos].pTopmostHead->uiFlags |= LEVELNODE_DYNAMIC;
627 //SetRenderFlags(RENDER_FLAG_MARKED);
628 SetRenderFlags(RENDER_FLAG_FULL);
629
630 // Hault soldier
631 // ATE: Only if in combat...
632 if ( gTacticalStatus.uiFlags & INCOMBAT )
633 {
634 HaultSoldierFromSighting( pSoldier, FALSE );
635 }
636 else
637 {
638 // ATE: Make sure we show locators...
639 gTacticalStatus.fLockItemLocators = FALSE;
640 }
641 if (!fItemsQuoteSaid && !gTacticalStatus.fLockItemLocators)
642 {
643 gTacticalStatus.fLockItemLocators = TRUE;
644
645 if ( gTacticalStatus.ubAttackBusyCount > 0 && ( gTacticalStatus.uiFlags & INCOMBAT ) )
646 {
647 gTacticalStatus.fItemsSeenOnAttack = TRUE;
648 gTacticalStatus.items_seen_on_attack_soldier = pSoldier;
649 gTacticalStatus.usItemsSeenOnAttackGridNo = (INT16)marker;
650 }
651 else
652 {
653 // Display quote!
654 if ( !AM_AN_EPC( pSoldier ) )
655 {
656 MakeCharacterDialogueEventSignalItemLocatorStart(*pSoldier, marker);
657 }
658 else
659 {
660 // Turn off item lock for locators...
661 gTacticalStatus.fLockItemLocators = FALSE;
662 SlideToLocation((INT16)marker);
663 }
664 }
665 fItemsQuoteSaid = TRUE;
666 }
667 }
668 }
669 }
670 tilesLeftToSee--;
671 }
672
673 if (tilesLeftToSee <= 0)
674 break;
675
676 if ( Blocking == FULL_BLOCKING || ( fTravelCostObs && !fThroughWindow ) )
677 {
678 break;
679 }
680
681 // CHECK FOR SLANT ROOF!
682 {
683 STRUCTURE* pStructure;
684 pStructure = FindStructure( (INT16)marker, STRUCTURE_SLANTED_ROOF );
685
686 if ( pStructure != NULL )
687 {
688 // ADD TO SLANTED ROOF LIST!
689 AddSlantRoofFOVSlot( (INT16)marker );
690 }
691 }
692
693 // Set gridno as revealed
694 if ( ubLevel == FIRST_LEVEL )
695 {
696 if ( gfBasement || gfCaves )
697 {
698 // OK, if we are underground, we don't want to reveal stuff if
699 // 1 ) there is a roof over us and
700 // 2 ) we are not in a room
701 if (gubWorldRoomInfo[marker] != NO_ROOM || TypeRangeExistsInRoofLayer(marker, FIRSTROOF, FOURTHROOF) == NULL)
702 {
703 gpWorldLevelData[ marker ].uiFlags |= MAPELEMENT_REVEALED;
704 if( gfCaves )
705 {
706 RemoveFogFromGridNo( marker );
707 }
708 }
709 }
710 else
711 {
712 gpWorldLevelData[ marker ].uiFlags |= MAPELEMENT_REVEALED;
713 }
714
715 // CHECK FOR ROOMS
716 {
717 if ( InAHiddenRoom( (INT16)marker, &ubRoomNo ) )
718 {
719 RemoveRoomRoof( (INT16)marker, ubRoomNo, pSoldier );
720 if ( ubRoomNo == ROOM_SURROUNDING_BOXING_RING && gWorldSectorX == BOXING_SECTOR_X && gWorldSectorY == BOXING_SECTOR_Y && gbWorldSectorZ == BOXING_SECTOR_Z )
721 {
722 // reveal boxing ring at same time
723 RemoveRoomRoof( (INT16)marker, BOXING_RING, pSoldier );
724 }
725 }
726 }
727 }
728 else
729 {
730 gpWorldLevelData[ marker ].uiFlags |= MAPELEMENT_REVEALED_ROOF;
731 }
732
733 // Check for blood....
734 UpdateBloodGraphics( (INT16)marker, ubLevel );
735
736 if (Blocking != NOTHING_BLOCKING &&
737 Blocking != BLOCKING_TOPLEFT_DOOR &&
738 Blocking != BLOCKING_TOPRIGHT_DOOR &&
739 Blocking != BLOCKING_TOPLEFT_WINDOW &&
740 Blocking != BLOCKING_TOPRIGHT_WINDOW &&
741 Blocking != BLOCKING_TOPRIGHT_OPEN_WINDOW &&
742 Blocking != BLOCKING_TOPLEFT_OPEN_WINDOW)
743 {
744 break;
745 }
746 //gpWorldLevelData[ marker ].uiFlags |= MAPELEMENT_SHADELAND;
747
748 }
749 } // End of duplicate check
750 else
751 {
752 if ( fTravelCostObs )
753 {
754 break;
755 }
756 }
757 } // end of one path
758 } // end of path loop
759 // Loop through all availible slant roofs we collected and perform cool stuff on them
760 ExamineSlantRoofFOVSlots( );
761 //pSoldier->needToLookForItems = FALSE;
762 //LookForDoors(pSoldier,UNAWARE);
763 }
764