Half-Life и Adrenaline Gamer форум

Всё об игре в Халф-Лайф и АГ
Текущее время: 29 апр 2024, 23:40

Часовой пояс: UTC + 5 часов [ Летнее время ]




Начать новую тему Ответить на тему  [ Сообщений: 23 ]  На страницу Пред.  1, 2, 3  След.
Автор Сообщение
 Заголовок сообщения: Re: Вопрос по " Zombie Mod X "
СообщениеДобавлено: 06 апр 2024, 23:31 
Не в сети
Аватара пользователя
Зарегистрирован:
18 сен 2014, 01:27
Последнее посещение:
26 апр 2024, 12:21
Сообщения: 173
Уверен, что много кто на этом форуме может поправить плагин за 10 минут. Просто не хотят помочь, или что? Для чего тогда создан этот форум...


Вернуться к началу
 Профиль 
  
 Заголовок сообщения: Re: Вопрос по " Zombie Mod X "
СообщениеДобавлено: 08 апр 2024, 23:22 
Не в сети
Аватара пользователя
Зарегистрирован:
22 окт 2014, 19:26
Последнее посещение:
29 апр 2024, 17:47
Сообщения: 1025
You don't seem lazy. Try this and tell me if there is an error so we can try to fix it.


Вложения:
Скачать плагин или Скачать исходник [zx_+score.sma - 40.16 КБ]
Скачиваний: 6

_________________
https://vk.com/kgbaghl
Вернуться к началу
 Профиль 
  
 Заголовок сообщения: Re: Вопрос по " Zombie Mod X "
СообщениеДобавлено: 09 апр 2024, 07:09 
Не в сети
Аватара пользователя
Зарегистрирован:
18 сен 2014, 01:27
Последнее посещение:
26 апр 2024, 12:21
Сообщения: 173
I'm not lazy, I'm just not good at writing code. Thank you for not ignoring me. I will definitely write when I get home and test your plugin.


Вернуться к началу
 Профиль 
  
 Заголовок сообщения: Re: Вопрос по " Zombie Mod X "
СообщениеДобавлено: 10 апр 2024, 21:24 
Не в сети
Аватара пользователя
Зарегистрирован:
18 сен 2014, 01:27
Последнее посещение:
26 апр 2024, 12:21
Сообщения: 173
Hello!
Your source does not compile either with my compiler or online:
Код:
Welcome to the AMX Mod X 1.8.1-300 Compiler.
Copyright (c) 1997-2013 ITB CompuPhase, AMX Mod X Team
 
/hlds/web/api/bin/user_include/hlstocks.inc(92) : error 017: undefined symbol "get_ent_data"
/hlds/web/api/bin/user_include/hlstocks.inc(93) : warning 203: symbol is never used: "client"
/hlds/web/api/bin/user_include/hlstocks.inc(99) : error 017: undefined symbol "set_ent_data"
/hlds/web/api/bin/user_include/hlstocks.inc(450) : error 017: undefined symbol "set_ent_data"
/hlds/web/api/bin/user_include/hlstocks.inc(514) : error 017: undefined symbol "set_ent_data"
zx_+score.sma(94) : error 029: invalid expression, assumed zero
zx_+score.sma(94) : error 008: must be a constant expression; assumed zero
zx_+score.sma(104) : error 029: invalid expression, assumed zero
zx_+score.sma(104) : error 008: must be a constant expression; assumed zero
zx_+score.sma(165) : error 017: undefined symbol "MAX_PLAYERS"
zx_+score.sma(165) : error 009: invalid array size (negative or zero)
zx_+score.sma(168) : error 017: undefined symbol "MAX_PLAYERS"
zx_+score.sma(168) : error 009: invalid array size (negative or zero)
zx_+score.sma(169) : error 017: undefined symbol "MAX_PLAYERS"
zx_+score.sma(169) : error 009: invalid array size (negative or zero)
zx_+score.sma(186) : error 017: undefined symbol "MAX_PLAYERS"
zx_+score.sma(186) : error 009: invalid array size (negative or zero)
zx_+score.sma(230) : error 033: array must be indexed (variable "-unknown-")
zx_+score.sma(292) : error 017: undefined symbol "create_cvar"
zx_+score.sma(295) : error 017: undefined symbol "create_cvar"
zx_+score.sma(296) : error 017: undefined symbol "create_cvar"
zx_+score.sma(297) : error 017: undefined symbol "create_cvar"
zx_+score.sma(300) : error 017: undefined symbol "create_cvar"
zx_+score.sma(301) : error 017: undefined symbol "create_cvar"
zx_+score.sma(302) : error 017: undefined symbol "create_cvar"
zx_+score.sma(303) : error 017: undefined symbol "create_cvar"
zx_+score.sma(306) : error 017: undefined symbol "create_cvar"
 
