Форум Pawn.Wiki - Воплоти мечту в реальность!: Проблема, цикл не правильно итерируется - Форум Pawn.Wiki - Воплоти мечту в реальность!

Перейти к содержимому

  • (4 Страниц) +
  • « Первая
  • 2
  • 3
  • 4
  • Вы не можете создать новую тему
  • Вы не можете ответить в тему

[ Pawn ]
Проблема, цикл не правильно итерируется

#31
Пользователь офлайн   Perdolinka 

  • Профессионал
  • Вставить ник
  • Раскрыть информацию

Просмотр сообщенияDigitalOneThe (26 мая 2023 - 20:53) писал:

Нажмите сюда, чтобы прочитать это сообщение. [Показать]

Нет) именно возвращаемый результат, а не поступаемый индекс. В блоке, где идёт обработка dFurniture_MainMenu у тебя уже имеется дебаг-сообщение, поэтому заместо имеющегося дебаг сообщения, добавь:

printf("find_idx %d, pos x %f", find_idx, eFurniture[find_idx][eFurniture_X]); 


И потом сверь результат позиции X у выбранного индекса и индекса в таблице. То бишь: выбрали например нулевой(первый) listitem, значит смотри соответствует ли результат первой из строк в таблице.
0

#32
Пользователь офлайн   DigitalOneThe 

  • Эксперт
  • Вставить ник
  • Раскрыть информацию

Просмотр сообщенияPerdolinka (26 мая 2023 - 21:00) писал:

Нажмите сюда, чтобы прочитать это сообщение. [Показать]


Не совпало,

LOG:
[21:05:01] find_idx 5, pos x 5.000000


Просмотр сообщенияPerdolinka (26 мая 2023 - 21:00) писал:

Нажмите сюда, чтобы прочитать это сообщение. [Показать]


Не совпало,

LOG:
[21:05:01] find_idx 5, pos x 5.000000


И кстати, я щас выбрал элемент в списке 0, но почему то вывело в логе 1:
find_idx 1, pos x 0.000000

0

#33
Пользователь офлайн   Perdolinka 

  • Профессионал
  • Вставить ник
  • Раскрыть информацию

Просмотр сообщенияDigitalOneThe (26 мая 2023 - 21:08) писал:

Нажмите сюда, чтобы прочитать это сообщение. [Показать]

Какой из listitem'ov ты нажал, начиная от нуля. И с каким конкретно совпадает, было бы неплохо уточнить этот момент. К тому же, был бы признателен за предоставление всеобщей картины, то бишь кода которой у тебя в конечном итоге стоит сейчас для этой системы.
0

#34
Пользователь офлайн   DigitalOneThe 

  • Эксперт
  • Вставить ник
  • Раскрыть информацию

Просмотр сообщенияPerdolinka (26 мая 2023 - 22:12) писал:

Нажмите сюда, чтобы прочитать это сообщение. [Показать]


Вот на 1 listitem я нажал:

Моя ссылка

вот что в консоли.

Моя ссылка

Совпадает вот с какой записью из бд

Моя ссылка

По сути всё совпало правильно, но я так понимаю, ты хочешь сделать так, что-бы не обращаться каждый раз к массиву с мебелью. Я правильно понял? Что find_idx, должен быть индекс из массива? Хотя тебе не даст это сделать порядок listitem, и вообще даже не логично будет это.

Сообщение отредактировал DigitalOneThe: 26 мая 2023 - 23:48

0

#35
Пользователь офлайн   Perdolinka 

  • Профессионал
  • Вставить ник
  • Раскрыть информацию

Просмотр сообщенияDigitalOneThe (26 мая 2023 - 22:40) писал:

Нажмите сюда, чтобы прочитать это сообщение. [Показать]

Знать бы ещё что ты конкретно хочешь реализовать, так было бы проще мыслить. Собственно, а как ты хочешь не обращаться к массиву каждый раз? Тебе же, кроме ид объекта и номера в базе, нужно ещё некие метаданные позже продемонстрировать о выбранной мебели. И, к слову, было бы неплохо предоставить архитектуру твоей таблицы. И что попадает в пункт номера в диалоге? Его ид в базе или ид индекса для доступа?
0

#36
Пользователь офлайн   DigitalOneThe 

  • Эксперт
  • Вставить ник
  • Раскрыть информацию

Просмотр сообщенияPerdolinka (26 мая 2023 - 23:41) писал:

Нажмите сюда, чтобы прочитать это сообщение. [Показать]


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

---------

Если конечно ты согласен на такое.

Я могу предоставить архитектуру основного массива, и архитектуру в базе данных, ну что-бы потом был понятен мне ориентир в коде, что к чему. Ну и если будет время, и твоё желание, то объяснишь что к чему, хотя ты мне уже в предыдущих темах отсылался на то, как работает твой код, думаю ты не будешь добавлять что-то особенного, или будешь, в общем не знаю.

Вот как реализована система в моде:

Массив с мебелью:

enum e_FURNITURE_INFO {
	eID,           						 // ID Элемента в массиве
	eHouseID,                       	                        // Идентификатор дома, который хранит в себе мебель.
	eFurniture_OBJ,       				       // ID Объекта
	eFurniture_ObjIdentifier,                            // Идентификатор объекта
	eFurniture_Count,               	              // Количество объекта.
	Float: eFurniture_X,           		             // Координата X.
	Float: eFurniture_Y,           		            // Координата X.
	Float: eFurniture_Z,           		           // Координата X.
	Float: eFurniture_RX,           	          // Координата оси X.
	Float: eFurniture_RY,           	         // Координата оси Y.
	Float: eFurniture_RZ,           	        // Координата оси Z.
	eFurniture_Owner[MAX_PLAYER_NAME],  // Владелец мебели
	bool: eFurniture_PlaceObject                  // Находится ли объект на сервере.
};

new eFurniture[MAX_FURNITURES][e_FURNITURE_INFO];


Метаданные для самой мебели, проще говоря, массив с объектами, и описанием какой-то из мебели в массиве.

enum e_FURNITURE_ITEMS { // Массив используется только для объектов интерьера, ни более, вся информации мебели дома, хранится в массиве eFurniture!
	eFurniture_ID,
	eFurniture_OBJ,
	eFurniture_Name[64]
};
new eFurnitureItems[55][e_FURNITURE_ITEMS] = {
// Бытовая техника
	{ 0, 1208, "Стиральная машина" },
	{ 1, 1518, "Телевизор, Чёрный" },
	{ 2, 1719, "DVD-Проигрыватель" },
	{ 3, 2099, "Музыкальный центр" },
	{ 4, 2149, "Микроволновка" },
	{ 5, 11743, "Кофеварка" },
	{ 6, 19786, "Телевизор [Плазма]" },
	{ 7, 19893, "Ноутбук" },
	{ 8, 19808, "Клавиатура" },
	{ 9, 2226, "BoomBox" },
// Ванная комната
	{ 10, 2514, "Унитаз" },
	{ 11, 2515, "Туалетная раковина" },
	{ 12, 2518, "Кухонная раковина" },
	{ 13, 2517, "Душевая кабинка" },
	{ 14, 2526, "Ванна" },
// Декорации
	{ 15, 1738, "Чугунная батарея" },
	{ 16, 1808, "Куллер с водой" },
	{ 17, 1829, "Открытый сейф" },
	{ 18, 2254, "Картина №-1" },
	{ 19, 2267, "Картина с титаником" },
	{ 20, 2275, "Картина с фруктами" },
	{ 21, 2332, "Закрытый сейф" },
	{ 22, 2737, "Доска" },
	{ 23, 2817, "Ковёр голубой с узорами" },
	{ 24, 2824, "Книги" },
	{ 25, 2826, "Журналы" },
	{ 26, 3077, "Стенд" },
	{ 27, 11728, "Навесной телефон" },
// Диваны/кровати
	{ 28, 1701, "Кровать №-1" },
	{ 29, 1712, "Диван" },
	{ 30, 1767, "Кресло" },
	{ 31, 14866, "Кровать №-2 (Элитная)" },
// Кухонная мебель
	{ 32, 2013, "Кухонная мебель №-1" },
	{ 33, 2014, "Кухонная мебель №-2" },
	{ 34, 2015, "Кухонная мебель №-3" },
	{ 35, 2016, "Кухонная мебель №-4" },
	{ 36, 2017, "Кухонная мебель №-5 (Плита)" },
	{ 37, 11706, "Мусорное ведро" },
// Освещение
	{ 38, 1734, "Круглая лампа" },
	{ 39, 2023, "Настольная лампа" },
	{ 40, 19806, "Люстра" },
// Столы, Стулья
	{ 41, 1433, "Стол №-1"},
	{ 42, 1516, "Стол №-2"},
	{ 43, 1663, "Кабинетное кресло"},
	{ 44, 1720, "Стул кухонный"},
	{ 45, 1827, "Стеклянный стол"},
	{ 46, 2086, "Стеклянный стол №-2"},
	{ 47, 2125, "Барный стул"},
	{ 48, 2086, "Стеклянный стол №-2"},
// Шкафы, Тумбы
	{ 49, 912, "Тумбочка" },
	{ 50, 2025, "Шкаф" },
	{ 51, 2091, "Шкаф с телевизором" },
	{ 52, 2161, "Книжная полка" },
	{ 53, 2608, "Книжная полка №-2" },
// Прочее
	{ 54, 2919, "Мешок" }
};


Собственно диалоги системы:

switch(dialogid) {
	case dFurniture_ListMain: {
		if (!response) {
			ClearPlayerCountListedFurn(playerid);
			return ClearPlayerFurnituresList(playerid);
		}
		
		if (response) {
			if (!strcmp(inputtext, ">>>")) {
				IncrementPlayerFurnituresPage(playerid);
				return ShowPlayerFurnitureListDialog(playerid, false);
			}
			
			if (!strcmp(inputtext, "<<<")) {
				DecrementPlayerFurniturePage(playerid);
				return ShowPlayerFurnitureListDialog(playerid, false, true);
			}
			
			SetPlayerFurnitureIdx(playerid, listitem);
			return ShowPlayerFurnitureEditMenu(playerid, listitem);
		}
		
		SetPlayerFurniturePage(playerid, 0);
        ClearPlayerCountListedFurn(playerid);
        return ClearPlayerFurnituresList(playerid);
	}
	
	case dFurniture_MainMenu: {
		if (!response) {
			ClearPlayerCountListedFurn(playerid);
			return ClearPlayerFurnituresList(playerid);
		}
		
		new page = GetPlayerFurniturePage(playerid);
		new index = GetPlayerFurnitureIdx(playerid);
		new find_idx = GetPlayerFurnitureListIndex(playerid, page, index);
		
		printf("find_idx %d, pos x %f", find_idx, eFurniture[find_idx][eFurniture_X]); 
	}
}

