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

Разминка на ножах (Knife warmup)

Утвержденные плагины для AMX Mod X администратором/модератором форума.

Модератор: Leonidddd

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

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

Разминка на ножах (Knife warmup)

Сообщение Subb98 » 30 мар 2016, 18:30

Текущая версия: 0.1 от 28.03.2016

Описание:
Данный плагин запускает разминку на ножах после события начала игры ('Game Commencing!'). Работает как на HLDS, так и на ReHLDS. Несмотря на небольшую задачу, которую выполняет плагин (с точки зрения пользователя), исходный код получился достаточно объёмным. Это связано с большим количеством нюансов и особенностей работы скрипта, о которых я всецело постараюсь рассказать далее.

Особенности:
  • запуск разминки при каждом событии 'Game Commencing!' (можно отключить для экономии ресурсов)
  • спаун игрока после выбора класса
  • 35 ед. здоровья при спауне (можно настроить)
  • респаун игрока после смерти (по типу Deathmatch)
  • забавные звуки при убийстве (стандартные)
  • блокировка стандартных HUD элементов: прицела, патронов, weaponlist'а, таймера и денег
  • блокировка HUD иконки оружия (для C4 у террористов, которая начинает мигать, когда игрок находится в зоне закладки бомбы)
  • блокировка использования заложников (в этом нет особой нужды, просто чтобы не вызывать лишних вопросов у игрока в определённых случаях)
  • удаление любого оружия, кроме ножа, при его добавлении в инвентарь игрока (также и при поднятии оружия на карте)
  • более информативный HUD таймер до окончания разминки вместо стандартного
  • информационные HUD сообщения игроку о текущем состоянии разминки (1 сообщение при первом спауне и 1 сообщение по завершении разминки)
Требования:
Модули:
  • Counter-Strike (cstrike.inc)
  • Engine (engine.inc)
  • Ham Sandwich (hamsandwich.inc)
  • RoundControl (roundcontrol.inc; опционально)
Настройки:

Код: Выделить всё
//#include <roundcontrol> // раскомментируйте эту строку, если на сервере не используется Regamedll_CS
//#define USE_PAUSE // раскомментируйте эту строку, если желаете, чтобы плагин прекратил работу после выполнения задачи
const MAX_PLAYERS = 32; // максимальное кол-во игроков на сервере, заменить своим (по умолчанию 32)
const WARMUP_TIME = 90; // кол-во времени в секундах, отведённое на разминку (по умолчанию 90)
const Float:RESPAWN_DELAY = 0.75; // кол-во времени в секундах, отведённое на задержку перед респауном (по умолчанию 0.75)
const Float:SHOW_MSG_DELAY = 0.5; // кол-во времени в секундах, отведённое на задержку перед отправкой HUD-сообщения (по умолчанию 0.5)
const Float:WARMUP_HEALTH = 35.0; // кол-во ед. здоровья, устанавливаемое игроку при спауне во время разминки (по умолчанию 35.0) 




Планируемые обновления:
  • реализовать WARMUP_TIME кваром, чтобы иметь возможность назначать для каждой карты собственное время (ранее поступали просьбы от игроков сократить время разминки; данный метод будет не совсем удобен, поэтому также рассматривается способ с расстановкой на картах случайных точек спаунов)
Примечание:
Самую первую версию этого плагина я писал в 2012-м или 2013-м году, наступило время произвести рефакторинг и новой версией я хотел бы поделиться со всеми, кто любит такое оружие, как нож и желает видеть разминку на ножах на своём сервере. Чего я ожидаю взамен? Конструктивной критики, указаний на недочёты в коде, предложений / пожеланий / идей по функционалу и т.д. Буду рад, если Вы данный плагин хотя бы не поленитесь протестировать и ещё больше мне будет приятно, если он Вам понравится.

Благодарности:
У вас нет необходимых прав для просмотра вложений в этом сообщении.
«Очень хорошо. Лучше вы, чем я» © Donald J. Trump
Аватара пользователя
Subb98
Модератор
 