Compilation aborted.
26 Errors.
terminate called after throwing an instance of 'std::bad_alloc'
  what():  St9bad_alloc
timeout: the monitored command dumped core

Код:
AMX Mod X Compiler 1.9.0.5271
Copyright (c) 1997-2006 ITB CompuPhase
Copyright (c) 2004-2013 AMX Mod X Team
 
/hlds/web/api/bin/amxx-1.9.0/include/dhudmessage.inc(19) : error 021: symbol already defined: "set_dhudmessage"
/hlds/web/api/bin/amxx-1.9.0/include/dhudmessage.inc(24) : error 010: invalid function or declaration
/hlds/web/api/bin/amxx-1.9.0/include/dhudmessage.inc(34) : error 010: invalid function or declaration
/hlds/web/api/bin/amxx-1.9.0/include/dhudmessage.inc(37) : error 021: symbol already defined: "show_dhudmessage"
/hlds/web/api/bin/amxx-1.9.0/include/dhudmessage.inc(42) : error 010: invalid function or declaration
/hlds/web/api/bin/amxx-1.9.0/include/dhudmessage.inc(44) : warning 218: old style prototypes used with optional semicolumns
/hlds/web/api/bin/amxx-1.9.0/include/dhudmessage.inc(45) : error 054: unmatched closing brace
/hlds/web/api/bin/amxx-1.9.0/include/dhudmessage.inc(46) : error 010: invalid function or declaration
/hlds/web/api/bin/amxx-1.9.0/include/dhudmessage.inc(49) : warning 218: old style prototypes used with optional semicolumns
/hlds/web/api/bin/amxx-1.9.0/include/dhudmessage.inc(50) : error 054: unmatched closing brace
/hlds/web/api/bin/amxx-1.9.0/include/dhudmessage.inc(51) : error 010: invalid function or declaration
/hlds/web/api/bin/amxx-1.9.0/include/dhudmessage.inc(54) : error 021: symbol already defined: "get_players"
/hlds/web/api/bin/amxx-1.9.0/include/dhudmessage.inc(56) : error 010: invalid function or declaration
/hlds/web/api/bin/amxx-1.9.0/include/dhudmessage.inc(58) : error 010: invalid function or declaration
/hlds/web/api/bin/amxx-1.9.0/include/dhudmessage.inc(63) : error 010: invalid function or declaration
/hlds/web/api/bin/amxx-1.9.0/include/dhudmessage.inc(65) : error 010: invalid function or declaration
/hlds/web/api/bin/amxx-1.9.0/include/dhudmessage.inc(67) : error 010: invalid function or declaration
/hlds/web/api/bin/amxx-1.9.0/include/dhudmessage.inc(70) : error 010: invalid function or declaration
/hlds/web/api/bin/amxx-1.9.0/include/dhudmessage.inc(79) : error 010: invalid function or declaration
/hlds/web/api/bin/amxx-1.9.0/include/dhudmessage.inc(82) : warning 218: old style prototypes used with optional semicolumns
/hlds/web/api/bin/amxx-1.9.0/include/dhudmessage.inc(83) : error 054: unmatched closing brace
/hlds/web/api/bin/amxx-1.9.0/include/dhudmessage.inc(84) : error 010: invalid function or declaration
/hlds/web/api/bin/amxx-1.9.0/include/dhudmessage.inc(86) : error 010: invalid function or declaration
/hlds/web/api/bin/amxx-1.9.0/include/dhudmessage.inc(90) : error 010: invalid function or declaration
/hlds/web/api/bin/amxx-1.9.0/include/dhudmessage.inc(95) : error 021: symbol already defined: "vformat"
/hlds/web/api/bin/amxx-1.9.0/include/dhudmessage.inc(96) : warning 218: old style prototypes used with optional semicolumns
/hlds/web/api/bin/amxx-1.9.0/include/dhudmessage.inc(97) : error 054: unmatched closing brace
/hlds/web/api/bin/amxx-1.9.0/include/dhudmessage.inc(100) : error 021: symbol already defined: "ArrayDestroy"
/hlds/web/api/bin/amxx-1.9.0/include/dhudmessage.inc(103) : error 010: invalid function or declaration
/hlds/web/api/bin/amxx-1.9.0/include/dhudmessage.inc(106) : error 025: function heading differs from prototype
 
