Description: Plugin allows Players arrange a Diversion! After next spawn (next round) Diversant player spawns on enemy (opposite) base with enemies uniform (skin).
How to deserve Diversion? Kill 5 (by default) enemies per round, or kill 13 (by default) in a row (without death).
Only one (1) player in team can do Diversion per round. Frags in Diversion not count and can not be used for new Diversion.
Original idea by War3 mod for Counter-Strike ("mole" item).
I accept remarks about language file, because my English not so good.
Console commands (ADMIN_RCON):
div_set "<name or #userid>" — set Player Diversion.
div_unset "<name or #userid>" — unset Diversion from Player (works only when Player not spawned yet as Diversant).
CVARS:
div_frags_pr "5" — how many enemies per round Player should kill for deserve Diversion. "0" — disable this feature.
div_frags "13" — how many enemies Player should kill in a row (without death) for deserve Diversion. "0" — disable this feature.
Caching cvar is not necessary here. you have no code called very often. Use pcvar directly. It will simplify your code as well.
Don't forget that MAX_PLAYERS is a define in 1.8.3-dev, so you should still define it in your plugin with a check against AMXX_VERSION_NUM < 183. Unless you're targeting this plugin to be used only in dev version?
There is no reason to use defines for customization. Use cvars, so people won't have to recompile the plugin.
You're misusing LANG_PLAYER. This one should be used only when you pass 0 as index, so when internally Amxx will loop over all players, this tells Amxx to use the current player's language. If you pass a player's index directly in a native, then you should this index instead.
Don't use #define for string which will be repeated more than one time. String will be allocated more than one time. Use instead new const.
Don't make private functions public. This should be used only on callback/forward, when function needs to be called outside of the plugin.
Use charsmax instead of hardcoding the max length. Exemple: read_argv(1, arg, charsmax(arg)), better for maintainability.
is_user_connected(id) && is_user_alive(id), first is pointless, an alive player is always connected.
team_swap is silly, you know before the old team, you should pass the new team instead.
You likely don't need model_swap, you can direcly call DLLFunc_ClientUserInfoChanged, game will pickup a model and will set it.
Caching cvar is not necessary here. you have no code called very often. Use pcvar directly. It will simplify your code as well.
It's make code more harder. For example, Player buy Diversion (waste $16000) and admin change cost (div_cost 5000). So, Player can lost their money. In this case I should write Diversion cost for every player who buy it.
Quote:
You likely don't need model_swap, you can direcly call DLLFunc_ClientUserInfoChanged, game will pickup a model and will set it.
Testet right now. I replaced "model_swap(id, CS_TEAM_CT)" to:
It's make code more harder. For example, Player buy Diversion (waste $16000) and admin change cost (div_cost 5000). So, Player can lost their money. In this case I should write Diversion cost for every player who buy it.
I've honestly no idea what your're talking about. i'm talking about instead of using get_cvar_num and caching the value in a global var 6.1 seconds later, you simply call directly get_pcvar_num directly where it's used. Never heard about cvar pointer?
Quote:
Both don't change Player model
It should be the first only and it should work, here below CS code.
You see well calling this function call SetPlayerModel. But actually it doesn't randomize (unless you set m_iModelName).
code
PHP Code:
void ClientUserInfoChanged(edict_t *pEntity, char *infobuffer) { if (!pEntity->pvPrivateData) return;
if (m_iTeam == TEAM_CT) { switch (m_iModelName) { default: case CLASS_URBAN: model = "urban"; break; case CLASS_GSG9: model = "gsg9"; break; case CLASS_SAS: model = "sas"; break; case CLASS_GIGN: model = "gign"; break; case CLASS_VIP: model = "vip"; break; } } else if (m_iTeam == TEAM_TERRORIST) { switch (m_iModelName) { default: case CLASS_TERROR: model = "terror"; break; case CLASS_LEET: model = "leet"; break; case CLASS_ARCTIC: model = "arctic"; break; case CLASS_GUERILLA: model = "guerilla"; break; } } else model = "urban";
if (strcmp(g_engfuncs.pfnInfoKeyValue(infobuffer, "model"), model)) g_engfuncs.pfnSetClientKeyValue(entindex(), infobuffer, "model", model); }
Well, I guess you can keep your code, not like it does really matter anyway.
You could then use an array instead of using a switch, it will make coder shorter and faster (trivial though).
Well, client will set default model based on latest known team index of player. Probably client knows team based on TeamInfo message. Maybe sending manually a TeamInfo with enemy team name after setting model (or before?). But well, it will likely update Scoreboard.