Обучение Скриптингу Skiptik

Сообщения
95
Реакции
6
Помог
2 раз(а)
Добрый день, создал топик своего обучения. Adidasman, дал добро.

Всем кто хочет помочь в этом не простом деле, заранее благодарен.
Код:
#include <amxmodx>
#include <cstrike>

#define Version "1.0"

enum _:ItemShop{
    ItemName[64],
    ItemCost = 0
}

enum _: ForwardData{
    iResult,
    iSelected
}

new Array:Items, iShopItem[ItemShop], iForwards[ForwardData];

public plugin_init(){
    register_plugin("Shop System", Version, "Skiptik");
    register_clcmd("say /shopmenu", "Show_ShopMenu");
    iForwards[iSelected] = CreateMultiForward("iSelected", ET_CONTINUE, FP_CELL, FP_CELL);
    Items = ArrayCreate(ItemShop, 1);
}

public Show_ShopMenu(id){
    new ItemSize = ArraySize(Items);
    if(!ItemSize){
        client_print(id, print_chat, "В магазине нет предметов");
        return PLUGIN_HANDLED;
    }
    new iMenu = menu_create("Выбирите магазин", "Handle_ShopMenu");
    new FormatItem[64];
    for(new i = 0; i < ItemSize; i++)
    {
        ArrayGetArray(Items, i, iShopItem)
        if(cs_get_user_money(id) >= iShopItem[ItemCost])
        {
            formatex(FormatItem, 63, "%s \y%d", iShopItem[ItemName], iShopItem[ItemCost]);
            menu_additem(iMenu, FormatItem);
        }else{
            formatex(FormatItem, 63, "%s \y%d",iShopItem[ItemName], iShopItem[ItemCost]);
            menu_addtext(iMenu, FormatItem);
        }
    }
    menu_display(id, iMenu, 0);
    return PLUGIN_HANDLED;
}

public Handle_ShopMenu(id, menu, item)
{
    menu_destroy(menu);
    if(item == MENU_EXIT) {
        return;
    }
    ExecuteForward(iForwards[iSelected], iForwards[iResult], id, item)
}

public plugin_natives()
{
    register_native("RegisterItem", "NativeRegisterItem", 1)
}

public NativeRegisterItem(plugin, params)
{
    enum {
        Name = 1,
        Cost
    };
    get_string(Name, iShopItem[ItemName], charsmax(iShopItem[ItemName]));
    iShopItem[ItemCost] = get_param(Cost);
    ArrayPushArray(Items, iShopItem);
    return ArraySize(Items) - 1;
}
У меня есть пару вопрос в реализации. Планирую сделать классы предметов, но возникает вопрос, как добавить эти самые классы при регистрации Item'a, и сделать автоматическое создание меню с этим классом если таков отсутствует.
9 Янв 2019
Код:
#include <amxmodx>

#define Version "1.0"

enum _: MenuItem{
    MenuName,
    HandleName
}

new Array:ItemsMenu, iMenuItem[MenuItem]

public plugin_init(){
    register_plugin("Menu System", Version, "Skiptik");
    ItemsMenu = ArrayCreate(MenuItem, 1);
}

public
Набросал кода чуток, и тут возник вопрос что писать в переменную public при регистрации меню ведь например Show_%s, MenuName не сделаешь..
9 Янв 2019
Код:
public CreateMenu(id){
    new iMenu = menu_create("%s", "Handle_%s", iMenuItem[MenuName], iMenuItem[HandleName]);
    menu_display(id);
    return PLUGIN_HANDLED;
}
 
Последнее редактирование:
Сообщения
95
Реакции
6
Помог
2 раз(а)
Эх, жаль что ни кто не откликнулся, можете закрыть тему.
 
Сообщения
1,277
Реакции
2,259
Помог
57 раз(а)
У меня есть пару вопрос в реализации. Планирую сделать классы предметов, но возникает вопрос, как добавить эти самые классы при регистрации Item'a, и сделать автоматическое создание меню с этим классом если таков отсутствует.
Нет условий, чтобы описать наиболее подходящий вариант реализации. Предложу вариант попроще, с использованием хардкода. Если нужна полная масштабируемость, вариант не подойдёт.

Допустим классы перечислены в энумерации ENUM (хардкод отдельным индклюдом где мы заодно можем расписать апи).
Структура итемов: "имя предмета" класс

Создаём основное меню, пункты это наши классы, от первого до последнего.
Создаём по динмассиву на каждый класс (точное кол-во динмассивов мы значем благодаря ENUM)
Создаём вторичное меню, оно будет фомировать список из элементов указанного массива с предметами.
Грузим предметы из конфига/через апи из других плагинов в динмассивы, используя класс как указатель, в какой массив помещать каждый конкретный предмет

