Difference between revisions of "Writing Multi-Game SourceMod Plugins"
(Another minor fix) |
(Safety save for player_death, hurt, SDKHooks TakeDamage) |
||
Line 1: | Line 1: | ||
Different Source games tend to have different quirks. This page discusses the more common quirks you'll run into. | Different Source games tend to have different quirks. This page discusses the more common quirks you'll run into. | ||
+ | |||
+ | == Detecting the current game == | ||
+ | |||
+ | In order to use what you learn from this document, you will need to detect which game the plugin is running on. | ||
+ | |||
+ | To detect the current game, use the GetEngineVersion() function, like this: | ||
+ | |||
+ | <pawn>new EngineVersion:g_EngineVersion; | ||
+ | |||
+ | // In OnPluginStart | ||
+ | g_EngineVersion = GetEngineVersion(); | ||
+ | </pawn> | ||
+ | |||
+ | This isn't always necessary for games that use different events, but it's still a good idea. | ||
== Round Start == | == Round Start == | ||
Line 95: | Line 109: | ||
| MvM Win Panel screen. '''winning_team''' is the winning team. Most data is not present in this event and is instead interpolated from the CTFPlayerResource netprops. | | MvM Win Panel screen. '''winning_team''' is the winning team. Most data is not present in this event and is instead interpolated from the CTFPlayerResource netprops. | ||
|} | |} | ||
+ | |||
+ | == player_death == | ||
+ | All games appear to use the player_death event, but the fields available to each game vary radically. | ||
+ | |||
+ | The quirks you need to know about are: | ||
+ | |||
+ | === Detecting Fake Deaths === | ||
+ | |||
+ | Team Fortress 2 introduced the concept of fake deaths. In order to detect if a death was fake, you need to do something like this: | ||
+ | |||
+ | <pawn> | ||
+ | // At top of file | ||
+ | #include <tf2_stocks> | ||
+ | |||
+ | // in player_death hook | ||
+ | new bool:bFake = g_EngineVersion == Engine_TF2 && GetEventInt(event, "death_flags") & TF_DEATHFLAG_DEADRINGER; | ||
+ | // if bFake is true, the it was a fake death | ||
+ | </pawn> | ||
+ | |||
+ | === Detecting Headshots === | ||
+ | |||
+ | Not all games support headshots, but those that do have them done differently. | ||
+ | |||
+ | Headshots can be detected in player_death similarly to this: | ||
+ | |||
+ | <pawn> | ||
+ | new bool:bHeadshot; | ||
+ | |||
+ | switch (g_EngineVersion) | ||
+ | { | ||
+ | case Engine_CSS, Engine_CSGO, Engine_L4D, Engine_L4D2: | ||
+ | { | ||
+ | bHeadshot = GetEventBool(event, "headshot"); | ||
+ | } | ||
+ | |||
+ | case Engine_TF2: | ||
+ | { | ||
+ | bHeadshot = GetEventInt(event, "customkill") == TF_CUSTOM_HEADSHOT; | ||
+ | } | ||
+ | } | ||
+ | </pawn> | ||
+ | |||
+ | Unfortunately, some games don't appear to track headshots for death (Half-Life 2: DeathMatch for example). | ||
+ | |||
+ | player_hurt is a bit trickier. | ||
+ | |||
+ | [insert example here] | ||
+ | |||
+ | SDKHooks OnTakeDamage also has some quirks. | ||
+ | |||
+ | [insert example here] |
Revision as of 14:29, 21 March 2014
Different Source games tend to have different quirks. This page discusses the more common quirks you'll run into.
Contents
Detecting the current game
In order to use what you learn from this document, you will need to detect which game the plugin is running on.
To detect the current game, use the GetEngineVersion() function, like this:
new EngineVersion:g_EngineVersion; // In OnPluginStart g_EngineVersion = GetEngineVersion();
This isn't always necessary for games that use different events, but it's still a good idea.
Round Start
Most plugin writers assume that hooking round_start will make things work on all games. Those plugin writers would be wrong.
Several games use other events instead or have behavior that needs to be taken into account.
Game | Fires round_start? | Alternate Event | Extra Quirks |
---|---|---|---|
Half-Life 2: DeathMatch | Yes | teamplay_round_start | teamplay_round_start is only fired for Team Deathmatch |
Day of Defeat: Source | No | dod_round_start | |
Team Fortress 2 | No | teamplay_round_start | full_round will be false if this is not the first round of a multi-round map. In Arena mode, the [Fortress 2 Events#arena_round_start|arena_round_start] event fires when players can start moving. |
Counter-Strike: Global Offensive | Yes | round_start is fired during warmup round |
Round End
round_end, like round_start, isn't the same across all games.
Most of the time, winner is the team ID of the winning team: 0 for stalemate, 2 for team 1 (Combine, Allies, Terrorists, RED, or Survivors), or 3 for team 2 (Rebels, Axis, Counter-Terrorists, BLU, or Infected).
Game | Fires round_end? | Alternate Event | Extra Quirks |
---|---|---|---|
Half-Life 2: DeathMatch | Yes | winner is a userid for Deathmatch or a team ID for Team Deathmatch | |
Day of Defeat: Source | No | dod_round_win | team is the winning team. |
Team Fortress 2 | No | See next section | See next section |
Nuclear Dawn | No | round_win | team is the winning team. type is the win reason. |
Team Fortress 2
Round End is so complicated in Team Fortress 2 that I'm giving it its own section. TF2 has not just one, but four different events for round end.
Game Mode | Event | Quirks |
---|---|---|
All | teamplay_round_win | team is the winning team. winreason was only recently fixed and its meaning depends on the game mode. |
All but Arena or MvM | teamplay_win_panel | Win Panel screen, includes each team's score and the scores of the top 3 players. winning_team is the winning team. winreason includes captured all points, time ran out, captured flags, etc... |
Arena | arena_win_panel | Arena Win Panel screen, includes each team's score and the scores of the top 3 players for each team. winning_team is the winning team. winreason can only be killed all players on the other team and captured point. |
MvM | pve_win_panel | MvM Win Panel screen. winning_team is the winning team. Most data is not present in this event and is instead interpolated from the CTFPlayerResource netprops. |
player_death
All games appear to use the player_death event, but the fields available to each game vary radically.
The quirks you need to know about are:
Detecting Fake Deaths
Team Fortress 2 introduced the concept of fake deaths. In order to detect if a death was fake, you need to do something like this:
// At top of file #include <tf2_stocks> // in player_death hook new bool:bFake = g_EngineVersion == Engine_TF2 && GetEventInt(event, "death_flags") & TF_DEATHFLAG_DEADRINGER; // if bFake is true, the it was a fake death
Detecting Headshots
Not all games support headshots, but those that do have them done differently.
Headshots can be detected in player_death similarly to this:
new bool:bHeadshot; switch (g_EngineVersion) { case Engine_CSS, Engine_CSGO, Engine_L4D, Engine_L4D2: { bHeadshot = GetEventBool(event, "headshot"); } case Engine_TF2: { bHeadshot = GetEventInt(event, "customkill") == TF_CUSTOM_HEADSHOT; } }
Unfortunately, some games don't appear to track headshots for death (Half-Life 2: DeathMatch for example).
player_hurt is a bit trickier.
[insert example here]
SDKHooks OnTakeDamage also has some quirks.
[insert example here]