Русское сообщество по скриптингу

Half-Life: Zombie Mod X

Все вопросы по работе и настройке AMXX и его плагинов.

Модератор: liFe iS GoOD

Правила форума
1. Запрещено материться и оскорблять других участников форума.
2. Запрещен флуд, оффтоп, дабл постинг во всех разделах форума, кроме раздела "Болтовня".
3. Запрещено взламывать сайт/форум или наносить любой вред проекту.
4. Запрещено рекламировать другие ресурсы.
5. Запрещено создавать темы без информативного названия. Название темы должно отображать ее смысл.

В данном разделе форума разрешено создавать темы, касающие только вопросов по AMX Mod X и его плагинам.

Half-Life: Zombie Mod X

Сообщение MayroN » 20 июл 2019, 03:47

Сам Мод Half-Life: Zombie Mod X работает на AMX X 1.9.0.


Возможно ли его переписать под 1.8.2 ?
Или же поправить те ошибки при компиляции на 1.8.2 - ну а вдруг заведёться )
Ошибки незначительные ( вроде как )))


Код: Выделить всё
/*
* Half-Life: Zombie Mod X
* Version: 1.0
* Author: rtxa
*
* -- Information --
*
* Requires AMX Mod X 1.9 and it's recommended to use Bugfixed and Improved HL Release to avoid any issues with player's count.
*
* - Round System.
* - Infection Mode
*   - Humans spawns in different locations, the virus is released after a while and someone turns out into a zombie.
*   - Zombies must infect all humans to win.
*   - Humans must eliminate all zombies to win.
*   - Every infection gives you one frag, every zombie you kill gives you five frags.
*
* -- Credits --
*
* Anggara_Nothing, for some useful codes.
* Zombie model from CSO ported by Koshak.
* Most resources are from CSO.
*
*/
 
#include <amxmisc>
#include <amxmodx>
#include <engine>
#include <fakemeta>
#include <fun>
#include <hamsandwich>
#include <hlstocks>
#include <msgstocks>
 
#define PLUGIN "Zombie Mod X"
#define PLUGIN_SHORT "ZX"
#define VERSION "1.0"
#define AUTHOR  "rtxa"
 
#pragma semicolon 1
 
// TaskIDs
enum (+= 100) {
   TASK_FIRSTROUND = 2019,
   TASK_ROUNDPRESTART,
   TASK_ROUNDSTART,
   TASK_ROUNDEND,
   TASK_FREEZEPERIOD,
   TASK_PLAYERSTATUS,
   TASK_ZOMBIEALERTSND,
   TASK_SENDTOSPEC,
   TASK_CHECKGAMESTATUS,
   TASK_ROUNDTIMER
};
 
new const WEAPONS_CLASSES
[][] = {
   "weapon_357",
   "weapon_9mmAR",
   "weapon_9mmhandgun",
   "weapon_crossbow",
   "weapon_egon",
   "weapon_gauss",
   "weapon_handgrenade",
   "weapon_hornetgun",
   "weapon_rpg",
   "weapon_satchel",
   "weapon_shotgun",
   "weapon_snark",
   "weapon_tripmine",
   "weaponbox"
};
 
new const AMMO_CLASSES
[][] = {
   "ammo_357",
   "ammo_9mmAR",
   "ammo_9mmbox",
   "ammo_9mmclip",
   "ammo_ARgrenades",
   "ammo_buckshot",
   "ammo_crossbow",
   "ammo_egonclip",
   "ammo_gaussclip",
   "ammo_glockclip",
   "ammo_mp5clip",
   "ammo_mp5grenades",
   "ammo_rpgclip"
};
 
new const ITEM_CLASSES
[][] = {
   "item_longjump",
   "item_suit",
   "item_battery",
   "item_healthkit",
};
 
new const FUNC_CLASSES
[][] = {
   "func_recharge",
   "func_healthcharger",
   "func_tank",
   "func_tankcontrols",
   "func_tanklaser",
   "func_tankmortar",
   "func_tankrocket",
};
 
new const NULL_SOUND
[] = "common/null.wav";
 
// half-life default sounds for dmg and use
new const CBAR_HIT1[] = "weapons/cbar_hit1.wav";
new const CBAR_HIT2[] = "weapons/cbar_hit2.wav";
new const CBAR_HITBOD1[] = "weapons/cbar_hitbod1.wav";
new const CBAR_HITBOD2[] = "weapons/cbar_hitbod2.wav";
new const CBAR_HITBOD3[] = "weapons/cbar_hitbod3.wav";
new const GUNPICKUP2[] = "items/gunpickup2.wav";
new const WPN_SELECT[] = "common/wpn_select.wav"; // use
new const WPN_DENYSELECT[] = "common/wpn_denyselect.wav"; // can't use
 
// round ambience music
new const ROUND_AMBIENCE[][] = { "sound/zx/ambience1.mp3" };
 
// round sounds
new const SND_ROUND_DRAW[][] = { "zx/round_draw_1.wav" };
new const SND_ROUND_WIN_HUMAN[][] = { "zx/round_win_human_1.wav" };
new const SND_ROUND_WIN_ZOMBI[][] = { "zx/round_win_zombi_1.wav" };
new const SND_ZMB_COMING[][] = { "zx/zmb_coming_1.wav", "zx/zmb_coming_2.wav" };
new const SND_ROUND_START[] = "zx/round_start_1.wav";
new const SND_VOX_20SECREMAIN[] = "zx/vox/20secremain.wav";
new const SND_VOX_COUNT[][] = {
   "common/null.wav",
   "zx/vox/one.wav",
   "zx/vox/two.wav",
   "zx/vox/three.wav",
   "zx/vox/four.wav",
   "zx/vox/five.wav",
   "zx/vox/six.wav",
   "zx/vox/seven.wav",
   "zx/vox/eight.wav",
   "zx/vox/nine.wav",
   "zx/vox/ten.wav"
};
 
// human sounds
new const SND_HUMAN_DEATH[][] = { "zx/human_death_1.wav", "zx/human_death_2.wav" };
 
// zombie sounds
new const SND_ZMB_ALERT[][] = { "zx/zmb_alert_1.wav", "zx/zmb_alert_2.wav"};
new const SND_ZMB_DEATH[][] = { "zx/zmb_death_1.wav", "zx/zmb_death_2.wav" };
new const SND_ZMB_HITBOD[][] = { "zx/zmb_attack_1.wav", "zx/zmb_attack_2.wav", "zx/zmb_attack_3.wav" };
new const SND_ZMB_HITWALL[][] = { "zx/zmb_wall_1.wav", "zx/zmb_wall_2.wav", "zx/zmb_wall_3.wav" };
new const SND_ZMB_HURT[][] = { "zx/zmb_hurt_1.wav", "zx/zmb_hurt_2.wav" };
 