При нажатии на пункт в основном меню открываем вторичное меню (меню класса) где перечисляем предметы данного класса от первого до последнего, выбирая циклом динмассив соотвествующий данному классу.
 
Последнее редактирование:
Сообщения
95
Реакции
6
Помог
2 раз(а)
BlackSignature, Именно так у меня в голове я представлял это, буду пробовать может создам что нибудь:D
Допустим классы перечислены в энумерации ENUM (хардкод отдельным индклюдом где мы заодно можем расписать апи).
Структура итемов: "имя предмета" класс

Создаём основное меню, пункты это наши классы, от первого до последнего.
Создал пункты меню с классами вот что получилось
Код:
#include <amxmodx>

#define Version "1.0"

enum _: ClassTypes {
    NameClass[80],
    ClassItems
}
new cWeapon
#define ClassCount 1
new const Class[ClassCount][ClassTypes] = {
    { "Холодное оружие", cWeapon },
    { "Огнестрельное", cWeapon }
}

public plugin_init(){
    register_plugin("Menu System", Version, "Skiptik");
    register_clcmd("say /menushop", "Show_ShopMenu");
}

public Show_ShopMenu(id){
    new iMenu =  menu_create("Выбирите пункт", "Handle_ShopMenu");
    for(new i; i < sizeof Class; i++) {
        new sData[128];
        formatex(sData, 63, "%s^n", Class[i]);
        menu_additem(iMenu, sData);
    }
}
Но есть не большая ошибка (12) : error 008: must be a constant expression; assumed zero
(13) : : warning 203: symbol is never used: ""
 
Последнее редактирование:

Garey

ninjaCow
Сообщения
417
Реакции
1,055
Помог
10 раз(а)
new cWeapon >> const cWeapon
 
Сообщения
95
Реакции
6
Помог
2 раз(а)
Garey, Изменил на new const cWeapon ошибки остались все те же, изменял как вы написали там вот ошибки
1547399441684.png
1547399467902.png
 
Последнее редактирование:

Garey

ninjaCow
Сообщения
417
Реакции
1,055
Помог
10 раз(а)
надо задать значение const cWeapon ~_~ P.S. вы уверены что вы не будете изменять значения в массиве "Class"? если не уверены то невижу смысла использовать "new const"
 
Сообщения
95
Реакции
6
Помог
2 раз(а)
Garey, Все я понял, исправил, спасибо.
14 Янв 2019
15 Янв 2019
Код:
#include <amxmodx>

#define Version "1.0"
#define ClassCount 2
enum _: iClassData{
    ClassName[64],
    ClassId
}

new g_iClassData[ClassCount][iClassData] = {
    static: g_iClassId[];
    g_iClassId[] = g_iClassData[ClassId]
    for(new i; i > g_iClassId; i +1){
        { "Холодное оружие", g_iClassId[i] },
        { "Огнестрельное оружие", g_iClassId[i] }
    }
}

public plugin_init(){
    register_plugin("Menu System", Version, "Skiptik");
    register_clcmd("say /menushop", "Show_ShopMenu");
}

public Show_ShopMenu(id){
    new iMenu =  menu_create("Выбирите пункт", "Handle_ShopMenu");
    for(new i; i < sizeof g_iClassData; i++) {
        new sData[128];
        formatex(sData, 63, "%s^n", g_iClassData[i]);
        menu_additem(iMenu, sData);
    }
}
Пришел к вот такому стилю и логики присвоения id класса, понимаю что не правильно, потому что есть ошибки, но мой мозг пока не смог придумать ни чего умнее этого, если кто направит в нужное русло то буду рад:D
Вот ошибки
(11) : error 029: invalid expression, assumed zero
(13) : error 010: invalid function or declaration
 
Последнее редактирование:
Сообщения
1,277
Реакции
2,259
Помог
57 раз(а)
Где вы понабрались такого? Кошмар!
Код:
new g_iClassData[ClassCount][iClassData] = {
    static: g_iClassId[];
    g_iClassId[] = g_iClassData[ClassId]
    for(new i; i > g_iClassId; i +1){
        { "Холодное оружие", g_iClassId[i] },
        { "Огнестрельное оружие", g_iClassId[i] }
    }
}

Вот пример работы со "структурой". Он не самый удачный, но вы хотя бы поймёте принцип:
Код:
const MAX_KNIFES = 32 // Макс. кол-во ножей. При необходимости увеличить.

