> > > > >

Обучение Скриптингу [sleedney]

Сообщения
107
Рейтинг
51
#1
Создал веточку для своего обучения.Wopox1337 дал добро :yes3:
21 Ноя 2017
wopox1337 , Учитель как время будет отвечай по возможности.
У меня есть код (код проигрывания музыки в конце раунда)
Код:
#include <amxmodx>
#include <amxmisc>

#define PLUGIN "End Round Music"
#define VERSION "2.0"
#define AUTHOR "Sho0ter"

#define TRACKSNUM 100

new ALLMusic[TRACKSNUM][128]
new CTMusic[TRACKSNUM][128]
new TMusic[TRACKSNUM][128]

new PlaylistSize
new CTNum
new TNum
new ALLNum
new SayText

new Mode[32]
new Configsdir[64]
new CurrentMap[64]
new File[96]
new Playlist[128]
new Play[128]
new PlayCommand[128]
new CheckFile[128]

new bool:Ermon[33]

new PcvarMode
new PcvarVol
new PcvarRadio
new PcvarDelay

public plugin_init()
{
register_plugin(PLUGIN, VERSION, AUTHOR)
register_dictionary("endroundmusic.txt")
register_event("SendAudio", "t_win", "a", "2&%!MRAD_terwin")
register_event("SendAudio", "ct_win", "a", "2&%!MRAD_ctwin")
PcvarMode = register_cvar("erm_mode", "1")
PcvarVol = register_cvar("erm_autovol", "0.5")
PcvarRadio = register_cvar("erm_radio", "1")
PcvarDelay = register_cvar("erm_delay", "20.0")
register_clcmd("say /ermon", "cmd_ermon", 0, " - turn on end round music")
register_clcmd("say /ermoff", "cmd_ermoff", 0, " - turn off end round music")
SayText = get_user_msgid("SayText");
return PLUGIN_CONTINUE
}

public plugin_precache()
{
get_configsdir(Configsdir, 63)
get_mapname(CurrentMap, 63)
formatex(Playlist, 127, "%s/endroundmusic/%s.ini", Configsdir, CurrentMap)
new Index = 0
while(CurrentMap[Index] != '_' && CurrentMap[Index] != '^0')
{
Index++
}
if(!file_exists(Playlist) && CurrentMap[Index] == '_')
{
CurrentMap[Index] = '^0'
formatex(Playlist, 127, "%s/endroundmusic/%s_.ini", Configsdir, CurrentMap)
}
if(!file_exists(Playlist))
{
formatex(Playlist, 127, "%s/endroundmusic/default.ini", Configsdir)
}
if(!file_exists(Playlist))
{
log_amx("Playlist <%s> not found.", Playlist)
set_fail_state("Playlist not found")
return PLUGIN_CONTINUE
}
PlaylistSize = file_size(Playlist, 1)
for(new i = 0; i <= PlaylistSize; i++)
{
new Buffer[128], len, Result
Result = read_file(Playlist, i, Buffer, sizeof(Buffer)-1, len)
if(!Result)
{
continue
}
parse(Buffer, File, 95, Mode, 31)
if(File[0] == ';' || File[0] == '/' || File[0] == ' ' || equal(File, ""))
{
continue
}
formatex(CheckFile, 127, "sound/%s", File)
if(!file_exists(CheckFile))
{
log_amx("File not found <%s>", CheckFile)
continue
}
if(equal(Mode, "CT"))
{
formatex(CTMusic[CTNum], 127, "%s", File)
CTNum++
precache_sound(File)
}
else if(equal(Mode, "TER"))
{
formatex(TMusic[TNum], 127, "%s", File)
TNum++
precache_sound(File)
}
else if(equal(Mode, "ALL"))
{
formatex(ALLMusic[ALLNum], 127, "%s", File)
ALLNum++
precache_sound(File)
}
}
if(CTNum == 0 && TNum == 0 && ALLNum == 0)
{
log_amx("Not found tracks in playlist.")
set_fail_state("Playlist empty")
return PLUGIN_CONTINUE
}
log_amx("Loaded tracks: CT <%d> TER <%d> ALL <%d>", CTNum, TNum, ALLNum)
return PLUGIN_CONTINUE
}