Сообщения: 5485
Зарегистрирован: 24 мар 2011, 19:42
Откуда: г. Пермь
Благодарил (а): 1329 раз.
Поблагодарили: 2343 раз.
Опыт программирования: Больше трех лет
Языки программирования: PHP

Re: Разминка на ножах (Knife warmup)

Сообщение airat0708 » 31 май 2016, 22:54

плагин хорош. подскажите как включить HUD элементы и HUD иконки оружия ?
Аватара пользователя
airat0708
 
Сообщения: 2
Зарегистрирован: 02 июл 2012, 22:57
Благодарил (а): 0 раз.
Поблагодарили: 1 раз.
Опыт программирования: Меньше недели
Языки программирования: Counter-Strike 1.6
Counter-Strike: Source
Team Fortress II
Left 4 Dead

Re: Разминка на ножах (Knife warmup)

Сообщение Subb98 » 31 май 2016, 23:11

airat0708, попробуйте такой вариант, если я верно вас понял. Не проверял:

Код: Выделить всё
/* ===============================================================================
 * Knife warmup 0.1 [28.03.2016]
 * Благодарности:
 * - Sanlerus: реализация отлова выбора класса
 * - s1lent: реализация и возможность использования 'Regamedll_CS', 'RoundControl'
 * - Safety1st: способы реализации некоторых функций из 'Uncommon Knife Warmup'
 * ============================================================================ */

#include <amxmodx>
#include <cstrike>
#include <engine>
#include <hamsandwich>
//#include <roundcontrol> // раскомментируйте эту строку, если на сервере не используется Regamedll_CS

#pragma semicolon 1

#define bit_set(%0,%1) (%1 |= (1<<%0))
#define bit_clear(%0,%1) (%1 &= ~(1<<%0))
#define bit_valid(%0,%1) (%1 & (1<<%0))
//#define USE_PAUSE // раскомментируйте эту строку, если желаете, чтобы плагин прекратил работу после выполнения задачи

const MAX_PLAYERS 32// максимальное кол-во игроков на сервере, заменить своим (по умолчанию 32)
const WARMUP_TIME 90// кол-во времени в секундах, отведённое на разминку (по умолчанию 90)
const Float:RESPAWN_DELAY 0.75// кол-во времени в секундах, отведённое на задержку перед респауном (по умолчанию 0.75)
const Float:SHOW_MSG_DELAY 0.5// кол-во времени в секундах, отведённое на задержку перед отправкой HUD-сообщения (по умолчанию 0.5)
const Float:WARMUP_HEALTH 35.0// кол-во ед. здоровья, устанавливаемое игроку при спауне во время разминки (по умолчанию 35.0)
/*const HW_CROSS_AMMO_WPNLIST = (1<<0);
const HW_TIMER = (1<<4);
const HW_MONEY = (1<<5);*/

new const KILL_SOUNDS[][] = {
    
"misc/sheep.wav""misc/killChicken.wav""misc/cow.wav"
};

enum {
    
WS_WAITING 1,
    
WS_BEGIN,
    
WS_IN_PROGRESS,
    
WS_ENDED
}

new 
HamHook:g_pHamSpawnHamHook:g_pHamAddPlayerItemHamHook:g_pHamGiveAmmoHamHook:g_pHamUseHamHook:g_pHamKilled;

#if defined _roundcontrol_included
new RoundControlHook:g_pCheckWinHook;
#else
new g_pRoundInfiniteg_szRoundInfinite[10];
#endif

new g_pRestartRound/*g_pHideWeaponMsgId, g_pStatusIconMsgId, */g_pHudSyncObj1g_pHudSyncObj2g_pThinkEntg_iConnectedBitsumg_iAliveBitsumg_iMessageBitsumg_iFrags[MAX_PLAYERS 1],
    
g_iWarmupState WS_WAITING/*g_pHideWeapon, */g_iTimerCount;

public 
plugin_precache() {
    for(new 
isizeof KILL_SOUNDSi++) {
        
precache_sound(KILL_SOUNDS[i]);
    }
}