Compilation aborted.
26 Errors.
terminate called after throwing an instance of 'std::bad_alloc'
  what():  std::bad_alloc
timeout: the monitored command dumped core
I tried removing the #include <dhudmessage> line.
Changed set_dhudmessage to set_hudmessage all lines. The plugin compiled, but it did not work on the server and did not show the score.


Вернуться к началу
 Профиль 
  
 Заголовок сообщения: Re: Вопрос по " Zombie Mod X "
СообщениеДобавлено: 11 апр 2024, 16:17 
Не в сети
Аватара пользователя
Зарегистрирован:
22 окт 2014, 19:26
Последнее посещение:
29 апр 2024, 17:47
Сообщения: 1025
Цитата:
Changed set_dhudmessage to set_hudmessage all lines.
In this case you do not need to change it, just delete :
Код:
//#include <dhudmessage>
Then compile it.

_________________
https://vk.com/kgbaghl


Вернуться к началу
 Профиль 
  
 Заголовок сообщения: Re: Вопрос по " Zombie Mod X "
СообщениеДобавлено: 11 апр 2024, 17:13 
Не в сети
Аватара пользователя
Зарегистрирован:
18 сен 2014, 01:27
Последнее посещение:
26 апр 2024, 12:21
Сообщения: 173
I did so, but the score is not shown on the screen at all


Вернуться к началу
 Профиль 
  
 Заголовок сообщения: Re: Вопрос по " Zombie Mod X "
СообщениеДобавлено: 12 апр 2024, 02:34 
Не в сети
Аватара пользователя
Зарегистрирован:
22 окт 2014, 19:26
Последнее посещение:
29 апр 2024, 17:47
Сообщения: 1025
Yes, I forgot to delete these two lines :)
Код:
   //RegisterHam(Ham_Touch, "trigger_multiple", "_trigger_multiple", 1);
   //RegisterHam(Ham_Killed, "player", "fw_PlayerKilled");
But I don't understand the way it is calculated. I think this mod is wrong because the score is that when the zombie returns to humans again, they get the same score as the zombie.
What I propose to modify is to determine the winner by the number of rounds the team wins and set a cap on the rounds :wink:

_________________
https://vk.com/kgbaghl


Вернуться к началу
 Профиль 
  
 Заголовок сообщения: Re: Вопрос по " Zombie Mod X "