#define MENU_NAME_LEN 64
#define CHAT_NAME_LEN 64
#define MDL_PATH_LEN 96
#define SOUND_PATH_LEN 48
#define AUTHID_LEN 24

enum _:KNIFE_DATA_STRUCT {
	KNIFE_DATA__LVL,
	KNIFE_DATA__MENU_NAME[MENU_NAME_LEN],
	KNIFE_DATA__CHAT_NAME[CHAT_NAME_LEN],
	KNIFE_DATA__MDL_V[MDL_PATH_LEN],
	KNIFE_DATA__MDL_P[MDL_PATH_LEN],
	KNIFE_DATA__S_HIT[SOUND_PATH_LEN],
	KNIFE_DATA__S_STAB[SOUND_PATH_LEN],
	KNIFE_DATA__S_HITWALL[SOUND_PATH_LEN],
	KNIFE_DATA__S_SLASH[SOUND_PATH_LEN],
	KNIFE_DATA__S_DEPLOY[SOUND_PATH_LEN]
}

new g_eKnifeData[MAX_KNIFES][KNIFE_DATA_STRUCT]

public plugin_precache() {
	register_plugin("Knife Menu", PLUGIN_DATE, "mx?!")

	new szPath[PLATFORM_MAX_PATH]

	get_localinfo("amxx_configsdir", szPath, chx(szPath))
	format(szPath, chx(szPath), "%s/%s", szPath, KNIFE_CFG_NAME)

	new iFile = fopen(szPath, "r")

	if(!iFile) {
		set_fail_state("Error opening '%s' file!", KNIFE_CFG_NAME)
	}

	new szTextBuffer[512], szLevel[4]

	while(!feof(iFile)) {
		if(g_iLoadedKnifes == MAX_KNIFES) {
			fclose(iFile)
			set_fail_state("Too many knifes! Increase 'MAX_KNIFES' in .sma!")
		}

		fgets(iFile, szTextBuffer, chx(szTextBuffer))

		if(szTextBuffer[0] != '"') {
			continue
		}

		parse( szTextBuffer,
			szLevel, chx(szLevel),
			g_eKnifeData[g_iLoadedKnifes][KNIFE_DATA__MENU_NAME], MENU_NAME_LEN - 1,
			g_eKnifeData[g_iLoadedKnifes][KNIFE_DATA__CHAT_NAME], CHAT_NAME_LEN - 1,
			g_eKnifeData[g_iLoadedKnifes][KNIFE_DATA__MDL_V], MDL_PATH_LEN - 1,
			g_eKnifeData[g_iLoadedKnifes][KNIFE_DATA__MDL_P], MDL_PATH_LEN - 1,
			g_eKnifeData[g_iLoadedKnifes][KNIFE_DATA__S_HIT], SOUND_PATH_LEN - 1,
			g_eKnifeData[g_iLoadedKnifes][KNIFE_DATA__S_STAB], SOUND_PATH_LEN - 1,
			g_eKnifeData[g_iLoadedKnifes][KNIFE_DATA__S_HITWALL], SOUND_PATH_LEN - 1,
			g_eKnifeData[g_iLoadedKnifes][KNIFE_DATA__S_SLASH], SOUND_PATH_LEN - 1,
			g_eKnifeData[g_iLoadedKnifes][KNIFE_DATA__S_DEPLOY], SOUND_PATH_LEN - 1
		);

		g_eKnifeData[g_iLoadedKnifes][KNIFE_DATA__LVL] = str_to_num(szLevel)
		g_iLoadedKnifes++
	}

	fclose(iFile)

	/* --- */

	for(new i; i < g_iLoadedKnifes; i++) {
		precache_model(g_eKnifeData[i][KNIFE_DATA__MDL_V])
		precache_model(g_eKnifeData[i][KNIFE_DATA__MDL_P])
		precache_sound(g_eKnifeData[i][KNIFE_DATA__S_HIT])
		precache_sound(g_eKnifeData[i][KNIFE_DATA__S_STAB])
		precache_sound(g_eKnifeData[i][KNIFE_DATA__S_HITWALL])
		precache_sound(g_eKnifeData[i][KNIFE_DATA__S_SLASH])
		precache_sound(g_eKnifeData[i][KNIFE_DATA__S_DEPLOY])
	}
}


Вот ещё пример: https://dev-cs.ru/resources/131/field?field=source
Смотрите
Код:
enum _: ENUM_DATA_RUNE_SETTINGS
и
Код:
new g_RuneSettings[ENUM_DATA_RUNE][ENUM_DATA_RUNE_SETTINGS]
 