// zombie claws model
new const MDL_ZMB_CLAWS[] = "models/zx/v_claws_zombie.mdl";
 
#define IsPlayer(%0) (%0 > 0 && %0 <= MaxClients)
 
#define HUMAN_TEAMID 1
#define ZOMBIE_TEAMID 2
 
#define ZOMBIE_ALERT_DELAY 13.5
 
// because player can't be send to spectator instantly when he connects, player is gonna be alive for a thousandth of a second,
// so that can mess with counting functions for players and make rounds never end.
// to fix it, we need to make those functions ignore those players and all will be fine.
new gHasReallyJoined[MAX_PLAYERS + 1];
 
// players list
new gPlayers[MAX_PLAYERS];
new gPlayersAlive[MAX_PLAYERS];
 
// count
new gNumPlayers;
new gNumPlayersAlive;
new gNumHumans; // alives
new gNumZombies; // alives
 
// gamerules
new bool:gRoundStarted;
 
// timers in seconds
new gCountDown;
new gRoundTime;
 
// freeze period
new gFreezeTime;
new Float:gSpeedBeforeFreeze[MAX_PLAYERS + 1];
 
// thunder effect sprites
new gSprLaserDot;
new gSprLgtning;
 
// hud sync handles
new gPlayerHudSync;
new gRoundTimeHudSync;
 
// players classes (human, zombie, etc...)
new gPlayerClass[33];
enum { CLASS_HUMAN, CLASS_ZOMBIE };
new const gPlayerClassMlKeys[][] = { "CLASS_HUMAN", "CLASS_ZOMBIE" }; // multilingual keys
 
// hud player status color
new gHudColor[3];
new Float:gHudX;
new Float:gHudY;
 
// server cvars
new gCvarDebug;
new gCvarSky;
new gCvarLight;
 
new gCvarFirstRoundTime
;
new gCvarMinPlayers;
new gCvarRoundTime;
new gCvarFreezeTime;
 
new gCvarHumanHealth
;
new gCvarHumanArmor;
new gCvarHumanGravity;
new gCvarHumanMaxSpeed;
new gCvarHumansFrags;
 
new gCvarZombieHealth
;
new gCvarZombieArmor;
new gCvarZombieGravity;
new gCvarZombieMaxSpeed;
new gCvarZombieFrags;
 
// Game mode name that should be displayed in server browser
public FwGetGameDescription() {
   forward_return(FMV_STRING, PLUGIN + " " + VERSION);
   return FMRES_SUPERCEDE;
}
 
public plugin_precache
() {
   if (get_global_float(GL_teamplay) < 1.0)
      set_fail_state("Not in teamplay mode! Check that ^"mp_teamplay^" value is correct.");
 
   if 
(__count_teams() != 2)
      set_fail_state("Only 2 teams are required! Check that ^"mp_teamplay^" value is correct.");
 
   
// precache models from mp_teamlist
   PrecacheTeamList();
 
   
// round ambience music
   PrecacheMP3List(ROUND_AMBIENCE, sizeof ROUND_AMBIENCE);
 
   
// round sounds
   precache_sound(SND_ROUND_START);
   precache_sound(SND_VOX_20SECREMAIN);
   PrecacheSoundList(SND_ROUND_WIN_HUMAN, sizeof SND_ROUND_WIN_HUMAN);
   PrecacheSoundList(SND_ROUND_WIN_ZOMBI, sizeof SND_ROUND_WIN_ZOMBI);
   PrecacheSoundList(SND_ROUND_DRAW, sizeof SND_ROUND_DRAW);
   PrecacheSoundList(SND_VOX_COUNT, sizeof SND_VOX_COUNT);
   PrecacheSoundList(SND_ZMB_COMING, sizeof SND_ZMB_COMING);
 
   
// human sounds
   PrecacheSoundList(SND_HUMAN_DEATH, sizeof SND_HUMAN_DEATH);
 
   
// zombie sounds
   PrecacheSoundList(SND_ZMB_HITWALL, sizeof SND_ZMB_HITWALL);
   PrecacheSoundList(SND_ZMB_HITBOD, sizeof SND_ZMB_HITBOD);
   PrecacheSoundList(SND_ZMB_ALERT, sizeof SND_ZMB_ALERT);
   PrecacheSoundList(SND_ZMB_HURT, sizeof SND_ZMB_HURT);
   PrecacheSoundList(SND_ZMB_DEATH, sizeof SND_ZMB_DEATH);
 
   
// zombie models
   precache_model(MDL_ZMB_CLAWS);
 
   
// thunder sprites
   gSprLaserDot = precache_model("sprites/laserdot.spr");
   gSprLgtning = precache_model("sprites/lgtning.spr");
 
   
// plugin version
   create_cvar("zx_version", VERSION, FCVAR_SERVER | FCVAR_SPONLY);
 
   
// misc cvars
   gCvarDebug = create_cvar("zx_debug", "0", FCVAR_SERVER);
   gCvarLight = create_cvar("zx_light", "f", FCVAR_SERVER);
   gCvarSky = create_cvar("zx_sky", "blood_", FCVAR_SERVER);
 
   
// round cvars
   gCvarMinPlayers = create_cvar("zx_minplayers", "2", FCVAR_SERVER);
   gCvarFirstRoundTime = create_cvar("zx_firstroundtime", "15.0", FCVAR_SERVER);
   gCvarRoundTime = create_cvar("zx_roundtime", "240", FCVAR_SERVER);
   gCvarFreezeTime = create_cvar("zx_freezetime", "3.0", FCVAR_SERVER);
 
   
// zombie cvars
   gCvarZombieHealth = create_cvar("zombie_health", "500", FCVAR_SERVER);
   gCvarZombieArmor = create_cvar("zombie_armor", "250", FCVAR_SERVER);
   gCvarZombieGravity = create_cvar("zombie_gravity", "0.5", FCVAR_SERVER);
   gCvarZombieMaxSpeed = create_cvar("zombie_maxspeed", "360.0", FCVAR_SERVER);
   gCvarZombieFrags = create_cvar("zombie_frags_infection", "1", FCVAR_SERVER);
 
   
// human cvars
   gCvarHumanHealth = create_cvar("human_health", "100", FCVAR_SERVER);
   gCvarHumanArmor = create_cvar("human_armor", "0", FCVAR_SERVER);
   gCvarHumanGravity = create_cvar("human_gravity", "1.0", FCVAR_SERVER);
   gCvarHumanMaxSpeed = create_cvar("human_maxspeed", "300.0", FCVAR_SERVER);
   gCvarHumansFrags = create_cvar("human_frags_kill", "5", FCVAR_SERVER);
 
   
// hud cvars
   bind_pcvar_float(create_cvar("zx_hud_x", "0.01", FCVAR_SERVER), gHudX);
   bind_pcvar_float(create_cvar("zx_hud_y", "0.1", FCVAR_SERVER), gHudY);
 
   new pcvar 
= create_cvar("zx_hud_color", "0 230 0", FCVAR_SERVER);
   hook_cvar_change(pcvar, "HookHudCvarChange");
   LoadColorsFromCvar(pcvar, gHudColor);
 
   
// set custom sky
   new sky[32];
   get_pcvar_string(gCvarSky, sky, charsmax(sky));
   if (strlen(sky)) {
      set_cvar_string("sv_skyname", sky);
      PrecacheSky(sky);
   }
}
 
