mirror of
https://github.com/Cesarus85/ringfall-mjolnir-vr.git
synced 2026-10-25 14:00:28 +01:00
Co-op: tell a player held back at a loading zone what it waits for
Going back to a BSP the team has been in waits for two thirds of the team, and a player on the trigger was never told so. They now see "Waiting for your team to go back: 1 of 2 here", at once and every three seconds while they wait. Each machine works it out for its own players with the count the host decides by, now one function, so nothing new goes over the network.
This commit is contained in:
1 parent
e55c29a97e
commit
a143d9490d
1 file changed
+82
-19
+82
-19
@@ -476,6 +476,10 @@ static struct
|
||||
long bsp_switch_time;
|
||||
/* the structure BSPs the players have been in this map, by bit */
|
||||
word visited_structure_bsps;
|
||||
/* when each local player was last told they wait for the team to go
|
||||
back, and the count they were told (players_coop_show_backtrack_wait) */
|
||||
long backtrack_message_times[MAXIMUM_LOCAL_PLAYERS];
|
||||
short backtrack_message_counts[MAXIMUM_LOCAL_PLAYERS];
|
||||
/* where each player last stood on the ground, and on which BSP: where
|
||||
everyone comes back when the last checkpoint was on another one */
|
||||
short ground_structure_bsp_index;
|
||||
@@ -2783,6 +2787,9 @@ them (world units, about 45 metres). Wide enough for a team walking through
|
||||
a doorway in a line, not for one player who ran back alone. */
|
||||
#define COOP_BACKTRACK_GATHER_DISTANCE 15.0f
|
||||
|
||||
/* how often a player waiting for the team to go back is reminded */
|
||||
#define COOP_BACKTRACK_MESSAGE_TICKS (3 * TICKS_PER_SECOND)
|
||||
|
||||
/* Co-op host, each tick: a player stranded for COOP_STRANDED_TICKS is moved
|
||||
beside a grounded teammate inside the BSP, else any teammate inside it, else
|
||||
to the last checkpoint. Skipped while scripts hold the controls, since
|
||||
@@ -2968,9 +2975,9 @@ void players_respawn_at_checkpoint(
|
||||
return;
|
||||
}
|
||||
|
||||
/* port: whether the unit stands in a trigger that switches away from the
|
||||
loaded structure BSP */
|
||||
static boolean players_coop_in_bsp_switch_trigger(
|
||||
/* port: the trigger that switches away from the loaded structure BSP the
|
||||
unit stands in, or NONE */
|
||||
static short players_coop_bsp_switch_trigger(
|
||||
long unit_index)
|
||||
{
|
||||
struct scenario *scenario = global_scenario_get();
|
||||
@@ -2984,11 +2991,11 @@ static boolean players_coop_in_bsp_switch_trigger(
|
||||
if (volume->source_structure_bsp_index == global_structure_bsp_index &&
|
||||
scenario_trigger_volume_test_object(volume->trigger_volume_index, unit_index))
|
||||
{
|
||||
return TRUE;
|
||||
return index;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
return NONE;
|
||||
}
|
||||
|
||||
/* port: whether a network co-op host lets any trigger switch the BSP yet.
|
||||
@@ -3017,14 +3024,16 @@ static boolean players_coop_bsp_switch_ready(
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* port: whether a network co-op host lets the unit on this trigger switch
|
||||
the BSP, which brings the whole team along. Not while the unit's machine
|
||||
is still loading the BSP the host has. Anyone can lead the team into a BSP
|
||||
it hasn't been in; going back to one needs two thirds of the team there,
|
||||
so one player can't drag everyone back through the level. */
|
||||
static boolean players_coop_bsp_switch_allowed(
|
||||
/* port: whether this trigger leads back to a BSP the team has been in and
|
||||
the unit on it must wait for more of the team: two thirds of the living
|
||||
players must be with it (in the trigger, or within
|
||||
COOP_BACKTRACK_GATHER_DISTANCE), so one player can't drag everyone back
|
||||
through the level. Also how many are there and how many it needs. */
|
||||
static boolean players_coop_backtrack_wait(
|
||||
short bsp_switch_trigger_volume_index,
|
||||
long unit_index)
|
||||
long unit_index,
|
||||
short *gathered_count,
|
||||
short *needed_count)
|
||||
{
|
||||
struct scenario_bsp_switch_trigger_volume *volume = TAG_BLOCK_GET_ELEMENT(
|
||||
&global_scenario_get()->bsp_switch_trigger_volumes, bsp_switch_trigger_volume_index,
|
||||
@@ -3033,14 +3042,13 @@ static boolean players_coop_bsp_switch_allowed(
|
||||
struct data_iterator iterator;
|
||||
struct player_datum *player;
|
||||
short living_count = 0;
|
||||
short gathered_count = 0;
|
||||
|
||||
if (!network_coop_player_has_structure_bsp(unit_get(unit_index)->unit.player_index))
|
||||
return FALSE;
|
||||
*gathered_count = 0;
|
||||
*needed_count = 0;
|
||||
if (!VALID_INDEX(volume->destination_structure_bsp_index, MAXIMUM_STRUCTURE_BSPS_PER_SCENARIO) ||
|
||||
!TEST_FLAG(players_coop_state.visited_structure_bsps, volume->destination_structure_bsp_index))
|
||||
{
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
data_iterator_new(&iterator, player_data);
|
||||
while ((player = data_iterator_next(&iterator)) != NULL)
|
||||
@@ -3054,11 +3062,64 @@ static boolean players_coop_bsp_switch_allowed(
|
||||
distance_squared3d(center, &teammate->object.bounding_sphere_center) <=
|
||||
COOP_BACKTRACK_GATHER_DISTANCE * COOP_BACKTRACK_GATHER_DISTANCE)
|
||||
{
|
||||
gathered_count++;
|
||||
(*gathered_count)++;
|
||||
}
|
||||
}
|
||||
/* (two thirds, rounded up) */
|
||||
*needed_count = (short)((living_count * 2 + 2) / 3);
|
||||
|
||||
return gathered_count * 3 >= living_count * 2;
|
||||
return *gathered_count < *needed_count;
|
||||
}
|
||||
|
||||
/* port: whether a network co-op host lets the unit on this trigger switch
|
||||
the BSP, which brings the whole team along: not while the unit's machine is
|
||||
still loading the host's BSP, nor back to one the team has been in until
|
||||
enough of it is there (players_coop_backtrack_wait) */
|
||||
static boolean players_coop_bsp_switch_allowed(
|
||||
short bsp_switch_trigger_volume_index,
|
||||
long unit_index)
|
||||
{
|
||||
short gathered_count;
|
||||
short needed_count;
|
||||
|
||||
return network_coop_player_has_structure_bsp(unit_get(unit_index)->unit.player_index) &&
|
||||
!players_coop_backtrack_wait(bsp_switch_trigger_volume_index, unit_index, &gathered_count, &needed_count);
|
||||
}
|
||||
|
||||
/* port: tells each of this machine's co-op players held back on a trigger
|
||||
how many of the team are there and how many it needs, at once and every
|
||||
COOP_BACKTRACK_MESSAGE_TICKS while they wait. Every machine works this out
|
||||
for its own players, as the host does for its decision. */
|
||||
static void players_coop_show_backtrack_wait(
|
||||
void)
|
||||
{
|
||||
short local_player_index;
|
||||
|
||||
for (local_player_index = 0; local_player_index < MAXIMUM_LOCAL_PLAYERS; local_player_index++)
|
||||
{
|
||||
long player_index = local_player_get_player_index(local_player_index);
|
||||
long unit_index = player_index != NONE ? player_get(player_index)->unit_index : NONE;
|
||||
short trigger_index = unit_index != NONE ? players_coop_bsp_switch_trigger(unit_index) : NONE;
|
||||
long *time = &players_coop_state.backtrack_message_times[local_player_index];
|
||||
short *count = &players_coop_state.backtrack_message_counts[local_player_index];
|
||||
short gathered_count;
|
||||
short needed_count;
|
||||
wchar_t text[64];
|
||||
|
||||
if (trigger_index == NONE ||
|
||||
!players_coop_backtrack_wait(trigger_index, unit_index, &gathered_count, &needed_count))
|
||||
{
|
||||
*time = 0;
|
||||
continue;
|
||||
}
|
||||
if (*time != 0 && *count == gathered_count && game_time_get() - *time < COOP_BACKTRACK_MESSAGE_TICKS)
|
||||
continue;
|
||||
*time = game_time_get();
|
||||
*count = gathered_count;
|
||||
usnprintf(text, NUMBEROF(text), L"Waiting for your team to go back: %d of %d here",
|
||||
gathered_count, needed_count);
|
||||
hud_print_message(local_player_index, text);
|
||||
}
|
||||
}
|
||||
|
||||
static void player_teleport_on_bsp_switch(
|
||||
@@ -3251,7 +3312,7 @@ void players_reconnect_to_structure_bsp(
|
||||
struct object_datum *unit = object_try_and_get(player->unit_index);
|
||||
|
||||
if (unit && scenario_leaf_index_from_point(&unit->object.bounding_sphere_center) != NONE &&
|
||||
!players_coop_in_bsp_switch_trigger(player->unit_index))
|
||||
players_coop_bsp_switch_trigger(player->unit_index) == NONE)
|
||||
{
|
||||
source_unit_index = player->unit_index;
|
||||
teleport_position = unit->object.position;
|
||||
@@ -4592,6 +4653,8 @@ void players_update_after_game(
|
||||
players_coop_state.structure_bsp_index = global_structure_bsp_index;
|
||||
players_coop_state.bsp_switch_time = game_time_get();
|
||||
}
|
||||
if (network_coop_active())
|
||||
players_coop_show_backtrack_wait();
|
||||
|
||||
data_iterator_new(&iterator, player_data);
|
||||
while (player = data_iterator_next(&iterator))
|
||||
|
||||
Reference in new issue
Block a user