PHP Code:
stock ChangeTeam(iClient, iTeam)
{
if (!IsValidClient(iClient))
{
return;
}
new iOldTeam = GetClientTeam(iClient);
if (iOldTeam != iTeam)
{
if (iOldTeam > TEAM_SPEC) // If player is already on RED or BLU / is NOT a spectator - This code works perfectly
{
if (IsPlayerAlive(iClient))
{
SetEntProp(iClient, Prop_Send, "m_lifeState", LifeState_Dead);
ChangeClientTeam(iClient, iTeam);
SetEntProp(iClient, Prop_Send, "m_lifeState", LifeState_Alive);
}
else
{
ChangeClientTeam(iClient, iTeam);
}
}
else // If player is a spectator or unassigned - This code causes so many problems I wat
{
ChangeClientTeam(iClient, iTeam); // Living spectator fix?
SetRandomClass(iClient); // If the player was a spectator beforehand, we need to give them a class again
// Not really fixed, because TF2_RespawnPlayer below won't respawn this spectator now???
// If we omit SetRandomClass, it can spawn them, but then the player is a living spectator that can't be attacked, but can teleport between observer points and attack via +attack in console to shoot rockets or swing melee.
// SetEntProp(iClient, Prop_Send, "m_lifeState", LifeState_Dead); // This doesn't do anything
}
TF2_RespawnPlayer(iClient);
TF2_RegeneratePlayer(iClient);
//RequestFrame(InstantRespawn, GetClientUserId(iClient));
}
}
I've been trying for weeks to fix the issue where plugins like
SwapTeam and AFK-Manager can move a player to spectator during non-queued arena mode, and make it so they don't respawn properly.
Basically:
In arena mode, with tf_arena_use_queue 0
The following commands:
jointeam spectate
spectate
Properly set you to spectate as "1 player waiting to play: Chdata"
However, ChangeClientTeam(Chdata, TEAM_SPEC)
Marks you as a "1 spectator: Chdata".
The 'player waiting to play' can properly be respawned with TF2_RespawnPlayer, forced to join team red/blu, etc.
The 'spectator' cannot. If you don't set the 'spectator's class when you try to move him to red/blu, it's possible for him to spawn as a "living spectator", whether you're Hale or a normal player.
Properties of a living spectator:
- Untested, but most likely your class was set to TFClass_None when you were moved to spec by ChangeClientTeam
- Has health (GetClientHealth will have your actual class's health or the bosses health)
- Is not on the spectator or unassigned team.
- m_Lifestate is alive.
- IsPlayerAlive returns true
- I have not tried IsClientObserver
- You can type +attack in console to attack and kill the enemy team. Your melee weapon will swing. You can even shoot rockets out of a rocket launcher.
- You are stuck in "spectate". Normal clicking with your +attack key will switch you between observerpoints in the map or spectating players.
- You can never 'noclip' spectate. In first person spec, you can move the camera but it will rapidly snap back in place to fit your target and feel glitchy. In third person spec, you can look around freely but you can't noclip.
- It's possible to sm_slay this player multiple times in a row without doing anything. The command responds with "Player was slayed" instead of "Player must be alive".
After I added SetRandomClass, now at least the player can no longer become a living spectator, capable of killing people. He'll count as "dead" in the sense that, if the boss is this player, or if it's the final player alive in arena mode, the round will end because the entire team is dead.
But just like the living spectator, this player cannot really be TF2_Respawn'd. Whenever you try to call it, nothing happens to them and their stuck on red/blu as a dead player. Also, it still says they're a "1 spectator: Chdata" in the tab menu.
Basically, you are now an eternally dead spectator.
Until you reconnect, you will always be marked as a spectator.
I tried setting lifestate to dead to see if it'd make respawning them work, but nope. Respawning them in a timer changes nothing.
Finally, if you go ahead and choose a class (either as living spectator or eternally dead spectator), the problem is fixed completely. You can now respawn again or be TF2_Respawned. But you will still appear as "1 spectator: Chdata" in the tab menu. And if you get moved to spectate again, you're broken again.
Code:
// m_lifeState
enum
{
LifeState_Alive = 0,
LifeState_UnOwen,
LifeState_Dead
}
Also, the latest AFK Manager was changed to FakeClientCommand ?Ex? jointeam spectate during non-queued arena, but it seemingly doesn't kick them to spectate at all or something. I also recently tried to use FakeClientCommand/Ex jointeam in a jointeam command listener to make it so you can only join one team, and joining the other team fakecommand joins you to the intended team, but it never seems to fire. FakeClientCommand of course results in an infinite loop, and Ex just does nothing - infact I was stuck being unable to get out of spectator after that. (The goal was to only allow spectators to join blu. Joining red was meant to force them to join blu too - I opted out for checking their team when the spawn and forcing their team to blue with the same ChangeTeam above, but with an extra function to teleport them to their spawn).
Also, for queued arena (tf_arena_use_queue 1), SwapTeam/AFK-Manager does this:
PHP Code:
PerformSwitchToSpec(client, target)
{
LogAction(client, target, "\"%L\" moved (to spectate) \"%L\"", client, target);
if (TF2)
{
if (g_TF2Arena)
{
// Arena Spectator Fix by Rothgar
SetEntProp(target, Prop_Send, "m_nNextThinkTick", -1);
SetEntProp(target, Prop_Send, "m_iDesiredPlayerClass", 0);
SetEntProp(target, Prop_Send, "m_bArenaSpectator", 1);
}
ChangeClientTeam(target, TEAM_SPEC);
}
else
{
ChangeClientTeam(target, TEAM_SPEC);
}
}
But bArenaSpectator, DesiredPlayerClass, ?and I guess NextThinkTick? all do nothing/are unusued when tf_arena_use_queue is 0.
__________________