[CS] Respawn on First Team Join

For scripting examples for learning how to use AMXX.
User avatar
Archive-Poster
Posts: 1267
Gender:
United States of America

[CS] Respawn on First Team Join

Post by Archive-Poster »

As you know, when a player is entering a server and join a team, depending on the round advancement, he will respawn or not.
Seeing lot of plugin where tasks are set and check few times if player is in a team and then respawn him, i've search a smoth way to respawn players in that situation.
Code has not be fully tested but should work fine.

Code: Select all

#include < amxmodx >
#include < fakemeta >
#include < hamsandwich >

#pragma semicolon 1

#define VERSION "0.1.0"
#define PLUGIN "Respawn on First Join"

const m_iJoiningState = 121;
const m_iMenu = 205;
const MENU_CHOOSEAPPEARANCE = 3;
const JOIN_CHOOSEAPPEARANCE = 4;

new HamHook:g_iHhCBasePlayerPreThink;

#define MaskEnt(%0)    ( 1<<(%0 & 31) )

new g_iBitHookPlayerPreThink;
#define MarkPlayerPreThink(%0)    g_iBitHookPlayerPreThink |= MaskEnt(%0)
#define ClearPlayerPreThink(%0)    g_iBitHookPlayerPreThink &= ~MaskEnt(%0)
#define HookPlayerPreThink(%0)    ( g_iBitHookPlayerPreThink & MaskEnt(%0) )

public plugin_init()
{
    register_plugin(PLUGIN, VERSION, "ConnorMcLeod");

    register_clcmd("menuselect", "ClCmd_MenuSelect_JoinClass"); // old style menu
    register_clcmd("joinclass", "ClCmd_MenuSelect_JoinClass"); // VGUI menu

    DisableHamForward( g_iHhCBasePlayerPreThink = RegisterHam(Ham_Player_PreThink, "player", "OnCBasePlayer_PreThink_Post", true) ); // register it for later
}

// player is pressing a key in an old style menu
// or player is sending joinclass command, either by typing it in console, either selecting a option from VGUI skins selection menu
public ClCmd_MenuSelect_JoinClass(id)
{
    // Don't need to check args here, because (assuming player is in the skin select menu, 
    // we gonna check this) if there is no arg, or if arg is bad, game gonna act as if player was choosing auto-select.
    // So first check if player is in the correct menu, pdata m_iMenu can just tell us
    // Then check if player has just joined the server, m_iJoiningState is used by the game for this
    if( get_pdata_int(id, m_iMenu) == MENU_CHOOSEAPPEARANCE && get_pdata_int(id, m_iJoiningState) == JOIN_CHOOSEAPPEARANCE )
    {
        // Enable PreThink for 1 frame if not already
        if( !g_iBitHookPlayerPreThink )
        {
            EnableHamForward( g_iHhCBasePlayerPreThink );
        }
        MarkPlayerPreThink(id);
    }
}

// Little explanation on what should happen after player has chosen a skin :
// In CBasePlayer::PreThink, if player pdata m_iJoiningState is different from 0, function CBasePlayer::JoinThink gonna be called
// In JoinThink function, if m_iJoiningState 5 it means that player has just chosen a skin, we had checked if pdata was 4 because player has not chosen a team yet
// Then game checks if that player can be respawn with function CGameRules::FPlayerCanRespawn (if no objective or no player in 1 team player can respawn, 
// else if we are less that 20sec after round start player can respawn, else player won't spawn)

// So now that PreThink and JoinThink have been called, let's check if player has been respawned or not.
public OnCBasePlayer_PreThink_Post( id )
{
    if( !HookPlayerPreThink(id) )
    {
        return HAM_IGNORED;
    }

    ClearPlayerPreThink(id);
    if( !g_iBitHookPlayerPreThink )
    {
        DisableHamForward( g_iHhCBasePlayerPreThink );
    }

    if( !is_user_alive(id) )
    {
        // if player has not been respawned by the game, let's force it.
        ExecuteHam(Ham_Spawn, id);
        return HAM_HANDLED;
    }
    return HAM_IGNORED;
} 
Could also force respawn doing this :

Code: Select all

#include < amxmodx >
#include < fakemeta >
#include < hamsandwich >

#pragma semicolon 1

#define VERSION "0.1.0"
#define PLUGIN "Respawn on First Join"

const m_iJoiningState = 121;
const m_iMenu = 205;
const MENU_CHOOSEAPPEARANCE = 3;
const JOIN_CHOOSEAPPEARANCE = 4;

public plugin_init()
{
    register_plugin(PLUGIN, VERSION, "ConnorMcLeod");

    register_clcmd("menuselect", "ClCmd_MenuSelect_JoinClass"); // old style menu
    register_clcmd("joinclass", "ClCmd_MenuSelect_JoinClass"); // VGUI menu
}

public ClCmd_MenuSelect_JoinClass(id)
{
    if( get_pdata_int(id, m_iMenu) == MENU_CHOOSEAPPEARANCE && get_pdata_int(id, m_iJoiningState) == JOIN_CHOOSEAPPEARANCE )
    {
        new command[11], arg1[32];
        read_argv(0, command, charsmax(command));
        read_argv(1, arg1, charsmax(arg1));
        engclient_cmd(id, command, arg1);
        ExecuteHam(Ham_Player_PreThink, id);
        if( !is_user_alive(id) )
        {
            ExecuteHamB(Ham_Spawn, id);
        }
        return PLUGIN_HANDLED;
    }
    return PLUGIN_CONTINUE;
} 

Who is online

Users browsing this forum: No registered users and 0 guests