public 
plugin_init() {
    
register_plugin("Knife warmup""0.1""Subb98");
    
register_clcmd("joinclass""CmdJoinClass");
    const 
JOIN_CLASS_MENU_KEYS MENU_KEY_1|MENU_KEY_2|MENU_KEY_3|MENU_KEY_4|MENU_KEY_5;
    
register_menucmd(register_menuid("Terrorist_Select"), JOIN_CLASS_MENU_KEYS"CmdJoinClass");
    
register_menucmd(register_menuid("CT_Select"), JOIN_CLASS_MENU_KEYS"CmdJoinClass");
    
register_event("HLTV""EventHLTV""a""1=0""2=0");
    
register_logevent("EventGameCommencing"2"1=Game_Commencing");
    
register_logevent("EventRoundStart"2"1=Round_Start");
    
register_logevent("EventRoundEnd"2"1=Round_End");
    new const 
ENT_CLASSNAME[] = "player";
    
DisableHamForward(g_pHamSpawn RegisterHam(Ham_SpawnENT_CLASSNAME"HamSpawnPlayerPost"1));
    
DisableHamForward(g_pHamAddPlayerItem RegisterHam(Ham_AddPlayerItemENT_CLASSNAME"HamAddPlayerItemPre"));
    
DisableHamForward(g_pHamGiveAmmo RegisterHam(Ham_GiveAmmoENT_CLASSNAME"HamGiveAmmoPre"));
    
DisableHamForward(g_pHamUse RegisterHam(Ham_Use"hostage_entity""HamUseHostagePre"));
    
DisableHamForward(g_pHamKilled RegisterHam(Ham_KilledENT_CLASSNAME"HamKilledPlayerPost"1));
    
#if !defined _roundcontrol_included
    
g_pRoundInfinite get_cvar_pointer("mp_round_infinite");
    
#endif
    
g_pRestartRound get_cvar_pointer("sv_restartround");
    
/*g_pHideWeaponMsgId = get_user_msgid("HideWeapon");
    g_pStatusIconMsgId = get_user_msgid("StatusIcon");*/
    
g_pHudSyncObj1 CreateHudSyncObj();
    
g_pHudSyncObj2 CreateHudSyncObj();
    
CreateThinkEntity();
}

#if !defined _roundcontrol_included
public plugin_cfg() {
    if(
g_pRoundInfinite) {
        
get_pcvar_string(g_pRoundInfiniteg_szRoundInfinitecharsmax(g_szRoundInfinite));
    }
}
#endif

public client_putinserver(id) {
    
ResetValues(id);
    if(!
is_user_bot(id) && !is_user_hltv(id)) {
        
bit_set(idg_iConnectedBitsum);
    }
}

public 
client_disconnect(id) {
    
ResetValues(id);
    
remove_task(id);
}

public 
CmdJoinClass(const id) {
    if(
g_iWarmupState == WS_IN_PROGRESS) {
        
set_task(RESPAWN_DELAY"TaskRespawn"id);
    }
}

public 
EventHLTV() {
    switch(
g_iWarmupState) {
        case 
WS_BEGIN: {
            
g_iWarmupState WS_IN_PROGRESS;
            
g_iMessageBitsum 0;
            
EnableHamForward(g_pHamSpawn);
            
EnableHamForward(g_pHamAddPlayerItem);
            
EnableHamForward(g_pHamGiveAmmo);
            
EnableHamForward(g_pHamUse);
            
EnableHamForward(g_pHamKilled);
            
//g_pHideWeapon = register_message(g_pHideWeaponMsgId, "MessageHideWeapon");
            #if defined _roundcontrol_included
            
g_pCheckWinHook SetBlockControl(RC_CheckWinConditions);
            
#else
            
if(g_pRoundInfinite) {
                
set_pcvar_num(g_pRoundInfinite1);
            }
            
#endif
            //set_msg_block(g_pStatusIconMsgId, BLOCK_SET);
        
}
        case 
WS_ENDED: {
            
entity_set_float(g_pThinkEntEV_FL_nextthinkget_gametime() + SHOW_MSG_DELAY);
        }
    }
}

