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

Сообщения
112
Реакции
26
Ребята, всем здравствуйте!
По совету создаю тему на форуме по обучению скриптингу.
И вот столкнулся с проблемой с массивом. Я вообще не лажу с ними.
Скопировал код из другого плагина, в котором данная функция (только массив) использовалась на рандом в сообщении, а мне надо, чтобы выбирало случайное значение из массива и подставляло под созданную переменную.
Вот часть кода с которым возникла проблема:
Код:
new const g_szMass[4][] = {
    "40",
    "50",
    "60",
    "70"
}
    if(g_Func == 2) iValue = g_szMass[random(sizeof(g_szMass))];
При попытке скомпилить ругается на строку с проверкой (error 006), то есть просит, что значение моей переменной должно равняться массиву.
Вот это должно быть массивом:
g_szMass[random(sizeof(g_szMass))];
Пытался найти инфу, но не нашел да и сложновато мне искать.
Поэтому снова прибегаю к вам за помощью.
 

Ayk

Сообщения
763
Реакции
476
Помог
19 раз(а)
1. new const g_szMass[4][] = {
можно написать как
new const g_szMass[][] = {
что позволит добавлять/удалять элементы массива не получая ошибки компиляции забыв подстроить размер массива.
Компилятор сам подберет нужный размер.
2. sizeof это оператор языка. Используется как sizeof g_szMass. Вернёт размер массива. В примере выше = 4.
3. Если часть кода не ясна, часто помогает разделить код на части по меньше, на составляющие.
iValue = g_szMass[random(sizeof(g_szMass))];
iValue = присвоение значения переменной типа инт
g_szMass[ ] обращение к ячейке массива (в данном случае, к ячейке содержащей массив, ибо двумерный массив. результат = массив ! )
random( ) - функция вернет случайное число между 0 (включительно) и параметром (исключительно).
sizeof g_szMass - во время компиляции будет заменен на размер массива (по факту).
Что в итоге?
рандом вернет число между 0 и 3, но вот обращение к массива вида g_szMass[0] вернет массив (строку) потому что g_szMass[][] двумерный массив.
А такое присвоение массива к инт переменной недопустимо.

Тебе нужно сделать так:
Код:
new const g_szMass[][] =
{
    "40",
    "50",
    "60",
    "70"
}

new szValue[4]
copy( szValue, charsmax(szValue), g_szMass[random(sizeof g_szMass)] )
new iValue = str_to_num( szValue ) // перевод строки в число
или же, сразу иметь массив чисел:
Код:
new const g_Mass[] =
{
    40,
    50,
    60,
    70
}
 
Сообщения
141
Реакции
201
Помог
5 раз(а)
а мне надо, чтобы выбирало случайное значение из массива и подставляло под созданную переменную.
сделай массив из чисел, а не из строк
конечно, можешь приколоться и получить числовое значение из строки при помощи str_to_num:
iValue = str_no_num(g_szMass[random(sizeof(g_szMass))]);
 
Сообщения
112
Реакции
26
Допер как создавать числовой массив и использовать его.
Спасибо, кто откликнулся.
Вот так переделал:
Код:
    new const g_szMass[] = { 40, 50, 60, 70 }
    new szValue = g_szMass[random(sizeof g_szMass)];
Правильно сделал? Будет брать из массива случайное число и подставлять в мою переменную?
 
Сообщения
141
Реакции
201
Помог
5 раз(а)
проверь))0
 
Сообщения
112
Реакции
26
Массив работает правильно.
У меня возникли еще несколько вопросов:
"- Стоит ли искать замену функциям других модулей на функции ReAPI и чем ReAPI в таком случае лучше по функционалу?

Вот список функций, которые возможно заменить на аналогичные ReAPI?
Модуль "<fakemeta_util>":
set_pev(id, pev_velocity, Float:{ 0.0, 0.0, 350.0 });
fm_set_rendering(id, kRenderFxNone, 0,0,0,kRenderNormal, 255);
if(user_has_weapon(id, CSW_SCOUT)) fm_strip_user_gun(id, CSW_SCOUT);
Модуль "<engine>":
find_sphere_class(id, "func_ladder", 18.0, name, 1)
entity_set_string(id, EV_SZ_viewmodel, "");
А вот функция гравитации модуля "<fakemeta_util>":
set_pev(id, pev_gravity, -2.0);
Будет аналогичная от ReAPI работать с отрицательным значением:
set_entvar(id, var_gravity, 1.00); ?
 

Ayk

Сообщения
763
Реакции
476
Помог
19 раз(а)
Стоит ли искать замену функциям других модулей на функции ReAPI
В основном ответ будет - нет. Для многого даже аналога не сделали, пример set_user_health().
чем ReAPI в таком случае лучше по функционалу?
Имеет то чего нет в других модулях.
Вот список функций, которые возможно заменить на аналогичные ReAPI?
Если речь о прямом изменении свойства, к примеру set_pev(id, pev_velocity, Float:{ 0.0, 0.0, 350.0 }); , то менять не стоит.
А вот, к примеру, fm_strip_user_gun(id, CSW_SCOUT); следует изменить на rg_ аналог.
Все зависит от конкретного случая.
 