public client_disconnect(id)
{
remove_task(id)
return PLUGIN_CONTINUE
}

public client_putinserver(id)
{
set_task(get_pcvar_float(PcvarDelay), "showerminfo", id)
return PLUGIN_HANDLED
}

public t_win()
{
if(!get_pcvar_num(PcvarMode))
{
return PLUGIN_HANDLED
}
if((!CTNum || !TNum) && ALLNum && get_pcvar_num(PcvarMode) != 2)
{
set_pcvar_num(PcvarMode, 2)
}
switch(get_pcvar_num(PcvarMode))
{
case 1:
{
formatex(Play, 127, "%s", TMusic[random_num(0, TNum-1)])
}
case 2:
{
formatex(Play, 127, "%s", ALLMusic[random_num(0, ALLNum-1)])
}
case 3:
{
new Randomizer = random_num(1, 2)
switch(Randomizer)
{
case 1:
{
formatex(Play, 127, "%s", TMusic[random_num(0, TNum-1)])
}
case 2:
{
formatex(Play, 127, "%s", ALLMusic[random_num(0, ALLNum-1)])
}
}
}
case 4:
{
new Randomizer = random_num(1, 3)
switch(Randomizer)
{
case 1:
{
formatex(Play, 127, "%s", CTMusic[random_num(0, CTNum-1)])
}
case 2:
{
formatex(Play, 127, "%s", TMusic[random_num(0, TNum-1)])
}
case 3:
{
formatex(Play, 127, "%s", ALLMusic[random_num(0, ALLNum-1)])
}
}
}
}
if(containi(Play, ".wav") != -1)
{
formatex(PlayCommand, 127, "spk %s", Play)
}
else if(containi(Play, ".mp3") != -1)
{
formatex(PlayCommand, 127, "mp3 play sound/%s", Play)
}
else
{
log_amx("Unsupported file type <%s>", Play)
return PLUGIN_HANDLED
}
for(new id = 0; id <= get_maxplayers(); id++)
{
if(!is_user_connected(id) || !Ermon[id])
{
continue
}
client_cmd(id, "stopsound")
client_cmd(id, "%s", PlayCommand)
if(get_pcvar_num(PcvarRadio))
{
client_cmd(id, "spk radio/terwin")
}
}
return PLUGIN_HANDLED
}

public ct_win()
{
if(!get_pcvar_num(PcvarMode))
{
return PLUGIN_HANDLED
}
if((!CTNum || !TNum) && ALLNum && get_pcvar_num(PcvarMode) != 2)
{
set_pcvar_num(PcvarMode, 2)
}
switch(get_pcvar_num(PcvarMode))
{
case 1:
{
formatex(Play, 127, "%s", CTMusic[random_num(0, CTNum-1)])
}
case 2:
{
formatex(Play, 127, "%s", ALLMusic[random_num(0, ALLNum-1)])
}
case 3:
{
new Randomizer = random_num(1, 2)
switch(Randomizer)
{
case 1:
{
formatex(Play, 127, "%s", CTMusic[random_num(0, CTNum-1)])
}
case 2:
{
formatex(Play, 127, "%s", ALLMusic[random_num(0, ALLNum-1)])
}
}
}
case 4:
{
new Randomizer = random_num(1, 3)
switch(Randomizer)
{
case 1:
{
formatex(Play, 127, "%s", CTMusic[random_num(0, CTNum-1)])
}
case 2:
{
formatex(Play, 127, "%s", TMusic[random_num(0, TNum-1)])
}
case 3:
{
formatex(Play, 127, "%s", ALLMusic[random_num(0, ALLNum-1)])
}
}
}
}
if(containi(Play, ".wav") != -1)
{
formatex(PlayCommand, 127, "spk %s", Play)
}
else if(containi(Play, ".mp3") != -1)
{
formatex(PlayCommand, 127, "mp3 play sound/%s", Play)
}
else
{
log_amx("Unsupported file type <%s>", PLUGIN, Play)
return PLUGIN_HANDLED
}
for(new id = 0; id <= get_maxplayers(); id++)
{
if(!is_user_connected(id) || !Ermon[id])
{
continue
}
client_cmd(id, "stopsound")
client_cmd(id, "%s", PlayCommand)
if(get_pcvar_num(PcvarRadio))
{
client_cmd(id, "spk radio/ctwin")
}
}
return PLUGIN_HANDLED
}