public 
EventGameCommencing() {
    if(
g_iWarmupState == WS_WAITING) {
        
g_iWarmupState WS_BEGIN;
    }
}

public 
EventRoundStart() {
    if(
g_iWarmupState == WS_IN_PROGRESS) {
        
entity_set_float(g_pThinkEntEV_FL_nextthinkget_gametime() + 1.0);
    }
}

public 
EventRoundEnd() {
    if(
g_iWarmupState == WS_IN_PROGRESS) {
        
g_iWarmupState WS_ENDED;
        
DisableHamForward(g_pHamSpawn);
        
DisableHamForward(g_pHamAddPlayerItem);
        
DisableHamForward(g_pHamGiveAmmo);
        
DisableHamForward(g_pHamUse);
        
DisableHamForward(g_pHamKilled);
        
//unregister_message(g_pHideWeaponMsgId, g_pHideWeapon);
        #if defined _roundcontrol_included
        
RemoveBlockControl(RC_CheckWinConditionsg_pCheckWinHook);
        
#else
        
if(g_pRoundInfinite) {
            
set_pcvar_string(g_pRoundInfiniteg_szRoundInfinite);
        }
        
#endif
        //set_msg_block(g_pStatusIconMsgId, BLOCK_NOT);
        
set_pcvar_float(g_pRestartRound1.0);
    }
}
/*
public MessageHideWeapon() {
    const ARG_FLAGS = 1;
    set_msg_arg_int(ARG_FLAGS, ARG_BYTE, get_msg_arg_int(ARG_FLAGS) | HW_CROSS_AMMO_WPNLIST | HW_TIMER | HW_MONEY);
}*/

public HamSpawnPlayerPost(const id) {
    if(
is_user_alive(id)) {
        
bit_set(idg_iAliveBitsum);
        if(!
bit_valid(idg_iMessageBitsum)) {
            
set_task(SHOW_MSG_DELAY"TaskWarmupStartMsg"id);
        }
        
entity_set_float(idEV_FL_healthWARMUP_HEALTH);
        
engclient_cmd(id"weapon_knife");
        
/*message_begin(MSG_ONE, g_pHideWeaponMsgId, _, id);
        write_byte(HW_CROSS_AMMO_WPNLIST | HW_TIMER | HW_MONEY);
        message_end();*/
    
}
}

public 
HamAddPlayerItemPre(const id, const pEnt) {
    if(
cs_get_weapon_id(pEnt) != CSW_KNIFE) {
        
entity_set_int(pEntEV_INT_flagsentity_get_int(pEntEV_INT_flags ) | FL_KILLME);
        
SetHamReturnInteger(0);
        return 
HAM_SUPERCEDE;
    }
    return 
HAM_IGNORED;
}

public 
HamGiveAmmoPre() {
    const 
NO_AMMO_STOP_PROCESSING = -1;
    
SetHamReturnInteger(NO_AMMO_STOP_PROCESSING);
    return 
HAM_SUPERCEDE;
}

public 
HamUseHostagePre() {
    return 
HAM_SUPERCEDE;
}

public 
HamKilledPlayerPost(const id, const pKiller) {
    
bit_clear(idg_iAliveBitsum);
    if(
bit_valid(pKillerg_iAliveBitsum)) {
        if(
g_iFrags[pKiller] == sizeof KILL_SOUNDS) {
            
g_iFrags[pKiller] = 0;
        }
        
emit_sound(pKillerCHAN_VOICEKILL_SOUNDS[g_iFrags[pKiller]], VOL_NORMATTN_NORM0PITCH_NORM);
        
g_iFrags[pKiller]++;
    }
    
set_task(RESPAWN_DELAY"TaskRespawn"id);
}