public plugin_init
() {
   register_plugin(PLUGIN, VERSION, AUTHOR);
 
   
// multilingual
   register_dictionary("zx.txt");
   register_dictionary("zx_help.txt");
 
   RegisterHamPlayer
(Ham_TakeDamage, "FwPlayerPreTakeDamage");
   RegisterHamPlayer(Ham_Killed, "FwPlayerPostKilled", true);
   RegisterHamPlayer(Ham_Spawn, "FwPlayerPreSpawn");
 
   
// block zombie use and pick up of items excepting buttons
   RegisterHamList(Ham_Use, FUNC_CLASSES, sizeof FUNC_CLASSES, "FwFuncEntsUse");
   RegisterHamList(Ham_Touch, ITEM_CLASSES, sizeof ITEM_CLASSES, "FwItemsTouch");
   RegisterHamList(Ham_Touch, AMMO_CLASSES, sizeof AMMO_CLASSES, "FwItemsTouch");
   RegisterHamList(Ham_Touch, WEAPONS_CLASSES, sizeof WEAPONS_CLASSES, "FwItemsTouch");
   RegisterHamList(Ham_AddPlayerItem, WEAPONS_CLASSES, sizeof WEAPONS_CLASSES, "FwItemsTouch");
 
   register_forward
(FM_GetGameDescription, "FwGetGameDescription");
   register_forward(FM_EmitSound, "FwEmitSound");
 
   
// client cmds
   register_clcmd("zx_restart", "CmdRoundRestart", ADMIN_BAN, "HELP_RESTART", _, true);
   register_clcmd("zx_sethuman", "CmdSetHuman", ADMIN_BAN, "HELP_SETHUMAN", _, true);
   register_clcmd("zx_setzombie", "CmdSetZombie", ADMIN_BAN, "HELP_SETZOMBIE", _, true);
   register_clcmd("spectate", "CmdSpectate");
   register_clcmd("drop", "CmdDrop");
 
   
// intermission mode
   register_event_ex("30", "EventIntermissionMode", RegisterEvent_Global);
 
   
// debug cmds
   register_concmd("zx_userinfo", "CmdUserInfo", ADMIN_IMMUNITY);
   register_concmd("zx_roundinfo", "CmdRoundInfo", ADMIN_IMMUNITY);
 
   
// create hud sync objects
   gPlayerHudSync = CreateHudSyncObj(); // show player's health, armor and class
   gRoundTimeHudSync = CreateHudSyncObj();
 
   
// set map lightning level
   new light[32];
   get_pcvar_string(gCvarLight, light, charsmax(light));
   set_lights(light);
 
   
// countdown for start the first round.
   gCountDown = get_pcvar_num(gCvarFirstRoundTime);
   FirstRoundCountdown();
}
 
public EventIntermissionMode
() {
   // stop round
   gRoundStarted = false;
   remove_task(TASK_FIRSTROUND);
   remove_task(TASK_ROUNDPRESTART);
   remove_task(TASK_ROUNDSTART);
   remove_task(TASK_FREEZEPERIOD);
 
   for 
(new i = 1; i < MaxClients; i++)
      remove_task(+ TASK_ZOMBIEALERTSND);
}
 
public FirstRoundCountdown
() {
   gCountDown--;
   client_print(0, print_center, "%l", "ROUND_FIRSTROUND", gCountDown);
 
   if 
(gCountDown == 0) {
      RoundPreStart();
      return;
   }
   set_task(1.0, "FirstRoundCountdown", TASK_FIRSTROUND);
}
 
public RoundPreStart
() {
   if (get_pcvar_num(gCvarDebug))
      log_amx("Function: RoundPreStart");
 
   gRoundStarted 
= false;
 
   
// remove tasks to avoid overlap
   remove_task(TASK_FIRSTROUND);
   remove_task(TASK_ROUNDPRESTART);
   remove_task(TASK_ROUNDSTART);
   remove_task(TASK_FREEZEPERIOD);
   remove_task(TASK_ROUNDTIMER);
 
   
// stop countdown sound
   Speak(0, NULL_SOUND);
   client_cmd(0, "mp3 stop");
 
   
// reset map stuff
   ResetMap();
 
   
// get players count
   zx_get_players(gPlayers, gNumPlayers);
 
   
// to all players...
   new player;
   for (new i; i < gNumPlayers; i++) {
      player = gPlayers[i];
      SetHuman(player, false);
      if (hl_get_user_spectator(player))
         zx_set_user_spectator(player, false);
      else
         zx_user_spawn
(player);
   }
 
   
// after freeze period, start with infection countdown
   StartFreezePeriod();
}
 
public RoundStartCountDown
() {
   if (gCountDown == 20) {
      Speak(0, SND_ROUND_START);
      PlaySound(0, SND_VOX_20SECREMAIN);
      PlayMp3(0, ROUND_AMBIENCE[random(sizeof ROUND_AMBIENCE)]);
   } else if (gCountDown <= 10 && gCountDown > 0) {
      PlaySound(0, SND_VOX_COUNT[gCountDown]);
   } else if (gCountDown <= 0) {
      RoundStart();
      return;
   }
   client_print(0, print_center, "%l", "ROUND_COUNTDOWN", gCountDown);
 
   gCountDown
--;
 
   set_task
(1.0, "RoundStartCountDown", TASK_ROUNDPRESTART);
}
 
