PDA

Просмотр полной версии : [Мануал] Система создания актёров прямо из игры [MySQL]



DeimoS
15.04.2021, 15:55
Описание:

Как и сказано в названии темы, данная система позволяет создавать актёров прямо из игры.
Система не конфликтует с актёрами, которые были созданы не через функционал данной системы.
Таблица, требуемая для работы системы, автоматически создастся при первом запуске сервера.



Команды:

/createactor [ID модели] <Имя> <Бессмертие (0-1)> <Здоровье>
Позволяет создавать актёра с указанными параметрами.
Все параметры, кроме "ID модели", являются необязательными.

Примечание:
Если желаете создать актёра с именем,
в котором будут пробелы,
сначала создайте актёра с любым именем
(или без него)
и после измените имя на нужное через /editactor


/editactor <ID актёра>
Позволяет отредактировать данные уже созданного актёра.
Если не указать ID конкретного скина, сервер попытается найти актёра в радиусе одного метра рядом с игроком. Иными словами, можно подойти вплотную к актёру, которого нужно отредактировать, и ввести "/editactor"


Зависимости:


Инклуды

foreach (https://github.com/Open-GTO/foreach/releases)
mdialog (https://github.com/Open-GTO/mdialog/releases)


Плагины

MySQL R40 и выше (https://github.com/pBlueG/SA-MP-MySQL/releases)
Pawn.CMD (https://github.com/katursis/Pawn.CMD/releases)
sscanf (https://github.com/maddinat0r/sscanf/releases)
Streamer by Incognito (https://github.com/samp-incognito/samp-streamer-plugin/releases)






В начало мода (после всех инклудов):

#define ACTOR_DB_HANDLE mysql_connection_ID
#define MAX_ACTOR_NAME 30
const ACTOR_COLOR_3D_TEXT = 0xFFFFFFFF;
const Float:ACTOR_3DTEXT_APPEND_Z = 1.1;

/*
"mysql_connection_ID" заменить на свою переменную, хранящую ID подключения к БД.

MAX_ACTOR_NAME - Максимальная длинна имени актёра (3D текст над ботом)

ACTOR_COLOR_3D_TEXT - Цвет 3D текста над актёром, хранящего "имя"

ACTOR_3DTEXT_APPEND_Z - Высота, на которую будет поднят 3D текст относительно центра скина
*/

enum e_ACTOR_INFO
{
actor_TableID,
actor_Name[MAX_ACTOR_NAME],
actor_ModelID,
Float:actor_PosX,
Float:actor_PosY,
Float:actor_PosZ,
Float:actor_PosA,
actor_Invulnerable,
Float:actor_Health,
actor_VirtualWorld,
actor_Interior,
STREAMER_TAG_3D_TEXT_LABEL:actor_3DText,
}
new ActorInfo[MAX_ACTORS][e_ACTOR_INFO];
new Iterator:iActors<MAX_ACTORS>;

new pVar__EditActor_ID[] = "pVar__EditActor_ID";
new pVar__EditActor_Pos[] = "pVar__EditActor_Pos";

new dEditActor_Main[] = "dEditActor_Main";
new dEditActor_SetName[] = "dEditActor_SetName";
new dEditActor_Model[] = "dEditActor_Model";
new dEditActor_Health[] = "dEditActor_Health";
new dEditActor_VW[] = "dEditActor_VW";
new dEditActor_Interior[] = "dEditActor_Interior";
new dEditActor_Delete[] = "dEditActor_Delete";


В OnGameModeInit, после кода подключения к БД.

LoadActorInfo();


В конец мода:

LoadActorInfo()
{
new Cache:r = mysql_query(ACTOR_DB_HANDLE, "SHOW TABLES LIKE 'actor_list'", true);

if(!cache_num_rows())
{
mysql_query(ACTOR_DB_HANDLE, "\
CREATE TABLE `actor_list` (\
`id` int(11) NOT NULL,\
`name` varchar(30) NOT NULL,\
`model_id` int(11) NOT NULL,\
`pos_x` float NOT NULL,\
`pos_y` float NOT NULL,\
`pos_z` float NOT NULL,\
`pos_a` float NOT NULL,\
`invulnerable` tinyint(1) NOT NULL DEFAULT '1',\
`health` float NOT NULL DEFAULT '100',\
`virtual_world` int(11) NOT NULL DEFAULT '-1',\
`interior` int(11) NOT NULL DEFAULT '-1'\
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT;\
", false);

mysql_query(ACTOR_DB_HANDLE, "\
ALTER TABLE `actor_list`\
ADD PRIMARY KEY (`id`);\
", false);


mysql_query(ACTOR_DB_HANDLE, "\
ALTER TABLE `actor_list`\
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;\
", false);

print("[MySQL] Таблица actor_list создана.");
}
else
{
cache_delete(r);

r = mysql_query(ACTOR_DB_HANDLE, "SELECT * FROM actor_list", true);

new row_count;
cache_get_row_count(row_count);

if(!row_count)
{
print("[MySQL] Таблица actor_list пуста.");
return;
}

if(row_count > MAX_ACTORS)
{
printf("[MySQL: Error] В таблице actor_list количество записей (%d) превышает значение MAX_ACTORS (%d)!", row_count, MAX_ACTORS);
}

new buff_actor_info[e_ACTOR_INFO];
for(new i, idx; i < row_count; i++)
{
cache_get_value_name_int(i, "id", buff_actor_info[actor_TableID]);
cache_get_value_name(i, "name", buff_actor_info[actor_Name], MAX_ACTOR_NAME);
cache_get_value_name_int(i, "model_id", buff_actor_info[actor_ModelID]);
cache_get_value_name_float(i, "pos_x", buff_actor_info[actor_PosX]);
cache_get_value_name_float(i, "pos_y", buff_actor_info[actor_PosY]);
cache_get_value_name_float(i, "pos_z", buff_actor_info[actor_PosZ]);
cache_get_value_name_float(i, "pos_a", buff_actor_info[actor_PosA]);
cache_get_value_name_int(i, "invulnerable", buff_actor_info[actor_Invulnerable]);
cache_get_value_name_float(i, "health", buff_actor_info[actor_Health]);
cache_get_value_name_int(i, "virtual_world", buff_actor_info[actor_VirtualWorld]);
cache_get_value_name_int(i, "interior", buff_actor_info[actor_Interior]);

idx = CreateDynamicActor(
buff_actor_info[actor_ModelID],
buff_actor_info[actor_PosX],
buff_actor_info[actor_PosY],
buff_actor_info[actor_PosZ],
buff_actor_info[actor_PosA],
buff_actor_info[actor_Invulnerable],
buff_actor_info[actor_Health],
buff_actor_info[actor_VirtualWorld],
buff_actor_info[actor_Interior]);

if(idx == INVALID_ACTOR_ID)
{
print("[MySQL: Error] При загрузке данных из таблицы actor_list произошла ошибка: превышен лимит актёров на сервере!");
break;
}
Iter_Add(iActors, idx);

ActorInfo[idx] = buff_actor_info;

CreateActor3DText(idx);
}
cache_delete(r);
}
}

stock CreateActor3DText(idx)
{
if(isnull(ActorInfo[idx][actor_Name]))
return;
ActorInfo[idx][actor_3DText] = CreateDynamic3DTextLabel(
ActorInfo[idx][actor_Name],
ACTOR_COLOR_3D_TEXT,
ActorInfo[idx][actor_PosX],
ActorInfo[idx][actor_PosY],
ActorInfo[idx][actor_PosZ]+ACTOR_3DTEXT_APPEND_Z,
30.0,
.testlos = 1,
.worldid = ActorInfo[idx][actor_VirtualWorld],
.interiorid = ActorInfo[idx][actor_Interior]);
}

stock UpdateActorData(idx, e_ACTOR_INFO:type)
{
new query_string[22+(28+13*4)+9+4+1] = "UPDATE actor_list SET ";
switch(type)
{
case actor_Name:
{
mysql_format(ACTOR_DB_HANDLE, query_string, sizeof(query_string),
"%sname='%e' ", query_string, ActorInfo[idx][type]);
}
case actor_ModelID:
{
format(query_string, sizeof(query_string),
"%smodel_id=%d ", query_string, ActorInfo[idx][type]);
}
case actor_PosX, actor_PosY, actor_PosZ, actor_PosA:
{
format(query_string, sizeof(query_string),
"%spos_x=%0.2f,pos_y=%0.2f,pos_z=%0.2f,pos_a=%0.2f ",
query_string,
ActorInfo[idx][actor_PosX],
ActorInfo[idx][actor_PosY],
ActorInfo[idx][actor_PosZ],
ActorInfo[idx][actor_PosA]);
}
case actor_Invulnerable:
{
format(query_string, sizeof(query_string),
"%sinvulnerable=%d ", query_string, ActorInfo[idx][type]);
}
case actor_Health:
{
format(query_string, sizeof(query_string),
"%shealth=%0.2f ", query_string, ActorInfo[idx][type]);
}
case actor_VirtualWorld:
{
format(query_string, sizeof(query_string),
"%svirtual_world=%d ", query_string, ActorInfo[idx][type]);
}
case actor_Interior:
{
format(query_string, sizeof(query_string),
"%sinterior=%d ", query_string, ActorInfo[idx][type]);
}
}
format(query_string, sizeof(query_string),
"%sWHERE id=%d", query_string, ActorInfo[idx][actor_TableID]);

mysql_tquery(ACTOR_DB_HANDLE, query_string, "");
}


stock Float:GetDynActorDistanceFromPoint(actorid, Float:x, Float:y, Float:z)
{
new Float:current_x, Float:current_y, Float:current_z;
if (GetDynamicActorPos(actorid, current_x, current_y, current_z) == 0)
return 0.0;
return VectorSize(x - current_x, y - current_y, z - current_z);
}

stock IsDynamicActorInRangeOfPoint(actorid, Float:range, Float:x, Float:y, Float:z)
{
new Float:dist = GetDynActorDistanceFromPoint(actorid, x, y, z);
return _:(dist < range) != 0;
}

Команды и функционал для них (так же в конец мода):

CMD:createactor(playerid, params[])
{
new modelid;
new invulnerable;
new Float:health;
new name[MAX_ACTOR_NAME];

if(sscanf(params, "iS()["#MAX_ACTOR_NAME"]I(1)F(100)", modelid, name, invulnerable, health))
{
SendClientMessage(playerid, 0xAAAAAAFF,
"Используйте: /createactor [Model (0-73, 75-311)] <Имя> <Бессмертие (0-1)> <Здоровье>");

SendClientMessage(playerid, 0xAAAAAAFF, "* Примечание:");
SendClientMessage(playerid, 0xAAAAAAFF, "Параметры в угловых скобках не обязательны.");
SendClientMessage(playerid, 0xAAAAAAFF, "Значения по умолчанию:");
SendClientMessage(playerid, 0xAAAAAAFF, "Бессмертие - \"1\"");
SendClientMessage(playerid, 0xAAAAAAFF, "Здоровье - \"100.0\"");
return 1;
}

if(!(0 <= modelid <= 73) && !(75 <= modelid <= 311))
{
SendClientMessage(playerid, 0xAAAAAAFF, "Ошибка: Допустимые значения для ModelID: 0-73, 75-311");
return 1;
}

if(!(0 <= invulnerable <= 1))
{
SendClientMessage(playerid, 0xAAAAAAFF, "Ошибка: Допустимые значения для invulnerable: 0-1");
return 1;
}

if(health <= 0.0)
{
SendClientMessage(playerid, 0xAAAAAAFF, "Ошибка: Здоровье не может быть меньше или равно нулю.");
return 1;
}


new Float:x;
new Float:y;
new Float:z;
GetPlayerPos(playerid, x, y, z);
new Float:a;
GetPlayerFacingAngle(playerid, a);

new worldid = GetPlayerVirtualWorld(playerid);
new interiorid = GetPlayerInterior(playerid);

new idx = CreateDynamicActor(modelid, x, y, z, a, invulnerable, health, worldid, interiorid);

if(idx == INVALID_ACTOR_ID)
{
SendClientMessage(playerid, 0xAAAAAAFF, "Ошибка: На сервере создано максимальное количество актёров.");
return 1;
}

Iter_Add(iActors, idx);

ActorInfo[idx][actor_Name][0] = '\0';
strcat(ActorInfo[idx][actor_Name], name, MAX_ACTOR_NAME);
ActorInfo[idx][actor_ModelID] = modelid;
ActorInfo[idx][actor_PosX] = x;
ActorInfo[idx][actor_PosY] = y;
ActorInfo[idx][actor_PosZ] = z;
ActorInfo[idx][actor_PosA] = a;
ActorInfo[idx][actor_Invulnerable] = invulnerable;
ActorInfo[idx][actor_Health] = health;
ActorInfo[idx][actor_VirtualWorld] = worldid;
ActorInfo[idx][actor_Interior] = interiorid;

x += (1.0 * floatsin(-a, degrees));
y += (1.0 * floatcos(-a, degrees));
SetPlayerPos(playerid, x, y, z);
SetPlayerFacingAngle(playerid, a-180.0);
SetCameraBehindPlayer(playerid);

CreateActor3DText(idx);

new query_string[12+11+4+(8+MAX_ACTOR_NAME)+(10+3)+(7+11)+(7+11)+(7+11)+(7+11)+(14+1)+(8+11)+(15+11)+(9+11)+1];
mysql_format(ACTOR_DB_HANDLE, query_string, sizeof(query_string),
"\
INSERT INTO \
actor_list \
SET \
name='%e',\
model_id=%d,\
pos_x=%f,\
pos_y=%f,\
pos_z=%f,\
pos_a=%f,\
invulnerable=%d,\
health=%f,\
virtual_world=%d,\
interior=%d\
",
name,
modelid,
x,
y,
z,
a,
invulnerable,
health,
worldid,
interiorid);
mysql_tquery(ACTOR_DB_HANDLE, query_string, "@MySQL__GetActorTableID", "i", idx);
return 1;
}

@MySQL__GetActorTableID(idx);
@MySQL__GetActorTableID(idx)
{
ActorInfo[idx][actor_TableID] = cache_insert_id();
}


CMD:editactor(playerid, params[])
{
new actor_id = -1;
if(sscanf(params, "i", actor_id))
{
new Float:x;
new Float:y;
new Float:z;
GetPlayerPos(playerid, x, y, z);

foreach(new i: iActors)
{
if(!IsDynamicActorInRangeOfPoint(i, 1.0, x, y, z))
continue;

SetPVarInt(playerid, pVar__EditActor_ID, i);
Dialog_Show(playerid, dEditActor_Main);
return 1;
}
SendClientMessage(playerid, 0xAAAAAAFF, "/editactor <ID актёра (1-1000)>");
return 1;
}
if(!Iter_Contains(iActors, actor_id))
{
SendClientMessage(playerid, 0xAAAAAAFF, "Ошибка: Указанный актёр не найден или создан не через систему создания актёров.");
return 1;
}

DeletePVar(playerid, pVar__EditActor_Pos);
SetPVarInt(playerid, pVar__EditActor_ID, actor_id);
Dialog_Show(playerid, dEditActor_Main);
return 1;
}


DialogCreate:dEditActor_Main(playerid)
{
if(!GetPVarType(playerid, pVar__EditActor_ID))
{
SendClientMessage(playerid, 0xAAAAAAFF, "При редактировании актёра произошла ошибка [#001]. Повторите попытку.");
return;
}

new idx = GetPVarInt(playerid, pVar__EditActor_ID);

new dialog_string[8+(14+MAX_ACTOR_NAME)+(25+3)+(29+10)+(27+13)+(34+11)+(27+11)+28+17+1] = "{FFFFFF}";

format(dialog_string, sizeof(dialog_string),
"\
Имя:\t{009900}%s\n\
{FFFFFF}Модель:\t{009900}%d\n\
{FFFFFF}Бессмертие:\t{009900}%s\n\
{FFFFFF}Здоровье:\t{009900}%0.2f\n\
{FFFFFF}Виртуальный мир:\t{009900}%d\n\
{FFFFFF}Интерьер:\t{009900}%d\n\
{FFFFFF}• Изменить позицию\t\n\
• Удалить актёра\t\n\
",
ActorInfo[idx][actor_Name],
ActorInfo[idx][actor_ModelID],
ActorInfo[idx][actor_Invulnerable] ? ("Бессмертен") : ("Смертен"),
ActorInfo[idx][actor_Health],
ActorInfo[idx][actor_VirtualWorld],
ActorInfo[idx][actor_Interior]);

Dialog_Open(playerid, dEditActor_Main, DIALOG_STYLE_TABLIST,
"Редактирование актёра", dialog_string, "Далее", "Закрыть");
}

DialogResponse:dEditActor_Main(playerid, response, listitem, inputtext[])
{
if(!response)
{
DeletePVar(playerid, pVar__EditActor_ID);
return 1;
}

if(!GetPVarType(playerid, pVar__EditActor_ID))
{
SendClientMessage(playerid, 0xAAAAAAFF, "При редактировании актёра произошла ошибка [#002]. Повторите попытку.");
return 1;
}

new idx = GetPVarInt(playerid, pVar__EditActor_ID);
switch(listitem)
{
case 0:
{
Dialog_Show(playerid, dEditActor_SetName);
}
case 1:
{
Dialog_Show(playerid, dEditActor_Model);
}
case 2:
{
ActorInfo[idx][actor_Invulnerable] = !ActorInfo[idx][actor_Invulnerable];
UpdateActorData(idx, actor_Invulnerable);
Streamer_SetIntData(STREAMER_TYPE_ACTOR, idx, E_STREAMER_INVULNERABLE, ActorInfo[idx][actor_Invulnerable]);
Streamer_Update(playerid, STREAMER_TYPE_ACTOR);

Dialog_Show(playerid, dEditActor_Main);
}
case 3:
{
Dialog_Show(playerid, dEditActor_Health);
}
case 4:
{
Dialog_Show(playerid, dEditActor_VW);
}
case 5:
{
Dialog_Show(playerid, dEditActor_Interior);
}
case 6:
{
SetPVarInt(playerid, pVar__EditActor_Pos, 1);

SendClientMessage(playerid, 0x00AA00AA, "Вы перешли в режим редактирования координат актёра.");
SendClientMessage(playerid, 0x00AA00AA, "Встаньте на желаемую позицию и нажмите на \"~k~~CONVERSATION_YES~\".");
SendClientMessage(playerid, 0x00AA00AA, "Для выхода из режима без изменения координат нажмите \"~k~~CONVERSATION_YES~\".");
}
case 7:
{
Dialog_Show(playerid, dEditActor_Delete);
}
}
return 1;
}

DialogInterrupt:dEditActor_Main(playerid)
{
DeletePVar(playerid, pVar__EditActor_ID);
return 1;
}


DialogCreate:dEditActor_SetName(playerid)
{
if(!GetPVarType(playerid, pVar__EditActor_ID))
{
SendClientMessage(playerid, 0xAAAAAAFF, "При редактировании актёра произошла ошибка [#003]. Повторите попытку.");
return;
}

new idx = GetPVarInt(playerid, pVar__EditActor_ID);

new dialog_string[8+(30+MAX_ACTOR_NAME)+1+30+1];
format(dialog_string, sizeof(dialog_string),
"{FFFFFF}\
Текущее имя: {00AA00}%s{FFFFFF}\n\
\n\
Укажите новое имя в окно ниже:\
", ActorInfo[idx][actor_Name]);

Dialog_Open(playerid, dEditActor_SetName, DIALOG_STYLE_INPUT,
"Редактирование актёра [Имя]", dialog_string, "Изменить", "Назад");
}

DialogResponse:dEditActor_SetName(playerid, response, listitem, inputtext[])
{
if(!response)
{
Dialog_Show(playerid, dEditActor_Main);
return 1;
}

if(strlen(inputtext) > MAX_ACTOR_NAME)
{
SendClientMessage(playerid, 0xAAAAAAFF, "Ошибка: Имя не должно быть длиннее "#MAX_ACTOR_NAME" символов.");
Dialog_Show(playerid, dEditActor_SetName);
return 1;
}

if(!GetPVarType(playerid, pVar__EditActor_ID))
{
SendClientMessage(playerid, 0xAAAAAAFF, "При редактировании актёра произошла ошибка [#004]. Повторите попытку.");
return 1;
}

new idx = GetPVarInt(playerid, pVar__EditActor_ID);

if(isnull(inputtext))
{
if(isnull(ActorInfo[idx][actor_Name]))
{
Dialog_Show(playerid, dEditActor_Main);
return 1;
}
else
{
ActorInfo[idx][actor_Name][0] = '\0';
DestroyDynamic3DTextLabel(ActorInfo[idx][actor_3DText]);
}
}
else
{
if(isnull(ActorInfo[idx][actor_Name]))
{
strcat(ActorInfo[idx][actor_Name], inputtext, MAX_ACTOR_NAME);
CreateActor3DText(idx);
Streamer_Update(playerid, STREAMER_TYPE_3D_TEXT_LABEL);
}
else
{
ActorInfo[idx][actor_Name][0] = '\0';
strcat(ActorInfo[idx][actor_Name], inputtext, MAX_ACTOR_NAME);
UpdateDynamic3DTextLabelText(ActorInfo[idx][actor_3DText], ACTOR_COLOR_3D_TEXT, inputtext);
Streamer_Update(playerid, STREAMER_TYPE_3D_TEXT_LABEL);
}
}
UpdateActorData(idx, actor_Name);

Dialog_Show(playerid, dEditActor_Main);
return 1;
}

DialogInterrupt:dEditActor_SetName(playerid)
{
DeletePVar(playerid, pVar__EditActor_ID);
return 1;
}


DialogCreate:dEditActor_Model(playerid)
{
if(!GetPVarType(playerid, pVar__EditActor_ID))
{
SendClientMessage(playerid, 0xAAAAAAFF, "При редактировании актёра произошла ошибка [#005]. Повторите попытку.");
return;
}

new idx = GetPVarInt(playerid, pVar__EditActor_ID);

new dialog_string[8+(30+3)+1+30+1];
format(dialog_string, sizeof(dialog_string),
"{FFFFFF}\
Текущая модель: {00AA00}%d{FFFFFF}\n\
\n\
Укажите новую модель в окно ниже:\
", ActorInfo[idx][actor_ModelID]);

Dialog_Open(playerid, dEditActor_Model, DIALOG_STYLE_INPUT,
"Редактирование актёра [ID скина]", dialog_string, "Изменить", "Назад");
}

DialogResponse:dEditActor_Model(playerid, response, listitem, inputtext[])
{
if(!response)
{
Dialog_Show(playerid, dEditActor_Main);
return 1;
}

new model_id;
if(sscanf(inputtext, "i", model_id))
{
Dialog_Show(playerid, dEditActor_Model);
return 1;
}

if(!(0 <= model_id <= 73) && !(75 <= model_id <= 311))
{
SendClientMessage(playerid, 0xAAAAAAFF, "Ошибка: Допустимые значения для модели: 0-73, 75-311");
Dialog_Show(playerid, dEditActor_Model);
return 1;
}

if(!GetPVarType(playerid, pVar__EditActor_ID))
{
SendClientMessage(playerid, 0xAAAAAAFF, "При редактировании актёра произошла ошибка [#006]. Повторите попытку.");
return 1;
}

new idx = GetPVarInt(playerid, pVar__EditActor_ID);

ActorInfo[idx][actor_ModelID] = model_id;
UpdateActorData(idx, actor_ModelID);
Streamer_SetIntData(STREAMER_TYPE_ACTOR, idx, E_STREAMER_MODEL_ID, model_id);
Streamer_Update(playerid, STREAMER_TYPE_ACTOR);

Dialog_Show(playerid, dEditActor_Main);
return 1;
}

DialogInterrupt:dEditActor_Model(playerid)
{
DeletePVar(playerid, pVar__EditActor_ID);
return 1;
}


DialogCreate:dEditActor_Health(playerid)
{
if(!GetPVarType(playerid, pVar__EditActor_ID))
{
SendClientMessage(playerid, 0xAAAAAAFF, "При редактировании актёра произошла ошибка [#007]. Повторите попытку.");
return;
}

new idx = GetPVarInt(playerid, pVar__EditActor_ID);

new dialog_string[8+(35+13)+1+35+1];
format(dialog_string, sizeof(dialog_string),
"{FFFFFF}\
Текущее здоровье: {00AA00}%0.2f{FFFFFF}\n\
\n\
Укажите новое значение в окно ниже:\
", ActorInfo[idx][actor_Health]);

Dialog_Open(playerid, dEditActor_Health, DIALOG_STYLE_INPUT,
"Редактирование актёра [Здоровье]", dialog_string, "Изменить", "Назад");
}

DialogResponse:dEditActor_Health(playerid, response, listitem, inputtext[])
{
if(!response)
{
Dialog_Show(playerid, dEditActor_Main);
return 1;
}

new Float:health;
if(sscanf(inputtext, "f", health))
{
Dialog_Show(playerid, dEditActor_Health);
return 1;
}

if(health <= 0.0)
{
SendClientMessage(playerid, 0xAAAAAAFF, "Ошибка: Здоровье не может быть меньше или равно нулю.");
Dialog_Show(playerid, dEditActor_Health);
return 1;
}

if(!GetPVarType(playerid, pVar__EditActor_ID))
{
SendClientMessage(playerid, 0xAAAAAAFF, "При редактировании актёра произошла ошибка [#008]. Повторите попытку.");
return 1;
}

new idx = GetPVarInt(playerid, pVar__EditActor_ID);

ActorInfo[idx][actor_Health] = health;
UpdateActorData(idx, actor_Health);
Streamer_SetFloatData(STREAMER_TYPE_ACTOR, idx, E_STREAMER_HEALTH, health);
Streamer_Update(playerid, STREAMER_TYPE_ACTOR);

Dialog_Show(playerid, dEditActor_Main);
return 1;
}

DialogInterrupt:dEditActor_Health(playerid)
{
DeletePVar(playerid, pVar__EditActor_ID);
return 1;
}


DialogCreate:dEditActor_VW(playerid)
{
if(!GetPVarType(playerid, pVar__EditActor_ID))
{
SendClientMessage(playerid, 0xAAAAAAFF, "При редактировании актёра произошла ошибка [#009]. Повторите попытку.");
return;
}

new idx = GetPVarInt(playerid, pVar__EditActor_ID);

new dialog_string[8+(42+11)+1+42+1];
format(dialog_string, sizeof(dialog_string),
"{FFFFFF}\
Текущий виртуальный мир: {00AA00}%d{FFFFFF}\n\
\n\
Укажите новый виртуальный мир в окно ниже:\
", ActorInfo[idx][actor_VirtualWorld]);

Dialog_Open(playerid, dEditActor_VW, DIALOG_STYLE_INPUT,
"Редактирование актёра [Виртуальный мир]", dialog_string, "Изменить", "Назад");
}

DialogResponse:dEditActor_VW(playerid, response, listitem, inputtext[])
{
if(!response)
{
Dialog_Show(playerid, dEditActor_Main);
return 1;
}

new virtual_world;
if(sscanf(inputtext, "i", virtual_world))
{
Dialog_Show(playerid, dEditActor_VW);
return 1;
}

if(virtual_world < -1)
{
SendClientMessage(playerid, 0xAAAAAAFF, "Ошибка: Виртуальный мир не может быть меньше -1!");
Dialog_Show(playerid, dEditActor_VW);
return 1;
}

if(!GetPVarType(playerid, pVar__EditActor_ID))
{
SendClientMessage(playerid, 0xAAAAAAFF, "При редактировании актёра произошла ошибка [#010]. Повторите попытку.");
return 1;
}

new idx = GetPVarInt(playerid, pVar__EditActor_ID);

ActorInfo[idx][actor_VirtualWorld] = virtual_world;
UpdateActorData(idx, actor_VirtualWorld);
Streamer_SetIntData(STREAMER_TYPE_ACTOR, idx, E_STREAMER_WORLD_ID, virtual_world);
Streamer_SetIntData(STREAMER_TYPE_3D_TEXT_LABEL, ActorInfo[idx][actor_3DText], E_STREAMER_WORLD_ID, virtual_world);
Streamer_Update(playerid, STREAMER_TYPE_ACTOR);
Streamer_Update(playerid, STREAMER_TYPE_3D_TEXT_LABEL);

Dialog_Show(playerid, dEditActor_Main);
return 1;
}

DialogInterrupt:dEditActor_VW(playerid)
{
DeletePVar(playerid, pVar__EditActor_ID);
return 1;
}


DialogCreate:dEditActor_Interior(playerid)
{
if(!GetPVarType(playerid, pVar__EditActor_ID))
{
SendClientMessage(playerid, 0xAAAAAAFF, "При редактировании актёра произошла ошибка [#011]. Повторите попытку.");
return;
}

new idx = GetPVarInt(playerid, pVar__EditActor_ID);

new dialog_string[8+(42+11)+1+42+1];
format(dialog_string, sizeof(dialog_string),
"{FFFFFF}\
Текущий интерьер: {00AA00}%d{FFFFFF}\n\
\n\
Укажите новый интерьер в окно ниже:\
", ActorInfo[idx][actor_Interior]);

Dialog_Open(playerid, dEditActor_Interior, DIALOG_STYLE_INPUT,
"Редактирование актёра [Интерьер]", dialog_string, "Изменить", "Назад");
}

DialogResponse:dEditActor_Interior(playerid, response, listitem, inputtext[])
{
if(!response)
{
Dialog_Show(playerid, dEditActor_Main);
return 1;
}

new interior;
if(sscanf(inputtext, "i", interior))
{
Dialog_Show(playerid, dEditActor_Interior);
return 1;
}

if(!(-1 <= interior <= 256))
{
SendClientMessage(playerid, 0xAAAAAAFF, "Ошибка: Интерьер не может быть меньше -1 или больше 256!");
Dialog_Show(playerid, dEditActor_Interior);
return 1;
}

if(!GetPVarType(playerid, pVar__EditActor_ID))
{
SendClientMessage(playerid, 0xAAAAAAFF, "При редактировании актёра произошла ошибка [#012]. Повторите попытку.");
return 1;
}

new idx = GetPVarInt(playerid, pVar__EditActor_ID);

ActorInfo[idx][actor_Interior] = interior;
UpdateActorData(idx, actor_Interior);
Streamer_SetIntData(STREAMER_TYPE_ACTOR, idx, E_STREAMER_INTERIOR_ID, interior);
Streamer_SetIntData(STREAMER_TYPE_3D_TEXT_LABEL, ActorInfo[idx][actor_3DText], E_STREAMER_INTERIOR_ID, interior);
Streamer_Update(playerid, STREAMER_TYPE_ACTOR);
Streamer_Update(playerid, STREAMER_TYPE_3D_TEXT_LABEL);

Dialog_Show(playerid, dEditActor_Main);
return 1;
}

DialogInterrupt:dEditActor_Interior(playerid)
{
DeletePVar(playerid, pVar__EditActor_ID);
return 1;
}


DialogCreate:dEditActor_Delete(playerid)
{
if(!GetPVarType(playerid, pVar__EditActor_ID))
{
SendClientMessage(playerid, 0xAAAAAAFF, "При редактировании актёра произошла ошибка [#013]. Повторите попытку.");
return;
}

new idx = GetPVarInt(playerid, pVar__EditActor_ID);

new dialog_string[8+(24+MAX_ACTOR_NAME)+1+48+1];
format(dialog_string, sizeof(dialog_string),
"{FFFFFF}\
Актёр: {00AA00}%s{FFFFFF}\n\
\n\
Вы действительно желаете удалить данного актёра?\
",
ActorInfo[idx][actor_Name]);
Dialog_Open(playerid, dEditActor_Delete, DIALOG_STYLE_MSGBOX,
"Удаление актёра", dialog_string, "Удалить", "Назад");
}

DialogResponse:dEditActor_Delete(playerid, response, listitem, inputtext[])
{
if(!response)
{
Dialog_Show(playerid, dEditActor_Main);
return 1;
}

if(!GetPVarType(playerid, pVar__EditActor_ID))
{
SendClientMessage(playerid, 0xAAAAAAFF, "При редактировании актёра произошла ошибка [#014]. Повторите попытку.");
return 1;
}

new idx = GetPVarInt(playerid, pVar__EditActor_ID);

Iter_Remove(iActors, idx);

DestroyDynamicActor(idx);
DestroyDynamic3DTextLabel(ActorInfo[idx][actor_3DText]);

new query_string[34+11+1];
format(query_string, sizeof(query_string),
"DELETE FROM actor_list WHERE id = %d", ActorInfo[idx][actor_TableID]);
mysql_tquery(ACTOR_DB_HANDLE, query_string);
return 1;
}

DialogInterrupt:dEditActor_Delete(playerid)
{
DeletePVar(playerid, pVar__EditActor_ID);
return 1;
}

В OnPlayerKeyStateChange

if(GetPVarType(playerid, pVar__EditActor_Pos))
{
if(newkeys & KEY_YES)
{
if(!GetPVarType(playerid, pVar__EditActor_ID))
{
SendClientMessage(playerid, 0xAAAAAAFF, "При редактировании актёра произошла ошибка [#015]. Повторите попытку.");
return 1;
}

new idx = GetPVarInt(playerid, pVar__EditActor_ID);


new Float:x;
new Float:y;
new Float:z;
GetPlayerPos(playerid, x, y, z);
new Float:a;
GetPlayerFacingAngle(playerid, a);

new worldid = GetPlayerVirtualWorld(playerid);
new interiorid = GetPlayerInterior(playerid);
ActorInfo[idx][actor_PosX] = x;
ActorInfo[idx][actor_PosY] = y;
ActorInfo[idx][actor_PosZ] = z;
ActorInfo[idx][actor_PosA] = a;
ActorInfo[idx][actor_VirtualWorld] = worldid;
ActorInfo[idx][actor_Interior] = interiorid;

new query_string[7+11+4+(7+13)+(7+13)+(7+13)+(7+13)+(15+11)+(10+3)+6+(3+11)+1];

format(query_string, sizeof(query_string),
"\
UPDATE \
actor_list \
SET \
pos_x=%0.2f,\
pos_y=%0.2f,\
pos_z=%0.2f,\
pos_a=%0.2f,\
virtual_world=%d,\
interior=%d \
WHERE \
id=%d\
",
x, y, z, a,
worldid, interiorid,
ActorInfo[idx][actor_TableID]);
mysql_tquery(ACTOR_DB_HANDLE, query_string);


Streamer_SetFloatData(STREAMER_TYPE_ACTOR, idx, E_STREAMER_X, x);
Streamer_SetFloatData(STREAMER_TYPE_3D_TEXT_LABEL, ActorInfo[idx][actor_3DText], E_STREAMER_X, x);

Streamer_SetFloatData(STREAMER_TYPE_ACTOR, idx, E_STREAMER_Y, y);
Streamer_SetFloatData(STREAMER_TYPE_3D_TEXT_LABEL, ActorInfo[idx][actor_3DText], E_STREAMER_Y, y);

Streamer_SetFloatData(STREAMER_TYPE_ACTOR, idx, E_STREAMER_Z, z);
Streamer_SetFloatData(STREAMER_TYPE_3D_TEXT_LABEL, ActorInfo[idx][actor_3DText], E_STREAMER_Z, z+ACTOR_3DTEXT_APPEND_Z);

Streamer_SetFloatData(STREAMER_TYPE_ACTOR, idx, E_STREAMER_ROTATION, a);

Streamer_SetIntData(STREAMER_TYPE_ACTOR, idx, E_STREAMER_WORLD_ID, worldid);
Streamer_SetIntData(STREAMER_TYPE_3D_TEXT_LABEL, ActorInfo[idx][actor_3DText], E_STREAMER_WORLD_ID, worldid);
Streamer_SetIntData(STREAMER_TYPE_ACTOR, idx, E_STREAMER_INTERIOR_ID, interiorid);
Streamer_SetIntData(STREAMER_TYPE_3D_TEXT_LABEL, ActorInfo[idx][actor_3DText], E_STREAMER_INTERIOR_ID, interiorid);

Streamer_Update(playerid, STREAMER_TYPE_ACTOR);
Streamer_Update(playerid, STREAMER_TYPE_3D_TEXT_LABEL);
DeletePVar(playerid, pVar__EditActor_Pos);



x += (1.0 * floatsin(-a, degrees));
y += (1.0 * floatcos(-a, degrees));
SetPlayerPos(playerid, x, y, z);
SetPlayerFacingAngle(playerid, a-180.0);
SetCameraBehindPlayer(playerid);


Dialog_Show(playerid, dEditActor_Main);
return 1;
}
else if(newkeys & KEY_NO)
{
DeletePVar(playerid, pVar__EditActor_Pos);
Dialog_Show(playerid, dEditActor_Main);
return 1;
}
}






Автор - DeimoS
Копирование данного материала без разрешения автора запрещено