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

Any thoughts on this code?


Post New Thread Reply   
 
Thread Tools Display Modes
Author Message
AnimalMonster
Senior Member
Join Date: May 2020
Old 11-18-2022 , 13:20   Any thoughts on this code?
Reply With Quote #1

I always wanted full control of the round and wanted to try a different approach.
Thoughts?

PHP Code:
/* Require Semicolons */
#pragma semicolon 1


/* ~(Includes)~ */
#include <amxmodx>
#include <amxmisc>
#include <fakemeta>
#include <hamsandwich>
#include <reapi>

#include <zextract_const>

/* ~(Debug)~ */
//#define DEBUG // Enables Debug


/* ~(Frame)~ */
#define NextFrame RequestFrame( "OnNextFrame" );


/* ~(Round)~ */
#define MaxRoundTime 540

#define PlayersAlive ( ( GetPlayers( TEAM_CT ) ) && ( GetPlayers( TEAM_TERRORIST ) ) )

new const RoundWinMessagesWinType ][  ] = {
    
"",
    
"Restarting",
    
"No One Won",
    
"Humans Win",
    
"Zombies Win"
};


/* ~(Cvar)~ */
#define CvarValueMaxLen CI_Value - CI_Name - CI_Id

enum cvarInfo
{
    
CI_Id,
    
CI_Name50 ],
    
CI_Value50 ],
    
FloatCI_flValue,
    
CI_IntValue
};

enum _plgCvars
{
    
PCV_WFPDelay,
    
PCV_WFPMin,
    
PCV_Rounds,
    
PCV_RoundStartDelay,
    
PCV_RoundEndDelay
};

new 
g_iCvarsplgCvars ][ cvarInfo ] = 
{
    { 
0"ZExtract_WfpDelay""3.0",  0.0},
    { 
0"ZExtract_WfpMinPlayers""2"0.0},
    { 
0"ZExtract_Rounds""10"0.0},
    { 
0"ZExtract_RoundStartDelay""15.0"0.0},
    { 
0"ZExtract_RoundEndDelay""5.0"0.0}
};


/* ~(Variables)~ */
new /*==*/ g_MaxRoundTime,
    
/*==*/ g_MaxRounds,
    
/*==*/ g_iRound,

    
Floatg_flRoundStartTime,
    
Floatg_flCountNextTime,
    
Floatg_flWFPTime,

    
boolg_bRoundStarted,
    
boolg_bRoundEnded,
    
boolg_bWFP,

    
RsTypeg_rRestart,

    
cvarRestart],
    
cvarRoundTime,
    
cvarFreezeTime,

    
imTextMsg,
    
imRoundTimer;


/* ~(Private Functions)~ */
RegisterCvars( )
{
    for ( new 
0plgCvars; ++)
    {
        
g_iCvars][ CI_Id ] = register_cvarg_iCvars][ CI_Name ], g_iCvars][ CI_Value ] );
        
bind_pcvar_stringg_iCvars][ CI_Id ], g_iCvars][ CI_Value ], CvarValueMaxLen );
        
bind_pcvar_floatg_iCvars][ CI_Id ], g_iCvars][ CI_flValue ] );
        
bind_pcvar_numg_iCvars][ CI_Id ], g_iCvars][ CI_IntValue ] );
    }
}

CheckRestart( )
{
    if ( 
g_rRestart Rs_Not )
        return;

    new 
cvarStr];

    
get_pcvar_stringcvarRestart], cvarStrcharsmaxcvarStr ) );

    if ( 
containcvarStr"." ) )
    {
        if ( 
get_pcvar_floatcvarRestart] ) > 0.0 )
        {
            
#if defined DEBUG
            
server_print"Server Game Restart" );
            
#endif
            
g_rRestart Rs_All;
            
OnRoundEnd( );
        }
    }
    else {
        if ( 
get_pcvar_numcvarRestart] ) > )
        {
            
#if defined DEBUG
            
server_print"Server Game Restart" );
            