public cmd_ermon(id)
{
Ermon[id] = true
client_cmd(id, "mp3volume %f", get_pcvar_float(PcvarVol))
client_cmd(id, "spk vox/activated")
green_print(id, "ERMON_MSG")
return PLUGIN_CONTINUE
}


public cmd_ermoff(id)
{
Ermon[id] = false
client_cmd(id, "mp3 stop")
client_cmd(id, "spk vox/deactivated")
green_print(id, "ERMOFF_MSG")
return PLUGIN_CONTINUE
}

public showerminfo(id)
{
Ermon[id] = true
client_cmd(id, "mp3volume %f", get_pcvar_float(PcvarVol))
green_print(id, "ERMINFO_MSG")
}

stock green_print(index, const message[])
{
new finalmsg[192];
formatex(finalmsg, 191, "^x04[ERM] ^x01%L", index, message);
message_begin(MSG_ONE, SayText, _, index);
write_byte(index);
write_string(finalmsg);
message_end();
}
Код может и устаревший но рабочий и проверенный годами.

Собственно вопрос?
Позволит ли мне движок cs 1.6 добавить в данный код функцию отображения на экране сервера худ(строчку) названия трека который проигрывается на сервере?
 
3  
Сообщения
261
Рейтинг
297
#2
Позволит ли мне движок cs 1.6 добавить в данный код функцию отображения на экране сервера худ(строчку) названия трека который проигрывается на сервере?
конечно :)
в функции воспроизведения просто выводите сообщение и все
так же убирайте, в функции остановки воспроизведения, если такое есть.
 
3  
Сообщения
2.014
Рейтинг
1948
#3
sleedney, задача - реализуема. :yes3:
Посмотри внимательно как устроен плагин. В каком моменте воспроизводится музыка. В том моменте, у тебя уже есть готовая переменная с отформатированным текстом с названием файла для воспроизведения.

Этот текст, готовый, ты можешь вывести с помощью set_hudmessage() / send_hudmessage().
 
3  
Сообщения
107
Рейтинг
51
#4
wopox1337, хотелось бы откусить кусочек и разобрать отдельно )
Код:
        formatex(CheckFile, 127, "sound/%s", File)
if(!file_exists(CheckFile))
{
log_amx("File not found <%s>", CheckFile)
continue
}
if(equal(Mode, "CT"))
{
formatex(CTMusic[CTNum], 127, "%s", File)
CTNum++
precache_sound(File)
}
else if(equal(Mode, "TER"))
{
formatex(TMusic[TNum], 127, "%s", File)
TNum++
precache_sound(File)
}
else if(equal(Mode, "ALL"))
{
formatex(ALLMusic[ALLNum], 127, "%s", File)
ALLNum++
precache_sound(File)
}

Данный код позволяет найти текст в файле и передать функцию для воспроизведения файла в зависимости от настроек хранения трек листа. Сами же функции "Play" запуска трека - находятся в
Код:
public ct_win()
и
Код:
public t_win()
 
 
Сообщения
107
Рейтинг
51
#6
wopox1337, есть небольшой вопросик ?
функция while — цикл, повторяющий одно и то же действие, пока условие продолжения цикла while остаётся истинным.
В "Pawn scripting" имеет одинаковую суть логики как и в" С++ " ?
или это одно и то же :scratch_one-s_head:
 
 
Сообщения
828
Рейтинг
888
#7
sleedney, while в любом ЯП имеет одну суть, главное при использовании определяться какая конструкция нужна в каждом случае:
1. while
2. do while
 
Последнее редактирование:
1  
Сообщения
828
Рейтинг
888
#9
Subb98, пардон, не проснулся видать на тот момент) исправился)
 
1  
Сообщения
107
Рейтинг
51
#10
wopox1337, hello how are you doing today? decided to decorate your day))
Если серьёзно то волнует одна строка. Поясни пожалуйста что это такое(строка ниже из плагина) , если будешь в состоянии.)

Код:
#define RESETBLINK_TASKID    45454
Код:
#include <amxmodx>
#include <hamsandwich>

new sprites[][] = {
        
    "",
    "number_1",
    "number_2",
    "number_3",
    "number_4",
    "number_5",
    "number_6",
    "number_7",
    "number_8",
    "number_9"

}

new g_maxplayers,g_statusicon // глобальные переменные
new cvColor,cvBlinkTime,cvOverCount // переменные

new play[33] // массив
new rgb[3] // массив

new Float:blinkTime // float Функция конвертирует целое число в дробное
new overCountSpr[40] // массив

#define RESETBLINK_TASKID    45454

public plugin_init(){ // plugin_init Функция вызывается при старте сервера,смене карты или рестарте сервера
        
    register_plugin("Kills Counter","0.3","serfreeman1337")
    
    g_maxplayers = get_maxplayers() // Функция узнает сколько максимально игроков может быть на сервере
    g_statusicon = get_user_msgid("StatusIcon")   // get_user_msgid Функция получает id клиенского сообщения (не путать с чатом)
    
    cvColor = register_cvar("ks_color","255 255 0") // цвет цифр в формате RGB
    cvBlinkTime = register_cvar("ks_blink_time","2.0") // время мигания значка
    cvOverCount = register_cvar("ks_over_count_spr","dmg_rad") // спрайт, который будет отображаться при превышении 9 убийств
    
    RegisterHam(Ham_Killed,"player","fw_PlayerKilled",1) // Ham_killed отлов события убийства игрока
    RegisterHam(Ham_Spawn,"player","fw_PlayerSpawn",1) // Ham_Spawn Событие респауна игрока.
    
}

public plugin_cfg(){ // plugin_cfg Функция вызывает при перезагрузке или старте сервера после plugin_ini
        
    new data[20],raw[3][5]
    get_pcvar_string(cvColor,data,19) // get_pcvar_string Функция получает символьное значение cvar
    
    parse(data,raw[0],4,raw[1],4,raw[2],4) // parse Функция получает содержание строки по аргументам.
    
    rgb[0] = str_to_num(raw[0]) // str_to_num Функция конвертирует строку в число
    rgb[1] = str_to_num(raw[1])
    rgb[2] = str_to_num(raw[2])
    
    blinkTime = get_pcvar_float(cvBlinkTime)
    get_pcvar_string(cvOverCount,overCountSpr,39)
    
}

public fw_PlayerSpawn(id)
    icon(id,0)

public fw_PlayerKilled(victim,killer){
        
    if(0 < killer <= g_maxplayers){
        if(get_user_team(killer) != get_user_team(victim) && ExecuteHam(Ham_IsAlive,killer))
            icon(killer,1)
    }
    
    icon(victim,0)
    
}