Сообщение отредактировал DigitalOneThe: 26 мая 2023 - 23:56

0

#37
Пользователь офлайн   Perdolinka 

  • Профессионал
  • Вставить ник
  • Раскрыть информацию

Просмотр сообщенияDigitalOneThe (26 мая 2023 - 23:43) писал:

Нажмите сюда, чтобы прочитать это сообщение. [Показать]

Хорошо, я завтра что-то придумаю на подобии системы бизнесов, о которой мы с тобой ранее говорили и попытаюсь более детальней разложить, чтоб ты понял наконец-то. Думаю, с бизнесами тебе немного ясно стало
0

#38
Пользователь офлайн   DigitalOneThe 

  • Эксперт
  • Вставить ник
  • Раскрыть информацию

Просмотр сообщенияPerdolinka (27 мая 2023 - 00:10) писал:

Хорошо, я завтра что-то придумаю на подобии системы бизнесов, о которой мы с тобой ранее говорили и попытаюсь более детальней разложить, чтоб ты понял наконец-то. Думаю, с бизнесами тебе немного ясно стало


Спасибо. И если не сложно, то реализуй это с MySQL R41-4. Насчёт более детальнее не надо, у меня всё таки есть опыт в программировании, хоть какой то, но есть, больше я шарю за MySQL, эти все запросы, ну и тем-более я начинал с Java, а Java для меня намного легче, и уж если я начну читать код абсолютно с нуля, навык чтения кода, и понимания той или иной детали у меня присутствует, это ещё не всё моим пределам опыта в программировании, писал много плагинов, на Minecraft, от лёгких заканчивая сложными, что например на основе плагина с редактированием мира, ну если ты хоть раз играл в майнкрафт, и приходилось ли тебе хоть раз вникать в майнкрафторские эти штучки, то я думаю ты понимаешь что такое WorldEdit, WorldGuard. А ещё бы не плохо узнать, каким образом можно выполнить асинхронное выполнение кода в Pawn, скажу так, насчёт плагина на редактирования мира, и д.р. плагинов - это делается очень легко, считай что разработка Minecraft плагинов не основывается на каком то написании своих функций, как это в Pawn (о том что, тебе на дадут готовый мод, с каким то жанром, xD), а в Java это так и есть, остаётся только более детальнее изучить основы этого языка, и всё, считай что любой плагин будет лёгким в реализации, а всё почему? Первый факт, игра очень популярная, а соответственно с этим, и есть много готовых вариаций, опытных программистов которые связаны с игрой Minecraft, ну к примеру, нужно тебе сделать хэш пароля, просто в интернете ищешь и всё, и тебе сразу предлагают готовые вариации, на разных сайтах. А если попытаться найти в интернете шифр каких то данных, и если ты даже найдёшь готовый вариант, а вопрос работает ли это? Так же и в Java.

Насчёт асинхронного потока, если что, в синхронный поток по сути должен отправляться сам код, а в асинхронный метод, должен отправляться callback.

И я уверен на все 100 процентов, что могут быть задержки при выполнении запросов в базу данных, и не известно ещё в каком количестве.

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

И кстати вот например из одних популярных плагинов на редактирование мира, представь ты удаляешь территорию с размером в 150 миллионов блоков, знаешь что произойдёт? Сервер может провиснуть, от выполнения команды например, но не залагать вовсе, то-есть блок кода встаёт в очередь, и как мне известно, пока другой код в очереди, все остальные операции от этого плагина не смогут выполнится. А всё другие операции от других плагинов - смогут выполнится.

Сообщение отредактировал DigitalOneThe: 27 мая 2023 - 00:40

0

#39
Пользователь офлайн   Perdolinka 

  • Профессионал
  • Вставить ник
  • Раскрыть информацию

Просмотр сообщенияDigitalOneThe (27 мая 2023 - 00:31) писал:

Нажмите сюда, чтобы прочитать это сообщение. [Показать]