public 
FwdThink(const pEnt) {
    switch(
g_iWarmupState) {
        case 
WS_IN_PROGRESS: {
            static 
iDiffiMin;
            
iDiff WARMUP_TIME g_iTimerCount++, iMin 0;
            
GetMinutes(iDiffiMin);
            
set_hudmessage(12864__0.96__1.00.00.01, -1);
            
ShowSyncHudMsg(0g_pHudSyncObj1"До конца разминки: %d:%d"iMiniDiff);
            if(
iDiff || iMin) {
                
entity_set_float(pEntEV_FL_nextthinkget_gametime() + 1.0);
            } else {
                
EventRoundEnd();
            }
        }
        case 
WS_ENDED: {
            
g_iWarmupState WS_WAITING;
            
g_iTimerCount 0;
            
set_hudmessage(0255__0.25__5.0__, -1);
            
ShowSyncHudMsg(0g_pHudSyncObj2"Приготовьтесь к бою!^nИгра началась!");
            
#if defined USE_PAUSE
            
pause("d");
            
#endif
        
}
    }
}

public 
TaskRespawn(const id) {
    if(
bit_valid(idg_iConnectedBitsum) && !bit_valid(idg_iAliveBitsum) && cs_get_user_team(id) != CS_TEAM_SPECTATOR) {
        
ExecuteHamB(Ham_CS_RoundRespawnid);
    }
}

public 
TaskWarmupStartMsg(const id) {
    if(
bit_valid(idg_iAliveBitsum)) {
        
set_hudmessage(2550__0.25__5.0__, -1);
        
ShowSyncHudMsg(idg_pHudSyncObj2"Приготовьтесь к бойне!^nРазминка на ножах началась!");
        
bit_set(idg_iMessageBitsum);
    }
}

CreateThinkEntity() {
    new const 
ENT_CLASSNAME[] = "_warmup_think_ent";
    if((
g_pThinkEnt create_entity("info_target"))) {
        
entity_set_string(g_pThinkEntEV_SZ_classnameENT_CLASSNAME);
        
register_think(ENT_CLASSNAME"FwdThink");
    } else {
        
set_fail_state("Failed to create think entity");
    }
}

ResetValues(const id) {
    
bit_clear(idg_iConnectedBitsum);
    
bit_clear(idg_iAliveBitsum);
    
bit_clear(idg_iMessageBitsum);
    
g_iFrags[id] = 0;
}

