Fix traps due to invalid level data
`Descent 2: Counterstrike` level 9 specifies a control center trigger on a side with no wall. This is not valid. In normal play, wall_toggle silently ignored this, and newdemo_pop_ctrlcen_triggers had undefined behavior. Add a warning in wall_toggle to report levels like this. Add handling in newdemo_pop_ctrlcen_triggers to detect and suppress this bogus data. `Descent 2: Counterstrike` level 11 specifies a control center trigger on a side with no child segment. This is not valid, so newdemo_pop_ctrlcen_triggers again had undefined behavior. Add handling to detect and suppress this bogus data. Reported-by: Descender1032 <https://forum.dxx-rebirth.com/showthread.php?tid=992>
This commit is contained in:
parent
c60c0352f0
commit
8ae4ef9eb5
|
@ -1937,9 +1937,29 @@ static void newdemo_pop_ctrlcen_triggers()
|
|||
for (int i = 0; i < ControlCenterTriggers.num_links; i++) {
|
||||
const auto &&seg = vmsegptridx(ControlCenterTriggers.seg[i]);
|
||||
const auto side = ControlCenterTriggers.side[i];
|
||||
const auto &&csegp = vmsegptr(seg->children[side]);
|
||||
const auto csegi = seg->children[side];
|
||||
if (csegi == segment_none)
|
||||
{
|
||||
/* Some levels specify control center triggers for
|
||||
* segments/sides that have no wall. `Descent 2:
|
||||
* Counterstrike` level 11, control center trigger 0 would
|
||||
* fault without this test.
|
||||
*/
|
||||
continue;
|
||||
}
|
||||
const auto &&csegp = vmsegptr(csegi);
|
||||
auto cside = find_connect_side(seg, csegp);
|
||||
const auto anim_num = vcwallptr(seg->sides[side].wall_num)->clip_num;
|
||||
const auto wall_num = seg->sides[side].wall_num;
|
||||
if (wall_num == wall_none)
|
||||
{
|
||||
/* Some levels specify control center triggers for
|
||||
* segments/sides that have no wall. `Descent 2:
|
||||
* Counterstrike` level 9, control center trigger 2 would
|
||||
* fault without this test.
|
||||
*/
|
||||
continue;
|
||||
}
|
||||
const auto anim_num = vcwallptr(wall_num)->clip_num;
|
||||
const auto n = WallAnims[anim_num].num_frames;
|
||||
const auto t = WallAnims[anim_num].flags & WCF_TMAP1
|
||||
? &side::tmap_num
|
||||
|
|
|
@ -1071,8 +1071,10 @@ void wall_toggle(const vmsegptridx_t segp, unsigned side)
|
|||
#endif
|
||||
return;
|
||||
}
|
||||
auto wall_num = segp->sides[side].wall_num;
|
||||
if (wall_num == wall_none) {
|
||||
const auto wall_num = segp->sides[side].wall_num;
|
||||
if (wall_num == wall_none)
|
||||
{
|
||||
LevelError("Ignoring attempt to toggle wall in segment %hu, side %u: no wall exists there.", segp.get_unchecked_index(), side);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue