@@ -317,7 +317,58 @@ void P_LineOpening(const line_t *linedef, const mobj_t *actor)
317
317
// these structures need to be updated.
318
318
//
319
319
320
- void P_UnsetThingPosition (mobj_t * thing )
320
+ static void P_UnsetThingPosition_Boom (mobj_t * thing )
321
+ {
322
+ if (!(thing -> flags & MF_NOSECTOR ))
323
+ {
324
+ // inert things don't need to be in blockmap?
325
+ // unlink from subsector
326
+ if (thing -> snext )
327
+ thing -> snext -> sprev = thing -> sprev ;
328
+
329
+ if (thing -> sprev )
330
+ ((mobj_t * )thing -> sprev )-> snext = thing -> snext ;
331
+ else
332
+ thing -> subsector -> sector -> thinglist = thing -> snext ;
333
+
334
+ // phares 3/14/98
335
+ //
336
+ // Save the sector list pointed to by touching_sectorlist.
337
+ // In P_SetThingPosition, we'll keep any nodes that represent
338
+ // sectors the Thing still touches. We'll add new ones then, and
339
+ // delete any nodes for sectors the Thing has vacated. Then we'll
340
+ // put it back into touching_sectorlist. It's done this way to
341
+ // avoid a lot of deleting/creating for nodes, when most of the
342
+ // time you just get back what you deleted anyway.
343
+ //
344
+ // If this Thing is being removed entirely, then the calling
345
+ // routine will clear out the nodes in sector_list.
346
+
347
+ sector_list = thing -> touching_sectorlist ;
348
+ thing -> touching_sectorlist = NULL ; //to be restored by P_SetThingPosition
349
+ }
350
+
351
+ if (!(thing -> flags & MF_NOBLOCKMAP ))
352
+ {
353
+ // inert things don't need to be in blockmap
354
+
355
+ if (thing -> bnext ) // unlink from block map
356
+ thing -> bnext -> bprev = thing -> bprev ;
357
+
358
+ if (thing -> bprev )
359
+ ((mobj_t * )thing -> bprev )-> bnext = thing -> bnext ;
360
+ else
361
+ {
362
+ int blockx = (thing -> x - bmaporgx )>>MAPBLOCKSHIFT ;
363
+ int blocky = (thing -> y - bmaporgy )>>MAPBLOCKSHIFT ;
364
+ if (blockx >=0 && blockx < bmapwidth &&
365
+ blocky >=0 && blocky < bmapheight )
366
+ blocklinks [blocky * bmapwidth + blockx ] = thing -> bnext ;
367
+ }
368
+ }
369
+ }
370
+
371
+ static void P_UnsetThingPosition_MBF (mobj_t * thing )
321
372
{
322
373
if (!(thing -> flags & MF_NOSECTOR ))
323
374
{
@@ -377,7 +428,61 @@ void P_UnsetThingPosition (mobj_t *thing)
377
428
//
378
429
// killough 5/3/98: reformatted, cleaned up
379
430
380
- void P_SetThingPosition (mobj_t * thing )
431
+ static void P_SetThingPosition_Boom (mobj_t * thing )
432
+ { // link into subsector
433
+ subsector_t * ss = thing -> subsector = R_PointInSubsector (thing -> x , thing -> y );
434
+ if (!(thing -> flags & MF_NOSECTOR ))
435
+ {
436
+ // invisible things don't go into the sector links
437
+ sector_t * sec = ss -> sector ;
438
+
439
+ thing -> sprev = NULL ;
440
+ thing -> snext = sec -> thinglist ;
441
+
442
+ if (sec -> thinglist )
443
+ sec -> thinglist -> sprev = (mobj_t * * )thing ;
444
+
445
+ sec -> thinglist = thing ;
446
+
447
+ // phares 3/16/98
448
+ //
449
+ // If sector_list isn't NULL, it has a collection of sector
450
+ // nodes that were just removed from this Thing.
451
+
452
+ // Collect the sectors the object will live in by looking at
453
+ // the existing sector_list and adding new nodes and deleting
454
+ // obsolete ones.
455
+
456
+ // When a node is deleted, its sector links (the links starting
457
+ // at sector_t->touching_thinglist) are broken. When a node is
458
+ // added, new sector links are created.
459
+
460
+ P_CreateSecNodeList (thing ,thing -> x ,thing -> y );
461
+ thing -> touching_sectorlist = sector_list ; // Attach to Thing's mobj_t
462
+ sector_list = NULL ; // clear for next time
463
+ }
464
+
465
+ // link into blockmap
466
+ if (!(thing -> flags & MF_NOBLOCKMAP ))
467
+ {
468
+ // inert things don't need to be in blockmap
469
+ int blockx = (thing -> x - bmaporgx )>>MAPBLOCKSHIFT ;
470
+ int blocky = (thing -> y - bmaporgy )>>MAPBLOCKSHIFT ;
471
+ if (blockx >=0 && blockx < bmapwidth && blocky >=0 && blocky < bmapheight )
472
+ {
473
+ mobj_t * * link = & blocklinks [blocky * bmapwidth + blockx ];
474
+ thing -> bprev = NULL ;
475
+ thing -> bnext = * link ;
476
+ if (* link )
477
+ (* link )-> bprev = (mobj_t * * )thing ;
478
+ * link = thing ;
479
+ }
480
+ else // thing is off the map
481
+ thing -> bnext = NULL , thing -> bprev = NULL ;
482
+ }
483
+ }
484
+
485
+ static void P_SetThingPosition_MBF (mobj_t * thing )
381
486
{ // link into subsector
382
487
subsector_t * ss = thing -> subsector = R_PointInSubsector (thing -> x , thing -> y );
383
488
if (!(thing -> flags & MF_NOSECTOR ))
@@ -435,6 +540,24 @@ void P_SetThingPosition(mobj_t *thing)
435
540
}
436
541
}
437
542
543
+ void (* P_UnsetThingPosition )(struct mobj_s * thing ) = P_UnsetThingPosition_MBF ;
544
+ void (* P_SetThingPosition )(struct mobj_s * thing ) = P_SetThingPosition_MBF ;
545
+
546
+ void P_SetThingPosition_SetFuncs (void )
547
+ {
548
+ if (!mbf_features )
549
+ {
550
+ P_UnsetThingPosition = P_UnsetThingPosition_Boom ;
551
+ P_SetThingPosition = P_SetThingPosition_Boom ;
552
+ }
553
+ else
554
+ {
555
+ P_UnsetThingPosition = P_UnsetThingPosition_MBF ;
556
+ P_SetThingPosition = P_SetThingPosition_MBF ;
557
+ }
558
+ }
559
+
560
+
438
561
//
439
562
// BLOCK MAP ITERATORS
440
563
// For each line/thing in the given mapblock,
@@ -609,11 +732,20 @@ dboolean P_BlockLinesIterator2(int x, int y, dboolean func(line_t*))
609
732
610
733
dboolean P_BlockThingsIterator (int x , int y , dboolean func (mobj_t * ))
611
734
{
612
- mobj_t * mobj ;
613
- if (!(x < 0 || y < 0 || x >=bmapwidth || y >=bmapheight ))
614
- for (mobj = blocklinks [y * bmapwidth + x ]; mobj ; mobj = mobj -> bnext )
615
- if (!func (mobj ))
616
- return false;
735
+ mobj_t * mobj , * first ;
736
+
737
+ if (x < 0 || y < 0 || x >= bmapwidth || y >= bmapheight )
738
+ return true;
739
+
740
+ for (mobj = blocklinks [y * bmapwidth + x ]; (first = mobj ); mobj = mobj -> bnext )
741
+ {
742
+ if (!func (mobj ))
743
+ return false;
744
+
745
+ if (mobj -> bnext == first )
746
+ I_Error ("P_BlockThingsIterator: Infitnite loop detected!" );
747
+ }
748
+
617
749
return true;
618
750
}
619
751
0 commit comments