Files
eltanschauung cdce33647a Fix co-op Pillar of Autumn softlock glitch
A co-op ALL-player trigger could advance after an unchecked teleport, or while (players) was empty during respawn. Pillar of Autumn then permanently closed its blast door with players still outside.

Preserve player-list provenance in the existing unused header word, block empty or unavailable player-list waits only on the co-op host, and recheck all arrivals after gathering. Use the existing crowd fallback and restore rejected placements instead of leaving a player outside the volume or on a BSP switch. Empty AI lists, non-waiting tests and non-host behavior retain their semantics; no network message or protocol changes.

Validated with 17 production-source gate tests and negative controls, covering 1-128 players, failed or displaced teleports, BSP boundaries, retries, list reuse, allocation failure and empty AI/player lists. Windows and Linux release builds and the full local regression suite pass.

(cherry picked from commit 49b4716c4be187a16800300671221a964094e6fb)
2026-10-20 07:25:20 -04:00

64 lines
1.6 KiB
C

/*
OBJECT_LISTS.H
*/
#ifndef __OBJECT_LISTS_H
#define __OBJECT_LISTS_H
#pragma once
/* ---------- constants */
/* ---------- macros */
#define object_list_header_get(index) ((struct object_list_header_datum*)(datum_get(object_list_header_data, (index))))
#define object_list_get(index) ((struct data_reference*)(datum_get(object_list_data, (index))))
/* ---------- structures */
struct object_list_header_datum
{
short identifier;
word flags; /* port: provenance, using the original unused word */
short reference_count;
short count;
long first_reference_index;
};
/* ---------- prototypes/OBJECT_LISTS.C */
void object_lists_initialize(void);
void object_lists_dispose(void);
void object_lists_initialize_for_new_map(void);
void object_lists_dispose_from_old_map(void);
long object_list_new(void);
/* port: distinguish an empty (players) result from an empty AI list. */
void object_list_mark_players(long list_index);
boolean object_list_is_players(long list_index);
void object_list_delete(long list_index);
void object_list_add(long object_list_index, long object_index);
long object_list_get_first(
long object_list_index,
long *reference_index);
long object_list_get_next(
long object_list_index,
long *reference_index);
void object_list_add_reference(
long object_list_index);
void object_list_remove_reference(
long object_list_index);
void object_list_gc(
void);
short object_list_count(
long object_list_index);
/* ---------- globals */
extern struct data_array *object_list_header_data;
extern struct data_array *object_list_data;
/* ---------- public code */
#endif // __OBJECT_LISTS_H