- Ошибка
-
Вместо стеклянной банки отображается дымовая граната в руке
- ОС
- Linux
- Amx Mod X
-
Authors (ReHLDS Team):
"Adidasman", "s1lent"
- Билд
-
ReHlds-3.13.0.783-dev_mpatch
- ReGamedll
-
ReGameDLL version: 5.21.0.556-dev
- Версия Metamod
-
Metamod-r v1.3.0.128, API (5:13)
- Список метамодулей
-
[ 1] Reunion RUN - reunion_mm_i386.so v0.1.0.133 ini Start Never
[ 2] ReAuthCheck RUN - reauthcheck_mm_i386.so v0.1.6 ini Start Never
[ 3] Rechecker RUN - rechecker_mm_i386.so v2.4 ini Chlvl ANY
[ 4] AMX Mod X RUN - amxmodx_mm_i386.so v1.9.0 ini Start ANY
[ 5] ReSemiclip RUN - resemiclip_mm_i386.so v2.3.9 ini Chlvl ANY
[ 6] ProcessCmds RUN - processcmds_mm_i386.so v1.1.9 ini Start Never
[ 7] VoiceTranscoder RUN - VoiceTranscoder.so v2020MA2 ini ANY ANY
[ 8] HitBox Fix RUN - hitbox_fix_mm_i386.so v1.0.10 ini Start ANY
[ 9] MySQL RUN - mysql_amxx_i386.so v1.8.3-Re pl4 ANY ANY
[10] Fun RUN - fun_amxx_i386.so v1.8.3-Re pl4 ANY ANY
[11] Engine RUN - engine_amxx_i386.so v1.8.3-Re pl4 ANY ANY
[12] FakeMeta RUN - fakemeta_amxx_i386.so v1.8.3-Re pl4 ANY ANY
[13] CStrike RUN - cstrike_amxx_i386.so v1.8.3-Re pl4 ANY ANY
[14] CSX RUN - csx_amxx_i386.so v1.8.3-Re pl4 ANY ANY
[15] Ham Sandwich RUN - hamsandwich_amxx_i386.so v1.8.3-Re pl4 ANY ANY
[16] ReAPI RUN - reapi_amxx_i386.so v5.22.0.254-dev pl4 ANY Never
[17] hackdetector RUN - hackdetector_amxx_i386.so v0.15.328.lite pl4 ANY ANY
[18] ReFullSlot RUN - refullslot_amxx_i386.so v1.2 pl4 ANY Never
- Список плагинов
-
[ 1] DopBan 2.8.2b kanagava dop_ban2.amxx running
[ 2] Aliases checker 1.0.3 kanagava alias_detector. running
[ 3] AIM detector 0.9.4.1b kanagava aim_detector_re running
[ 4] FreshBans 1.3.8b kanagava fresh_bans_for_ running
[ 5] admin_loader 0.3.7 kanagava admin_loader_fo running
[ 6] WebHS 0.1 kanagava fb_web_online.a running
[ 7] ReChecker Logging freesrv custom rc_logging.amxx running
[ 8] RC BaseChanger freesrv custom rc_basechanger. stopped
[ 9] [183] Ultimate Weapons 22.11.15 SKAJIbnEJIb ultimate_weapon running
[ 10] [183] Ultimate Gag 17.12.22BE SKAJIbnEJIb ultimate_gag.am running
[ 11] [ReAMX] Team Balancer 17.10.30 Sanlerus team_balancer.a running
[ 12] [183] Cvar On Map 19.12.07 SKAJIbnEJIb cvar_on_map.amx running
[ 13] Menus Front-End 20.06.06 SKAJIbnEJIb & AM amxmodmenu_rbs. running
[ 14] [183] Chat Controller 20.06.06 SKAJIbnEJIb chat_controller running
[ 15] MapChooser RBS 15.07.15 SKAJIbnEJIb & UF mapchooser_rbs. running
[ 16] NextMap 15.07.15 SKAJIbnEJIb & AM nextmap.amxx running
[ 17] TimeLeft 15.07.15 SKAJIbnEJIb & AM timeleft.amxx running
[ 18] [183] Army Ranks Ultim 20.06.06 SKAJIbnEJIb army_ranks_ulti running
[ 19] [183] AR Vampire 20.06.06 SKAJIbnEJIb ar_vampire.amxx running
[ 20] [183] Chat RBS 20.06.06 SKAJIbnEJIb chat_rbs.amxx running
[ 21] [183] MapsMenu RBS 20.06.06 SKAJIbnEJIb & AM mapsmenu_rbs.am running
[ 22] [190] Snipers RBS 20.06.06 SKAJIbnEJIb snipers_rbs.amx running
[ 23] [183] Stats Configurat 20.06.06 SKAJIbnEJIb & AM statscfg_rbs.am running
[ 24] [183] StatsX RBS 21.03.23 SKAJIbnEJIb & AM statsx_rbs.amxx running
[ 25] [183] CsStats MySQL 22.11.15 SKAJIbnEJIb csstats_mysql.a running
[ 26] [183] CsStats Editor 20.06.06 SKAJIbnEJIb csstats_editor. running
[ 27] [183] FunGun Updater 17.10.30 SKAJIbnEJIb FunGunUpdater.a stopped
[ 28] [183] Parachute RBS 20.06.06 SKAJIbnEJIb & KR parachute_rbs.a running
[ 29] [183] DemoRecorder RBS 20.06.06 SKAJIbnEJIb demorecorder_rb running
[ 30] Reset Score 1.0 SKAJIbnEJIb resetscore_rbs. running
[ 31] [183] High Ping Kicker 20.06.06 SKAJIbnEJIb hpk_rbs.amxx running
[ 32] [183] VIP RBS 20.07.20 SKAJIbnEJIb vip_rbs.amxx running
[ 33] [183] Damager RBS 20.06.06 SKAJIbnEJIb damager_rbs.amx running
[ 34] [190] Ultimate Knife 22.11.15 SKAJIbnEJIb ultimate_knife. running
[ 35] [183] Ultimate Models 21.03.23 SKAJIbnEJIb ultimate_models running
[ 36] [183] Admin Mode 20.06.06 SKAJIbnEJIb admin_mode.amxx running
[ 37] [183] Ultimate Flags 22.11.15 SKAJIbnEJIb ultimate_flags. running
[ 38] Mockery Of Players 15.07.15 Sanlerus mockery_of_play running
[ 39] [183] Block Reconnect 20.06.06 ShaTalKiN Block_Reconnect running
[ 40] [183] No Team Flash 20.06.06 SKAJIbnEJIb NoTeamFlash.amx running
[ 41] [183] AR Bets 20.06.06 SKAJIbnEJIb ar_bets.amxx running
[ 42] [183] AC Spectator ESP 20.06.06 SKAJIbnEJIb & Ko ac_esp.amxx running
[ 43] [183] Stuck RBS 20.06.06 SKAJIbnEJIb & NL stuck_rbs.amxx running
[ 44] [183] AfkKicker RBS 22.11.15 SKAJIbnEJIb afkkicker_rbs.a running
[ 45] [183] Screen Player 20.06.06 SKAJIbnEJIb screen_player.a running
[ 46] [183] Anti Parovoz 20.06.06 SKAJIbnEJIb & Sh anti_parovoz.am running
[ 47] [183] SlayLosers RBS 20.06.06 SKAJIbnEJIb & d3 slaylosers_rbs. running
[ 48] [183] WeaponMenu RBS 22.11.15 SKAJIbnEJIb weaponmenu_rbs. running
[ 49] [183] BackWeapons RBS 20.06.06 SKAJIbnEJIb & ho backweapons_rbs running
[ 50] [183] Ad From Server 20.06.06 SKAJIbnEJIb ad_from_server. running
[ 51] [183] VoteBan RBS 20.06.06 SKAJIbnEJIb voteban_rbs.amx running
[ 52] [183] Blind RBS 20.06.06 SKAJIbnEJIb blind_rbs.amxx running
[ 53] [183] Top Award RBS 20.06.06 SKAJIbnEJIb topaward_rbs.am running
[ 54] [183] Skill ELO 22.11.15 SKAJIbnEJIb skill_elo.amxx running
[ 55] [183] Kill Assist RBS 20.06.06 SKAJIbnEJIb & Di killassist_rbs. running
[ 56] [183] Shit RBS 20.06.06 SKAJIbnEJIb shit_rbs.amxx running
[ 57] [183] Nick FIX RBS 20.06.06 SKAJIbnEJIb nickfix_rbs.amx running
[ 58] Admin Commands 1.8.3-Re AMXX Dev Team admincmd.amxx running
[ 59] Admin Help 1.8.3-Re AMXX Dev Team adminhelp.amxx running
[ 60] Slots Reservation 1.8.3-Re AMXX Dev Team adminslots.amxx running
[ 61] Multi-Lingual System 1.8.3-Re AMXX Dev Team multilingual.am running
[ 62] Commands Menu 1.8.3-Re AMXX Dev Team cmdmenu.amxx running
[ 63] Players Menu 1.8.1.3746 AMXX Dev Team plmenu.amxx running
[ 64] Teleport Menu 1.8.3-Re AMXX Dev Team telemenu.amxx running
[ 65] Plugin Menu 1.8.3-Re AMXX Dev Team pluginmenu.amxx running
[ 66] Admin Chat 1.8.3-Re AMXX Dev Team adminchat.amxx running
[ 67] Admin Votes 1.8.3-Re AMXX Dev Team adminvote.amxx running
[ 68] Pause Plugins 1.8.3-Re AMXX Dev Team pausecfg.amxx running
[ 69] Restrict Weapons 1.8.3-Re AMXX Dev Team restmenu.amxx running
[ 70] CS Misc. Stats 1.8.3-Re AMXX Dev Team miscstats.amxx running
[ 71] Killer screen fade 1.0 Flazh killerscreenfad running
[ 72] Game Namer 1.2 NeuroToxin gamenamechanger running
[ 73] Lucia 1.0 joaquimandrade lucia.amxx running
[ 74] Descriptive 'Fire in t 0.1 VEN descriptive_fir running
[ 75] Bad Camper 1.4 beta Brad Jones bad_camper.amxx running
[ 76] Grenade Mode 0.7 wDetCS gomode.amxx running
[ 77] Ultimate KillStreak Ad 0.7 SAMURAI ut_killstreak_a running
[ 78] Hud_Info+IP 2.0 DeIIyTaT Hud_InfoIP.amxx running
[ 79] Erotic Bomb 0.4 8dp & Spection erotic_bomb.amx running
[ 80] C4 Timer 1.1 SAMURAI & Remod: c4_timer.amxx running
[ 81] c4 timer 1.1 cheap_suit c4timer.amxx running
[ 82] C4 CD Voice 1.1 c4timer_by_msk18 c4cdvoice.amxx running
[ 83] Kill Icon 0.1 muxaz kill_icon.amxx running
[ 84] Scope Alert 1.1 xPaw ScopeAlert.amxx running
[ 85] SpecList 1.2a FatalisDK speclist_rus.am running
[ 86] Nade Messages 1.0 v3x nademessages.am running
[ 87] HudTextArgs Blocker 1.1 joaquimandrade hud_text_blocke running
[ 88] Mode 2x2 2.5re s1lent mode.amxx running
[ 89] [ReAPI] Healthnade 0.0.9f DEV-CS.RU Commun reapi_healthnad running
- Автор плагина
- BlackSignature
- Версия плагина
- [fork] Healthnade 0.0.9f
- Исходный код
-
/*
Форк лечебной гранаты на основе Healthnade 0.0.2 от F@nt0M: https://dev-cs.ru/resources/992/
GitHub: https://github.com/Giferns/HealthNade
0.0.3f:
* Добавлена возможность пить зелье на ПКМ (спасибо AnonymousAmx, MayroN, Psycrow)
* Опция HEAL_AMOUNT переименована в HEAL_AMOUNT_THROW
* Добавлена опция HEAL_AMOUNT_DRINK
* Добавлены опции USAGE_MSG и FULL_HP_MSG
* Заменена модель в руках (v_) на модель с анимацией выпивания
* Добавлен звук выпивания (обрататие внимание, модель содержит другие пути к звукам!)
0.0.4f:
* Добавлена опция MIN_ROUND (минимальный раунд для автовыдачи по флагу)
0.0.5f:
* Добавлен натив HealthNade_GiveNade()
0.0.6f:
* Перенос параметров хилки в переменные сущности: https://github.com/Giferns/HealthNade/pull/1
0.0.7f:
* Добавлены квары и словарь
0.0.8f:
* Фикс учёта mp_nadedrops (теперь учитывает значение на лету)
* Добавлен недостающий учёт квара HealthNade_Give
* Значение квара HealthNade_Give по-умолчанию теперь 1 (было 0)
* Исправлена логика создания кастомного веапонбокса
0.0.9f:
* Добавлен квар HealthNade_SlotId
*/
new const PLUGIN_VERSION[] = "0.0.9f";
#pragma semicolon 1
#include <amxmodx>
#include <fakemeta>
#include <hamsandwich>
#include <reapi>
#include <xs>
#include <healthnade>
enum E_NadeDropType {
NadeDrop_Off = 0,
NadeDrop_On = 1,
NadeDrop_ByCvar = 2,
}
enum E_Cvars {
Float:Cvar_ExplodeRadius,
Float:Cvar_ThrowHealingAmount,
Float:Cvar_DrinkHealingAmount,
bool:Cvar_Give,
Cvar_Give_AccessFlags[16],
Cvar_Give_MinRound,
bool:Cvar_Msg_FullHp,
bool:Cvar_Msg_UsageHint,
E_NadeDropType:Cvar_NadeDrop,
InventorySlotType:Cvar_SlotId,
}
new gCvars[E_Cvars];
#define Cvar(%1) gCvars[Cvar_%1]
new const DICTIONARY_FILENAME[] = "HealthNade.ini";
#define LangS(%1) fmt("%l", %1)
const WeaponIdType:WEAPON_ID = WEAPON_SMOKEGRENADE;
const WeaponIdType:WEAPON_NEW_ID = WEAPON_GLOCK;
const WeaponIdType:WEAPON_FAKE_ID = WeaponIdType:75;
new const WEAPON_NAME[] = "weapon_smokegrenade";
new const AMMO_NAME[] = "HealthNade";
new const WEAPON_NEW_NAME[] = "reapi_healthnade/weapon_healthnade";
new const ITEM_CLASSNAME[] = "weapon_healthnade";
new const GRENADE_CLASSNAME[] = "healthnade";
const AMMO_ID = 16;
const InventorySlotType:ITEM_SLOT = GRENADE_SLOT;
new const VIEWMODEL[] = "models/reapi_healthnade/v_drink9.mdl";
new const WEAPONMODEL[] = "models/reapi_healthnade/p_healthnade.mdl";
new const WORLDMODEL[] = "models/reapi_healthnade/w_healthnade.mdl";
new const SOUND_PULLPIN[] = "weapons/holywater_pinpul.wav";
new const SOUND_DEPLOY[] = "weapons/holywater_deploy.wav";
new const SOUND_DRINK[] = "weapons/holywater_drink.wav";
new const SOUND_EXPLODE[] = "weapons/reapi_healthnade/heal.wav";
// TODO: Вынести остальные пути в константы
#define rg_get_current_round() (get_member_game(m_iTotalRoundsPlayed) + 1)
// copy_entvar(const iEntFrom, const iEntTo, const EntVar:iVar)
#define copy_entvar(%1,%2,%3) set_entvar(%2, %3, get_entvar(%1, %3))
new SpriteCylinder, SpriteExplode, SpriteShape;
new MsgIdWeaponList, MsgIdAmmoPickup, MsgIdStatusIcon, MsgIdScreenFade;
#if WEAPON_NEW_ID != WEAPON_GLOCK
new FwdRegUserMsg, MsgHookWeaponList;
#endif
new g_iCvarNadeDrops;
public plugin_precache() {
register_plugin("[ReAPI] Healthnade", PLUGIN_VERSION, "DEV-CS.RU Community");
register_dictionary(DICTIONARY_FILENAME);
InitCvars();
precache_generic("sprites/reapi_healthnade/weapon_healthnade.txt");
precache_generic("sprites/reapi_healthnade/640hud128.spr");
precache_model(VIEWMODEL);
precache_model(WEAPONMODEL);
precache_model(WORLDMODEL);
precache_sound(SOUND_PULLPIN);
precache_sound(SOUND_DEPLOY);
precache_sound(SOUND_DRINK);
SpriteExplode = precache_model("sprites/reapi_healthnade/heal_explode.spr");
SpriteShape = precache_model("sprites/reapi_healthnade/heal_shape.spr");
SpriteCylinder = precache_model("sprites/shockwave.spr");
precache_sound("weapons/reapi_healthnade/heal.wav");
#if WEAPON_NEW_ID != WEAPON_GLOCK
MsgIdWeaponList = get_user_msgid("WeaponList");
if (MsgIdWeaponList) {
MsgHookWeaponList = register_message(MsgIdWeaponList, "HookWeaponList");
} else {
FwdRegUserMsg = register_forward(FM_RegUserMsg, "RegUserMsg_Post", true);
}
#endif
}
public plugin_init() {
register_clcmd(WEAPON_NEW_NAME, "CmdSelect");
RegisterHookChain(RG_CBasePlayer_OnSpawnEquip, "CBasePlayer_OnSpawnEquip_Post", true);
RegisterHookChain(RG_CBasePlayer_Killed, "CBasePlayer_Killed_Pre", false);
RegisterHookChain(RG_CSGameRules_CleanUpMap, "CSGameRules_CleanUpMap_Post", true);
RegisterHookChain(RG_CBasePlayer_GiveAmmo, "CBasePlayer_GiveAmmo_Pre", false);
RegisterHookChain(RG_CBasePlayerWeapon_DefaultDeploy, "CBasePlayerWeapon_DefaultDeploy_Pre", false);
RegisterHam(Ham_Item_Deploy, WEAPON_NAME, "Item_Deploy_Post", true);
RegisterHam(Ham_Item_Holster, WEAPON_NAME, "Item_Holster_Post", true);
RegisterHam(Ham_Weapon_SecondaryAttack, WEAPON_NAME, "CBasePlayerWeapon_SecondaryAttack_Post", true);
RegisterHam(Ham_Item_PostFrame, WEAPON_NAME, "CBasePlayerWeapon_ItemPostFrame_Pre");
RegisterHookChain(RG_CBasePlayer_ThrowGrenade, "CBasePlayer_ThrowGrenade_Pre", false);
MsgIdAmmoPickup = get_user_msgid("AmmoPickup");
MsgIdStatusIcon = get_user_msgid("StatusIcon");
MsgIdScreenFade = get_user_msgid("ScreenFade");
#if WEAPON_NEW_ID == WEAPON_GLOCK
MsgIdWeaponList = get_user_msgid("WeaponList");
UTIL_WeapoList(
MSG_INIT, 0,
WEAPON_NEW_NAME,
AMMO_ID, 1,
-1, -1, Cvar(SlotId), 4, WEAPON_NEW_ID,
ITEM_FLAG_LIMITINWORLD | ITEM_FLAG_EXHAUSTIBLE
);
#else
if (FwdRegUserMsg) {
unregister_forward(FM_RegUserMsg, FwdRegUserMsg, true);
}
unregister_message(MsgIdWeaponList, MsgHookWeaponList);
#endif
}
#if WEAPON_NEW_ID != WEAPON_GLOCK
public RegUserMsg_Post(const name[]) {
if (strcmp(name, "WeaponList") == 0) {
MsgIdWeaponList = get_orig_retval();
MsgHookWeaponList = register_message(MsgIdWeaponList, "HookWeaponList");
}
}
public HookWeaponList(const msg_id, const msg_dest, const msg_entity) {
enum {
arg_name = 1,
arg_ammo1,
arg_ammo1_max,
arg_ammo2,
arg_ammo2_max,
arg_slot,
arg_position,
arg_id,
arg_flags,
};
if (msg_dest != MSG_INIT || WeaponIdType:get_msg_arg_int(arg_id) != WEAPON_NEW_ID) {
return PLUGIN_CONTINUE;
}
set_msg_arg_string(arg_name,WEAPON_NEW_NAME);
set_msg_arg_int(arg_ammo1, ARG_BYTE, AMMO_ID);
set_msg_arg_int(arg_ammo1_max, ARG_BYTE, 1);
set_msg_arg_int(arg_ammo2, ARG_BYTE, -1);
set_msg_arg_int(arg_ammo2_max, ARG_BYTE, -1);
set_msg_arg_int(arg_slot, ARG_BYTE, _:Cvar(SlotId) - 1);
set_msg_arg_int(arg_position, ARG_BYTE, 4);
set_msg_arg_int(arg_flags, ARG_BYTE, ITEM_FLAG_LIMITINWORLD | ITEM_FLAG_EXHAUSTIBLE);
return PLUGIN_CONTINUE;
}
#endif
public CBasePlayer_OnSpawnEquip_Post(const id) {
if (!Cvar(Give) || !UserHasFlagsS(id, Cvar(Give_AccessFlags))) {
return;
}
if(rg_get_current_round() < Cvar(Give_MinRound)) {
return;
}
giveNade(id);
}
public CBasePlayer_Killed_Pre(const id) {
if (Cvar(NadeDrop) == NadeDrop_Off) {
return;
}
if (Cvar(NadeDrop) == NadeDrop_ByCvar) {
switch (g_iCvarNadeDrops) {
case 0:
return;
case 1: {
new iItem = get_member(id, m_rgpPlayerItems, ITEM_SLOT);
if (is_nullent(iItem) || !FClassnameIs(iItem, ITEM_CLASSNAME)) {
return;
}
}
}
}
if (!get_member(id, m_rgAmmo, AMMO_ID)) {
return;
}
new eEnt, Float:fOrigin[3];
get_entvar(id, var_origin, fOrigin);
new Float:fVelocity[3];
get_entvar(id, var_velocity, fVelocity);
xs_vec_mul_scalar(fVelocity, 0.75, fVelocity);
eEnt = rg_create_entity("info_target");
if(is_nullent(eEnt)) {
return;
}
set_entvar(eEnt, var_classname, "healthnade_drop");
engfunc(EngFunc_SetOrigin, eEnt, fOrigin);
set_entvar(eEnt, var_movetype, MOVETYPE_TOSS);
set_entvar(eEnt, var_solid, SOLID_TRIGGER);
engfunc(EngFunc_SetModel, eEnt, WORLDMODEL);
engfunc(EngFunc_SetSize, eEnt, Float:{-6.0, -6.0, -1.0}, Float:{6.0, 6.0, 1.0});
set_entvar(eEnt, var_velocity, fVelocity);
SetThink(eEnt, "think_healthnade_drop");
set_entvar(eEnt, var_nextthink, get_gametime() + get_cvar_float("mp_item_staytime"));
SetTouch(eEnt, "touch_healthnade_drop");
}
public think_healthnade_drop(const eEnt) {
if(is_entity(eEnt)) {
set_entvar(eEnt, var_flags, FL_KILLME);
}
}
public touch_healthnade_drop(const eEnt, const id) {
if (
is_nullent(eEnt)
|| !is_user_connected(id)
|| get_member(id, m_rgAmmo, AMMO_ID)
) {
return;
}
set_entvar(eEnt, var_nextthink, -1.0);
set_entvar(eEnt, var_flags, FL_KILLME);
giveNade(id);
}
public CmdSelect(const id) {
if (!is_user_alive(id)) {
return PLUGIN_HANDLED;
}
new item = rg_get_player_item(id, ITEM_CLASSNAME, ITEM_SLOT);
if (item != 0 && get_member(id, m_pActiveItem) != item) {
rg_switch_weapon(id, item);
}
return PLUGIN_HANDLED;
}
public CSGameRules_CleanUpMap_Post() {
new ent = rg_find_ent_by_class(NULLENT, GRENADE_CLASSNAME, false);
while (ent > 0) {
destroyNade(ent);
ent = rg_find_ent_by_class(ent, GRENADE_CLASSNAME, false);
}
ent = rg_find_ent_by_class(NULLENT, "healthnade_drop", false);
while (ent > 0) {
destroyNade(ent);
ent = rg_find_ent_by_class(ent, "healthnade_drop", false);
}
}
public CBasePlayer_GiveAmmo_Pre(const id, const amount, const name[]) {
if (strcmp(name, AMMO_NAME) != 0) {
return HC_CONTINUE;
}
giveAmmo(id, amount, AMMO_ID, 1);
SetHookChainReturn(ATYPE_INTEGER, AMMO_ID);
return HC_SUPERCEDE;
}
public CBasePlayerWeapon_DefaultDeploy_Pre(const item, const szViewModel[], const szWeaponModel[], const iAnim, const szAnimExt[], const skiplocal) {
new UserId = get_member(item, m_pPlayer);
if (FClassnameIs(item, ITEM_CLASSNAME)) {
SetHookChainArg(2, ATYPE_STRING, VIEWMODEL);
SetHookChainArg(3, ATYPE_STRING, WEAPONMODEL);
if (Cvar(Msg_UsageHint)) {
client_print(UserId, print_center, "%L", UserId, "HEALTHNADE_USAGE_HINT");
}
}
new WeaponIdType:wid = WeaponIdType:rg_get_iteminfo(item, ItemInfo_iId);
if (wid != WEAPON_ID && wid != WEAPON_FAKE_ID) {
return HC_CONTINUE;
}
new lastItem = get_member(UserId, m_pLastItem);
if (is_nullent(lastItem) || item == lastItem) {
return HC_CONTINUE;
}
if (WeaponIdType:rg_get_iteminfo(lastItem, ItemInfo_iId) == WEAPON_ID) {
SetHookChainArg(6, ATYPE_INTEGER, 0);
}
return HC_CONTINUE;
}
public Item_Deploy_Post(const item) {
if (WeaponIdType:rg_get_iteminfo(item, ItemInfo_iId) == WEAPON_FAKE_ID) {
rg_set_iteminfo(item, ItemInfo_iId, WEAPON_ID);
}
new other = get_member(get_member(item, m_pPlayer), m_rgpPlayerItems, ITEM_SLOT);
while (!is_nullent(other)) {
if (item != other && WeaponIdType:rg_get_iteminfo(other, ItemInfo_iId) == WEAPON_ID) {
rg_set_iteminfo(other, ItemInfo_iId, WEAPON_FAKE_ID);
}
other = get_member(other, m_pNext);
}
}
public Item_Holster_Post(const item) {
new other = get_member(get_member(item, m_pPlayer), m_rgpPlayerItems, ITEM_SLOT);
while (!is_nullent(other)) {
if (item != other && WeaponIdType:rg_get_iteminfo(other, ItemInfo_iId) == WEAPON_FAKE_ID) {
rg_set_iteminfo(other, ItemInfo_iId, WEAPON_ID);
}
other = get_member(other, m_pNext);
}
}
enum {
HG_ANIMATION_IDLE = 0,
HG_ANIMATION_PULLPIN,
HG_ANIMATION_THROW,
HG_ANIMATION_DEPLOY,
HG_ANIMATION_DRINK
};
public CBasePlayerWeapon_SecondaryAttack_Post(weapon) {
if(!is_entity(weapon) || !FClassnameIs(weapon, ITEM_CLASSNAME)) {
return;
}
set_member(weapon, m_Weapon_flNextSecondaryAttack, 0.3);
if(get_member(weapon, m_flStartThrow) > 0.0) {
return;
}
new pPlayer = get_member(weapon, m_pPlayer);
new iBpAmmo = get_member(pPlayer, m_rgAmmo, AMMO_ID);
if(!iBpAmmo) {
return;
}
if(Float:get_entvar(pPlayer, var_health) >= Float:get_entvar(pPlayer, var_max_health)) {
if (Cvar(Msg_FullHp)) {
client_print(pPlayer, print_center, "%L", pPlayer, "HEALTHNADE_FULL_HP");
}
return;
}
const Float:fAnimTime = 3.15; // 63 frames / 20 fps
set_member(weapon, m_Weapon_flTimeWeaponIdle, fAnimTime);
set_member(weapon, m_Weapon_flNextPrimaryAttack, fAnimTime);
set_member(weapon, m_Weapon_flNextSecondaryAttack, fAnimTime);
SendWeaponAnimation(pPlayer, HG_ANIMATION_DRINK);
}
// PostFrame() а не WeaponIdle() т.к. при прожатых IN_ATTACK|IN_ATTACK2|IN_RELOAD WeaponIdle() не вызывается
// т.е. зажатие любой из этих кнопок приведёт к неработоспособности логики
public CBasePlayerWeapon_ItemPostFrame_Pre(weapon) {
if(/*!is_entity(weapon) || */!FClassnameIs(weapon, ITEM_CLASSNAME)) {
return;
}
if(get_member(weapon, m_Weapon_flTimeWeaponIdle) > 0.0) {
return;
}
new pPlayer = get_member(weapon, m_pPlayer);
if(get_entvar(pPlayer, var_weaponanim) != HG_ANIMATION_DRINK) {
return;
}
// Нам надо обеспечить вызов WeaponIdle()
// https://github.com/s1lentq/ReGameDLL_CS/blob/67cc153f5d0abab1e42b32a83ef4a470c8781a5c/regamedll/dlls/weapons.cpp#L1007
// https://github.com/s1lentq/ReGameDLL_CS/blob/67cc153f5d0abab1e42b32a83ef4a470c8781a5c/regamedll/dlls/weapons.cpp#L1019
// https://github.com/s1lentq/ReGameDLL_CS/blob/67cc153f5d0abab1e42b32a83ef4a470c8781a5c/regamedll/dlls/weapons.cpp#L1092
set_entvar(pPlayer, var_button, get_entvar(pPlayer, var_button) & ~(IN_ATTACK|IN_ATTACK2|IN_RELOAD));
new iBpAmmo = get_member(pPlayer, m_rgAmmo, AMMO_ID);
if(!iBpAmmo) {
return;
}
set_member(pPlayer, m_rgAmmo, iBpAmmo - 1, AMMO_ID);
// RetireWeapon() средствами regamedll если бпаммо нет, либо отправка анимации деплоя
// https://github.com/s1lentq/ReGameDLL_CS/blob/b979b5e84f36dc0eb870f97da670b700756217f1/regamedll/dlls/wpn_shared/wpn_smokegrenade.cpp#L225
set_member(weapon, m_flReleaseThrow, 0.1);
ExecuteHamB(Ham_TakeHealth, pPlayer, get_entvar(weapon, var_HealthNade_DrinkHealingAmount), DMG_GENERIC);
UTIL_ScreenFade(pPlayer);
}
stock SendWeaponAnimation(const id, const iAnimation) {
set_entvar(id, var_weaponanim, iAnimation);
message_begin(MSG_ONE_UNRELIABLE, SVC_WEAPONANIM, .player = id);
write_byte(iAnimation);
write_byte(0);
message_end();
}
public CBasePlayer_ThrowGrenade_Pre(const id, const item, const Float:vecSrc[3], const Float:vecThrow[3], const Float:time, const const usEvent) {
if (!FClassnameIs(item, ITEM_CLASSNAME)) {
return HC_CONTINUE;
}
new grenade = throwNade(id, item, vecSrc, vecThrow, time);
SetHookChainReturn(ATYPE_INTEGER, grenade);
return HC_SUPERCEDE;
}
public GrenadeTouch(const grenade, const other) {
if (!is_nullent(grenade)) {
explodeNade(grenade);
}
}
public GrenadeThink(const grenade) {
if (!is_nullent(grenade)) {
explodeNade(grenade);
}
}
giveNade(const id) {
new item = rg_get_player_item(id, ITEM_CLASSNAME, ITEM_SLOT);
if (item != 0) {
giveAmmo(id, 1, AMMO_ID, 1);
return item;
}
item = rg_create_entity(WEAPON_NAME, false);
if (is_nullent(item)) {
return NULLENT;
}
new Float:origin[3];
get_entvar(id, var_origin, origin);
set_entvar(item, var_origin, origin);
set_entvar(item, var_spawnflags, get_entvar(item, var_spawnflags) | SF_NORESPAWN);
set_member(item, m_Weapon_iPrimaryAmmoType, AMMO_ID);
set_member(item, m_Weapon_iSecondaryAmmoType, -1);
set_entvar(item, var_classname, ITEM_CLASSNAME);
set_entvar(item, var_HealthNade_Radius, Cvar(ExplodeRadius));
set_entvar(item, var_HealthNade_ThrowHealingAmount, Cvar(ThrowHealingAmount));
set_entvar(item, var_HealthNade_DrinkHealingAmount, Cvar(DrinkHealingAmount));
dllfunc(DLLFunc_Spawn, item);
set_member(item, m_iId, WEAPON_NEW_ID);
rg_set_iteminfo(item, ItemInfo_pszName, WEAPON_NEW_NAME);
rg_set_iteminfo(item, ItemInfo_pszAmmo1, AMMO_NAME);
rg_set_iteminfo(item, ItemInfo_iMaxAmmo1, 1);
rg_set_iteminfo(item, ItemInfo_iId, WEAPON_FAKE_ID);
rg_set_iteminfo(item, ItemInfo_iPosition, 4);
rg_set_iteminfo(item, ItemInfo_iWeight, 1);
dllfunc(DLLFunc_Touch, item, id);
if (get_entvar(item, var_owner) != id) {
set_entvar(item, var_flags, FL_KILLME);
return NULLENT;
}
return item;
}
giveAmmo(const id, const amount, const ammo, const max) {
if (get_entvar(id, var_flags) & FL_SPECTATOR) {
return;
}
new count = get_member(id, m_rgAmmo, ammo);
new add = min(amount, max - count);
if (add < 1) {
return;
}
set_member(id, m_rgAmmo, count + add, ammo);
emessage_begin(MSG_ONE, MsgIdAmmoPickup, .player = id);
ewrite_byte(ammo);
ewrite_byte(add);
emessage_end();
}
throwNade(const id, const item, const Float:vecSrc[3], const Float:vecThrow[3], const Float:time) {
new grenade = rg_create_entity("info_target", false);
if (is_nullent(grenade)) {
return 0;
}
set_entvar(grenade, var_classname, GRENADE_CLASSNAME);
set_entvar(grenade, var_movetype, MOVETYPE_BOUNCE);
set_entvar(grenade, var_solid, SOLID_BBOX);
engfunc(EngFunc_SetOrigin, grenade, vecSrc);
new Float:angles[3];
get_entvar(id, var_angles, angles);
set_entvar(grenade, var_angles, angles);
set_entvar(grenade, var_owner, id);
if (time < 0.1) {
set_entvar(grenade, var_nextthink, get_gametime());
set_entvar(grenade, var_velocity, Float:{0.0, 0.0, 0.0});
} else {
set_entvar(grenade, var_nextthink, get_gametime() + time);
set_entvar(grenade, var_velocity, vecThrow);
}
set_entvar(grenade, var_sequence, random_num(3, 6));
set_entvar(grenade, var_framerate, 1.0);
set_entvar(grenade, var_gravity, 0.5);
set_entvar(grenade, var_friction, 0.8);
engfunc(EngFunc_SetModel, grenade, WORLDMODEL);
copy_entvar(item, grenade, var_HealthNade_Radius);
copy_entvar(item, grenade, var_HealthNade_ThrowHealingAmount);
SetTouch(grenade, "GrenadeTouch");
SetThink(grenade, "GrenadeThink");
return grenade;
}
explodeNade(const grenade) {
new Float:origin[3];
get_entvar(grenade, var_origin, origin);
new Float:fRadius = get_entvar(grenade, var_HealthNade_Radius);
UTIL_BeamCylinder(origin, SpriteCylinder, 1, 5, 30, 1, {10, 255, 40}, 255, 5, fRadius);
UTIL_CreateExplosion(origin, 65.0, SpriteExplode, 30, 20, (TE_EXPLFLAG_NOSOUND | TE_EXPLFLAG_NOPARTICLES));
UTIL_SpriteTrail(origin, SpriteShape);
rh_emit_sound2(grenade, 0, CHAN_WEAPON, SOUND_EXPLODE, VOL_NORM, ATTN_NORM, 0, PITCH_NORM);
new id = get_entvar(grenade, var_owner);
new team = get_member(id, m_iTeam);
for (new player = 1, Float:playerOrigin[3]; player <= MaxClients; player++) {
if (!is_user_alive(player) || get_member(player, m_iTeam) != team) {
continue;
}
get_entvar(player, var_origin, playerOrigin);
if (get_distance_f(origin, playerOrigin) < fRadius) {
ExecuteHamB(Ham_TakeHealth, player, get_entvar(grenade, var_HealthNade_ThrowHealingAmount), DMG_GENERIC);
UTIL_ScreenFade(player);
}
}
destroyNade(grenade);
}
destroyNade(const grenade) {
SetTouch(grenade, "");
SetThink(grenade, "");
set_entvar(grenade, var_flags, FL_KILLME);
}
InitCvars() {
bind_pcvar_float(create_cvar(
"HealthNade_ExplodeRadius", "300.0", FCVAR_NONE,
LangS("HEALTHNADE_CVAR_EXPLODE_RADIUS"),
true, 1.0
), Cvar(ExplodeRadius));
bind_pcvar_float(create_cvar(
"HealthNade_ThrowHealingAmount", "20.0", FCVAR_NONE,
LangS("HEALTHNADE_CVAR_THROW_HEALING_AMOUNT")
), Cvar(ThrowHealingAmount));
bind_pcvar_float(create_cvar(
"HealthNade_DrinkHealingAmount", "35.0", FCVAR_NONE,
LangS("HEALTHNADE_CVAR_DRINK_HEALING_AMOUNT")
), Cvar(DrinkHealingAmount));
bind_pcvar_num(create_cvar(
"HealthNade_Give", "1", FCVAR_NONE,
LangS("HEALTHNADE_CVAR_GIVE")
), Cvar(Give));
bind_pcvar_string(create_cvar(
"HealthNade_Give_AccessFlags", "t", FCVAR_NONE,
LangS("HEALTHNADE_CVAR_GIVE_ACCESS_FLAGS")
), Cvar(Give_AccessFlags), charsmax(Cvar(Give_AccessFlags)));
bind_pcvar_num(create_cvar(
"HealthNade_Give_MinRound", "1", FCVAR_NONE,
LangS("HEALTHNADE_CVAR_GIVE_MIN_ROUND"),
true, 1.0
), Cvar(Give_MinRound));
bind_pcvar_num(create_cvar(
"HealthNade_Msg_UsageHint", "1", FCVAR_NONE,
LangS("HEALTHNADE_CVAR_MSG_USAGE_HINT"),
true, 0.0, true, 1.0
), Cvar(Msg_UsageHint));
bind_pcvar_num(create_cvar(
"HealthNade_Msg_FullHp", "1", FCVAR_NONE,
LangS("HEALTHNADE_CVAR_MSG_FULL_HP"),
true, 0.0, true, 1.0
), Cvar(Msg_FullHp));
bind_pcvar_num(create_cvar(
"HealthNade_NadeDrop", "2", FCVAR_NONE,
LangS("HEALTHNADE_CVAR_NADE_DROP"),
true, 0.0, true, 2.0
), Cvar(NadeDrop));
bind_pcvar_num(create_cvar(
"HealthNade_SlotId", "4", FCVAR_NONE,
LangS("HEALTHNADE_CVAR_SLOT_ID"),
true, 1.0, true, 5.0
), Cvar(SlotId));
AutoExecConfig(true, "HealthNade");
bind_pcvar_num(get_cvar_pointer("mp_nadedrops"), g_iCvarNadeDrops);
}
stock rg_get_player_item(const id, const classname[], const InventorySlotType:slot = NONE_SLOT) {
new item = get_member(id, m_rgpPlayerItems, slot);
while (!is_nullent(item)) {
if (FClassnameIs(item, classname)) {
return item;
}
item = get_member(item, m_pNext);
}
return 0;
}
stock bool:IsBlind(const player) {
return bool:(Float:get_member(player, m_blindUntilTime) > get_gametime());
}
stock UTIL_WeapoList(
const type,
const player,
const name[],
const ammo1,
const maxAmmo1,
const ammo2,
const maxammo2,
const InventorySlotType:slot,
const position,
const WeaponIdType:id,
const flags
) {
message_begin(type, MsgIdWeaponList, .player = player);
write_string(name);
write_byte(ammo1);
write_byte(maxAmmo1);
write_byte(ammo2);
write_byte(maxammo2);
write_byte(_:slot - 1);
write_byte(position);
write_byte(_:id);
write_byte(flags);
message_end();
}
stock UTIL_StatusIcon(const player, const type, const sprite[], const color[3]) {
message_begin(MSG_ONE, MsgIdStatusIcon, .player = player);
write_byte(type); // 0 - hide 1 - show 2 - flash
write_string(sprite);
write_byte(color[0]);
write_byte(color[1]);
write_byte(color[2]);
message_end();
}
stock UTIL_ScreenFade(const player, const Float:fxTime = 1.0, const Float:holdTime = 0.3, const color[3] = {170, 255, 0}, const alpha = 80) {
if (IsBlind(player)) {
return;
}
const FFADE_IN = 0x0000;
message_begin(MSG_ONE_UNRELIABLE, MsgIdScreenFade, .player = player);
write_short(FixedUnsigned16(fxTime));
write_short(FixedUnsigned16(holdTime));
write_short(FFADE_IN);
write_byte(color[0]);
write_byte(color[1]);
write_byte(color[2]);
write_byte(alpha);
message_end();
}
stock UTIL_BeamCylinder(const Float:origin[3], const sprite, const framerate, const life, const width, const amplitude, const color[3], const bright, const speed, const Float:size) {
message_begin_f(MSG_PVS, SVC_TEMPENTITY, origin, 0);
write_byte(TE_BEAMCYLINDER);
write_coord_f(origin[0]);
write_coord_f(origin[1]);
write_coord_f(origin[2]);
write_coord_f(origin[0]);
write_coord_f(origin[1]);
write_coord_f(origin[2] + size);
write_short(sprite);
write_byte(0);
write_byte(framerate);
write_byte(life);
write_byte(width);
write_byte(amplitude);
write_byte(color[0]);
write_byte(color[1]);
write_byte(color[2]);
write_byte(bright);
write_byte(speed);
message_end();
}
stock UTIL_CreateExplosion(const Float:origin[3], const Float:vecUp, const modelIndex, const scale, const frameRate, const flags) {
message_begin_f(MSG_PVS, SVC_TEMPENTITY, origin, 0);
write_byte(TE_EXPLOSION);
write_coord_f(origin[0]);
write_coord_f(origin[1]);
write_coord_f(origin[2] + vecUp);
write_short(modelIndex);
write_byte(scale);
write_byte(frameRate);
write_byte(flags);
message_end();
}
stock UTIL_SpriteTrail(Float:origin[3], const sprite, const cound = 20, const life = 20, const scale = 4, const noise = 20, const speed = 10) {
message_begin(MSG_BROADCAST, SVC_TEMPENTITY); // MSG_PVS
write_byte(TE_SPRITETRAIL);
write_coord_f(origin[0]);
write_coord_f(origin[1]);
write_coord_f(origin[2] + 20.0);
write_coord_f(origin[0]);
write_coord_f(origin[1]);
write_coord_f(origin[2] + 80.0);
write_short(sprite);
write_byte(cound);
write_byte(life);
write_byte(scale);
write_byte(noise);
write_byte(speed);
message_end();
}
stock FixedUnsigned16(Float:value, scale = (1 << 12)) {
return clamp(floatround(value * scale), 0, 0xFFFF);
}
bool:UserHasFlagsS(const UserId, const sFlags[], const bool:bStrict = false) {
if (!sFlags[0]) {
return true;
}
new iFlags = read_flags(sFlags);
new iUserFlags = get_user_flags(UserId);
return bStrict
? (iUserFlags & iFlags) == iFlags
: (iUserFlags & iFlags) > 0;
}
public plugin_natives() {
register_native("HealthNade_GiveNade", "_HealthNade_GiveNade");
}
public _HealthNade_GiveNade() {
enum { player = 1 };
new pPlayer = get_param(player);
if(is_user_alive(pPlayer)) {
return giveNade(pPlayer);
}
return NULLENT;
}
нет модели стеклянной банки