Что это такое:
Этот include добавляет хранилище данных трёх типов с возможностью работы с ними (aka PVar/GVar).

Спросите: и зачем?
Если честно сложно ответить. Я просто загорелся желанием такое сделать, для меня это было интересно и я получил для себя опыт. Было перепробовано множества вариантом реализации. Получилось, что получилось

Использование:
Просто подключите include и используйте функции взаимодействия с хранилищем:
Код:
SD_SetFloat(0, "test_float", 6.4333);
SD_SetInt(0, "test_int", 5);
SD_SetString(0, "test_string", "Hello, World");
    
//
new value_string[144];
SD_GetString(0, "test_string", value_string);

printf("%d", SD_GetInt(0, "test_int"));
printf("%f", SD_GetFloat(0, "test_float"));
printf("%s", value_string);

SD_SetFloat(0, "test_float", 55.21);
SD_SetInt(0, "test_int", 665);
SD_SetString(0, "test_string", "Hello, Nikita");
//

SD_Free(0, "test_int");
SD_Free(0, "test_float"); 
SD_Free(0, "test_string");
Зависимости:
  • foreach или y_iterate


Исходный код:
Код:
/*
License: 
    Copyright [2022] [shierru]

    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at

        http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.

Thank's:
    Y_Less => Inspiration and desire to develop

Thank you very much to:
	Thiadmer => Pawn
	Kye/Kalcor => SA:MP
*/

// Macros's
#if defined _SD_included
    #endinput
#endif
#define _SD_included

#tryinclude <YSI\y_iterate>

#if !defined _inc_y_iterate
    #include <foreach>
#endif

#if !defined YSI_VERSION
    #define __COMPILER_STATIC_ENUM enum

    #if __PawnBuild >= 2
		#undef __COMPILER_STATIC_ENUM
		#define __COMPILER_STATIC_ENUM static enum
	#endif
#endif

#define SD_INVALID_DATA_IDENTIFIER          (-1)

#define SD_MAX_DATA_VALUE_CELLS             (144)
#define SD_MAX_DATA_NAME                    (24)
#define SD_MAX_DATA_STRING                  (244)

__COMPILER_STATIC_ENUM E_STORAGE_DATA
{
    E_STORAGE_DATA_NAME[SD_MAX_DATA_NAME],
    // Value's
    E_STORAGE_DATA_VALUE,
    Float:E_STORAGE_DATA_VALUE_FLOAT,
    E_STORAGE_DATA_VALUE_STRING[SD_MAX_DATA_STRING]
}

static
    SD_gsStorage[MAX_PLAYERS][SD_MAX_DATA_VALUE_CELLS][E_STORAGE_DATA],
    IteratorArray:SD_gsArray[MAX_PLAYERS]<SD_MAX_DATA_VALUE_CELLS>;

/*-------------------------------------------------------------------------*//**
 * <param name="playerid">playerid</param>
 * <param name="name">data name</param>
 * <param name="value">value to set</param>
 * <remarks>    
    This function is a layer between the internal static functions and the external publicly available functions.
 * </remarks>
 *//*------------------------------------------------------------------------**/

stock SD_SetInt(playerid, const name[SD_MAX_DATA_NAME], value)
    return _SetInt(playerid, name, value);

/*-------------------------------------------------------------------------*//**
 * <param name="playerid">playerid</param>
 * <param name="name">data name</param>
 * <param name="value">value to set</param>
 * <remarks>    
    This function is a layer between the internal static functions and the external publicly available functions.
 * </remarks>
 *//*------------------------------------------------------------------------**/

stock SD_SetFloat(playerid, const name[SD_MAX_DATA_NAME], Float:value)
    return _SetFloat(playerid, name, value);

/*-------------------------------------------------------------------------*//**
 * <param name="playerid">playerid</param>
 * <param name="name">data name</param>
 * <param name="value">value to set</param>
 * <remarks>    
    This function is a layer between the internal static functions and the external publicly available functions.
 * </remarks>
 *//*------------------------------------------------------------------------**/

stock SD_SetString(playerid, const name[SD_MAX_DATA_NAME], const string[SD_MAX_DATA_STRING])
    return _SetString(playerid, name, string);