public icon(id,style){
        
    if(!style){
        if(!play[id])
            return PLUGIN_CONTINUE
            
        message_begin(MSG_ONE,g_statusicon,_,id)
        write_byte(0)
        write_string(play[id] < 10 ? sprites[play[id]] : overCountSpr)
        message_end()
        
        play[id] = 0
        
        return PLUGIN_CONTINUE
    }
    
    if(0 < play[id] < 10){
        message_begin(MSG_ONE,g_statusicon,_,id)
        write_byte(0)
        write_string(sprites[play[id]])
        message_end()
    }
    
    play[id] ++

    message_begin(MSG_ONE,g_statusicon,_,id)
    write_byte(blinkTime > 0.0 ? 2 : 1)
    write_string(play[id] < 10 ? sprites[play[id]] : overCountSpr) // // write_string Функция изменяет одну строку
    write_byte(rgb[0]) // red
    write_byte(rgb[1]) // green
    write_byte(rgb[2]) // blue
    message_end()
    
    if(blinkTime > 0.0){
        remove_task(RESETBLINK_TASKID + id)
        set_task(2.0,"resetblink",RESETBLINK_TASKID + id)
    }
    
    return PLUGIN_CONTINUE
    
}

public resetblink(tId){
        
    new id = tId - RESETBLINK_TASKID
    
    if(!is_user_connected(id))
        return
    
    message_begin(MSG_ONE,g_statusicon,_,id) // message_begin Функция генирирует клиентские сообщения
    write_byte(1) // write_byte Функция изменяет один бит
    write_string(play[id] < 10 ? sprites[play[id]] : overCountSpr) // write_string Функция изменяет одну строку
    write_byte(rgb[0]) // red
    write_byte(rgb[1]) // green
    write_byte(rgb[2]) // blue
    message_end()
    
}
 
 
Сообщения
1.228
Рейтинг
1239
#11
Sleedney, ID таска. По сути некий идентификатор задачи. Для каждого плагина свой набор и они не пересекаются. Часто используют если надо сделать какое то действие над игроком через некий промежуток времени
 
2  
Сообщения
422
Рейтинг
82
#12
fantom, а зачем вводить ид таска дефайном, когда можно в set_task это сделать? тоже интересно стало
 
 
Сообщения
339
Рейтинг
583
#14
sbelov020, магическое число не имеет значения, название макроса может дать это значение. Что вы будете делать, когда у вас в плагине 100 задач висит на тасках? Будете запоминать каждые оффсеты или просто дадите имя задаче?
 
3  
Сообщения
422
Рейтинг
82
#15
Mistrick, вот теперь понятно. просто видел данный прием где 1-2 таска всего
 
 
Сообщения
107
Рейтинг
51
#16
Доброго времени суток. При компиляции плагина возникла ошибка. Ошибка правильности порядка действий для выражения.
В общем я её исправил хотелось бы уточнить не повлияло ли это на порядок действий выражения с лева на право.Если есть время дайте ответ пожалуйста.

CSS:
до

( C<O || C==O || BL==1*point || BL<=CL && H>(H1-Range) && H<(H1+Range)

 && H1>H2 && H1>H3 && H1>H4 && H1>H5 && H1>H6 && H1>H7 && H1>H8 )

CSS:
после

( C<O || C==O || BL==1*point || (BL<=CL && H>(H1-Range) && H<(H1+Range)

 && H1>H2 && H1>H3 && H1>H4 && H1>H5 && H1>H6 && H1>H7 && H1>H8 ))
 
 
Сообщения
1.228
Рейтинг
1239
#17
Sleedney, я не вижу изменений если честно. Но призаюсь условие страшное
 
2  
Сообщения
107
Рейтинг
51
#18
fantom, Если будет время хотелось бы увидеть как в вашем понимании выглядит данное условие в более приличном виде.
 
 
Сообщения
1.228
Рейтинг
1239
#20
Если будет время хотелось бы увидеть как в вашем понимании выглядит данное условие в более приличном виде.
Из того куска ничего не понятно. Но условие сложно читаемо (можна даже сказать вовсе не читаемо). Человеку первый раз заглянувшему в код будет сложно понят что тут происходит
 
 
> > > > >