Сообщения
95
Реакции
6
Помог
2 раз(а)
new g_iClassData[ClassCount][iClassData] = { static: g_iClassId[]; g_iClassId[] = g_iClassData[ClassId] for(new i; i > g_iClassId; i +1){ { "Холодное оружие", g_iClassId }, { "Огнестрельное оружие", g_iClassId } } }
Я тут пытался сделать выдачу своего ID каждому классу, но что то не очень вышло
Понял как оно строиться, но остался вопрос, как сделать выдачу ид класса? у меня вот с этим проблемы есть
 
Сообщения
1,277
Реакции
2,259
Помог
57 раз(а)
Skiptik,
Код:
enum _:ITEM_CLASS_ENUM {
	ITEM_CLASS__1,
	ITEM_CLASS__2,
	ITEM_CLASS__3,
	ITEM_CLASS__4
}

enum _:ITEM_DATA_STRUCT {
	ITEM_DATA__NAME[48],
	ITEM_DATA__CLASS
}

new const g_eItemData[][ITEM_DATA_STRUCT] = {
	{ "Предмет1", ITEM_CLASS__1 },
	{ "Предмет2", ITEM_CLASS__2 },
	{ "Предмет3", ITEM_CLASS__3 },
	{ "Предмет4", ITEM_CLASS__4 }
}
 
Сообщения
95
Реакции
6
Помог
2 раз(а)
BlackSignature, Ааа. понял, я просто думал что оно выдается через iCLass + id вот так думал должно выдаваться, спасибо, буду изучать)
 
Сообщения
95
Реакции
6
Помог
2 раз(а)
Вот что вышло, но появились ошибочки, и вопрос,
Вопрос: как связать iClassId and iClassIdHeroes, что б iClassIdHeroes понимал к какому классу он относиться и открывался в той меню которая принадлежит его классу
Код:
#include <amxmodx>

#define Version "1.0"

enum _: iClassID{
    OneClassID,
    TwoClassID
}

new g_iClassID[iClassID];

enum _: iHeroesStructClass{
    iClassName[64],
    iClassId = 1,
}

new g_iClassHeroues[][iHeroesStructClass] = {
    { "Гильдия убийц", g_iClassID[OneClassID] },
    { "Гильдия магов", g_iClassID[TwoClassID] }
}

enum _: iHeroesStruct{
    iHeroesName[64],
    iClassIdHeroes = 1,
    iAccessHeroes
}

new g_iHeroes[][iHeroesStruct] = {
    { "Смерть", g_iClassID[OneClassID], ADMIN_ALL },
    { "Ведьма", g_iClassID[TwoClassID], ADMIN_LEVEL_B }
}

public plugin_init(){
    register_plugin("Menu System", Version, "Skiptik");
    register_clcmd("say /menuheroes", "Show_HeroesMenu");
}

public Show_HeroesMenu(id){
    new iMenu =  menu_create("Выбирите гильдию", "Show_HeroesMenu");
    new sTemp[10];

    for(new i; i < sizeof g_iClassHeroues; i++) {
        new sData[128];
        formatex(sData, 63, "%s", g_iClassHeroues[i][iClassName]);

        num_to_str(i, sTemp, charsmax(sTemp));
        menu_additem(iMenu, sData, sTemp);
    }
    menu_setprop(iMenu, MPROP_NEXTNAME, "Вперед")
    menu_setprop(iMenu, MPROP_BACKNAME, "Выход")
    menu_display(id, iMenu, 0);
    return PLUGIN_HANDLED;
}

public Handle_Menu(id, iMenu, item)
{
    menu_destroy(iMenu);
    if(item == MENU_EXIT) {
        return PLUGIN_HANDLED;
    }

    new sData[30], sName[64], iAccess, iCallBack;
    menu_item_getinfo(iMenu, item, iAccess, sData, charsmax(sData), sName, charsmax(sName), iCallBack);

    new iKey = str_to_num(sData);

    switch(iKey) {
        case 0: {
            Show_GuildDeath(id)
        }
        case 1: {
            Show_GuildMagic(id)
        }
    }

    return PLUGIN_HANDLED;
}

public Show_GuildDeath(id){
    new iMenu =  menu_create("Гильдия убийц^nВыбирите рассу", "Handle_GuildDeath");
    new sTemp[10];
    for(new i; i < sizeof g_iHeroes; i++) {
        new sData[128];
        formatex(sData, 63, "%s", g_iHeroes[i][iHeroesName]);

        num_to_str(i, sTemp, charsmax(sTemp));
        menu_additem(iMenu, sData, sTemp);
    }
    menu_setprop(iMenu, MPROP_BACKNAME, "Выход")
    menu_display(id, iMenu, 0);
    return PLUGIN_HANDLED;
}