/*-------------------------------------------------------------------------*//**
 * <param name="playerid">playerid</param>
 * <param name="name">data name</param>
 * <remarks>    
    This function is a layer between the internal static functions and the external publicly available functions.
 * </remarks>
 *//*------------------------------------------------------------------------**/

stock SD_GetInt(playerid, const name[SD_MAX_DATA_NAME]) 
{
    new value;
    _GetInt(playerid, name, value);
    return value;
}

/*-------------------------------------------------------------------------*//**
 * <param name="playerid">playerid</param>
 * <param name="name">data name</param>
 * <remarks>    
    This function is a layer between the internal static functions and the external publicly available functions.
 * </remarks>
 *//*------------------------------------------------------------------------**/

stock Float:SD_GetFloat(playerid, const name[SD_MAX_DATA_NAME]) 
{
    new Float:value;
    _GetFloat(playerid, name, value);
    return value;
}

/*-------------------------------------------------------------------------*//**
 * <param name="playerid">playerid</param>
 * <param name="name">data name</param>
 * <param name="string">string</param>
 * <remarks>
    
    
 * </remarks>
 * <remarks>    
    This function is a layer between the internal static functions and the external publicly available functions.
 * </remarks>
 *//*------------------------------------------------------------------------**/

stock SD_GetString(playerid, const name[SD_MAX_DATA_NAME], string[])
    return _GetString(playerid, name, string);

/*-------------------------------------------------------------------------*//**
 * <param name="playerid">playerid</param>
 * <param name="name">data name</param>
 * <remarks>
    This function clears an array with data about values, data name and the like.
    The function does not clear data from memory!

    This function is a layer between the internal static functions and the external publicly available functions.
 * </remarks>
 *//*------------------------------------------------------------------------**/

stock SD_Free(playerid, const name[SD_MAX_DATA_NAME])
    return _Free(playerid, name);

/*-------------------------------------------------------------------------*//**
 * <param name="playerid">playerid</param>
 * <param name="name">data name</param>
 * <param name="value">valut to set</param>
 * <remarks>
    This feature is original and is only available within this include.
 * </remarks>
 *//*------------------------------------------------------------------------**/

static stock 
    _SetInt(playerid, const name[SD_MAX_DATA_NAME], value)
{
    new 
        identifier = _GetIdentifier(playerid, name);

    if(identifier == SD_INVALID_DATA_IDENTIFIER)
        identifier = _AddData(playerid, name);

    SD_gsStorage[playerid][identifier][E_STORAGE_DATA_VALUE] = value;
    return 1;
}

/*-------------------------------------------------------------------------*//**
 * <param name="playerid">playerid</param>
 * <param name="name">data name</param>
 * <param name="value">valut to set</param>
 * <remarks>
    This feature is original and is only available within this include.
 * </remarks>
 *//*------------------------------------------------------------------------**/

static stock 
    _SetFloat(playerid, const name[SD_MAX_DATA_NAME], Float:value)
{
    new 
        identifier = _GetIdentifier(playerid, name);

    if(identifier == SD_INVALID_DATA_IDENTIFIER)
        identifier = _AddData(playerid, name);

    SD_gsStorage[playerid][identifier][E_STORAGE_DATA_VALUE_FLOAT] = value;
    return 1;
}

/*-------------------------------------------------------------------------*//**
 * <param name="playerid">playerid</param>
 * <param name="name">data name</param>
 * <param name="string">string to set</param>
 * <remarks>
    This feature is original and is only available within this include.
 * </remarks>
 *//*------------------------------------------------------------------------**/

static stock 
    _SetString(playerid, const name[SD_MAX_DATA_NAME], const string[SD_MAX_DATA_STRING])
{
    new 
        identifier = _GetIdentifier(playerid, name);

    if(identifier == SD_INVALID_DATA_IDENTIFIER)
        identifier = _AddData(playerid, name);
    
    memcpy(SD_gsStorage[playerid][identifier][E_STORAGE_DATA_VALUE_STRING], string, 0, sizeof(string) * (cellbits / charbits));
    return 1;
}

/*-------------------------------------------------------------------------*//**
 * <param name="playerid">playerid</param>
 * <param name="name">data name</param>
 * <param name="value">value to input on data</param>
 * <remarks>
    This feature is original and is only available within this include.
 * </remarks>
 *//*------------------------------------------------------------------------**/