#endif
            
g_rRestart Rs_All;
            
OnRoundEnd( );
        }
    }

    
get_pcvar_stringcvarRestart], cvarStrcharsmaxcvarStr ) );

    if ( 
containcvarStr"." ) )
    {
        if ( 
get_pcvar_floatcvarRestart] ) > 0.0 )
        {
            
#if defined DEBUG
            
server_print"Server Round Restart" );
            
#endif
            
g_rRestart Rs_Round;
            
OnRoundEnd( );
        }
    }
    else {
        if ( 
get_pcvar_numcvarRestart] ) > )
        {
            
#if defined DEBUG
            
server_print"Server Round Restart" );
            
#endif
            
g_rRestart Rs_Round;
            
OnRoundEnd( );
        }
    }
}

CheckRoundEndFloatflGameTime )
{
    static 
FloatTimePassed;
    
TimePassed = ( flGameTime g_flRoundStartTime );

    if ( ( 
0.0 > ( floatg_MaxRoundTime ) - TimePassed ) ) || !PlayersAlive )
    {
        
OnRoundEnd( );
    }

    
#if defined DEBUG
    
server_print"CheckRoundEnd Works: PlayersAlive:%i"PlayersAlive);
    
#endif
}

CheckWFP( )
{
    static 
PlayersOnPlayersOn get_playersnum( );
    static 
FloatflGameTimeflGameTime get_gametime( );

    if ( !
g_bWFP && PlayersOn >= g_iCvarsPCV_WFPMin ][ CI_IntValue ] )
    {
        return;
    }

    if ( 
PlayersOn g_iCvarsPCV_WFPMin ][ CI_IntValue ] && !g_bWFP )
    {
        
g_bWFP true;
        
g_bRoundEnded true;
    }

    if ( 
g_bWFP && PlayersOn >= g_iCvarsPCV_WFPMin ][ CI_IntValue ] )
    {
        if ( 
g_flRoundStartTime g_flWFPTime )
            
g_flWFPTime flGameTime;

        if ( 
flGameTime g_flWFPTime g_iCvarsPCV_WFPDelay ][ CI_flValue ] )
        {
            
g_bWFP false;
            
OnRoundEnd( );
        }
    }

    
#if defined DEBUG
    
server_print"WaitForPlayers: Players: %i, Required: %i, Waiting: %i, Passed Delay: %i, Delay: %.2f"PlayersOng_iCvarsPCV_WFPMin ][ CI_IntValue ], g_bWFPflGameTime g_flWFPTime g_iCvarsPCV_WFPDelay ][ CI_flValue ], g_iCvarsPCV_WFPDelay ][ CI_flValue ] );
    
#endif
}

CountFloatflGameTime )
{
    static 
FloatTimePassed;
    
TimePassed = ( flGameTime g_flRoundStartTime ) - 1.0;

    static 
FloatStartDelay;
    
StartDelay g_iCvarsPCV_RoundStartDelay ][ CI_flValue ];

    if ( 
TimePassed StartDelay )
    {
        
OnRoundStart( );
    }
    else if ( 
g_flCountNextTime flGameTime )
    {
        
g_flCountNextTime += 1.0;

        
PrintCenter_"Game Starting in %i.."floatroundStartDelay TimePassed ) );
    }
}

/* ~(plugin_* Functions)~ */
public plugin_init()
{
    
/* Register to AMXX PLugin's List */
    
register_plugin"ZExtract: Rounds""v1.0""DeclineD" );

    
/* Handle "Round Start/End" */
    
register_event"HLTV""OnRoundStart2""a""1=0""2=0" );
    
RegisterHookChainRG_RoundEnd"OnRoundEnd2" );

    
/* Handle "Map Change" */
    