СообщениеДобавлено: 13 апр 2024, 01:36 
Не в сети
Аватара пользователя
Зарегистрирован:
18 сен 2014, 01:27
Последнее посещение:
26 апр 2024, 12:21
Сообщения: 173
abdobiskra
Hello. 1. Your plugin is an older version "1.0", could you rewrite your code to the new version of the plugin "1.1"?
Код:
/*
* Half-Life: Zombie Mod X
* Version: 1.1
* 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,
   TASK_NVISION
};

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" };

// nightvision sounds
new const SND_NVG_ON[] = "zx/items/nvg_on.wav";
new const SND_NVG_OFF[] = "zx/items/nvg_off.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

new bool:gIsNgtVisionOn[MAX_PLAYERS + 1];

// 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

new gCvarNgtVisionColor[3];

// 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);

   // nightvision sounds
   precache_sound(SND_NVG_ON);
   precache_sound(SND_NVG_OFF);

   // 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;
   pcvar = create_cvar("zx_hud_color", "0 230 0", FCVAR_SERVER);
   hook_cvar_change(pcvar, "HookHudCvarChange");
   LoadColorsFromCvar(pcvar, gHudColor);

   pcvar = create_cvar("zx_nightvision_color", "255 0 0", FCVAR_SERVER);
   hook_cvar_change(pcvar, "HookNightVisionCvarChange");
   LoadColorsFromCvar(pcvar, gCvarNgtVisionColor);

   // 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");
   register_forward(FM_CmdStart, "FwCmdStart");

   register_message(get_user_msgid("ScreenFade"), "OnScreenFadeMsg");

   // 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(i + 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_connect(id) {
   gIsNgtVisionOn[id] = false;
}

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) {
   set_user_nvision(id, false);
   // 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) {
   set_user_nvision(victim, false);

   // 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));
         if (!gIsNgtVisionOn[victim])
            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);

   // turn off flashlight
   new effects = pev(id, pev_effects);
   if (effects & EF_DIMLIGHT) {
        set_pev(id, pev_effects, effects & ~EF_DIMLIGHT);
        message_begin(MSG_ONE, get_user_msgid("Flashlight"), _, id);
        write_byte(0);
        write_byte(100);
        message_end();
   }

   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;
}

/* Nightvision
*/
public FwCmdStart(id, handle) {
   if (!is_user_alive(id))
      return FMRES_IGNORED;
   
   // Check if it's a flashlight impulse
   if (get_uc(handle, UC_Impulse) & 100) {
      if (hl_get_user_team(id) == ZOMBIE_TEAMID) {
         // block it and instead use nightvision
         set_uc(handle, UC_Impulse, 0);
         if (!gIsNgtVisionOn[id]) {
            set_user_nvision(id, true);
            gIsNgtVisionOn[id] = true;
            PlaySound(id, SND_NVG_ON);
         } else {
            set_user_nvision(id, false);
            gIsNgtVisionOn[id] = false;
            PlaySound(id, SND_NVG_OFF);
         }

      }
   }

   return FMRES_IGNORED;
}

public OnScreenFadeMsg(msg_id, msg_dest, msg_entity) {
   if (!gIsNgtVisionOn[msg_entity])
      return PLUGIN_CONTINUE;
   
   if (hl_get_user_team(msg_entity) != ZOMBIE_TEAMID)
      return PLUGIN_CONTINUE;

   // do not cancel screenfade from bomb flash in crossfire
   if (get_msg_arg_int(4) != 255 || get_msg_arg_int(5) != 255 || get_msg_arg_int(6) != 255 || get_msg_arg_int(7) < 200)
      return PLUGIN_CONTINUE;
   
   remove_task(TASK_NVISION + msg_entity);
   set_task(get_msg_arg_int(1) / 4096.0, "TaskRestoreNgtVision", TASK_NVISION + msg_entity); // restore nightvision when the screenfade has finished
   
   return PLUGIN_CONTINUE;
}

public TaskRestoreNgtVision(taskid) {
   new id = taskid - TASK_NVISION;
   if (!gIsNgtVisionOn[id])
      return;

   new r = gCvarNgtVisionColor[0];
   new g = gCvarNgtVisionColor[1];
   new b = gCvarNgtVisionColor[2];
   fade_user_screen(id, 1.0, 0.0, ScreenFade_StayOut, r, g, b, 75);
}

public set_user_nvision(id, bool:flag) {
   static defaultMapLight[2];
   get_pcvar_string(gCvarLight, defaultMapLight, charsmax(defaultMapLight));
   strtolower(defaultMapLight); // Converts all chars in string to lower case
      
   message_begin(MSG_ONE_UNRELIABLE, SVC_LIGHTSTYLE, _, id);
   write_byte(0);
   write_string(flag ? "#" : defaultMapLight);
   message_end();

   new r = gCvarNgtVisionColor[0];
   new g = gCvarNgtVisionColor[1];
   new b = gCvarNgtVisionColor[2];

   fade_user_screen(id, 1.0, 0.0, ScreenFade_StayOut, r, g, b, 75);

   if (flag)
      fade_user_screen(id, 1.0, 0.0, ScreenFade_StayOut, r, g, b, 75);
   else
      fade_user_screen(id, 1.0, 0.0, ScreenFade_StayOut, 0, 0, 0, 0);
   
   gIsNgtVisionOn[id] = flag;
}

