Обучение и помощь по скриптингу для MIRDOBRO777

Сообщения
111
Реакции
26
С менюшкой так и не разобрался.
Другой вопрос.
Подскажите, пожалуйста, есть ли возможность осуществить отлов срабатывания флешки в воздухе?
То есть мне надо написать плагин, который будет либо отлавливать срабатывание флешки в воздухе, либо проверять, что флешка сработала на любой поверхности и оставила черный след.
После таких проверок уже наказывать или нет игрока.
Можно так и какие функции можно задействовать, включая ReAPI?
 

Garey

ninjaCow
Сообщения
411
Реакции
1,051
Помог
10 раз(а)
RG_CGrenade_ExplodeFlashbang
 
Сообщения
111
Реакции
26
Приветствую ребята!
Переделал магазин под новое меню и все вроде бы работает, но...
Пункты прячет при отсутствии прохождения проверок.
Отображает за каждую команду правильное число пунктов, а вот покупает смещенно.
То есть, за ТТ 3 доступных пункта:
1. HE (при нажатии ничего не покупается)
2. Flash (покупается HE)
3. Frost (покупается Flash)
Почему происходит смещение пунктов?
Подскажите, пожалуйста.
Вот весь код:
Код:
#include <amxmodx>
#include <reapi>
#define VERSION "1.0"
#define is_user_vip(%0) (get_user_flags(%0) & VIP_FLAG)
#define get_player_money(%1)    get_member(%1, m_iAccount)
/* Настройки */
#define VIP_FLAG (ADMIN_IMMUNITY|ADMIN_LEVEL_H)
new const prefix[] = "^1[^4SHOP^1]"
const iTime = 5
const iCostRoll = 80
const iRoundLimitPlayer = 1
const iRoundLimitVip = 2
const iMapLimitPlayer = 10
const iMapLimitVip = 20
const g_Discount = 20
enum _:ItemData { ItemCase[10], ItemName[64], ItemGive[20], ItemAmmo, ItemCost, ItemTeam }
new const g_ItemList[][ItemData] = {
{ "weapon", "AWP", "weapon_awp", 1, 300, 2 },
{ "nade", "HE", "weapon_hegrenade", 1, 50, 0 },
{ "nade", "Flash", "weapon_flashbang", 1, 90, 1 },
{ "nade", "Frost", "weapon_smokegrenade", 1, 120, 1 }
};
new g_RoundCounter[MAX_PLAYERS+1], g_MapCounter[MAX_PLAYERS+1], g_NowUsed[MAX_PLAYERS+1], g_LastTry;
public plugin_init() {
 register_plugin("Nade Shop", VERSION, "MIRDOBRO");
 register_clcmd("say /shop", "OpenMenu");
 register_clcmd("say /mt", "OpenMenu");
 RegisterHookChain(RG_CSGameRules_RestartRound, "@refwd_NewRound_Post", true);
}
@refwd_NewRound_Post() {
for (new i = 1; i <= MAX_PLAYERS; i++) {
g_RoundCounter[i] = 0;
}
}
public OpenMenu(id) {
new sysTime = get_systime();
g_LastTry = g_NowUsed[id];
new TimeRemaining = iTime - (sysTime - g_LastTry);
new authid[32], name[32];
get_user_authid(id,authid,31);
 get_user_name(id,name,31);
 if(!is_user_alive(id)) {
client_print_color(id, print_team_red, "%s ^3Доступно только ^4живым ^3игрокам", prefix);
return PLUGIN_HANDLED;
}
 if(g_RoundCounter[id] == iRoundLimitPlayer && !is_user_vip(id)) {
log_to_file("addons\amxmodx\logs\round_player.txt" , "^nНик: %s, %s^nБаланс: $%d, Лимит: %d/%d^n", name, authid, get_player_money(id), g_RoundCounter[id], iRoundLimitPlayer);
client_print_color(id, print_team_red, "%s ^3Достигнут лимит открытия магазина в этом раунде", prefix);
return PLUGIN_HANDLED;
}
else
if(g_RoundCounter[id] == iRoundLimitVip) {
log_to_file("addons\amxmodx\logs\round_vip.txt" , "^nНик: %s, %s^nБаланс: $%d, Лимит: %d/%d^n", name, authid, get_player_money(id), g_RoundCounter[id], iRoundLimitVip);
client_print_color(id, print_team_red, "%s ^3Достигнут лимит открытия магазина в этом раунде", prefix);
return PLUGIN_HANDLED;
}
 if(g_MapCounter[id] == iMapLimitPlayer && !is_user_vip(id)) {
client_print_color(id, print_team_red, "%s ^3Достигнут лимит открытия магазина на этой карте", prefix);
return PLUGIN_HANDLED;
}
else
if(g_MapCounter[id] == iMapLimitVip) {
log_to_file("addons\amxmodx\logs\map_vip.txt" , "^nНик: %s, %s^nБаланс: $%d, Лимит: %d/%d^n", name, authid, get_player_money(id), g_MapCounter[id], iMapLimitVip);
client_print_color(id, print_team_red, "%s ^3Достигнут лимит открытия магазина на этой карте", prefix);
return PLUGIN_HANDLED;
}
 if(iTime > (sysTime - g_LastTry)) {
log_to_file("addons\amxmodx\logs\time.txt" , "^nНик: %s, %s^nБаланс: $%d, Время: %d, Осталось: %d^n", name, authid, get_player_money(id), iTime, TimeRemaining);
client_print_color(id, print_team_red, "%s ^3Следующую покупку можно совершить через ^4%d^3 сек., осталось подождать ^4%d^3 сек.", prefix, iTime, TimeRemaining);
return PLUGIN_HANDLED;
 }
 GoMenu(id);
return PLUGIN_HANDLED;
}
GoMenu(id) {
new iPlayerMoney = get_player_money(id);
new NumLimit, szTitle[128], szItem[128], iDiscount, CurrentTime[32];
new NowTime = get_time("%H",CurrentTime,31);

if(is_user_vip(id) || (NowTime >= 15 && NowTime < 17)) {
NumLimit = iMapLimitVip;
iDiscount = g_Discount;
} else {
NumLimit = iMapLimitPlayer;
iDiscount = 0;
}
 new authid[32], name[32];
get_user_authid(id,authid,31);
 get_user_name(id,name,31);
 formatex(szTitle, charsmax(szTitle), "\wБаланс: \r$%d \w| Скидка: \r%d%%^n\wПокупок за карту: \r%d/%d^n", iPlayerMoney, iDiscount, g_MapCounter[id], NumLimit);
new iMenu = menu_create(szTitle, "MenuHandler");
if(menu_pages(iMenu) > 1) {
formatex(szItem, charsmax(szItem), "%s^n\yСтраница: \r", szTitle);
menu_setprop(iMenu, MPROP_TITLE, szItem);
}
 for(new i = 0; i < sizeof(g_ItemList); i++) {
new iCost = g_ItemList[i][ItemCost] - g_ItemList[i][ItemCost] * iDiscount / 100;
 new iTeam = g_ItemList[i][ItemTeam];
 new szNum[3];
num_to_str(i, szNum, charsmax(szNum));
formatex(szItem, charsmax(szItem), "^n\w%s [ \y$%d \w]", g_ItemList[i][ItemName], iCost);
if(iTeam == 0 && iPlayerMoney >= iCost)
menu_additem(iMenu, szItem, szNum);
else if(iTeam == 1 && get_member(id, m_iTeam) == CS_TEAM_T && iPlayerMoney >= iCost)
menu_additem(iMenu, szItem, szNum);
else if(iTeam == 0 || iTeam == 2 && get_member(id, m_iTeam) == CS_TEAM_CT && iPlayerMoney >= iCost)
menu_additem(iMenu, szItem, szNum);
}
 menu_setprop(iMenu, MPROP_BACKNAME, "\yНазад");
menu_setprop(iMenu, MPROP_NEXTNAME, "\yДалее");
 menu_setprop(iMenu, MPROP_EXITNAME, "\rЗакрыть");
 menu_display(id, iMenu);
return PLUGIN_HANDLED
}
public MenuHandler(id, iMenu, iItem) {
if(!is_user_alive(id) || iItem == MENU_EXIT) {
menu_destroy(iMenu);
return PLUGIN_HANDLED;
}
 new iDiscount, CurrentTime[32];
new iPlayerMoney = get_player_money(id);
new NowTime = get_time("%H",CurrentTime,31);
if(is_user_vip(id) || (NowTime >= 15 && NowTime < 17)) iDiscount = g_Discount;
else iDiscount = 0;
new iCost = g_ItemList[iItem][ItemCost] - g_ItemList[iItem][ItemCost] * iDiscount / 100;
 new iTeam = g_ItemList[iItem][ItemTeam];
 if(iItem != MENU_EXIT) {
if(iTeam == 0 && iPlayerMoney >= iCost)
GiveItem(id, iItem);
else if(iTeam == 1 && get_member(id, m_iTeam) == CS_TEAM_T && iPlayerMoney >= iCost)
GiveItem(id, iItem);
else if(iTeam == 0 || iTeam == 2 && get_member(id, m_iTeam) == CS_TEAM_CT && iPlayerMoney >= iCost)
GiveItem(id, iItem);
else menu_destroy(iMenu);
}
 return PLUGIN_HANDLED;
}
GiveItem(id, i) {
 new iAmmo = g_ItemList[i][ItemAmmo];
 new iDiscount, CurrentTime[32], sysTime = get_systime();
new NowTime = get_time("%H",CurrentTime,31);
if(is_user_vip(id) || (NowTime >= 15 && NowTime < 17)) iDiscount = g_Discount;
else iDiscount = 0;
 new iCost = g_ItemList[i][ItemCost] - g_ItemList[i][ItemCost] * iDiscount / 100;
 switch(g_ItemList[i][ItemCase]) {
case 'n': {
rg_give_item(id, g_ItemList[i][ItemGive]);
rg_set_user_bpammo(id, rg_get_weapon_info(g_ItemList[i][ItemGive], WI_ID), iAmmo);
rg_add_account(id, get_player_money(id) - iCost, AS_SET);
g_RoundCounter[id]++;
g_MapCounter[id]++;
g_NowUsed[id] = sysTime;
log_to_file("addons\amxmodx\logs\nade.txt", "^nCase: %s, Name: %s^nItem: %s, Ammo: %d, Cost: %d^nBalance: $%d^n", g_ItemList[i][ItemCase], g_ItemList[i][ItemName], g_ItemList[i][ItemGive], g_ItemList[i][ItemAmmo], iCost, get_player_money(id));
client_print_color(id, print_team_red, "%s ^3Вы успешно купили ^4%s", prefix, g_ItemList[i][ItemName]);
}
case 'w': {
rg_remove_item(id, g_ItemList[i][ItemGive], true);
new iWpn = rg_give_item(id, g_ItemList[i][ItemGive], GT_REPLACE);
if(is_nullent(iWpn)) return;
set_member(iWpn, m_Weapon_iClip, iAmmo);
rg_set_user_bpammo(id, rg_get_weapon_info(g_ItemList[i][ItemGive], WI_ID), 0);
rg_add_account(id, get_player_money(id) - iCost, AS_SET);
g_RoundCounter[id]++;
g_MapCounter[id]++;
g_NowUsed[id] = sysTime;
log_to_file("addons\amxmodx\logs\weapon.txt", "^nCase: %s, Name: %s^nItem: %s, Ammo: %d, Cost: %d^nBalance: $%d^n", g_ItemList[i][ItemCase], g_ItemList[i][ItemName], g_ItemList[i][ItemGive], g_ItemList[i][ItemAmmo], iCost, get_player_money(id));
client_print_color(id, print_team_red, "%s ^3Вы успешно купили ^4%s", prefix, g_ItemList[i][ItemName]);
}
}
}
 