GetMinutes(&iSec, &iMin) {
    const 
SECONDS_IN_MINUTE 60;
    
iMin iSec SECONDS_IN_MINUTEiSec %= SECONDS_IN_MINUTE;
«Очень хорошо. Лучше вы, чем я» © Donald J. Trump
Аватара пользователя
Subb98
Модератор
 
Сообщения: 5485
Зарегистрирован: 24 мар 2011, 19:42
Откуда: г. Пермь
Благодарил (а): 1329 раз.
Поблагодарили: 2343 раз.
Опыт программирования: Больше трех лет
Языки программирования: PHP

Re: Разминка на ножах (Knife warmup)

Сообщение Капитан » 02 дек 2016, 17:40

Добрый день, очень понравился плагин.
Но есть ошибка в логах, включил дебаг и вот, в исходникe ничего не менял.

Код: Выделить всё
L 12/01/2016 - 23:04:48: [AMXX] Run time error 4: index out of bounds 
L 12/01/2016 - 23:04:48: [AMXX]    [0] knife_warmup.sma::ResetValues (line 274)
L 12/01/2016 - 23:04:48: [AMXX]    [1] knife_warmup.sma::client_disconnect (line 101)
Последний раз редактировалось Капитан 02 дек 2016, 18:25, всего редактировалось 1 раз.
Аватара пользователя
Капитан
 
Сообщения: 12
Зарегистрирован: 06 мар 2016, 21:05
Благодарил (а): 14 раз.
Поблагодарили: 0 раз.

Re: Разминка на ножах (Knife warmup)

Сообщение Subb98 » 02 дек 2016, 18:23

Капитан, добрый день. Вообще, странно, что появилась эта ошибка, могу посоветовать сделать следующее:

Код: Выделить всё
ResetValues(const id) {
    
bit_clear(idg_iConnectedBitsum);
    
bit_clear(idg_iAliveBitsum);
    
bit_clear(idg_iMessageBitsum);
    
g_iFrags[id] = 0;

>>

Код: Выделить всё
ResetValues(const id) {
    
bit_clear(idg_iConnectedBitsum);
    
bit_clear(idg_iAliveBitsum);
    
bit_clear(idg_iMessageBitsum);
    if(
is_user_connected(id)) {
        
g_iFrags[id] = 0;
    }
«Очень хорошо. Лучше вы, чем я» © Donald J. Trump
Аватара пользователя
Subb98
Модератор
 
Сообщения: 5485
Зарегистрирован: 24 мар 2011, 19:42
Откуда: г. Пермь
Благодарил (а): 1329 раз.
Поблагодарили: 2343 раз.
Опыт программирования: Больше трех лет
Языки программирования: PHP

Re: Разминка на ножах (Knife warmup)

Сообщение Капитан » 02 дек 2016, 18:25

Спасибо большое, проверю и отпишусь.
Аватара пользователя
Капитан
 
Сообщения: 12
Зарегистрирован: 06 мар 2016, 21:05
Благодарил (а): 14 раз.
Поблагодарили: 0 раз.

Re: Разминка на ножах (Knife warmup)

Сообщение Капитан » 03 дек 2016, 15:44

Есть опять ошибка:

Код: Выделить всё
12/03/2016 - 12:02:33: [AMXX] Run time error 4: index out of bounds 
L 12/03/2016 - 12:02:33: [AMXX]    [0] knife_warmup.sma::ResetValues (line 275)
L 12/03/2016 - 12:02:33: [AMXX]    [1] knife_warmup.sma::client_putinserver (line 94)
L 12/03/2016 - 12:04:01: [AMXX] Displaying debug trace (plugin "knife_warmup.amxx")
L 12/03/2016 - 12:04:01: [AMXX] Run time error 4: index out of bounds 
L 12/03/2016 - 12:04:01: [AMXX]    [0] knife_warmup.sma::ResetValues (line 275)
L 12/03/2016 - 12:04:01: [AMXX]    [1] knife_warmup.sma::client_disconnect (line 101)
Аватара пользователя
Капитан
 
Сообщения: 12
Зарегистрирован: 06 мар 2016, 21:05
Благодарил (а): 14 раз.
Поблагодарили: 0 раз.

Re: Разминка на ножах (Knife warmup)

Сообщение Subb98 » 03 дек 2016, 15:58

Капитан, прикрепите, пожалуйста, также исходный код.
«Очень хорошо. Лучше вы, чем я» © Donald J. Trump
Аватара пользователя
Subb98
Модератор
 
Сообщения: 5485
Зарегистрирован: 24 мар 2011, 19:42
Откуда: г. Пермь
Благодарил (а): 1329 раз.
Поблагодарили: 2343 раз.
Опыт программирования: Больше трех лет
Языки программирования: PHP

Re: Разминка на ножах (Knife warmup)

Сообщение Капитан » 03 дек 2016, 17:59

Вот, пожалуйста.
У вас нет необходимых прав для просмотра вложений в этом сообщении.
Аватара пользователя
Капитан
 
Сообщения: 12
Зарегистрирован: 06 мар 2016, 21:05
Благодарил (а): 14 раз.
Поблагодарили: 0 раз.

Re: Разминка на ножах (Knife warmup)

Сообщение Leonidddd » 04 дек 2016, 01:22

Капитан, обратите внимание на
Код: Выделить всё
const MAX_PLAYERS = 16;

Сколько у Вас максимальное кол-во игроков на сервере?
Скорее-всего больше, так бы ошибки подобной никогда не было бы.
Аватара пользователя
Leonidddd
Модератор
 
Сообщения: 2557
Зарегистрирован: 08 апр 2012, 18:13
Откуда: г. Запорожье
Благодарил (а): 192 раз.
Поблагодарили: 718 раз.

След.

Вернуться в Утвержденные плагины

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

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