PDA

Просмотр полной версии : [Вопрос] Как получить переменную в инклуде из мода



Mr.X
05.11.2019, 12:48
Добрый день

Описание:

В моде есть массив с данными аккаунта,

static SelectCMName[24][MAX_PLAYERS];

#define SYNC_TYPES (6)

enum pInfo {
pID,
pName[MAX_PLAYER_NAME],
pKey[32],
pEmail[64],
pRefer[MAX_PLAYER_NAME],
SyncTime[SYNC_TYPES],
LastSyncUpdate[SYNC_TYPES]
}
new PlayerInfo[MAX_PLAYERS][pInfo];

//цветами чата и т.п.

#define COLOR_LIGHTBLUE 0x33CCFFFF



Планирую разделить мод на модули
К нему будут подключены несколько инклудов с различными системами, такими как кланы, работы, дома, машины ну и в таком духе.
Хочу сделать их полностью независимыми, чтоб можно было отключать каждую систему без вреда для работы мода.
Использую перехваты функций.

В каждом инклуде будут использоваться одинаковые цвета и переменные.
К примеру:

#include "clan_system.inc"

//Пример одного из диалогов

case D_CLAN_RANK:
{
if(!response) return true;
new string[128],giveplayerid;
if(sscanf(SelectCMName[playerid],"u",giveplayerid)) return true;
if(sscanf(inputtext,"i",strval(inputtext))) return ShowPlayerDialog(playerid,D_CLAN_RANK,DIALOG_STYLE_INPUT,""FPHEAD"Повысuть/Понuзuть",""FPMSG"Какой ранг Вы хотuте выдать uгроку?","Выбрать","Отмена");

if(strval(inputtext) < 1 || strval(inputtext) > 8) return ErrorMes(playerid, "Ранг может быть от 1 до 8.");

if(IsPlayerConnected(giveplayerid))
{
if(FamilyInfo[playerid][fID] != FamilyInfo[giveplayerid][fID]) return ErrorMes(playerid, "Этот uгрок не состоuт в вашем клане.");
if(playerid == giveplayerid) return ErrorMes(playerid, "Вы не можете uзменuть себе ранг.");
if(FamilyInfo[giveplayerid][fType]) return ErrorMes(playerid, "Вы не можете uзменuть ранг этому uгроку.");

if(strval(inputtext) > FamilyInfo[giveplayerid][fRank])

format(string, sizeof(string), "Вы былu повышены до %d ранга лuдером %s",strval(inputtext), PlayerInfo[playerid][pName]);
SendClientMessage(giveplayerid, COLOR_LIGHTBLUE, string);
format(string, sizeof(string), "Вы повысuлu uгрока %s до %d ранга.", PlayerInfo[giveplayerid][pName], strval(inputtext));
SendClientMessage(playerid, COLOR_LIGHTBLUE, string);
}
else
{
format(string, sizeof(string), "Вы былu понuжены до %d ранга лuдером %s",strval(inputtext), PlayerInfo[playerid][pName]);
SendClientMessage(giveplayerid, COLOR_LIGHTBLUE, string);
format(string, sizeof(string), "Вы понuзuлu uгрока %s до %d ранга.", PlayerInfo[giveplayerid][pName], strval(inputtext));
SendClientMessage(playerid, COLOR_LIGHTBLUE, string);
}
UpdatePlayerClanTeam(giveplayerid, 0, strval(inputtext));
}
else
{
format(string, sizeof(string), "Вы выдалu uгроку %s %d ранг.", SelectCMName[playerid], strval(inputtext));
SendClientMessage(playerid, COLOR_LIGHTBLUE, string);
format(string,sizeof(string),"UPDATE `samp_clanteam` SET `Rank` = '%d' WHERE `Name`='%s'",
strval(inputtext), SelectCMName[playerid]);
mysql_tquery(MYSQL_DEFAULT_HANDLE, string);
}
}


Собственно сам вопрос:

Как лучше всего получать значения этих переменных из мода, чтоб не объявлять их в каждый раз для каждого инклуда? И не было конфликтов.

- - - Добавлено - - -

В голову приходит следующий способ:



#if !defined COLOR_LIGHTBLUE
#define COLOR_LIGHTBLUE 0x33CCFFFF
#endif


Но каждый раз объявлять его и прочие переменные в каждом инклуде считаю не совсем корректно.
Может есть способ получше?

DeimoS
05.11.2019, 13:36
Во-первых, использовать перехваты для реализации "модульности" скрипта - такая себе затея. Что ты будешь делать, когда в одном из новых инклудов тебе нужно, например, OnGameModeInit вызывать самым первым из всех инклудов, а OnPlayerConnect, при этом, вызывать последним? :)

Во-вторых, твоя проблема решается заголовочными файлами. То есть, вынеси все общие макросы/переменные в отдельный файл и подключи его выше всех остальных инклудов, в которых уже будут использоваться эти макросы/переменные.
Либо можно сделать отдельный инклуд с функциями, которые уже будут возвращать нужные значения цвета и т.п., если речь идёт именно о константных значениях.

Mr.X
05.11.2019, 14:18
Касательно подключения макросов понял.
А по поводу модульности, как лучше делать если не перехватами?

vvw
05.11.2019, 17:57
Во-первых, использовать перехваты для реализации "модульности" скрипта - такая себе затея. Что ты будешь делать, когда в одном из новых инклудов тебе нужно, например, OnGameModeInit вызывать самым первым из всех инклудов, а OnPlayerConnect, при этом, вызывать последним? :)

А зачем нам зависимость от порядка исполнения? Можно использовать y_hooks, которая позволяет для специфичных библиотек, вроде samp-fixes, вызвать их код горантированно раньше вашего.

DeimoS
05.11.2019, 23:58
Касательно подключения макросов понял.
А по поводу модульности, как лучше делать если не перехватами?

В инклудах создавать функции и вызывать их в пабликах основного мода. Таким образом ты наглядно будешь видеть порядок вызова твоего кода и сможешь его в любой момент изменить.
Вот тут подробно обсуждали этот вопрос - http://pro-pawn.ru/showthread.php?15165-Geebrox


А зачем нам зависимость от порядка исполнения? Можно использовать y_hooks, которая позволяет для специфичных библиотек, вроде samp-fixes, вызвать их код горантированно раньше вашего.

Потому что есть множество систем, код которых нужно вызывать в конкретный момент, а не абы как? Например, из таблицы данные загружать обязательно после подключения к БД, а проверки в каком-либо паблике делать перед большинством инклудов, но не после инклуда античита.
Можно, конечно, извратиться с перехватами, но придётся в голове держать порядок вызова всех функций в инклудах для каждого паблика. И всё непонятно ради чего, когда можно сделать проще и удобнее.


UPD: Перехваты, объективно, удобны в инклудах, которые публикуются для использования другими людьми, дабы обеспечить упрощённое подключение инклуда. Но использовать их в модульном моде - затея такая себе. Максимум - для перехвата нативных функций, по типу выдачи денег и т.п. Хотя я и тут советовал бы делать свои функции, дабы потом не беспокоиться о том, что все инклуды, в которых будет использоваться GivePlayerMoney, должны быть ниже инклуда с перехватом. Да и код, в целом, будет понятнее.