public RoundStart
() {
   if (get_pcvar_num(gCvarDebug))
      log_amx("Function: RoundStart");
 
   
// clean center msgs
   client_print(0, print_center, "");
 
   zx_get_players
(gPlayers, gNumPlayers);
 
   
// stop any sound from round countdown
   Speak(0, NULL_SOUND);
 
   new minPlayers 
= get_pcvar_num(gCvarMinPlayers);
 
   
// check if there are enough players alive to start a round
   zx_get_players_alive(gPlayersAlive, gNumPlayersAlive);
   if (gNumPlayersAlive < minPlayers) {
      if (gNumPlayers > 0) { // avoid show this message when sv is empty
         client_print(0, print_chat, "[%s %s] %l", PLUGIN_SHORT, VERSION, "ROUND_MINPLAYERS", minPlayers);
         client_print(0, print_center, "%l", "ROUND_RESTART");
      }
      set_task(5.0, "RoundPreStart", TASK_ROUNDPRESTART);
      return;
   }
 
   new randomPlayer 
= gPlayersAlive[random(gNumPlayersAlive)];
 
   
// turn a random human in zombie
   DeathMsg(randomPlayer, 0, "virus");
   SetZombie(randomPlayer);
 
   gRoundStarted 
= true;
 
   
// set round time
   StartRoundTimer(get_pcvar_num(gCvarRoundTime));
}
 
 
public RoundEnd
() {
   if (get_pcvar_num(gCvarDebug))
      log_amx("Function: RoundEnd");
 
   gRoundStarted 
= false;
 
   zx_get_team_alives
(gNumHumans, HUMAN_TEAMID);
   zx_get_team_alives(gNumZombies, ZOMBIE_TEAMID);
 
   if 
(gNumHumans > 0 && !gNumZombies) { // humans win
      client_print(0, print_center, "%l", "ROUND_HUMANSWIN");
      PlaySound(0, SND_ROUND_WIN_HUMAN[random(sizeof SND_ROUND_WIN_HUMAN)]);
   } else if (gNumZombies > 0 && !gNumHumans) { // zombies win
      client_print(0, print_center, "%l", "ROUND_ZOMBIESWIN");
      PlaySound(0, SND_ROUND_WIN_ZOMBI[random(sizeof SND_ROUND_WIN_ZOMBI)]);
   } else { // draw
      client_print(0, print_center, "%l", "ROUND_DRAW");
      PlaySound(0, SND_ROUND_DRAW[random(sizeof SND_ROUND_DRAW)]);
   }
 
   SetAllGodMode
();
 
   
// call for a new round
   set_task(8.0, "RoundPreStart", TASK_ROUNDPRESTART);
}
 
public CheckGameStatus
() {
   if (!gRoundStarted || task_exists(TASK_ROUNDEND))
      return;
 
   if 
(get_pcvar_num(gCvarDebug))
      log_amx("Function: CheckGameStatus");
 
   zx_get_team_alives
(gNumHumans, HUMAN_TEAMID);
   zx_get_team_alives(gNumZombies, ZOMBIE_TEAMID);
 
   
// finish round when there are no zombies or humans alive
   // note: allowing to delay round end, it let us get a draw when last 2 players kill each other
   if (gNumHumans < 1 || gNumZombies < 1)
      set_task(0.5, "RoundEnd", TASK_ROUNDEND);
}
 
public client_putinserver
(id) {
   gHasReallyJoined[id] = false;
   set_task(0.1, "TaskPutInServer", id);
}
 
// Some things have to be delayed to be able to work, I explain you why for some.
public TaskPutInServer(id) {
   TaskShowPlayerStatus(id + TASK_PLAYERSTATUS);
   hl_set_teamnames(id, fmt("%l", "TEAMNAME_HUMANS"), fmt("%l", "TEAMNAME_ZOMBIES")); // message isn't received by the client at that moment
   hl_set_user_spectator(id, true); // bots can't be send to spec, they're invalid in putinserver. Also, it cause issues with scoreboard on real clients.
   gHasReallyJoined[id] = true;
}
 
public client_remove
(id) {
   remove_task(id + TASK_PLAYERSTATUS);
   CheckGameStatus();
}
 
public client_kill
(id) {
   return PLUGIN_HANDLED; // block kill cmd
}
 
public FwPlayerPreSpawn
(id) {
   // if player has to spec, don't let him spawn...
   if (task_exists(TASK_SENDTOSPEC + id))
      return HAM_SUPERCEDE;
   return HAM_IGNORED;
}
 
public FwItemsTouch
(entity, caller) {
   if (IsPlayer(caller) && hl_get_user_team(caller) == ZOMBIE_TEAMID)
      return HAM_SUPERCEDE;
   return HAM_IGNORED;
}
 
public FwFuncEntsUse
(entity, caller, activator, use_type) {
   if (use_type == USE_SET && hl_get_user_team(caller) == ZOMBIE_TEAMID)
      return HAM_SUPERCEDE;
   return HAM_IGNORED;
}
 
public FwPlayerPostKilled
(victim, attacker) {
   // give points to attacker by team
   if (victim != attacker && is_user_connected(attacker))
      if (hl_get_user_team(victim) == ZOMBIE_TEAMID) {
         PlaySound(0, SND_ZMB_DEATH[random(sizeof SND_ZMB_DEATH)]);
         hl_set_user_frags(attacker,  get_user_frags(attacker) + (get_pcvar_num(gCvarHumansFrags) - 1));
      } else
         hl_set_user_frags
(attacker,  get_user_frags(attacker) + (get_pcvar_num(gCvarZombieFrags) - 1));
 
   
// send victim to spec
   set_task(3.0, "SendToSpec", victim + TASK_SENDTOSPEC);
 
   CheckGameStatus
();
 
   return HAM_IGNORED
;
}
 