Сообщения
1,668
Реакции
1,495
Помог
24 раз(а)
В основном ответ будет - нет. Для многого даже аналога не сделали, пример set_user_health().
Чо ты врешь? var_health.
Не стоит забыть, что оно плавающее.

Если речь о прямом изменении свойства, к примеру set_pev(id, pev_velocity, Float:{ 0.0, 0.0, 350.0 });, то менять не стоит.
Пора уже выпиливать это дерьмецо и юзать нормальный модуль.

Вот список функций, которые возможно заменить на аналогичные ReAPI?
Да, все можно поменять.
 
Сообщения
112
Реакции
26
В основном ответ будет - нет. Для многого даже аналога не сделали, пример set_user_health().
Я выдаю здоровье вот так:
Код:
#define set_player_health(%1,%2)    set_entvar(%1, var_health, %2)
    new Float:FloatIncreaseHealth = float(g_IncreaseHealth), Float:FloatPlayerMaxHealth = float(iPlayerMaxHealth);
    if((Float:get_entvar(id, var_health) + FloatIncreaseHealth) >= FloatPlayerMaxHealth)
    set_player_health(id, FloatPlayerMaxHealth);
    else set_entvar(id, var_health, Float:get_entvar(id, var_health) + FloatIncreaseHealth);
Если речь о прямом изменении свойства, к примеру set_pev(id, pev_velocity, Float:{ 0.0, 0.0, 350.0 }); , то менять не стоит.
Данная функция работает в связке с отрицательной гравитацией о которой я тоже спрашивал.
А вот, к примеру, fm_strip_user_gun(id, CSW_SCOUT); следует изменить на rg_ аналог.
В данном случае мне необходимо проверять наличие данного типа оружия в инвентаре игрока и, в случае обнаружения, отбирать, а затем выполнять функцию по выдаче нового оружия с заранее заданными настройками.
Например, отобрать скаут и выдать заново с одним патроном. Если не проводить проверку на уже наличие данного оружия в инвентаре, то просто докупаются патроны и скаут становится с полной обоймой.
12 Авг 2019
Да, все можно поменять.
Если не затруднит, то можете написать замену или ссылки на них (функции).
 

Ayk

Сообщения
763
Реакции
476
Помог
19 раз(а)
Чо ты врешь? var_health.
О чём ты? Я же явно указал, что не сделали аналога в виде функции!
И до РеАПИ был pev_health , но все юзали get/set_user_health().

Ну а так, да, я согласен, старьё не нужно.

В данном случае мне необходимо проверять наличие данного типа оружия в инвентаре игрока и, в случае обнаружения, отбирать, а затем выполнять функцию по выдаче нового оружия с заранее заданными настройками.
Например, отобрать скаут и выдать заново с одним патроном. Если не проводить проверку на уже наличие данного оружия в инвентаре, то просто докупаются патроны и скаут становится с полной обоймой.
Не отбирай если он нужен. Сразу установи нужное количество патрон, и в обойму и в запас.
 
Сообщения
112
Реакции
26
Не отбирай если он нужен. Сразу установи нужное количество патрон, и в обойму и в запас.
В том-то и дело, что есть необходимость в проверке и отборе именно определенного оружия.
Мне надо выдавать оружие всего только с одним патроном, а если у игрока это оружие есть, то через меню магазина он просто докупит полную обойму.
Вот пример полной покупки оружия:
Код:
    if(user_has_weapon(id, CSW_AK47)) fm_strip_user_gun(id, CSW_AK47);
    new iAK47 = give_item(id, "weapon_ak47");
    cs_set_user_bpammo(id,CSW_AK47,0);
    cs_set_weapon_ammo(iAK47, random(2));
Это не переделанный код под ReAPI, поэтому и выдача оружия через другой модуль.
Суть я объяснил вроде. И Вы можете подсказать аналоги на ReAPI или ссылки на них (тот список, что я указывал выше).
 
Сообщения
2,143
Реакции
1,223
Помог
44 раз(а)
О чём ты? Я же явно указал, что не сделали аналога в виде функции!
И до РеАПИ был pev_health , но все юзали get/set_user_health().
Сделай сам. В чем проблема? get/set_user_health() работает по аналогичному принципу pev_health и var_health.
 
Сообщения
2,491
Реакции
2,790
Помог
61 раз(а)
Да, все можно поменять.
ну не совсем все. Да и реапи не создавался как полная универсальная замена всем модулям (engine, fakemeta, hamsandwich).

А так в целом согласен. Если юзается уже реапи, то я точно бы менял все pev_* на var_*. И много нативов в амхх, fun и engine по сути делают set/get_entvar и set/get_member. Явный пример get/set_user_health