RegisterHookChainRG_CSGameRules_GoToIntermission"ReHook_ChangeMap" );

    
/* Register plugin cvars */
    
RegisterCvars( );

    
/* Get Pointer of Game Cvars */
    
cvarRestart] = get_cvar_pointer"sv_restart" );
    
cvarRestart] = get_cvar_pointer"sv_restartround" );
    
cvarRoundTime get_cvar_pointer"mp_roundtime" );
    
cvarFreezeTime get_cvar_pointer"mp_freezetime" );

    
/* Get Required MsgIds for the plugin */
    
imTextMsg get_user_msgid"TextMsg" );
    
imRoundTimer get_user_msgid"RoundTime" );

    
/* Rounds */
    
g_MaxRounds get_pcvar_numg_iCvarsPCV_Rounds ][ CI_Id ] );
    
g_flRoundStartTime get_gametime( );

    
/* Have a check function on every frame */
    
NextFrame
}

public 
plugin_precache( )
{
    
}

public 
plugin_natives( )
{
    
}


/* ~(Public Functions)~ */
// [ Round ]
public OnRoundStart( )
{
    
g_bRoundStarted true;
}

public 
OnRoundStart2( )
{
    if ( !( 
g_rRestart Rs_Not ) || !g_bWFP )
    {
        ++
g_iRound;
    }

    
g_rRestart Rs_Not;
    
g_bRoundEnded false;
    
g_bRoundStarted false;

    
g_MaxRoundTime GetRoundTime( );

    
g_flRoundStartTime get_gametime( );
    
g_flCountNextTime g_flRoundStartTime 1.0;

    
SetRoundTimer( );

    
#if defined DEBUG
    
server_print"Server Round Started" );
    
#endif
}

public 
OnRoundEnd( )
{
    if ( 
g_bWFP )
        return;

    
#if defined DEBUG
    
server_print"Server Round Ending" );
    
#endif

    
static FloatTimePassed;
    
TimePassed = ( get_gametime() - g_flRoundStartTime 1.0 );

    
g_bRoundEnded true;

    new 
WinTypeiWinWinStatusfWinScenarioEventEndRoundWinEvent;

    if ( 
g_rRestart Rs_Not )
    {
        
iWin WIN_RESTART;
        
fWin WINSTATUS_NONE;
        
WinEvent ROUND_GAME_RESTART;

        
set_pcvar_num(cvarRestart], 0);
        
set_pcvar_num(cvarRestart], 0);
    }
    else if ( ( 
0.0 > ( floatg_MaxRoundTime ) - TimePassed ) ) )
    {
        
iWin WIN_DRAW;
        
fWin WINSTATUS_DRAW;
        
WinEvent ROUND_END_DRAW;

    }
    else if ( 
GetPlayersTEAM_CT ) == )
    {
        
iWin WIN_ZOMBIE;
        
fWin WINSTATUS_TERRORISTS;
        
WinEvent ROUND_TERRORISTS_WIN;
    }
    else if ( 
GetPlayersTEAM_TERRORIST ) == )
    {
        
iWin WIN_HUMAN;
        
fWin WINSTATUS_CTS;
        
WinEvent ROUND_CTS_WIN;
    }

    
rg_round_end(g_iCvarsPCV_RoundEndDelay ][ CI_flValue ], fWinWinEventRoundWinMessagesiWin ], "");
}

public 
OnRoundEnd2WinStatusstatusScenarioEventEndRoundeventFloattmDelay )
{
    
SetHookChainReturn(ATYPE_BOOLfalse);
    return 
HC_SUPERCEDE;
}

// [ Checks ]
public OnNextFrame( )
{
    static 
FloatflGameTime
    
flGameTime get_gametime( );

    
// Resume game if not waiting for players
    
if ( !g_bWFP )
    {
        
// Functions that will be called in pre-game
        
if ( !g_bRoundStarted && !g_bRoundEnded )
        {
            
CountflGameTime );
        }
        
// Functions that will be called in game
        
else if ( !g_bRoundEnded )
        {
            
CheckRoundEndflGameTime );
        }
        