public FwPlayerPreTakeDamage
(victim, inflictor, attacker, Float:damage, damagetype) {
   if (!is_user_alive(victim) || !IsPlayer(attacker))
      return HAM_IGNORED;
 
   new victimTeam 
= hl_get_user_team(victim);
   new attackerTeam = hl_get_user_team(attacker);
 
   
// human attacks zombie
   if (victimTeam == ZOMBIE_TEAMID && attackerTeam == HUMAN_TEAMID) {
      static Float:zombieDmgTime[MAX_PLAYERS + 1];
      if (zombieDmgTime[victim] <= get_gametime()) {
         zombieDmgTime[victim] = get_gametime() + 0.3;
         emit_sound(victim, CHAN_BODY, SND_ZMB_HURT[random(sizeof SND_ZMB_HURT)], VOL_NORM, 0.35, 0, random_num(95, 105));
         fade_user_screen(victim, 0.5, 2.0, ScreenFade_FadeIn, 255, 32, 32, 75);
      }
   } else if (attackerTeam == ZOMBIE_TEAMID && victimTeam == HUMAN_TEAMID) { // zombie attacks human
      // if damage isn't from his claws, block it
      if (!IsPlayer(inflictor))
         return HAM_SUPERCEDE;
 
      
// change claws damage
      if (get_user_weapon(attacker) == HLW_CROWBAR) {
         switch(damage) {
            case 25.0: SetHamParamFloat(4, 75.0); // body hit
            case 75.0: SetHamParamFloat(4, 100.0); // head hit
         }
         SetHamParamInteger(5, DMG_ALWAYSGIB); // always gib human
      }
 
      
// note: sometimes it shows wrong team color
      // maybe, because the message is sent directly to the player, but the current team of all players from client is not updated yet,
      // until it gets to UpdateUserInfo, maybe delaying the deathmsg to the next frame will fix it, but it too much work, i prefer to keep it simple.
      DeathMsg(victim, attacker, "virus");
 
      
// make victim a zombie
      SetZombie(victim);
 
      
// give points for infection to attacker and add a death to victim
      hl_set_user_deaths(victim, hl_get_user_deaths(victim) + 1);
      hl_set_user_frags(attacker, get_user_frags(attacker) + 1);
 
      return HAM_SUPERCEDE
;
   }
 
   return HAM_IGNORED
;
}
 
public ZombieAlertSnd
(taskid) {
   new id = taskid - TASK_ZOMBIEALERTSND;
 
   if 
(!is_user_alive(id) || hl_get_user_team(id) == HUMAN_TEAMID)
      return;
 
   emit_sound
(id, CHAN_AUTO, SND_ZMB_ALERT[random(sizeof SND_ZMB_ALERT)], VOL_NORM, 0.50, 0, random_num(95, 105));
   set_task(ZOMBIE_ALERT_DELAY, "ZombieAlertSnd", taskid);
}
 
public SetZombieClaws
(id) {
   // crowbar is gonna be his claws
   give_item(id, "weapon_crowbar");
   // weapon in first person
   set_pev(id, pev_viewmodel2, MDL_ZMB_CLAWS);
   // remove weapon from third person
   set_pev(id, pev_weaponmodel2, "");
}
 
SetZombie
(id, checkGameStatus = true, screenEffects = true) {
   if (get_pcvar_num(gCvarDebug))
      log_amx("Function: SetZombie");
 
   remove_task
(id+TASK_ZOMBIEALERTSND);
 
   if 
(!is_user_connected(id))
      return;
 
   gPlayerClass
[id] = CLASS_ZOMBIE;
 
   ChangePlayerTeam
(id, ZOMBIE_TEAMID);
 
   hl_strip_user_weapons
(id);
 
   
// give zombie claws
   SetZombieClaws(id);
 
   
// health, armor, gravity, speed and lj
   set_user_health(id, get_pcvar_num(gCvarZombieHealth));
   set_user_armor(id, get_pcvar_num(gCvarZombieArmor));
   set_user_gravity(id, get_pcvar_float(gCvarZombieGravity)); // 0.5 would be like sv_gravity 400
   set_user_maxspeed(id, get_pcvar_float(gCvarZombieMaxSpeed));
   hl_set_user_longjump(id, true, false);
 
   
// screen effects
   if (screenEffects) {
      fade_user_screen(id, 0.5, 3.0, ScreenFade_FadeIn, 255, 32, 32, 180);
      shake_user_screen(id, 16.0, 4.0, 16.0);
   }
 
   
// thunder effect
   LightningEffect(id);
 
   
// become zombie sound
   PlaySound(0, SND_ZMB_COMING[random(sizeof SND_ZMB_COMING)]);
   emit_sound(id, CHAN_AUTO, SND_HUMAN_DEATH[random(sizeof SND_HUMAN_DEATH)], VOL_NORM, 0.35, 0, random_num(95, 105));
   set_task(ZOMBIE_ALERT_DELAY, "ZombieAlertSnd", id + TASK_ZOMBIEALERTSND);
 
   if 
(checkGameStatus)
      CheckGameStatus();
}
 
SetHuman
(id, bool:checkGameStatus = true) {
   if (get_pcvar_num(gCvarDebug))
      log_amx("Function: SetHuman");
 
   if 
(!is_user_connected(id))
      return;
 
   ChangePlayerTeam
(id, HUMAN_TEAMID);
 
   gPlayerClass
[id] = CLASS_HUMAN;
 
   
// health, armor, gravity, speed
   set_user_health(id, get_pcvar_num(gCvarHumanHealth));
   set_user_armor(id, get_pcvar_num(gCvarHumanArmor));
   set_user_gravity(id, get_pcvar_float(gCvarHumanGravity)); // 1.0 would be like sv_gravity 800
   set_user_maxspeed(id, get_pcvar_float(gCvarHumanMaxSpeed));
 
   if 
(checkGameStatus)
      CheckGameStatus();
 
   return
;
}
 
public SendToSpec
(taskid) {
   new id = taskid - TASK_SENDTOSPEC;
   if (!is_user_alive(id) || is_user_bot(id))
      hl_set_user_spectator(id, true);
}
 
stock GetLightningStart
(origin[3]) {
   new Float:originThunder[3];
   originThunder[0] = float(origin[0]);
   originThunder[1] = float(origin[1]);
   originThunder[2] = float(origin[2]);
 
   while
(engfunc(EngFunc_PointContents, originThunder) == CONTENTS_EMPTY)
      originThunder[2] += 5.0;
 
   
// uncomment this if you want thunder only come out from sky
   //return engfunc(EngFunc_PointContents, originThunder) == CONTENTS_SKY ? floatround(originThunder[2]) : origin[2];
   return floatround(originThunder[2]);
}
 
stock LightningEffect
(id) {
   new footPos[3];
   GetUserFootOrigin(id, footPos);
 
   
// thunder falls on the zombie
   new lgntningPos[3]; lgntningPos = footPos;
   lgntningPos[2] = GetLightningStart(footPos);
   te_create_beam_between_points(footPos, lgntningPos, gSprLgtning, _, _, 10, 125, 30, 255, 0, 0, 230, 100);
 
   
// beam disc on floor
   new axis[3]; axis = footPos;
   axis[2] += 200; // beam radius
   te_create_beam_disk(footPos, gSprLgtning, axis, 0, 0, 10, _, _, 255, 0, 0, 200);
 
   
// drop red spheres
   new eyesPos[3];
   get_user_origin(id, eyesPos, 1);
   te_create_model_trail(footPos, eyesPos, gSprLaserDot, 10, 10, 3, 25, 10); // note: 40 balls will overflow
 
   new origin
[3];
   get_user_origin(id, origin);
 
   
// red light for 3 seconds
   te_create_dynamic_light(origin, 20, 255, 0, 0, 30, 30);
}
 
