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

New Round / Player Spawn / Round Start / Round End - do Not mess it


Post New Thread Reply   
 
Thread Tools Display Modes
Author Message
VEN
Veteran Member
Join Date: Jan 2005
Old 07-28-2006 , 09:31   New Round / Player Spawn / Round Start / Round End - do Not mess it
Reply With Quote #1

Intro

I posting this because i saw so numerous mistakes/questions at this area of srcipting. This is the one of the common problems amongst the coders and even not only beginners! New Round / Player Spawn / Round Start / Round End is a different things so read the below explanations and do not mess them.

Usual call order of the events is listed below:
  1. New Round
  2. Player Spawn
  3. Round Start
  4. Round End

1. New Round

The "New Round" is happen at the "Freeze Time" start. The "Freeze Time" is a time in Counter-Strike when all players are "freezed" which means that they can't walk and do a primary attacks.

In the past years the most common way that was used to determine this event was the use of the "RoundTime" event with a "Time" message argument check, but there was a certain issues which makes this metod inefficient:
  • this event is specified, i.e. is sent to every player, so if there are no players no a server then it's not possible to detect the "New Round" with this method;
  • this event is also can be the same for the "Round Start" because the value of the "mp_freezetime" server CVar can be equal to the value of the "Time" argument of the "RoundTime" message, so it is not accurate enough.