C Minecraft'om дел не имел, честно говоря. Но, ассинхронное выполнение кода можна замутить, используя магию из PawnPlus под названием потоки. threaded(sync_explicit) и всё, что идёт внутри этого блока, будет выполняться ассинхронно. Тестировал на собственном примере, выполняя увесистый код прямиком в ином потоке(если точнее, то речь была о создании динамических объектов на рандомной позиции ежесекундно, причём, координаты основывались не на тех, что в массиве, а генерировались рандомным образом) и, по итогу, если выполнять всё это дело синхронно, то будет либо краш, либо бешенные пролаги, но ассинхронная же методика избавляет нас от этого и можно спокойно выполнять себе другие цели. Хотя, есть некие моменты, когда может быть достигнут эффект "гонки" и, исходя из этого, некоторые функции могут выполняться не последовательно, а хаотично. Хотя, будем честны, о ассинхронном программировании в Pawn я читал давно и потому, кое какие моменты, всё же стоило освежить в памяти. К тому же, threaded(sync_explicit) всего лишь макрос, работающий если определено соответствующее поведение(то бишь, определена директива поведения непосредственно), в ином же случае приходится использовать: thread_detach, чтобы отвязать весь последующий код от основного потока и потом, по завершении ассинхронного кода, нужно обратно его привязать к основному потоку, используя thread_attach.

Теперь, давай ближе к делу, ибо, учитывая мой заряд на ноуте, не знаю смогу ли я доделать это сейчас или, непосредственно, после зарядки. В любом случае, это будет сегодня.

Начнём, пожалуй, с начала, разобрав массив и элементы перечисления, отвечающие за метаданные для мебели.
Сам по себе масссив, как я тебе говорил, лучше всего сделать не двумерным(MAX_FURNITURES и структура), а непосредственно, трёхмерным, если известен лимит мебели на дом конечно. И, в конечном итоге, мы будем иметь такую картину:

new g_house_furniture[MAX_HOUSES][MAX_FURNITURES][/* структура */];


Естественно, если лимит нам не известен и такой мебели, допустим, может быть тысяч десять условных, то загрузка в массив и последующее обращение к нему, может быть далеко не производительным. Единственный выход привязывать эти все метаданные непосредственно к созданному объекту мебели. Собственно, об этом далее и, к тому же, я слегка переделал структуру с метаданными, убрав кое какие элементы и также, саму архитектуру основной таблицы, распределив систему по нескольким таблицам.


#define MAX_FURNITURE_LOAD_DATA (9)
#define MAX_FURNITURE_ITEMS (55)
#define MAX_FURNITURE_ITEM_NAME_LEN (28)
#define MAX_FURNITURE_ON_PAGE (20)

enum E_FURNITURE_STRUCT
{
	F_HOUSE_ID, /* идентификатор дома из базы данных, которому принадлежит мебель */ 
	F_SLOT, /* слот(позиция) среди остальной мебели */
	F_ID, /* ID мебели, для получения неких метаданных(её имени, модели объекта) о ней из массива. */
	Float: F_POS_X, /* Координата X */
	Float: F_POS_Y, /* Координата Y */
	Float: F_POS_Z, /* Координата Z */
	Float: F_POS_RX, /* Координата оси rX */
	Float: F_POS_RY, /* Координата оси rY */
	Float: F_POS_RZ /* Координата оси rZ */
}

enum E_FURNITURE_ITEM_STRUCT
{
	FI_MODELID,
	FI_NAME[MAX_FURNITURE_ITEM_NAME_LEN]
}

enum 
{
	FURNITURE_LOAD_TYPE_HOUSE,
	FURNITURE_LOAD_TYPE_SLOT,
	FURNITURE_LOAD_TYPE_ID,
	FURNITURE_LOAD_TYPE_POS,
	FURNITURE_LOAD_TYPE_ROT_POS = 6
}

enum E_HOUSE_FURN_OBJ_STRUCT
{
	HFO_MIN,
	HFO_MAX
}

enum E_PLAYER_FURN_STRUCT
{
	PF_PAGE,
	PF_COUNT_LISTED
}

new g_house_furn_obj[MAX_HOUSES][E_HOUSE_FURN_OBJ_STRUCT];

new g_player_furniture[MAX_PLAYERS][E_PLAYER_FURN_STRUCT];

new g_player_furniture_list[MAX_PLAYERS][MAX_FURNITURE_ON_PAGE];

new g_furniture_items[MAX_FURNITURE_ITEMS][E_FURNITURE_ITEM_STRUCT] = 
{
	// Бытовая техника
	{1208, "Стиральная машина"},
	{1518, "Телевизор, Чёрный"},
	{1719, "DVD-Проигрыватель"},
	{2099, "Музыкальный центр"},
	{2149, "Микроволновка"},
	{11743, "Кофеварка"},
	{19786, "Телевизор [Плазма]"},
	{19893, "Ноутбук"},
	{19808, "Клавиатура"},
	{2226, "BoomBox"},
	// Ванная комната
	{2514, "Унитаз"},
	{2515, "Туалетная раковина"},
	{2518, "Кухонная раковина"},
	{2517, "Душевая кабинка"},
	{2526, "Ванна"},
// Декорации
	{1738, "Чугунная батарея"},
	{1808, "Куллер с водой"},
	{1829, "Открытый сейф"},
	{2254, "Картина №-1"},
	{2267, "Картина с титаником"},
	{2275, "Картина с фруктами"},
	{2332, "Закрытый сейф"},
	{2737, "Доска"},
	{2817, "Ковёр голубой с узорами"},
	{2824, "Книги"},
	{2826, "Журналы"},
	{3077, "Стенд"},
	{11728, "Навесной телефон"},
// Диваны/кровати
	{1701, "Кровать №-1"},
	{1712, "Диван"},
	{1767, "Кресло"},
	{14866, "Кровать №-2 (Элитная)"},
// Кухонная мебель
	{2013, "Кухонная мебель №-1"},
	{2014, "Кухонная мебель №-2"},
	{2015, "Кухонная мебель №-3"},
	{2016, "Кухонная мебель №-4"},
	{2017, "Кухонная мебель №-5 (Плита)"},
	{11706, "Мусорное ведро"},
// Освещение
	{1734, "Круглая лампа"},
	{2023, "Настольная лампа"},
	{19806, "Люстра"},
// Столы, Стулья
	{1433, "Стол №-1"},
	{1516, "Стол №-2"},
	{1663, "Кабинетное кресло"},
	{1720, "Стул кухонный"},
	{1827, "Стеклянный стол"},
	{2086, "Стеклянный стол №-2"},
	{2125, "Барный стул"},
	{2086, "Стеклянный стол №-2"},
// Шкафы, Тумбы
	{912, "Тумбочка"},
	{2025, "Шкаф"},
	{2091, "Шкаф с телевизором"},
	{2161, "Книжная полка"},
	{2608, "Книжная полка №-2"},
// Прочее
	{2919, "Мешок"}
};