stock GetUserFootOrigin
(id, origin[3]) {
   new Float:temp, Float:ground[3];
   pev(id, pev_absmin, ground);
   temp = ground[2];
   pev(id, pev_origin, ground);
   ground[2] = temp + 2.0;
 
   for 
(new i; i < 3; i++) {
      origin[i] = floatround(ground[i]);
   }
}
 
 
public StartFreezePeriod
() {
   for (new i; i < gNumPlayers; i++) {
      FreezePlayer(gPlayers[i]);
   }
   gFreezeTime = get_pcvar_num(gCvarFreezeTime);
   TaskFreezePeriod();
}
 
public TaskFreezePeriod
() {
   if (gFreezeTime <= 0) {
      zx_get_players(gPlayers, gNumPlayers);
      for (new i; i < gNumPlayers; i++) {
         FreezePlayer(gPlayers[i], false);
      }
      // countdown for start round
      gCountDown = 20;
      RoundStartCountDown();
      return;
   }
   client_print(0, print_center, "%l", "ROUND_FREEZE", gFreezeTime);
 
   gFreezeTime
--;
 
   set_task
(1.0, "TaskFreezePeriod", TASK_FREEZEPERIOD);
}
 
FreezePlayer
(id, freeze = true) {
   if (freeze) {
      gSpeedBeforeFreeze[id] = get_user_maxspeed(id);
      set_user_maxspeed(id, 1.0);
      BlockPlayerWeapons(id, float(get_pcvar_num(gCvarFreezeTime)));
   } else {
      set_user_maxspeed(id, gSpeedBeforeFreeze[id]);
   }
}
 
BlockPlayerWeapons
(id, Float:time) {
   new weapon;
   for (new i = 1; i < 6; i++) {
      weapon = get_ent_data_entity(id, "CBasePlayer", "m_rgpPlayerItems", i);
      while (weapon != -1) {
         set_ent_data_float(weapon, "CBasePlayerWeapon", "m_flNextPrimaryAttack", time);
         set_ent_data_float(weapon, "CBasePlayerWeapon", "m_flNextSecondaryAttack", time);
         weapon = get_ent_data_entity(weapon, "CBasePlayerItem", "m_pNext");
      }
   }
}
 
StartRoundTimer
(seconds) {
   gRoundTime = seconds;
   RoundTimerThink();
   set_task_ex(1.0, "RoundTimerThink", TASK_ROUNDTIMER, _, _, SetTask_Repeat);
}
 
public RoundTimerThink
() {
   ShowRoundTimer();
   if (gRoundStarted) {
      if (gRoundTime > 0)
         gRoundTime--;
      else
         RoundEnd
();
   }
}
 
public ShowRoundTimer
() {
   new r, g, b;
   if (gRoundTime >= 120) { // green color
      r = 0;
      g = 255;
      b = 0;
   } else if (gRoundTime >= 60) { // brown color
      r = 250;
      g = 170;
      b = 0;
   } else { // red color
      r = 255;
      g = 50;
      b = 50;
   }
 
   set_hudmessage
(r, g, b, 0.01, -0.1, 0, 0.01, gRoundStarted ? 600.0 : 1.0, 0.2, 0.2);
   ShowSyncHudMsg(0, gRoundTimeHudSync, "%l: %i:%02i", "ROUND_TIMELEFT", gRoundTime / 60, gRoundTime % 60);
}
 
public FwEmitSound
(id, channel, sample[], Float:volume, Float:attn, flag, pitch) {
   if (!is_user_connected(id) || hl_get_user_team(id) != ZOMBIE_TEAMID)
      return FMRES_IGNORED;
 
   
// replace default sounds with zombie sounds.
   if (equal(sample, CBAR_HIT1) || equal(sample, CBAR_HIT2)) {
      emit_sound(id, channel, SND_ZMB_HITWALL[random(sizeof SND_ZMB_HITWALL)], VOL_NORM, ATTN_NORM, 0, PITCH_NORM);
      return FMRES_SUPERCEDE;
   } else if (equal(sample, CBAR_HITBOD1) || equal(sample, CBAR_HITBOD2) || equal(sample, CBAR_HITBOD3)) {
      emit_sound(id, channel, SND_ZMB_HITBOD[random(sizeof SND_ZMB_HITBOD)], VOL_NORM, ATTN_NORM, 0, PITCH_NORM);
      return FMRES_SUPERCEDE;
   } else if (equal(sample, WPN_DENYSELECT) || equal(sample, WPN_SELECT) || equal(sample, GUNPICKUP2)) { // remove +use sounds
      return FMRES_SUPERCEDE;
   }
 
   return FMRES_IGNORED
;
}
 
public CmdSpectate
(id) {
   return PLUGIN_HANDLED;
}
 
public CmdDrop
(id) {
   // don't let to zombie drop his claws
   if (hl_get_user_team(id) == ZOMBIE_TEAMID) {
      client_print(id, print_console, "Can you drop part of you arm?"); // GoT
      return PLUGIN_HANDLED;
   }
   return PLUGIN_CONTINUE;
}
 
public CmdRoundRestart
(id, level, cid) {
   if (!cmd_access(id, level, cid, 0))
      return PLUGIN_HANDLED;
   RoundPreStart();
   return PLUGIN_HANDLED;
}
 
public CmdRoundInfo
(id, level, cid) {
   if (!cmd_access(id, level, cid, 0))
      return PLUGIN_HANDLED;
   PrintRoundInfo(id);
   return PLUGIN_HANDLED;
}
 
public CmdUserInfo
(id, level, cid) {
   if (!cmd_access(id, level, cid, 1))
      return PLUGIN_HANDLED;
 
   new target
[32];
   read_argv(1, target, charsmax(target));
 
   if 
(equal(target, "")) {
      PrintUserInfo(id, id);
      return PLUGIN_HANDLED;
   }
 
   new player 
= cmd_target(id, target);
 
   if 
(!player)
      return PLUGIN_HANDLED;
 
   PrintUserInfo
(id, player);
   return PLUGIN_HANDLED;
}
 