Сообщения
111
Реакции
26
Здравия, ребята!
Подскажите, пожалуйста, почему не работает функция срабатывания флешки о поверхность и какой функцией от ReAPI можно все это заменить?
Вот часть кода, который я использую:
Код:
RegisterHam(Ham_Touch, "grenade", "fw_touch")
public bool:is_solid(ent) return ( ent ? ( (entity_get_int(ent, EV_INT_solid) > SOLID_TRIGGER) ? true : false ) : true );
public fw_touch(toucher, touched) {
if(!pev_valid(toucher) || get_member(toucher, m_iId) != WEAPON_FLASHBANG) return HC_CONTINUE;
if(is_solid(touched)) {
// make_explode(toucher);
// entity_set_float(toucher, EV_FL_nextthink, 0.001);
set_pev(toucher, pev_dmgtime, 0.0);
}
 return HC_CONTINUE;
}
 
Сообщения
432
Реакции
409
Помог
14 раз(а)
Тач работает только на энтити, если нужна коллизия с картой - FM_ShouldCollide
 
  • Нравится
Реакции: Ayk
Сообщения
1,419
Реакции
2,508
Помог
59 раз(а)
MIRDOBRO777, весь код, как и тот что до этого, без пробелов и табуляции, какой-то скрытый замысел в этом? Читабельность кода на нуле.
 