stock IsFurnitureIDValid(furnitureid)
	return (0 <= furnitureid <= (sizeof g_furniture_items - 1));

stock GetFurnitureItemModelID(furnitureid)
{
	if(!IsFurnitureIDValid(furnitureid))
		return 0;

	return g_furniture_items[furnitureid][FI_MODELID];
}

stock GetFurnitureItemName(furnitureid, const buffer[])
{
	if(!IsFurnitureIDValid(furnitureid))
		return 0;

	return format
	(
		buffer, MAX_FURNITURE_ITEM_NAME_LEN,
		"%s",
		g_furniture_items[furnitureid][FI_NAME]
	);
}

stock IsHouseFirstFurnObject(houseid)
	return (g_house_furn_obj[houseid] == 0);

stock SetHouseMinFurnObjectID(houseid, objectid)
	return g_house_furn_obj[houseid][HFO_MIN] = objectid;

stock SetHouseMaxFurnObjectID(houseid, objectid)
	return g_house_furn_obj[houseid][HFO_MAX] = objectid;

stock CreateHouseFurniture(houseid, slot, furnitureid, Float: pos_x, Float: pos_y, Float: pos_z,
Float: pos_rx, Float: pos_ry, Float: pos_rz, is_furniture_last)
{
	new objectid = CreateDynamicObject
	(
		GetFurnitureItemModelID(furnitureid),
		pos_x,
		pos_y,
		pos_z,
		pos_rx,
		pos_ry,
		pos_rz,
		.worldid = houseid
	);

	if(!IsValidDynamicObject(objectid))
		return 0;

	if(IsHouseFirstFurnObject(houseid))
		SetHouseMinFurnObjectID(houseid, objectid);

	if(is_furniture_last)
		SetHouseMaxFurnObjectID(houseid, objectid);

	new fmt_str[] = "%d %d %d %.4f %.4f %.4f %.4f %.4f %.4f",
		result_str[sizeof fmt_str + 
					(- 4 + 20) + 
					(- 2 + 5) + 
					(- 24 + 54)];

	format
	(
		result_str, sizeof result_str, 
		fmt_str, 
		houseid,
		slot,
		furnitureid,
		pos_x, 
		pos_y,
		pos_z,
		pos_rx,
		pos_ry,
		pos_rz
	);

	return Streamer_SetArrayData
	(
		STREAMER_TYPE_OBJECT, 
		objectid, 
		E_STREAMER_EXTRA_ID,
		result_str
	);	
}

stock GetPlayerFurniturePage(playerid)
    return g_player_furniture[playerid][PF_PAGE];

stock ClearPlayerFurnData(playerid)
{
	new player_furn_empty_data[E_PLAYER_FURN_STRUCT];

	return g_player_furniture[playerid] = player_furn_empty_data;
}

stock ClearPlayerFurnListData(playerid)
{
	for(new idx; idx < sizeof g_player_furniture_list[]; idx ++)
		g_player_furniture_list[playerid][idx] = 0;

	return 1;
}

stock IsFurnitureListIndexValid(index)
    return (0 <= index <= (sizeof g_player_furniture_list[] - 1));

stock GetPlayerFurnitureListIndex(playerid, index)
{
    if(!IsFurnitureListIndexValid(index))
        return 0;

    return g_player_furniture_list[playerid][index];
}

stock SetPlayerFurnitureListIndex(playerid, index, value)
{
    if(!IsFurnitureListIndexValid(index))
        return 0;

    return g_player_furniture_list[playerid][index] = value;
}

stock GetPlayerFurnListFirstIndex(playerid)
	return GetPlayerFurnitureListIndex(playerid, 0);

stock GetPlayerFurnitureListLastIndex(playerid)
    return GetPlayerFurnitureListIndex(playerid, (sizeof g_player_furniture_list[] - 1));

stock AddPlayerCountListedFurniture(playerid, count)
    return g_player_furniture[playerid][PF_COUNT_LISTED] += count;