Of course i haven't like that method so i had to think of something more efficient. So some months ago after a little research i've discovered the new method which does not have the issues that is listed above:
PHP Code:
register_event("HLTV""event_new_round""a""1=0""2=0"
Notice the two conditions.

Note that this event is not called for very first round, i.e. on map start. If you need to catch that moment as well then in the most cases it's enough to use the plugin_init() or plugin_cfg() forward functions.

Also i was amazed at how many mistakes was made even by the "expirienced" coders in try to detect the "New Round"! The most common mistake was:
PHP Code:
register_event("ResetHUD""newRound""b"
which is completely incorrect. The "ResetHUD" is a specified event which is called under many circumstances for every player. So sometimes you can get more than even one hundred such "newRound" function calls per a single round!


2. Player Spawn

I think no need to explain what the "Player Spawn" is. But many of the coders still do not know how to detect this event correctly.

If you are using AMX Mod X v1.8 or higher, or if you have the "Ham Sandwich" module installed the most simple and efficient way of the "Player Spawn" detection is a hook of the "Spawn" function itself:
PHP Code:
RegisterHam(Ham_Spawn"player""fwHamPlayerSpawnPost"1
The last parameter means that the registered function will be called right after player spawn (post variant of the hook) and not right before player spawn (pre variant of the hook). At least for Counter-Strike it's also necessary to skip registered function call for a dead players. This call is happen when a player enters a server. The most common example is shown below:
PHP Code:
#include <amxmodx>
#include <hamsandwich>
 
public plugin_init() {
        
RegisterHam(Ham_Spawn"player""fwHamPlayerSpawnPost"1)
}
 
public 
fwHamPlayerSpawnPost(iPlayer) {
        if (
is_user_alive(iPlayer)) {
                
// player spawned
        
}

If the above method isn't suitable for you for some reasons, it's possible to use the different more "famous" method of the "ResetHUD" event hook that doesn't require an additional module but is more complex.

You should note that the use of that method may even lead to a server crash. It could happen because the plugin actions is performed on a player in the middle of his spawn process. The example of such "dangerous" action is a call of the strip_user_weapons() fun module's function.

Many of plugin writers does know that the "ResetHUD" event is called on a player spawn but not all of them does know that this event is also called when a player is enter a server (at least in Counter-Strike), on "fullupdate" client command execution, demo recording and round restart attempt (on Counter-Strike's "sv_restartround" / "sv_restart" CVar change for alive players). So to use the "ResetHUD" to detect the "Player Spawn" we will need to filter out all that actions.

The moment when a player is joined a server can be filtered out by registering the "ResetHUD" event with a "e" flag which means that the registered function will be called on alive players. Note that sometimes that "e" flag will also allow a calls of the registered function on a dead players as well (this is a bug of the AMX Mod X core that has been fixed in version 1.80). So it's recommended to do the "alive" check inside of the registered function itself.

The execution of the "fullupdate" client command and the start of a demo recording can be filtered out by blocking the command:
PHP Code:
// ...
register_clcmd("fullupdate""clcmd_fullupdate")
// ...
 
public clcmd_fullupdate() {
    
// stops the command but allows to "catch" it by any other running plugin
    
return PLUGIN_HANDLED_MAIN

Though that method is simple it's recommended to not block the "fullupdate" command since it is used (automatically) on a client side on demo recording to properly update the HUD display and pass a proper data to a demo file on a beginning of a record process. Instead of "fullupdate" command block it's enough to just skip a call of the registered (to the "ResetHUD" event) function at the time when that command is issued on a client side.

As for round restart attempt, probably some of you does think that it's not necessary to filter this event out because it's always called right before "New Round". This is incorrect - not always, it's possible to set "sv_restartround" / "sv_restart" CVar value for example to 60 so new round will be delayed for one full minute! Therefore to filter this out as well on round restart attempt for every alive player we will have to skip the call of the registered to the "ResetHUD" event function.

The result code that is able to detect the "Player Spawn" is shown below:
PHP Code:
#include <amxmodx>
#include <fakemeta>
 
#define MAX_CLIENTS 32
 
new bool:g_bPlayerNonSpawnEvent[MAX_CLIENTS 1]
 
new 
g_iFwFmClientCommandPost
 
public plugin_init() {
        
register_event("ResetHUD""fwEvResetHUD""b")
        
register_event("TextMsg""fwEvGameWillRestartIn""a""2=#Game_will_restart_in")
        
register_clcmd("fullupdate""fwCmdClFullupdate")
}
 
public 
fwEvResetHUD(iPlayerId) {
        if (!
is_user_alive(iPlayerId))
                return
 
        if (
g_bPlayerNonSpawnEvent[iPlayerId]) {
                
g_bPlayerNonSpawnEvent[iPlayerId] = false
                
return
        }
 
        
fwPlayerSpawn(iPlayerId)
}
 
public 
fwEvGameWillRestartIn() {
        static 
iPlayers[32], iPlayersNumi
        get_players
(iPlayersiPlayersNum"a")
        for (
0iPlayersNum; ++i)
                
g_bPlayerNonSpawnEvent[iPlayers[i]] = true
}
 
public 
fwCmdClFullupdate(iPlayerId) {
        
g_bPlayerNonSpawnEvent[iPlayerId] = true
        
static const szFwFmClientCommandPost[] = "fwFmClientCommandPost"
        
g_iFwFmClientCommandPost register_forward(FM_ClientCommandszFwFmClientCommandPost1)
        return 
PLUGIN_CONTINUE
}
 
public 
fwFmClientCommandPost(iPlayerId) {
        
unregister_forward(FM_ClientCommandg_iFwFmClientCommandPost1)
        
g_bPlayerNonSpawnEvent[iPlayerId] = false
        
return FMRES_HANDLED
}
 
public 
fwPlayerSpawn(iPlayerId) {
        
// player spawned


3. Round Start

The "Round Start" is happen at the "Freeze Time" end.

Many of the coders does think that the "Round Start" and "New Round" is the same event and doing a things that is related to the "New Round" in "Round Start" but this is incorrect. Some of the coders especially in the past have used the "RoundTime" event to detect the "Round Start", but again this is inefficient method (the details can be found in the "New Round" section of the article).

The correct method that can be used to detect the "Round Start" is shown below:
PHP Code:
register_logevent("logevent_round_start"2"1=Round_Start"

4. Round End

The "Round End" is happen right at the moment when one of the teams is completed objectives: all players in the opposite team is killed, all hostages is rescued, time of the round is up, etc.

Some of the coders does think that the "Round End" and "New Round" is the same event and doing a things that is related to the "New Round" in the "Round End" but this is incorrect.

The correct method that can be used to detect the "Round End" is shown below:
PHP Code:
register_logevent("logevent_round_end"2"1=Round_End"

Still confused?

Still confused and don't really sure which from the above events should be used in your plugin? Review the below examples that may help you to understand the things better.
  • The "New Round" event can be used to move a spawn point entities or to play a music for a players if a freeze time is too long.
  • The "Player Spawn" can be used to alter a player's properties like start health, weapons, etc.
  • The "Round Start" can be used to create your own "buytime" for a plugins that provide a purchasable items or when you want to create a surprise item.
  • The "Round End" can be used to protect a players with a godmode until the "New Round" or to create a quick minigame until the "New Round".

Last edited by VEN; 03-22-2008 at 09:23.
VEN is offline
TheNewt
Donor
Join Date: Jun 2006
Location: Where I live.
Old 07-28-2006 , 11:22   Re: New Round/Player Spawn/Round Start/Round End - do Not mess it
Reply With Quote #2

*Clap clap clap*
Thanks, I was wondering why ResetHUD activated so many times, (I added some print_console, and logs to show debug msg's, they kept popping up, several times over.)
__________________
Quote:
toe3_ left the chat room. (G-lined (AUTO Excessive connections from a single host.))
TheNewt is offline
VEN
Veteran Member
Join Date: Jan 2005
Old 07-28-2006 , 12:17   Re: New Round/Player Spawn/Round Start/Round End - do Not mess it
Reply With Quote #3

Ughhh... I'd wish to know who was that guy who gave to the AMX/X coders this line:
Code:
register_event("ResetHUD", "newRound", "b")
>;-I
VEN is offline
Deviance
Veteran Member
Join Date: Nov 2004
Location: Sweden
Old 07-28-2006 , 13:32   Re: New Round/Player Spawn/Round Start/Round End - do Not mess it
Reply With Quote #4

nice tut VEN
Deviance is offline
Marticus
Member
Join Date: Nov 2004
Old 07-29-2006 , 04:02   Re: New Round/Player Spawn/Round Start/Round End - do Not mess it
Reply With Quote #5

I've been looking for clarification on this topic. It's nice to see someone took the time to lay it out for us. Is it worthy of a wiki entry?
__________________
"Sell not virtue to purchase wealth, nor Liberty to purchase power." -Ben Franklin 1706-1790
Marticus is offline
Hawk552
AMX Mod X Moderator
Join Date: Aug 2005
Old 07-29-2006 , 10:33   Re: New Round/Player Spawn/Round Start/Round End - do Not mess it
Reply With Quote #6

Quote:
Originally Posted by RapHero2000
yeah its definatly very helpfull . if all the information is true it definatly deserves a entrance in the wkipidia. does clear up alot of false information bbeing spread about this issue gj. this is getting added to my favs
It's not a "wikipedia". Wikipedia is an implementation of a wiki.
__________________
Hawk552 is offline
Send a message via AIM to Hawk552
Freecode
Never Fall Asleep
Join Date: Jan 2004
Old 07-30-2006 , 03:39   Re: New Round/Player Spawn/Round Start/Round End - do Not mess it
Reply With Quote #7

Quote:
Originally Posted by VEN
Also i was amazed at how many mistakes was made even by "expirienced" coders in try to detect a New Round!
i would disagree. Most of the experienced coders know this. We just choose that name which might make you think that its a new round. Just recently i started naming it something more proper (new_spawn( id ) )
Freecode is offline
Zenith77
Veteran Member
Join Date: Aug 2005
Old 08-15-2006 , 11:28   Re: New Round/Player Spawn/Round Start/Round End - do Not mess it
Reply With Quote #8

For those of you that use fakemeta, you can do this:

Code:
/* Plugin generated by AMXX-Studio */ #include <amxmodx> #include <amxmisc> #include <fakemeta> #define PLUGIN "New Plugin" #define VERSION "1.0" #define AUTHOR "Author" public plugin_init() {     register_plugin(PLUGIN, VERSION, AUTHOR)     register_forward(FM_Spawn, "Forward_Spawn", 1); } public Forward_Spawn(ent) {     if (!is_user_alive(ent)) // you could also use is_user_connected()         return FMRES_IGNORED;             // Code...         return FMRES_HANDLED; }

Never tested this before though, so someone let me know if I'm wrong.
__________________
Quote:
Originally Posted by phorelyph View Post
your retatred
Zenith77 is offline
P34nut
AMX Mod X Beta Tester
Join Date: Feb 2006
Location: Netherlands
Old 08-15-2006 , 12:03   Re: New Round/Player Spawn/Round Start/Round End - do Not mess it
Reply With Quote #9

Does not work AFAIK
__________________
All you need to change the world is one good lie and a river of blood
P34nut is offline
Zenith77
Veteran Member
Join Date: Aug 2005
Old 08-15-2006 , 12:39   Re: New Round/Player Spawn/Round Start/Round End - do Not mess it
Reply With Quote #10

AFAIK?
__________________
Quote:
Originally Posted by phorelyph View Post
your retatred
Zenith77 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 13:34.


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