/* Nightvision End
*/

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_") != -1 || contain(classname, "ammo_") != -1 || 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 = (1 + copyc(teamnames[nIdx], charsmax(teamnames[]), teamlist, ';'));

   while (nLen < strlen(teamlist) && ++nIdx < HL_MAX_TEAMS)
      nLen += (1 + 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);
}

public HookNightVisionCvarChange(pcvar, const old_value[], const new_value[]) {
   StrToRGB(new_value, gCvarNgtVisionColor);
}

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);
}

The new version of the plugin has night vision. I'm trying to transfer your code to my customized zx.sma but it absolutely does not want to compile.
2. I did as you wrote

Код:
   //RegisterHam(Ham_Touch, "trigger_multiple", "_trigger_multiple", 1);
   //RegisterHam(Ham_Killed, "player", "fw_PlayerKilled");

When I take your plugin, it compiles without errors and works on the server. Now the counting of people and zombies is visible on the screen, BUT it is being kept completely incorrectly. If a person kills a zombie, then the person gets 1 frag, and the zombie gets -3. And if a zombie infects a person, then the zombies get 4, and people in general can write even more than zombies.

Добавлено спустя 4 минуты 43 секунды:
abdobiskra
Цитата:
I think this mod is wrong because the score is that when the zombie returns to humans again, they get the same score as the zombie.
Yes, you are right about that.


Вернуться к началу
 Профиль 
  
 Заголовок сообщения: Re: Вопрос по " Zombie Mod X "
СообщениеДобавлено: 13 апр 2024, 04:00 
Не в сети
Аватара пользователя
Зарегистрирован:
22 окт 2014, 19:26
Последнее посещение:
29 апр 2024, 17:47
Сообщения: 1025
So I think the ideal way to calculate this is as I told you, which is to count the number of rounds instead of the number of victims.
try this :
Вложение:
Скачать плагин или Скачать исходник [zx.sma - 42.52 КБ]
Скачиваний: 1


I brought it from the mod I made, it is very similar to it, I am not sure it was copied :friends:

_________________
https://vk.com/kgbaghl


Вернуться к началу
 Профиль 
  
 Заголовок сообщения: Re: Вопрос по " Zombie Mod X "
СообщениеДобавлено: 14 апр 2024, 01:21 
Не в сети
Аватара пользователя
Зарегистрирован:
18 сен 2014, 01:27
Последнее посещение:
26 апр 2024, 12:21
Сообщения: 173
abdobiskra
Hi!
First I tried your plugin, it compiled without errors, after fixing dhudmessage in hudmessage.
Then I transferred your code to my zx.sma and FINALLY IT WORKED!!! I understand that you did not regret providing your personal plugin from your server.
I thought that only the team count would be visible and I never expected that the plugin would be so wonderful. It shows the number of people and zombies, the round number and the team score. This is much more than I needed. Thank you very much for your work!!!
When testing this plugin, I noticed that the countdown to the end of the round in the lower left corner disappeared from the screen (this encouraged players to move faster when the time ran out). But this is not critical for me.
The server also has the playername_mm.dll module installed, which writes the name of the enemy or friendly team when aiming at them. But now it has stopped showing the team names when aiming the sight. I think this is due to overload of the hud channel. But for me this is not critical either.
This plugin that you provided me is much more important for the server, and it also creates beauty :)
Thank you very much for your help with this mod!!!


Вернуться к началу
 Профиль 
  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 23 ]  На страницу Пред.  1, 2, 3  След.

Часовой пояс: UTC + 5 часов [ Летнее время ]


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

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


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  
Создано на основе phpBB® Forum Software © phpBB Group
Русская поддержка phpBB