stock DivPlayerCountListedFurniture(playerid, count)
    return g_player_furniture[playerid][PF_COUNT_LISTED] -= count;

stock GetPlayerCountListedFurniture(playerid)
    return g_player_furniture[playerid][PF_COUNT_LISTED];

stock IncrementPlayerFurniturePage(playerid)
    return g_player_furniture[playerid][PF_PAGE] ++;

stock DecrementPlayerFurniturePage(playerid)
    return g_player_furniture[playerid][PF_PAGE] --;

/* Почему именно цикл, а не разницу между наибольшим и наименьшим? Ответ прост: а что, если мы, допустим, 
решим продать(хотя, у тебя пока нет этой системы) какую то мебель из диапазона и тем, самым объект удалится 
и допустим, возлагая бы мы надежды на разницу между числами, мы бы получили не то число, что нам нужно.
К тому же, стоит не забывать после каких-либо действий, уничтожающих минимальный/максимальный из объектов
мебели, присваивать на его место либо следующий, если это минимальный объект, иначе предыдущий. */
stock GetHouseCountOfFurniture(houseid)
{
	new count,
		furn_data[E_FURNITURE_STRUCT],
		fmt_buffer[] = "%d %d %d %.4f %.4f %.4f %.4f %.4f %.4f",
		buffer[sizeof fmt_buffer + 
				(- 4 + 20) + 
				(- 2 + 5) + 
				(- 24 + 54)];

	for(new idx = GetHouseMinFurnObjectID(houseid), size = GetHouseMaxFurnObjectID(houseid); idx < size; idx ++)
	{
		Streamer_GetArrayData(STREAMER_TYPE_OBJECT, idx, E_STREAMER_EXTRA_ID, buffer);

		sscanf(buffer, "e<dddffffff>", furn_data[F_HOUSE_ID], furn_data[F_SLOT], furn_data[F_ID], furn_data[F_POS_X], furn_data[F_POS_Y], furn_data[F_POS_Z], furn_data[F_POS_RX], furn_data[F_POS_RY], furn_data[F_POS_RZ]);

		if(furn_data[F_HOUSE_ID] != houseid)
			continue;

		count ++;
	}

	return count; 
}

stock ShowPlayerInfoAboutFurnDialog(playerid, index)
{
    new fmt_str[] = 
    {
		"ID дома: %d\n"\
        "Слот мебели: %d\n"\
		"Модель мебели: %d\n"\
		"Название мебели: %s\n"\
		"Позиция по X: %.4f\n"\
		"Позиция по Y: %.4f\n"\
		"Позиция по Z: %.4f\n"\
		"Позиция по rX: %.4f\n"\
		"Позиция по rY: %.4f\n"\
		"Позиция по rZ: %.4f"
    },
    result_str[sizeof fmt_str +
            	(- 4 + 20) +
            	(- 2 + 5) +
                (- 2 + (MAX_FURNITURE_ITEM_NAME_LEN - 1)) +
				(- 24 + 54)],
    objectid = GetPlayerFurnitureListIndex(playerid, index),
	furn_data[E_FURNITURE_STRUCT],
	fmt_buffer[] = "%d %d %d %.4f %.4f %.4f %.4f %.4f %.4f",
	buffer[sizeof fmt_buffer + 
				(- 4 + 20) + 
				(- 2 + 5) + 
				(- 24 + 54)];

	Streamer_GetArrayData(STREAMER_TYPE_OBJECT, objectid, E_STREAMER_EXTRA_ID, buffer);

	sscanf(buffer, "e<dddffffff>", furn_data[F_HOUSE_ID], furn_data[F_SLOT], furn_data[F_ID], furn_data[F_POS_X], furn_data[F_POS_Y], furn_data[F_POS_Z], furn_data[F_POS_RX], furn_data[F_POS_RY], furn_data[F_POS_RZ]);

	new modelid = GetFurnitureItemModelID(furn_data[F_ID]),
		name[MAX_FURNITURE_ITEM_NAME_LEN];

	GetFurnitureItemName(furn_data[F_ID], name);

	format
	(
		result_str, sizeof result_str, 
		fmt_str, 
		furn_data[F_HOUSE_ID],
		furn_data[F_SLOT],
		modelid,
		name,
		furn_data[F_POS_X], furn_data[F_POS_Y], furn_data[F_POS_Z], 
		furn_data[F_POS_RX], furn_data[F_POS_RY], furn_data[F_POS_RZ]
	);

    return ShowPlayerDialog
    (
        playerid, DIALOG_INFO_FURNITURE, DIALOG_STYLE_LIST, 
        "{FFFFFF}Информация о мебели", 
        result_str, 
        "{bcbcbc}Закрыть", ""
    );
}