public Handle_GuildDeath(id, iMenu, item){
    menu_destroy(iMenu);
    if(item == MENU_EXIT) {
        return PLUGIN_HANDLED;
    }

    new sData[30], sName[64], iAccess, iCallBack;
    menu_item_getinfo(iMenu, item, iAccess, sData, charsmax(sData), sName, charsmax(sName), iCallBack);

    new iKey = str_to_num(sData);

    switch(iKey) {
        case 0: {
            // Смерть
        }
    }
    return PLUGIN_HANDLED;
}

public Show_GuildMagic(id){
    new iMenu =  menu_create("Гильдия ведьм^nВыбирите рассу", "Handle_GuildMagic");
    new sTemp[10];
    for(new i; i < sizeof g_iHeroes; i++) {
        new sData[128];
        formatex(sData, 63, "%s", g_iHeroes[i][iHeroesName]);

        num_to_str(i, sTemp, charsmax(sTemp));
        menu_additem(iMenu, sData, sTemp);
    }
    menu_setprop(iMenu, MPROP_BACKNAME, "Выход")
    menu_display(id, iMenu, 0);
    return PLUGIN_HANDLED;
}

public Handle_GuildMagic(id, iMenu, item){
    menu_destroy(iMenu);
    if(item == MENU_EXIT) {
        return PLUGIN_HANDLED;
    }

    new sData[30], sName[64], iAccess, iCallBack;
    menu_item_getinfo(iMenu, item, iAccess, sData, charsmax(sData), sName, charsmax(sName), iCallBack);

    new iKey = str_to_num(sData);

    switch(iKey) {
        case 0: {
            // Ведьма
        }
    }
    return PLUGIN_HANDLED;
}
Код:
(18) : error 008: must be a constant expression; assumed zero
(29) : error 008: must be a constant expression; assumed zero
(19) : warning 203: symbol is never used: ""
 
Сообщения
2,491
Реакции
2,795
Помог
61 раз(а)
Skiptik,
Код:
new g_iClassHeroues[][iHeroesStructClass] = {
    { "Гильдия убийц", g_iClassID[OneClassID] },
    { "Гильдия магов", g_iClassID[TwoClassID] }
}
Код:
new g_iHeroes[][iHeroesStruct] = {
    { "Смерть", g_iClassID[OneClassID], ADMIN_ALL },
    { "Ведьма", g_iClassID[TwoClassID], ADMIN_LEVEL_B }
}
Так нельзя в павне делать. Он не понимает такого

Что вы хотите сделать конкретно
 
Сообщения
198
Реакции
273
Помог
5 раз(а)
Skiptik, по поводу меню - попробуй глянуть в сторону Dynamic Menu
 
Сообщения
95
Реакции
6
Помог
2 раз(а)
fantom, Хочу сделать:
1. Создание меню с классом как в плагине выше, тоесть у меню есть свой класс
2. Создание каких любо items в это меню которое подходит к этому классу, поясню, если у Item совподает класс с классом меню то этот Item виден в этой меню
 
Сообщения
1,697
Реакции
1,510
Помог
25 раз(а)
Чот вы очень сложно всё делаете. Просто регаете все итемы одним списком, но как аргумент ещё указываете класс (так же как и, например, цена). И потом когда показываете меню просто сравниваите класс игрока и класс у итема.
Как подсказка: для динамичности необязательно сразу инициализировать итемы. Сначала можно узнать класс игрока и потом уже его использовать при "регистрации".
 
Сообщения
198
Реакции
273
Помог
5 раз(а)
Skiptik, если мне не изменяет память, то в моём меню один предмет можно зарегать на нескольких менюшках.
 
Сообщения
1,697
Реакции
1,510
Помог
25 раз(а)
Ах да, раз вы ещё и новую систему юзаете, то можно в инфу о итеме писать индекс из ария.
 
Сообщения
95
Реакции
6
Помог
2 раз(а)
fl0wer, я правильно вас понял?
C++:
#include <amxmodx>

#define Version 0.1

enum iClassRace {
    NameClassRace[80],
    IdClassRace
}

enum iHeroesClass{
    NameHeroes[80],
    IdClassRaceHero,
    IdHeroes,
    AccessHeroes,
}

new g_iClassRace[iClassRace][iHeroesClass];

public plugin_init(){
    register_plugin("Test", "0.1", "Skiptik")
}
далее планирую просто выдать IdClassRace значение 1 и его увеличивать с шагом 1 и выдать IdClassRaceHero значение расы и эти два аргумента сравнивать если одинаковые то добавлять в класс расу, ту рассу которая совпадает
 

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

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