Raised This Month: $51 Target: $400
 12% 

[CS] Respawn on First Team Join


Post New Thread Reply   
 
Thread Tools Display Modes
Author Message
ConnorMcLeod
Veteran Member
Join Date: Jul 2006
Location: France (95)
Old 08-02-2012 , 23:18   [CS] Respawn on First Team Join
Reply With Quote #1

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.

PHP Code:
#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(PLUGINVERSION"ConnorMcLeod");

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

    
DisableHamForwardg_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(idm_iMenu) == MENU_CHOOSEAPPEARANCE && get_pdata_int(idm_iJoiningState) == JOIN_CHOOSEAPPEARANCE )
    {
        
// Enable PreThink for 1 frame if not already
        
if( !g_iBitHookPlayerPreThink )
        {
            
EnableHamForwardg_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_Postid )
{
    if( !
HookPlayerPreThink(id) )
    {
        return 
HAM_IGNORED;
    }

    
ClearPlayerPreThink(id);
    if( !
g_iBitHookPlayerPreThink )
    {
        
DisableHamForwardg_iHhCBasePlayerPreThink );
    }

    if( !
is_user_alive(id) )
    {
        
// if player has not been respawned by the game, let's force it.
        
ExecuteHam(Ham_Spawnid);
        return 
HAM_HANDLED;
    }
    return 
HAM_IGNORED;


Could also force respawn doing this :
Spoiler
__________________
- tired and retired -

- my plugins -

Last edited by ConnorMcLeod; 06-21-2013 at 18:23.
ConnorMcLeod is offline
dFF
sıɹɹoɥɔ ʞɔnu
Join Date: Oct 2009
Old 08-03-2012 , 03:38   Re: [CS] Respawn on First Team Join
Reply With Quote #2

What happen when more players call (same time) OnCBasePlayer_PreThink_Post and DisableHamForward can be disable Player_PreThink and others players can't respawned [don't have time to call ExecuteHam(Ham_Spawn, id)]. It's possible to happen that ?


It's a problem if using a little task (like 1.0) in ClCmd_MenuSelect_JoinClass and spawn player in that's task ?

Last edited by dFF; 08-03-2012 at 03:40.
dFF is offline
xPaw
Retired AMX Mod X Moderator
Join Date: Jul 2008
Old 08-03-2012 , 04:34   Re: [CS] Respawn on First Team Join
Reply With Quote #3

Quote:
Originally Posted by dFF View Post
It's a problem if using a little task (like 1.0) in ClCmd_MenuSelect_JoinClass and spawn player in that's task ?
Quote:
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.
__________________
xPaw is offline
dFF
sıɹɹoɥɔ ʞɔnu
Join Date: Oct 2009
Old 08-03-2012 , 05:01   Re: [CS] Respawn on First Team Join
Reply With Quote #4

Oh my bad !!
dFF is offline
Backstabnoob
Veteran Member
Join Date: Feb 2009
Location: Iwotadai Dorm
Old 08-03-2012 , 06:57   Re: [CS] Respawn on First Team Join
Reply With Quote #5

Good job, going to test this.
__________________
Currently busy working on a very large scale anime database project.
Backstabnoob is offline
joropito
AlliedModders Donor
Join Date: Mar 2009
Location: pfnAddToFullPack
Old 08-03-2012 , 09:33   Re: [CS] Respawn on First Team Join
Reply With Quote #6

Quote:
Originally Posted by dFF View Post
What happen when more players call (same time) OnCBasePlayer_PreThink_Post and DisableHamForward can be disable Player_PreThink and others players can't respawned [don't have time to call ExecuteHam(Ham_Spawn, id)]. It's possible to happen that ?
Just after the CLCMD is processed, PlayerPreThink is called so there's no way to hit Prethink asynchronously.


Other way to achieve this is hooking CHalfLifeMultiplay::FPlayerCanRespawn and return 1 if first join but this can only be done using Rage or Orpheu.
__________________

Divide et vinces
approved plugins | steam account

I don't accept PM for support. Just ask on forums.
If you're looking for private work, PM me.
joropito is offline
Send a message via MSN to joropito
ConnorMcLeod
Veteran Member
Join Date: Jul 2006
Location: France (95)
Old 08-03-2012 , 10:59   Re: [CS] Respawn on First Team Join
Reply With Quote #7

Yes, forgot to say that i was searching a way with only default modules.
__________________
- tired and retired -

- my plugins -
ConnorMcLeod is offline
hleV
Veteran Member
Join Date: Mar 2007
Location: Lithuania
Old 08-05-2012 , 13:55   Re: [CS] Respawn on First Team Join
Reply With Quote #8

I think this can be done by setting the pdata m_iSpawnTimes (365) to 0 at a correct event.
hleV is offline
joropito
AlliedModders Donor
Join Date: Mar 2009
Location: pfnAddToFullPack
Old 08-05-2012 , 14:19   Re: [CS] Respawn on First Team Join
Reply With Quote #9

Quote:
Originally Posted by hleV View Post
I think this can be done by setting the pdata m_iSpawnTimes (365) to 0 at a correct event.
That is not enought.
There's a check on GameRules->m_fRoundCount. You can't spawn after 20 seconds of round start.
__________________

Divide et vinces
approved plugins | steam account

I don't accept PM for support. Just ask on forums.
If you're looking for private work, PM me.
joropito is offline
Send a message via MSN to joropito
Arkshine
AMX Mod X Plugin Approver
Join Date: Oct 2005
Old 08-05-2012 , 14:35   Re: [CS] Respawn on First Team Join
Reply With Quote #10

Without orpheu, I don't think.

This offset is used in CHalfLifeMultiplay::FPlayerCanRespawn as main check.
Reseted in ClientPutInServer and CHalfLifeMultiplay::RestartRound.
Increased in CBasePlayer::Spawn

Here the code where it's used :
Code:
BOOL CHalfLifeMultiplay::FPlayerCanRespawn( CBasePlayer *pPlayer ) {     if( pPlayer->m_iSpawnTimes <= 0 )     {         m_iNumCTs = CountTeamPlayers( TEAM_CT );         m_iNumTerrorists = CountTeamPlayers( TEAM_T );                 if( m_iNumCTs <= 0 || m_iNumTerrorists <= 0 || m_flRoundCount + 20.0 >= gpGlobals->time )         {             return pPlayer->m_iTeam != TEAM_SPECTATOR;         }         else if( fadetoblack.value != 0 )         {             UTIL_ScreenFade( pPlayer->pev, 0.0, 3.0, 3.0, 255, 5 );         }     }         return FALSE; }


If you manage to reset the offset, you will have to deal with m_flRoundCount, which is CGameRules offset and can't be modified without orpheu at least.

EDIT: Ninja'd by Joropito.
__________________

Last edited by Arkshine; 08-06-2012 at 09:56.
Arkshine is offline
Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -4. The time now is 02:00.


Powered by vBulletin®
Copyright ©2000 - 2024, vBulletin Solutions, Inc.
Theme made by Freecode