diff --git a/source/games/duke/src/player_d.cpp b/source/games/duke/src/player_d.cpp index 8cd788408..304c21f8f 100644 --- a/source/games/duke/src/player_d.cpp +++ b/source/games/duke/src/player_d.cpp @@ -890,7 +890,10 @@ static void shootlaser(DDukeActor* actor, int p, int sx, int sy, int sz, int sa) } } - bomb->s.hitag = bomb->GetIndex(); // sigh... + // this originally used the sprite index as tag to link the laser segments. + // This value is never used again to reference an actor by index. Decouple this for robustness. + ud.bomb_tag = (ud.bomb_tag + 1) & 32767; + bomb->s.hitag = ud.bomb_tag; S_PlayActorSound(LASERTRIP_ONWALL, bomb); bomb->s.xvel = -20; ssp(bomb, CLIPMASK0); diff --git a/source/games/duke/src/savegame.cpp b/source/games/duke/src/savegame.cpp index c973477a7..0cb9cfc67 100644 --- a/source/games/duke/src/savegame.cpp +++ b/source/games/duke/src/savegame.cpp @@ -379,6 +379,7 @@ void GameInterface::SerializeGameState(FSerializer& arc) ("marker", ud.marker) ("ffire", ud.ffire) ("levelclock", ud.levelclock) + ("bomb_tag", ud.bomb_tag) .Array("sectorextra", sectorextra, numsectors) ("rtsplaying", rtsplaying) diff --git a/source/games/duke/src/spawn_d.cpp b/source/games/duke/src/spawn_d.cpp index bda23f9f1..a6da2433d 100644 --- a/source/games/duke/src/spawn_d.cpp +++ b/source/games/duke/src/spawn_d.cpp @@ -339,7 +339,8 @@ int spawn_d(int j, int pn) sp->yrepeat=5; act->SetOwner(act); - sp->hitag = i; // hijack + ud.bomb_tag = (ud.bomb_tag + 1) & 32767; + sp->hitag = ud.bomb_tag; sp->xvel = 16; ssp(act, CLIPMASK0); diff --git a/source/games/duke/src/types.h b/source/games/duke/src/types.h index d76e0a277..35be0880f 100644 --- a/source/games/duke/src/types.h +++ b/source/games/duke/src/types.h @@ -132,6 +132,7 @@ struct user_defs short from_bonus; short last_level, secretlevel; + short bomb_tag; int const_visibility;