stock ShowPlayerFurnitureListDialog(playerid, bool: is_first_page = true, bool: is_page_prev = false) 
{
    if(IsHouseFirstFurnObject(/* тут ид дома игрока */))
        return SendClientMessage(playerid, -1, "У вашего дома нет мебели");
        
    new fmt_str[] = "{ffd966}%d",
        result_str[sizeof fmt_str + (- 2 + 10)],
        dest[sizeof result_str * MAX_FURNITURE_ON_PAGE] = 
        idx = -1,
        page = GetPlayerBusinessPage(playerid),
        //0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19

    if(is_page_prev == false)
    {
        if(is_first_page == false)
        {
            IncrementPlayerBusinessPage(playerid);
        	page = GetPlayerBusinessPage(playerid);
        }

        for(new i = GetHouseMinFurnObjectID(/* ид дома игрока */, end = GetHouseMaxFurnObjectID(/* ид дома игрока */); i <= end; i ++)
        {      
            if(idx == (sizeof g_player_furniture_list[] - 1))
                break;

            if(i < GetPlayerFurnitureListLastIndex(playerid))
                continue;

            SetPlayerFurnitureListIndex(playerid, ++ idx, i);

            format(result_str, sizeof result_str, fmt_str, i);
            strcat(dest, result_str);
	}

        if(!idx)
            return SendClientMessage(playerid, -1, "У Вашего дома нет мебели");

        AddPlayerCountListedFurniture(playerid, idx + 1);
    }
    else
    {
        idx = MAX_FURNITURE_ON_PAGE;

        new count_of_furn;

        for(new end = GetHouseMaxFurnObjectID(/* ид дома игрока */); end >= GetHouseMinFurnObjectID(/* ид дома игрока */; end --)
        {
            if(end > GetPlayerFurnListFirstIndex(playerid))
                continue;

            if(!idx)
                break;

            SetPlayerFurnitureListIndex(playerid, -- idx, end);

            count_of_furn ++;
        }

        for(new j; j < count_of_furn; j ++)
        {
            format(result_str, sizeof result_str, fmt_str, GetPlayerFurnitureListIndex(playerid, j));
            strcat(dest, result_str);
        }
        DivPlayerCountListedFurniture(playerid, count_of_furn);
    }
            
    new count = GetHouseCountOfFurniture(/* ид дома игрока */);

    if(GetPlayerCountListedFurniture(playerid) != count)
        strcat(dest, "\n{93c47d}>>>\t\t");

    if(page)
        strcat(dest, "\n{f44336}<<<\t\t");

    new fmt_buffer[] = "Список мебели вашего дома [%d/%d]", 
        buffer[sizeof fmt_buffer + (- 4 + 6)],
        result = (count % MAX_BUSINESS_ON_PAGE != 0 ? 1 : 0);

    format
    (
        buffer, sizeof buffer, 
        fmt_buffer, 
        page + 1,
        ((count / MAX_BUSINESS_ON_PAGE) + result)
        );
        
    return ShowPlayerDialog
    (
        playerid, DIALOG_FURNITURE_MAIN, DIALOG_STYLE_LIST, 
        buffer,
        dest, 
        "Выбрать", "Закрыть"
    );
}

/* В OnGameModeInit */
@__OnLoadFurniture();
@__OnLoadFurniture() 
{
	new Cache: query_result = mysql_query
	(
		/* ид соединения */,
		"SELECT COUNT(*) AS count_furniture FROM houses_furniture"
	),
	count_furniture;
	
	cache_get_value_name_int(0, "count_furniture", count_furniture);
		
	cache_delete(query_result);

	new furn_data[E_FURNITURE_STRUCT],
		fmt_str[] =
		{
			"(SELECT hf.house_id AS object1,NULL AS object2,NULL AS object3,NULL AS object4,NULL AS object5"\
			" FROM houses_furniture hf LEFT JOIN houses h ON hf.house_id=h.house_id"\
			" WHERE hf.house_id > %d LIMIT 1)"\
			" UNION ALL"\
			" (SELECT hfs.house_id,hfs.slot,NULL,NULL,NULL FROM houses_furniture_slots hfs"\
			" LEFT JOIN houses h ON hfs.house_id=h.house_id"\
			" WHERE hfs.house_id > %d LIMIT 1)"\
			" UNION ALL"\
			" (SELECT hfi.house_id,hfi.slot,hfi.furniture_id,NULL,NULL FROM houses_furniture_ids hfi"\
			" LEFT JOIN houses_furniture_slots hfs ON hfi.house_id=hfs.house_id AND hfi.slot=hfs.slot"\
			" WHERE hfi.house_id > %d AND hfi.slot > %d LIMIT 1)"\
			" UNION ALL"\
			" (SELECT hfp.house_id,hfp.slot,hfp.pos_x,hfp.pos_y,hfp.pos_z FROM houses_furniture_positions hfp"\
			" LEFT JOIN houses_furniture_slots hfs ON hfp.house_id=hfs.house_id AND hfp.slot=hfs.slot"\
			" WHERE hfp.house_id > %d AND hfp.slot > %d LIMIT 1)"\
			" UNION ALL"\
			" (SELECT hfrp.house_id,hfrp.slot,hfrp.r_pos_x,hfrp.r_pos_y,"\
			"hfrp.r_pos_z FROM houses_furniture_rot_positions hfrp"\
			" LEFT JOIN houses_furniture_slots hfs ON hfrp.house_id=hfs.house_id AND hfrp.slot=hfs.slot"\
			" WHERE hfrp.house_id > %d AND hfrp.slot > %d LIMIT 1)"
		},
		result_str[sizeof fmt_str + (- 10 + 50) + (- 6 + 30)];

	for(new idx; idx < count_furniture; idx ++)
	{
		format
		(
			result_str, sizeof result_str, 
			fmt_str,
			furn_data[F_HOUSE_ID],
			furn_data[F_HOUSE_ID],
			furn_data[F_HOUSE_ID],
			furn_data[F_SLOT],
			furn_data[F_HOUSE_ID],
			furn_data[F_SLOT],
			furn_data[F_HOUSE_ID],
			furn_data[F_SLOT]
		);

		query_result = mysql_query(/* ид соединения */, result_str);

		for(new j; j < MAX_FURNITURE_LOAD_DATA; j ++)
		{
			if(FURNITURE_LOAD_TYPE_POS <= j <= (FURNITURE_LOAD_TYPE_POS + 2))
			{
				cache_get_value_name_float(j, "object3", furn_data[F_POS_X]);
				cache_get_value_name_float(j, "object4", furn_data[F_POS_Y]);
				cache_get_value_name_float(j, "object5", furn_data[F_POS_Z]);
			}

			if(FURNITURE_LOAD_TYPE_ROT_POS <= j <= (FURNITURE_LOAD_TYPE_ROT_POS + 2))
			{
				cache_get_value_name_float(j, "object3", furn_data[F_POS_RX]);
				cache_get_value_name_float(j, "object4", furn_data[F_POS_RY]);
				cache_get_value_name_float(j, "object5", furn_data[F_POS_RZ]);
			}

			switch(j)
			{
				case FURNITURE_LOAD_TYPE_HOUSE:
					cache_get_value_name_int(j, "object1", furn_data[F_HOUSE_ID]);
				case FURNITURE_LOAD_TYPE_SLOT: 
					cache_get_value_name_int(j, "object2", furn_data[F_SLOT]);
				case FURNITURE_LOAD_TYPE_ID:
					cache_get_value_name_int(j, "object3", furn_data[F_ID]);
			}

			CreateHouseFurniture
			(
				furn_data[F_HOUSE_ID],
				furn_data[F_SLOT],
				furn_data[F_ID], 
				furn_data[F_POS_X], furn_data[F_POS_Y], furn_data[F_POS_Z], 
				furn_data[F_POS_RX], furn_data[F_POS_RY], furn_data[F_POS_RZ],
				(idx == (count_furniture - 1))
			);
		}
	}
	return printf("<МЕБЕЛИ ЗАГРУЖЕНО>: [%d]", count_furniture);
}

public OnDialogResponse(playerid, dialogid, response, listitem, const inputtext[])
{
    switch(dialogid)
    {
    	case DIALOG_FURNITURE_MAIN: 
        {
            if(response)
            {
                if(!strcmp(inputtext, ">>>", true)) 
                    return ShowPlayerBusinessListDialog(playerid, false);

                if(!strcmp(inputtext, "<<<", true)) 
                    return ShowPlayerBusinessListDialog(playerid, false, true);

                return ShowPlayerInfoAboutBusinDialog(playerid, listitem);
            }

            ClearPlayerFurnData(playerid);
            return ClearPlayerFurnList(playerid);
        }
    }

	return 1;
}



Собственно, тебе остаётся лишь создать диалоги с соответствующим именем. Думаю, суть запроса объяснять не нужно, ибо ты более-менее разбираешься в MYSQL. По логике вещей, код должен работать. Так, как я не знал лимита мебели для дома, то решил привязать данные непосредственно к объекту. Сегодня у меня уже не осталось сил объяснять, если честно, возможно завтра. Хотя, тут нечего объяснять, ибо это, по сути дела, идентичный код. Вопрос, скорее, в работоспособности, ибо я его не тестировал и, в целом, делал, не имея базовой идеи. Архитектура таблиц, думаю, ясна. Если, по традиции, будут нюансы, то можешь писать, ибо повторяю: я его не тестировал

Сообщение отредактировал Perdolinka: 28 мая 2023 - 10:58

0

#40
Пользователь офлайн   DigitalOneThe 

  • Эксперт
  • Вставить ник
  • Раскрыть информацию

Просмотр сообщенияPerdolinka (27 мая 2023 - 21:38) писал:

Нажмите сюда, чтобы прочитать это сообщение. [Показать]


Насчёт функции OnLoadFurniture, мне всё делать так-же как и с загрузкой других данных из базы?

То-есть, ну:

new rows;
cache_get_data(rows);

if (rows) {
    ...
}, // и вообще, нужна ли тут проверка на то существуют ли строки.


И кстати, что за object1, object2, object3? Это типа сможет всего 3 объекта в доме хранится? Чёт я не особо понял

Сообщение отредактировал DigitalOneThe: 28 мая 2023 - 12:55

0

Поделиться темой:


  • (4 Страниц) +
  • « Первая
  • 2
  • 3
  • 4
  • Вы не можете создать новую тему
  • Вы не можете ответить в тему

1 человек читают эту тему
0 пользователей, 1 гостей, 0 скрытых пользователей


Яндекс.Метрика