1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
//! TF2's player respawns: how the game brings a player back, dead or not, and
//! where to intercept it.
//!
//! Every respawn of a player goes through `CTFPlayer::ForceRespawn`, which the
//! game calls through the player's vtable: respawn waves, a round's restart,
//! `game_forcerespawn`'s inputs, choosing a class, and the script bindings'
//! `ForceRespawn` included. Only direct calls of the player's `Spawn` bypass
//! it: a player's first spawn as it is put in the server, and scripts'
//! `DispatchSpawn` of a player.
//!
//! [`sdk_raw::tf2::respawn`] holds the function's signature and its vtable
//! slot, [`FORCE_RESPAWN_SLOT`](sdk_raw::tf2::respawn::FORCE_RESPAWN_SLOT).
//! `metamod_source`'s `respawn_hooks` hook it, to see every such respawn
//! before the game and to refuse it. [`force_respawn`] calls it, to respawn a
//! player as the game would.
use crateEntity;
use crate::;
use vcall;
/// Respawns a TF2 player or bot as the game's own respawns do, through its
/// `CTFPlayer::ForceRespawn`, dead or alive.
///
/// The game spawns the player afresh as the class they chose
/// (`m_iDesiredPlayerClass`), and removes their buildings and projectiles if
/// that changes their class. It does nothing for a player who has chosen no
/// class, and, in arena, nothing during its own pre-game (`GR_STATE_PREGAME`)
/// or while it waits for players without arena's queue (`tf_arena_use_queue`
/// 0). Otherwise it spawns them whatever the round's state, arena's stalemate
/// included, and whatever their team: it does not check that they are on a
/// playing team, so check that first, as the game's own callers do.
///
/// Hooks of `ForceRespawn` see the call as they see the game's own respawns,
/// and may refuse it, as `metamod_source`'s `respawn_hooks` can. Spawning runs
/// the game's, other plugins', and this plugin's own spawn callbacks
/// synchronously, before this returns. They must keep to the contract of
/// [`Server::new`].
///
/// # Errors
///
/// Fails with [`RespawnError::NotTfPlayer`] unless the server runs TF2 and
/// `player`'s datamaps include `CTFPlayer`, and with
/// [`RespawnError::MarkedForDeletion`] for a player marked for deletion,
/// before the game is called.
/// Why [`force_respawn`] could not respawn a player.