// Functions that will be called in post-game
        
else
        {

        }
    }

    
/* Functions that will be called anyway */
    
CheckRestart( );
    
CheckWFP( );

    
/* Keep calling the next frame */
    
NextFrame
}


/* ~(Map Change)~ */
public ReHook_ChangeMap( )
{
    return 
HC_SUPERCEDE;
}


/* ~(Stock Functions)~ */
stock GetRoundTime( )
{
    new 
rTime[5], fTime[5];
    
get_pcvar_string(cvarRoundTimerTimecharsmax(rTime));
    
get_pcvar_string(cvarFreezeTimefTimecharsmax(fTime));

    new 
iRTime floatround( ( containrTime"." ) ? str_to_floatrTime ) : floatstr_to_numrTime ) ) ) * 60.0 );
    new 
iFTime = ( containfTime"." ) ? floatroundstr_to_floatfTime ) ) : str_to_numfTime ) );

    if ( 
iRTime MaxRoundTime )
        
iRTime MaxRoundTime;

    
iRTime += iFTime;

    return 
iRTime;
}

stock SetRoundTimer( )
{
    
message_beginMSG_BROADCASTimRoundTimer );
    
write_shortg_MaxRoundTime );
    
message_end( );
}

stock GetPlayersTeamNameTeam )
{
    new 
ctt;

    
rg_initialize_player_countstct );

    switch( 
Team )
    {
        case 
TEAM_CT: return ct;
        case 
TEAM_TERRORIST: return t;
        default: return 
0;
    }

    return 
0;
}

stock PrintCenter(id 0, const msg[ ] = ""any:...)
{
    new 
szMsg150 ];
    
vformatszMsgcharsmaxszMsg ), msg);

    
message_begin( ( id == MSG_BROADCAST MSG_ONE_UNRELIABLE ), imTextMsg_id );
    
write_byte);
    
write_stringszMsg );
    
message_end( );

    
server_printszMsg );


Last edited by AnimalMonster; 11-18-2022 at 13:20.
AnimalMonster is offline
fysiks
Veteran Member
Join Date: Sep 2007
Location: Flatland, USA
Old 11-18-2022 , 16:37   Re: Any thoughts on this code?
Reply With Quote #2

What exactly is your question?
__________________
fysiks is offline
Dexon
Member
Join Date: Aug 2019
Old 11-20-2022 , 03:59   Re: Any thoughts on this code?
Reply With Quote #3