Сообщения
111
Реакции
26
voed, спасибо за подсказку! Работает.
Но я хочу, чтобы только флешка так срабатывала и сделал вот такую проверку:
if(GetGrenadeType(toucher) != CSW_FLASHBANG) return HC_CONTINUE;
При компиляции ругается "Warning 213" на данную строку.
В чем несовпадение аргументов?
w0w, я незрячий и мне удобнее так перемещаться по коду. Извините, что визуально выглядит некрасиво...
 
Сообщения
111
Реакции
26
Приветствую, ребята!
Подскажите, пожалуйста, как из массива взять нужную строку.
Вот, например, массив:
Код:
enum _:MassData { SID[32], DATE[16], NUM }
new const g_Massive[][MassData] = {
{ "STEAM_0:0:987654321", "31.12.2020", 5 },
{ "STEAM_0:0:123456789", "29.02.2020", 10 }
};
После нужно из данного массива, пробежась по нему, выбрать ту строку, в которой совпадет STEAM_ID игрока на сервере со STEAM_ID из массива:
Код:
 get_user_authid(id, szSteamID[id], charsmax(szSteamID));
 for(new i = 0; i < sizeof(g_Massive); i++) {
if(equal(szSteamID[id], "g_Warning[i][SID]")) {
выполняю функцию
}
}
При совпадении айдишников в функции отображает все содержимое массива, а мне надо отсеять только одну строку, которая совпала по требуемым характеристикам. В моем случае - это совпадение STEAM_ID-шников.
Например, выводить в MOTD информацию из строки массива о игроке, который по STEAM_ID прошел проверку. А мне выводит, пока что в логи, все строки массива.
Вроде описал доступно проблему.
 