public CmdSetHuman
(id, level, cid) {
   if (!cmd_access(id, level, cid, 1))
      return PLUGIN_HANDLED;
 
   new target 
= id;
 
   new arg
[MAX_NAME_LENGTH];
   read_argv(1, arg, charsmax(arg));
 
   if 
(!equal(arg, ""))
      target = cmd_target(id, arg, CMDTARGET_ONLY_ALIVE);
 
   if 
(target)
      SetHuman(target);
 
   return PLUGIN_HANDLED
;
}
 
public CmdSetZombie
(id, level, cid) {
   if (!cmd_access(id, level, cid, 1))
      return PLUGIN_HANDLED;
 
   new target 
= id;
 
   new arg
[MAX_NAME_LENGTH];
   read_argv(1, arg, charsmax(arg));
 
   if 
(!equal(arg, ""))
      target = cmd_target(id, arg, CMDTARGET_ONLY_ALIVE);
 
   if 
(target)
      SetZombie(target);
 
   return PLUGIN_HANDLED
;
}
 
stock PrintUserInfo
(caller, target) {
   new model[16], m_szTeamName[16];
   new team = hl_get_user_team(target, model, charsmax(model));
   get_ent_data_string(target, "CBasePlayer", "m_szTeamName", m_szTeamName, charsmax(m_szTeamName));
 
   new iuser1 
= pev(target, pev_iuser1);
   new iuser2 = pev(target, pev_iuser2);
 
   new dead 
= pev(target, pev_deadflag);
 
   new alive 
= is_user_alive(target);
 
   new modelIndex 
= pev(target, pev_modelindex);
 
   client_print
(caller, print_chat, "[Player Info] Team: %i; Model: %s; m_szTeamName: %s; Model Index %i;", team, model, m_szTeamName, modelIndex);
   client_print(caller, print_chat, "[Player Info] iuser1: %i; iuser2: %i Alive: %i; Dead: %i", iuser1, iuser2, alive, dead);
}
 
stock PrintRoundInfo
(id) {
   new text[192];
   formatex(text, charsmax(text), "[Round Info] Alives: %i; Humans: %i; Zombies: %i; RoundStarted: %i", gNumPlayersAlive, gNumHumans, gNumZombies, gRoundStarted);
   client_print(id, print_chat, "%s", text);
   server_print("%s", text);
}
 
public TaskShowPlayerStatus
(taskid) {
   new id = taskid - TASK_PLAYERSTATUS;
   ShowPlayerStatus(id);
   set_task(0.5, "TaskShowPlayerStatus", taskid);
}
 
stock ShowPlayerStatus
(id) {
   new target = id;
 
   new r
, g, b;
   r = gHudColor[0];
   g = gHudColor[1];
   b = gHudColor[2];
 
   new mlKey
[32] = "HUD_STATUS";
   if (!is_user_connected(id) || is_user_bot(id))
      return;
 
   if 
(hl_get_user_spectator(id)) {
      target = pev(id, pev_iuser2);
      if (is_user_connected(target)) {
         mlKey = "HUD_STATUS_SPEC";
         r = g = b = 230; // white color
      } else
         return
;
   }
 
   set_hudmessage
(r, g, b, gHudX, gHudY, 0, 6.0, 120.0, 0.0, 0.0);
   ShowSyncHudMsg(id, gPlayerHudSync, "%l^n%s %s^n", mlKey, target, clamp(pev(target, pev_health), 0), pev(target, pev_armorvalue), gPlayerClassMlKeys[gPlayerClass[target]], PLUGIN, VERSION);
}
 
zx_get_players
(players[MAX_PLAYERS], &num) {
   num = 0;
   for (new id = 1; id <= MaxClients; id++) {
      if (!is_user_hltv(id) && is_user_connected(id) && gHasReallyJoined[id]) {
         players[num++] = id;
      }
   }
}
 
zx_get_players_alive
(players[MAX_PLAYERS], &num) {
   num = 0;
   for (new id = 1; id <= MaxClients; id++) {
      if (is_user_alive(id) && gHasReallyJoined[id]) {
         players[num++] = id;
      }
   }
}
 
// get_players() by team give false values sometimes, use this.
zx_get_team_alives(&teamAlives, teamindex) {
   teamAlives = 0;
   for (new id = 1; id <= MaxClients; id++)
      if (is_user_alive(id) && hl_get_user_team(id) == teamindex && gHasReallyJoined[id])
         teamAlives++;
}
 
zx_set_user_spectator
(client, bool:spectator = true) {
   if (!spectator)
      remove_task(client + TASK_SENDTOSPEC); // remove task to let him respawn
   hl_set_user_spectator(client, spectator);
}
 
zx_user_spawn
(client) {
   remove_task(client + TASK_SENDTOSPEC); // if you dont remove this, he will not respawn
   hl_user_spawn(client);
}
 
ResetMap
() {
   ClearCorpses();
   ClearField();
   RespawnItems();
   ResetFuncChargers();
}
 
ClearCorpses
() {
   new ent;
   while ((ent = find_ent_by_class(ent, "bodyque")))
      set_pev(ent, pev_effects, EF_NODRAW);
}
 
// this will clean entities like tripmines, satchels, etc...
ClearField() {
   static const fieldEnts[][] = { "bolt", "monster_snark", "monster_satchel", "monster_tripmine", "beam", "weaponbox" };
 
   for 
(new i; i < sizeof fieldEnts; i++)
      remove_entity_name(fieldEnts[i]);
 
   new ent
;
   while ((ent = find_ent_by_class(ent, "rpg_rocket")))
      set_pev(ent, pev_dmg, 0);
 
   ent 
= 0;
   while ((ent = find_ent_by_class(ent, "grenade")))
      set_pev(ent, pev_dmg, 0);
}
 
// this will reset hev and health chargers
ResetFuncChargers() {
   new classname[32];
   for (new i; i < global_get(glb_maxEntities); i++) {
      if (pev_valid(i)) {
         pev(i, pev_classname, classname, charsmax(classname));
         if (equal(classname, "func_recharge")) {
            set_pev(i, pev_frame, 0);
            set_pev(i, pev_nextthink, 0);
            set_ent_data(i, "CRecharge", "m_iJuice", 30);
         } else if (equal(classname, "func_healthcharger")) {
            set_pev(i, pev_frame, 0);
            set_pev(i, pev_nextthink, 0);
            set_ent_data(i, "CWallHealth", "m_iJuice", 75);
         }
      }
   }
}
 