В данном случае мне необходимо проверять наличие данного типа оружия в инвентаре игрока и, в случае обнаружения, отбирать, а затем выполнять функцию по выдаче нового оружия с заранее заданными настройками.
Например, отобрать скаут и выдать заново с одним патроном. Если не проводить проверку на уже наличие данного оружия в инвентаре, то просто докупаются патроны и скаут становится с полной обоймой.
https://dev-cs.ru/amxx/reapi_gamedll/rg_remove_item/view. В описанном вами случае можно просто вызвать удаление без какой либо проверки. Пусть модуль займется этим за вас.

И до РеАПИ был pev_health , но все юзали get/set_user_health().
Ну тут уже все зависит от скриптера. Юзали наверно потjмоу, что не хотели подрубать фм модуль в плагин. Не знаю точно. Но по сути одно и то же одно и то же. Но заглянув в натив я заметил что он еще умеет убивать при отрицательном значении ))))
 
Сообщения
112
Реакции
26
Ребята, спасибо за подсказки!
Я вот и начал с функции, на которую ответили большей информацией.
Сделал выдачу оружия с отбиранием.
Задумал сделать выдачу случайного итема из массива, но... снова массив.
Вот код:
Код:
#include <amxmodx>
#include <reapi>

enum _:WEAPONS_DATA { ITEM_CASE[10], ITEM_NAME[20], VALUE_AMMO };
new g_ItemList[][WEAPONS_DATA] = {
    { "weapon", "weapon_deagle", 5 },
    { "nade", "weapon_hegrenade", 10 },
    { "nade", "weapon_flashbang", 0 },
    { "nade", "weapon_smokegrenade", 0 }
};

public plugin_init() {
    register_plugin("Testing", "1.0", "Admin");
    register_clcmd("say /r", "@Test");
}

@Test(id) {
    for(new i; i < sizeof g_ItemList; i++) {
    new iS = random(i);
    GiveItem(id, g_ItemList[iS][ITEM_CASE], g_ItemList[iS][ITEM_NAME], g_ItemList[iS][VALUE_AMMO]);
}
}

GiveItem(id, szCase[], szItem[], iValue) {
    switch(szCase[0]) {
    case 'n': {
    rg_give_item(id, szItem, iValue < 3 ? GT_APPEND : GT_REPLACE);
    rg_set_user_bpammo(id, rg_get_weapon_info(szItem, WI_ID), iValue);
}
    case 'w': {
    rg_remove_item(id, szItem, true);
    new iWpn = rg_give_item(id, szItem);
    set_member(iWpn, m_Weapon_iClip, random(iValue));
}
}
}
В логах ругается на вот эту строку (смещение строк из-за удаления лишнего из кода):
GiveItem(id, g_ItemList[iS][ITEM_CASE], g_ItemList[iS][ITEM_NAME], g_ItemList[iS][VALUE_AMMO]);
L 08/12/2019 - 22:23:47: [AMXX] Run time error 4: index out of bounds
L 08/12/2019 - 22:23:47: [AMXX] [0] s.sma::@Test (line 29)

Соответственно ничего рандомного из массива не выдает.
Я понимаю, что начудил с кодом рандома, но не пойму как правильно задать одну случайную строку для выдачи.
 

Ayk

Сообщения
763
Реакции
476
Помог
19 раз(а)
Код:
    for(new i; i < sizeof g_ItemList; i++) {
    new iS = random(i);
    GiveItem(id, g_ItemList[iS][ITEM_CASE], g_ItemList[iS][ITEM_NAME], g_ItemList[iS][VALUE_AMMO]);
}
Ты проходишь циклом по всему массиву. Так в чем смысл рандома?
Если хочешь выдать только 1 рандомное оружие из массива - убирай цикл. А если всё оружие из массива - убирай рандом.
 
Сообщения
112
Реакции
26
Если хочешь выдать только 1 рандомное оружие из массива - убирай цикл. А если всё оружие из массива - убирай рандом.
Убрал цикл, изменив код:
Код:
    new iS = g_ItemList[random(sizeof(g_ItemList))];
    GiveItem(id, g_ItemList[iS][ITEM_CASE], g_ItemList[iS][ITEM_NAME], g_ItemList[iS][VALUE_AMMO]);
Но он теперь при компиляции ругается на неизвестный массив (error 033) на строку:
new iS = g_ItemList[random(sizeof(g_ItemList))];
 
Последнее редактирование модератором:

Ayk

Сообщения
763
Реакции
476
Помог
19 раз(а)
new iS = g_ItemList[random(sizeof(g_ItemList))];
И опять же, это как раз то, что обсуждалось в начале темы.
Обращение к первому dimension у 2-dimendions array возвращает массив(!!)(в данном примере), который нельзя присвоить инт переменой.

Код:
-    new iS = g_ItemList[random(sizeof(g_ItemList))];
+    new iS = random(sizeof g_ItemList);
    GiveItem(id, g_ItemList[iS][ITEM_CASE], g_ItemList[iS][ITEM_NAME], g_ItemList[iS][VALUE_AMMO]);
 
Последнее редактирование:

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

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