Сообщения
111
Реакции
26
fantom,
А как правильно сравнить STEAM_ID из массива с айди игрока?
Потому что такое сравнение не катит. Не пойму как извлечь из массива текст, с числами проще, поставил знак "=" и можно работать дальше.
 
Сообщения
111
Реакции
26
Nordic Warrior,
я так и сравниваю (выше пример из кода), но проверка не проходит. В чем причина?
if(equal(szSteamID[id], "g_Warning[i][SID]")) {
Извиняюсь, что не заметил сообщение выше. Уже подсказали; причина в кавычках.
Спасибо вам, ребята, за подсказки!
 
Последнее редактирование:
Сообщения
111
Реакции
26
Приветствую!
Решил попробовать поработать с системой "nvault", но снова проблемы.
Ниже с комментариями написал части кода.
Проблема заключается, что не записывает и не считывает данные. Где косяк, подскажите, пожалуйста.
Регистрация переменных:
new g_Vault, UserData[MAX_PLAYERS+1];
Открытие файла и считывание очков игрока при коннекте по его СТИМ_ИД:
Код:
public plugin_init() {
g_Vault = nvault_open(VAULT_NAME);
}
public client_putinserver(id) {
if(is_user_bot(id) || is_user_hltv(id)) return;
 get_user_authid(id, szSteamId, charsmax(szSteamId))
 nvault_get(g_Vault, szSteamId, UserData[id]);
log_to_file("addons\amxmodx\logs\points_connected.txt", "^n%d^n", UserData[id]);
}
Выполнение функции плагина и запись в файл очков:
Код:
public Roll(const id) {
new iRandom = random(100), iReward, name[32], szLogGame[256];
 get_user_name(id, name, charsmax(name));
 new szDir[] = "addons/amxmodx/logs/game";
if(!dir_exists(szDir)) mkdir(szDir);
for(new i = 0; i < sizeof(g_szSpecialChars); i++ ) {
if(contain(name, g_szSpecialChars[i]))
replace_all(name, charsmax(name), g_szSpecialChars[i], "");
trim(name);
}
formatex(g_szLogFile, charsmax(g_szLogFile), "%s/%s.log", szDir, name);
new szName[32]; get_user_name(id, szName, charsmax(szName));
formatex(szLogGame, charsmax(szLogGame), "^nНик игрока: %s, %s^n", szName, szSteamId);
 if(!file_exists(g_szLogFile)) write_file(g_szLogFile, szLogGame);
 if(iRandom == 0 || iRandom == 50 && SelectPlayer[id] == 3) {
UserData[id]++;
iReward = g_Bet[id] * 9;
rg_add_account(id, get_player_money(id) + iReward, AS_SET);
client_print_color(id, print_team_red, "%s ^4Поздравляем! На этот раз Вы угадали совпадение выпавшего числа: ^3%d", prefix, iRandom);
formatex(szLogGame, charsmax(szLogGame), "Ставка: %d, Баланс: %d^nЧисло: %d [Zero], %d^n", g_Bet[id], get_player_money(id), iRandom, SelectPlayer[id]);
}
else if(iRandom < 50 && SelectPlayer[id] == 1) {
UserData[id]++;
iReward = g_Bet[id] * 1;
rg_add_account(id, get_player_money(id) + iReward, AS_SET);
client_print_color(id, print_team_red, "%s ^4Поздравляем! На этот раз Вы угадали совпадение выпавшего числа: ^3%d", prefix, iRandom);
formatex(szLogGame, charsmax(szLogGame), "Ставка: %d, Баланс: %d^nЧисло: %d [Low], %d^n", g_Bet[id], get_player_money(id), iRandom, SelectPlayer[id]);
}
else if(iRandom >= 51 && SelectPlayer[id] == 2) {
UserData[id]++;
iReward = g_Bet[id] * 1;
rg_add_account(id, get_player_money(id) + iReward, AS_SET);
client_print_color(id, print_team_red, "%s ^4Поздравляем! На этот раз Вы угадали совпадение выпавшего числа: ^3%d", prefix, iRandom);
formatex(szLogGame, charsmax(szLogGame), "Ставка: %d, Баланс: %d^nЧисло: %d [Hi], %d^n", g_Bet[id], get_player_money(id), iRandom, SelectPlayer[id]);
} else {
client_print_color(id, print_team_red, "%s ^3Увы, но на этот раз Вы не угадали совпадение выпавшего числа: ^4%d", prefix, iRandom);
rg_add_account(id, get_player_money(id) - g_Bet[id], AS_SET);
UserData[id]--;
formatex(szLogGame, charsmax(szLogGame), "Ставка: %d, Баланс: %d^nЧисло: %d [Fail], %d^nОчков: %d^n", g_Bet[id], get_player_money(id), iRandom, SelectPlayer[id], UserData[id]);
}
log_to_file("addons\amxmodx\logs\points.txt", "^n%d^n", UserData[id]);
nvault_set(g_Vault, szSteamId, UserData[id]);
 write_file(g_szLogFile, szLogGame);

return PLUGIN_HANDLED;
}
Смена карты и закрытие файла:
Код:
public plugin_end() {
if(g_Vault != INVALID_HANDLE) nvault_close(g_Vault);
}
 
Сообщения
111
Реакции
26
Доброго времени!
Подскажите, пожалуйста, возможно в новой системе меню при наличии 2-х и более страниц, после нажатия любого из пунктов на 2-ой или 3-ей страницах, возвращать игрока не на первую страницу меню, а на ту, в которой был нажат пункт?
У меня есть меню с двумя страницами.
В том меню игроки производят настройки под себя, т.е нажимают на пункт и он меняет ВКЛ. на ОТКЛ. и наоборот.
После нажатия пункта на второй странице, я возвращаю игрока в меню, но возврат происходит на первую страницу.
Возможно сделать возврат на вторую страницу после нажатия пункта?
 
Сообщения
111
Реакции
26
BlackSignature, еще вопросик. А есть возможность проверки на какой странице был нажат пункт?
 
Сообщения
111
Реакции
26
Доброго времени!
Ребята, объясните, пожалуйста, как можно получить имя файла из папки, которое было нажато на определенном пункте меню.
Т.е. вот эта строка:
formatex(MotdFile, charsmax(MotdFile), "addons\amxmodx\logs\users\%s.log", имя выбранного файла из меню);
Я проверяю папку на наличие файлов логов, после строю меню и когда админ нажимает определенный пункт меню, то мне надо показать мотд окно именно с тем файлом, который он выбрал.
Как такое можно сделать?
Помогите, пожалуйста. Код визуально трудно читабелен. Простите, что так пишу.
Вот код плагина (я не знаю где надо расставлять TAB на каждой строке, просто мне так удобно перемещаться по коду с помощью стрелок):
Код:
#include <amxmodx>
public plugin_init() {
 register_plugin("Logs Menu", "1.0", "MIRDOBRO777");
 register_clcmd("say /s", "Command_ShowLogsMenu");
}
public Command_ShowLogsMenu(id) {
if(!(get_user_flags(id) & ADMIN_LEVEL_B)) {
client_print_color(id, print_team_red, "^1[^4LOGS^1] ^3У Вас нет доступа к данному меню");
return PLUGIN_HANDLED;
}
 new szTitle[128], szItem[64];
formatex(szTitle, charsmax(szTitle), "\yМеню логов подключений игроков^n");
new iMenu = menu_create(szTitle, "MenuHandler");
if(menu_pages(iMenu) > 1) {
formatex(szItem, charsmax(szItem), "%s^n\yСтраница: \r", szTitle);
menu_setprop(iMenu, MPROP_TITLE, szItem);
}
 new logName[32], lenLogName;
new dir = open_dir("addons\amxmodx\logs\users", logName, charsmax(logName));
if(dir) {
while(next_file(dir, logName, charsmax(logName))) {
lenLogName = strlen(logName);

if(lenLogName > 4 && equali(logName[lenLogName - 4], ".log", 4)) {
 logName[lenLogName-4] = '^0'
 formatex(szItem, charsmax(szItem), "\w%s", logName);
new szNum[3];
num_to_str(lenLogName, szNum, charsmax(szNum));
menu_additem(iMenu, szItem, szNum);
}
}

close_dir(dir);
}
 menu_setprop(iMenu, MPROP_BACKNAME, "\yНазад");
menu_setprop(iMenu, MPROP_NEXTNAME, "\yДалее");
 menu_setprop(iMenu, MPROP_EXITNAME, "\rЗакрыть");
 menu_display(id, iMenu);
return PLUGIN_HANDLED
}
public MenuHandler(id, iMenu, iItem) {
if(iItem == MENU_EXIT) {
menu_destroy(iMenu);
return PLUGIN_HANDLED ;
}
 new MotdFile[64];
formatex(MotdFile, charsmax(MotdFile), "addons\amxmodx\logs\users\%s.log", имя выбранного файла из меню);
show_motd(id, MotdFile, "Логи подключений");
return PLUGIN_HANDLED;
}
 

Пользователи, просматривающие эту тему

Сейчас на форуме нет ни одного пользователя.
Сверху Снизу