// This will respawn all weapons, ammo and items of the map
RespawnItems() {
   new classname[32];
   for (new i; i < global_get(glb_maxEntities); i++) {
      if (pev_valid(i)) {
         pev(i, pev_classname, classname, charsmax(classname));
         if (contain(classname, "weapon_") != -|| contain(classname, "ammo_") != -|| contain(classname, "item_") != -1) {
            set_pev(i, pev_nextthink, get_gametime());
         }
      }
   }
}
 
// Change player team by teamid without killing him.
ChangePlayerTeam(id, teamId) {
   static gameTeamMaster, gamePlayerTeam, spawnFlags;
 
   if 
(!gameTeamMaster) {
      gameTeamMaster = create_entity("game_team_master");
      set_pev(gameTeamMaster, pev_targetname, "changeteam");
   }
 
   if 
(!gamePlayerTeam) {
      gamePlayerTeam = create_entity("game_player_team");
      DispatchKeyValue(gamePlayerTeam, "target", "changeteam");
   }
 
   set_pev
(gamePlayerTeam, pev_spawnflags, spawnFlags);
 
   DispatchKeyValue
(gameTeamMaster, "teamindex", fmt("%i", teamId - 1));
 
   ExecuteHamB
(Ham_Use, gamePlayerTeam, id, 0, USE_ON, 0.0);
}
 
// Execute this post client_putinserver
// Change team names from VGUI Menu and VGUI Scoreboard (the last one only works with vanilla clients)
hl_set_teamnames(id, any:...) {
   new teamNames[10][16];
   new numTeams = clamp(numargs() - 1, 0, 10);
 
   for 
(new i; i < numTeams; i++)
      format_args(teamNames[i], charsmax(teamNames[]), 1 + i);
 
   
// Send new team names
   message_begin(MSG_ONE, get_user_msgid("TeamNames"), _, id);
   write_byte(numTeams);
   for (new i; i < numTeams; i++)
      write_string(teamNames[i]);
   message_end();
}
 
SetAllGodMode
() {
   zx_get_players(gPlayers, gNumPlayers);
   for (new i; i < gNumPlayers; i++)
      set_user_godmode(gPlayers[i], true);
}
 
DeathMsg
(victim, attacker, const type[]) {
   static deathMsg;
   if (!deathMsg)
      deathMsg = get_user_msgid("DeathMsg");
 
   message_begin
(MSG_ALL, deathMsg);
   write_byte(attacker);
   write_byte(victim);
   write_string(type);
   message_end();
}
 
PrecacheTeamList
() {
   new teamlist[192], teamnames[HL_MAX_TEAMS][HL_TEAMNAME_LENGTH];
   get_cvar_string("mp_teamlist", teamlist, charsmax(teamlist));
 
   new nIdx
, nLen = (+ copyc(teamnames[nIdx], charsmax(teamnames[]), teamlist, ';'));
 
   while 
(nLen < strlen(teamlist) && ++nIdx < HL_MAX_TEAMS)
      nLen += (+ copyc(teamnames[nIdx], charsmax(teamnames[]), teamlist[nLen], ';'));
 
   new file
[128];
   for (new i; i < HL_MAX_TEAMS; i++) {
      formatex(file, charsmax(file), "models/player/%s/%s.mdl", teamnames[i], teamnames[i]);
      if (file_exists(file))
         engfunc(EngFunc_PrecacheModel, file);
   }
}
 
PrecacheSky
(const sky[]) {
   static const skyPostFix[][] = { "rt", "lf", "bk", "ft", "dn", "up" };
 
   new file
[192];
   for (new i; i < sizeof skyPostFix; i++) {
      formatex(file, charsmax(file), "gfx/env/%s%s.tga", sky, skyPostFix[i]);
      if (!file_exists(file)) {
         log_amx("Sky files don't exist! Aborting precache.");
         return;
      }
      precache_generic(file);
   }
}
 
PlaySound
(id, const sound[]) {
   new snd[128];
   RemoveExtension(sound, snd, charsmax(snd), ".wav"); // remove wav extension to avoid "missing sound file _period.wav"
   client_cmd(id, "spk ^"%s^"", snd);
}
 
PlayMp3
(id, const file[]) {
   client_cmd(id, "mp3 loop %s", file);
}
 
Speak
(id, const speak[]) {
   new spk[128];
   RemoveExtension(speak, spk, charsmax(spk), ".wav"); // remove wav extension to avoid "missing sound file _period.wav"
   client_cmd(id, "speak ^"%s^"", spk);
}
 
RemoveExtension
(const input[], output[], length, const ext[]) {
   copy(output, length, input);
 
   new idx 
= strlen(input) - strlen(ext);
   if (idx < 0) return 0;
 
   return replace
(output[idx], length, ext, "");
}
 
PrecacheSoundList
(const sndList[][], size) {
   for (new i; i < size; i++)
      precache_sound(sndList[i]);
}
 
PrecacheMP3List
(const sndList[][], size) {
   for (new i; i < size; i++)
      precache_generic(sndList[i]);
}
 
RegisterHamList
(Ham:function, const EntityClassList[][], size, const Callback[], Post = 0, bool:specialBot = false) {
   for (new i; i < size; i++)
      RegisterHam(function, EntityClassList[i], Callback, Post, specialBot);
}
 
public HookHudCvarChange
(pcvar, const old_value[], const new_value[]) {
   StrToRGB(new_value, gHudColor);
}
 
LoadColorsFromCvar
(pcvar, rgb[3]) {
   new color[12];
   get_pcvar_string(pcvar, color, charsmax(color));
   StrToRGB(color, rgb);
}
 
// the input string must be in this format "r g b" e.g. "128 0 256"
Float:StrToRGB(const string[], rgb[3]) {
   new arg[3][12]; // hold parsed vector
   parse(string, arg[0], charsmax(arg[]), arg[1], charsmax(arg[]), arg[2], charsmax(arg[]));
 
   for 
(new i; i < sizeof arg; i++)
      rgb[i] = clamp(str_to_num(arg[i]), 0, 255);
}


Скачать Мод
Вы должны зарегистрироваться, чтобы видеть ссылки.
МультиМод CS
Аватара пользователя
MayroN
 
Сообщения: 673
Зарегистрирован: 10 окт 2010, 18:23
Откуда: Украина, г. Белая Церковь
Благодарил (а): 149 раз.
Поблагодарили: 86 раз.
Опыт программирования: Около года
Языки программирования: На которых говорю...

Вернуться в Вопросы по AMXX и его плагинам

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 7