I didn't look through fully your code but if you have complete control over timer you can also hide the that and show for example a hud msg instead of that.
PHP Code:
@HideCD_TIMER(iId){
    
message_begin(MSG_ALL,get_user_msgid("HideWeapon"), .player iId);
    
write_byte((1<<4));
    
message_end();

    
message_begin(MSG_ALL,get_user_msgid("Crosshair"), .player iId);
    
write_byte(0);
    
message_end();

You can save here the msgid-s in a global variable. Seems like I forgot to do it in my plugin.
__________________
[ExTasY] Zombie Mutation [ZOMBIE NPC]

Join now!

Video: https://www.youtube.com/watch?v=fNahCsS8DOU&t=328s
DC: https://discord.gg/swARTUZCZ4

Creating private plugins, reference above.
Dexon is offline
AnimalMonster
Senior Member
Join Date: May 2020
Old 11-20-2022 , 08:39   Re: Any thoughts on this code?
Reply With Quote #4

Quote:
Originally Posted by fysiks View Post
What exactly is your question?
Thoughts on how to improve the code and maybe reduce the code but keep the same idea? and also i hate set_task so that's why i thought of using RequestFrame, too many task ids and you can't use less than 0.1 seconds in the delay and also task's one second is less than game's one second. It is also kinda like game making, checking everything every frame.

Quote:
Originally Posted by Dexon View Post
I didn't look through fully your code but if you have complete control over timer you can also hide the that and show for example a hud msg instead of that.
PHP Code:
@HideCD_TIMER(iId){
    
message_begin(MSG_ALL,get_user_msgid("HideWeapon"), .player iId);
    
write_byte((1<<4));
    
message_end();

    
message_begin(MSG_ALL,get_user_msgid("Crosshair"), .player iId);
    
write_byte(0);
    
message_end();

You can save here the msgid-s in a global variable. Seems like I forgot to do it in my plugin.
Hud messages are not something to rely on as if the player has ping or lag or anything the hud message will dissapear for a split second, for me that's something that looks horrible, take as example zombie plague's info hud when you get hit by mutiple players, it flickers and also the whole point is to use what cs uses and replace entierly how cs is handling the rounds and map change. Kinda if you replace a weapon's functionality by hooking Pre PostFrame and returning HAM_SUPERCEDE, the weapon doesn't work anymore.

Last edited by AnimalMonster; 11-20-2022 at 08:49.
AnimalMonster is offline
fysiks
Veteran Member
Join Date: Sep 2007
Location: Flatland, USA
Old 11-20-2022 , 18:57   Re: Any thoughts on this code?
Reply With Quote #5

You're actually adding overhead by having to create a hook on every frame by calling RequestFrame() on every frame. If you need something faster than the minimum set_task() then I've seen smart people on here (e.g. Bugsy) recommend using a thinking entity to execute your code. This will not have the extra overhead in every frame like you have here.

Even if you need to execute on every frame, I think there are much better ways to do it that doesn't need to re-create the hook every time. For example, the forward server_frame() executes at the beginning of every frame already but it does warn you that "more specific hooks and forwards should be used whenever possible."


Also, instead of:

PHP Code:
#define CvarValueMaxLen CI_Value - CI_Name - CI_Id 
You can simply use sizeof or charsmax() (depending what which you need):

PHP Code:
sizeof g_iCvars[][CI_Value]
// or
charsmax(g_iCvars[][CI_Value]) 
Not a functional change and the only downside is that it requires the variable which is declared using that enum but shouldn't really matter since you've only used it in one variable.
__________________
fysiks is offline
AnimalMonster
Senior Member
Join Date: May 2020
Old 12-01-2022 , 15:16   Re: Any thoughts on this code?
Reply With Quote #6

Quote:
Originally Posted by fysiks View Post
You're actually adding overhead by having to create a hook on every frame by calling RequestFrame() on every frame. If you need something faster than the minimum set_task() then I've seen smart people on here (e.g. Bugsy) recommend using a thinking entity to execute your code. This will not have the extra overhead in every frame like you have here.

Even if you need to execute on every frame, I think there are much better ways to do it that doesn't need to re-create the hook every time. For example, the forward server_frame() executes at the beginning of every frame already but it does warn you that "more specific hooks and forwards should be used whenever possible."


Also, instead of:

PHP Code:
#define CvarValueMaxLen CI_Value - CI_Name - CI_Id 
You can simply use sizeof or charsmax() (depending what which you need):

PHP Code:
sizeof g_iCvars[][CI_Value]
// or
charsmax(g_iCvars[][CI_Value]) 
Not a functional change and the only downside is that it requires the variable which is declared using that enum but shouldn't really matter since you've only used it in one variable.
Using an entity was my first thought since i didn't know there existed the RequestFrame. Before trying any of these i tried with simply using supercede on round end reapi hook and check every 0.1 but it was too much.. another way i could do and would maybe or maybe not be my best try is to check the round end and etc at the disconnect, connect, kill and spawn of players and round end to check if the time's up.

Last edited by AnimalMonster; 12-01-2022 at 15:16.
AnimalMonster is offline
Reply


Thread Tools
Display Modes

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 05:33.


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