static stock 
    _GetInt(playerid, const name[SD_MAX_DATA_NAME], &value)
{
    new 
        identifier = _GetIdentifier(playerid, name);

    if(identifier == SD_INVALID_DATA_IDENTIFIER)
        return 0;
    
    value = SD_gsStorage[playerid][identifier][E_STORAGE_DATA_VALUE];
    return 1;
}

/*-------------------------------------------------------------------------*//**
 * <param name="playerid">playerid</param>
 * <param name="name">data name</param>
 * <param name="value">value to input on data</param>
 * <remarks>
    This feature is original and is only available within this include.
 * </remarks>
 *//*------------------------------------------------------------------------**/

static stock 
    _GetFloat(playerid, const name[SD_MAX_DATA_NAME], &Float:value)
{
    new 
        identifier = _GetIdentifier(playerid, name);

    if(identifier == SD_INVALID_DATA_IDENTIFIER)
        return 0;
    
    value = SD_gsStorage[playerid][identifier][E_STORAGE_DATA_VALUE_FLOAT];
    return 1;
}

/*-------------------------------------------------------------------------*//**
 * <param name="playerid">playerid</param>
 * <param name="name">data name</param>
 * <param name="string">string to get</param>
 * <remarks>
    This does not use a direct string return. 
    Because if used incorrectly it can lead to big problems.

    This feature is original and is only available within this include.
 * </remarks>
 *//*------------------------------------------------------------------------**/

static stock 
    _GetString(playerid, const name[SD_MAX_DATA_NAME], string[])
{
    new 
        identifier = _GetIdentifier(playerid, name);

    if(identifier == SD_INVALID_DATA_IDENTIFIER)
        return 0;
    
    memcpy(string, SD_gsStorage[playerid][identifier][E_STORAGE_DATA_VALUE_STRING], 0, SD_MAX_DATA_STRING * (cellbits / charbits), SD_MAX_DATA_STRING);
    return 1;
}

/*-------------------------------------------------------------------------*//**
 * <param name="playerid">playerid</param>
 * <param name="name">data name</param>
 * <remarks>
    This feature is original and is only available within this include.
 * </remarks>
 *//*------------------------------------------------------------------------**/

static stock 
    _AddData(playerid, const name[SD_MAX_DATA_NAME])
{
    new
        index = Iter_Free(SD_gsArray[playerid]);

    memcpy(SD_gsStorage[playerid][index][E_STORAGE_DATA_NAME], name, 0, sizeof(name) * (cellbits / charbits));

    Iter_Add(SD_gsArray[playerid], index);

    return index;
}

/*-------------------------------------------------------------------------*//**
 * <param name="playerid">playerid</param>
 * <param name="name">data name</param>
 * <remarks>
    This function clears an array with data about values, data name and the like.
    The function does not clear data from memory!

    This feature is original and is only available within this include.
 * </remarks>
 *//*------------------------------------------------------------------------**/

static stock 
    _Free(playerid, const name[SD_MAX_DATA_NAME])
{
    new 
        identifier = _GetIdentifier(playerid, name);
    
    if(identifier == SD_INVALID_DATA_IDENTIFIER)
        return 0;
    
    static const empty_data[E_STORAGE_DATA];
    SD_gsStorage[playerid][identifier] = empty_data;

    Iter_Remove(SD_gsArray[playerid], identifier);
    return 1;
}

/*-------------------------------------------------------------------------*//**
 * <param name="playerid">playerid</param>
 * <param name="name">data name</param>
 * <remarks>
    This function is only available within the include.
 * </remarks>
 *//*------------------------------------------------------------------------**/

static stock 
    _GetIdentifier(playerid, const name[SD_MAX_DATA_NAME])
{
    foreach(new i: SD_gsArray[playerid])
    {
        if(!strcmp(name, SD_gsStorage[playerid][i][E_STORAGE_DATA_NAME], false, cellmax)) {
            return i;
        }
    }
    return SD_INVALID_DATA_IDENTIFIER;
}

#if !defined YSI_VERSION
    #undef __COMPILER_STATIC_ENUM
#endif
На этом конец, это мой первый опыт в написание публичных работ, так что не судите строго