Рейтинг - 5.0 (1)

В этом уроке мы будем учится работать с файлом "shopping.dat" и рассмотрим основные опкоды для работы с ним.

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

Внутри файла есть две основные секции (в начале идёт название "section"): prices и shops. В первой секции идёт описание товаров (предметов), а во второй — описание магазинов, в которых и будут эти товары.

Секция "prices"

Секция "prices" дополнительно разделена на типы, используя тоже ключевое слово "section". Эти типы группируют товары по определённому признаку. По умолчанию используются 6 типов: "CarMods", "Clothes", "Haircuts", "Tattoos", "Food" и "Weapons". Есть ещё 3 пустые секции, которые не используются в игре ("Furniture", "Gifts" и "Property").

Формат каждого типа отличается по своей структуре. Давайте разбираться с тем, что есть. Каждый тип гарантировано имеет 7 параметров:

ПараметрКоличествоОписание
name1Идентификатор предмета
nametag1GXT-имя предмета
stats to change4На какие характеристики игрока будет влиять покупка (используется не всегда)
price1Цена товара

Идентификатор предмета — это уникальное имя. Его мы запомним, так как чуть ниже он будет упомянут. Отдельное внимание нужно обратить на характеристики. Они описаны четырьмя параметрами, но влиять можно только на два стата.

Характеристики описаны в следующей последовательности:

ИМЯ_СТАТА_1 ЗНАЧЕНИЕ_СТАТА_1 ИМЯ_СТАТА_2 ЗНАЧЕНИЕ_СТАТА_2

Вот таблица статов, которые можно использовать:

ХарактеристикаОписание
fatВлияет на вес Карла
healthВлияет на здоровье Карла
caloriesВлияет на вес и здоровье Карла
staminaВлияет на выносливость Карла
respectВлияет на уважение Карла
sexyВлияет на привлекательность Карла

Значение стата указывается числом. Если покупка не влияет на характеристику, то используется 0. Если влияет, то положительное число будет увеличивать характеристику, а отрицательное — уменьшать (значения от -128 до 127). Если стат вообще не нужно использовать, то достаточно поставить символ - (вместо имени и значения). Пример:

ИМЯ_СТАТА_1 ЗНАЧЕНИЕ_СТАТА_1 - -
respect 0 sexy 0
respect 0 - -

Это основные параметры. Некоторые секции имеют в своём формате дополнительные параметры (extra; встречаются в секицях "тату", "причёски" и "одежда"). Они представлены в виде целых чисел или строк (в скрипте строки конвертируются в число алгоритмом CRC).

Секция "shops"

С товарами разобрались. Перейдём к магазинам. Структура этой секции проще. Она содержит в себе другие секции, которые описывают магазины. Общая структура такова:

section NAME
 type TYPE
 item ID
end

Имя секции (NAME) — уникальный идентификатор. Это имя используется в одном из опкодов, поэтому запомним его. Далее "type" — это слово указывает, какие товары будут использованы из секции "prices". Имя типа совпадает с именем секции, которые я описывал ранее. Далее идут предметы (по одному на строку). После слова "item" пишется уникальный идентификатор предмета.

Практика

С теорией мы кое-как разобрались. Давайте теперь посмотрим на опкоды, которые используются для работы с файлом "shopping.dat". Сначала идёт загрузка цен и магазинов:

075E: load_shopping_data_PRICES_subsection "ammun1" 
075D: load_shopping_data_SHOPS_subsection "Weapons"

Обратите внимание, что названия опкодов неправильные (на момент написания статьи)! Опкод 075E загружает информацию о магазинах, а 075D — о ценах. Я не увидел разницы в порядке их загрузки. Рекомендую использовать именно представленный мной порядок, именно так их использовали разработчики.

Здесь:
"ammun1" - имя (идентификатор) магазина
"Weapons" - тип (группа) цен

Как только работа с магазинами завершена, нам нужно выгрузить из памяти эту информацию, используя опкод:

087C: release_shopping_data

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

07B0: get_active_shop_name_to s$CURRENT_SHOP_ID

Изначально я думал, что этот опкод получает имя интерьера, но оказалось совсем другое :)

Здесь:
s$CURRENT_SHOP_ID - переменная, в которую будет записан ID (имя) загруженного магазина. Возвращает пустую строку, если ничего не загружено.

Давайте посмотрим, что можно сделать после загрузки! Первым на очереди станет опкод:

075F: store_shopping_data_entries_number_to $MAX_ITEMS_COUNT

Он получает количество товаров, которые есть в магазине. В нашем случае туда будет записано число 16 (это по умолчанию). Запомним переменную $MAX_ITEMS_COUNT и идём дальше:

0760: store_shopping_data_index 0 textureCRC_to $ITEM

Этот опкод позволяет сохранить идентификатор предмета за указанным индексом. Не обращайте внимания на описание; "textureCRC_to" не соответствует действительности (надеюсь, что это скоро исправят).

Здесь:
0 - индекс
$ITEM - сохраняется идентификатор предмета

Индекс — это номер в списке товаров в текущем магазине. Диапазон варьируется в зависимости от количества товаров. Максимальный индекс мы можем получить, отняв единицу от количества товаров (опкод 075F). Таким образом мы можем перебрать весь список товаров, используя этот код:

0A8F: $MAX_INDEX = $MAX_ITEMS_COUNT - 1 // int
for $CURRENT_INDEX = 0 TO $MAX_INDEX 
 0760: store_shopping_data_index $CURRENT_INDEX textureCRC_to $ITEM 
 // ...
end

Дальше идут опкоды, которые позволяют извлечь информацию о предмете:

0761: get_shopping_item_with_textureCRC $ITEM price_to $PPRICE
078C: get_shopping_item_with_textureCRC $ITEM nametag_to s$GXT

Опкод 0761 получает цену предмета, а 075F — GXT-ключ с названием товара. Давайте напишем небольшой скрипт, который будет выводить информацию о товаре:

// ...
075E: load_shopping_data_PRICES_subsection "ammun1" 
075D: load_shopping_data_SHOPS_subsection "Weapons"

075F: store_shopping_data_entries_number_to $MAX_ITEMS_COUNT
0A8F: $MAX_INDEX = $MAX_ITEMS_COUNT - 1 // int
03F0: enable_text_draw 1

while true
wait 0 
 if
 00E1: player 0 pressed_key 15 // ~k~~VEHICLE_ENTER_EXIT~
 then
 jump @end
 end
 0@ = 20.0
 for $CURRENT_INDEX = 0 TO $MAX_INDEX 
 0760: store_shopping_data_index $CURRENT_INDEX textureCRC_to $ITEM 
 
 0761: get_shopping_item_with_textureCRC $ITEM price_to $PPRICE
 078C: get_shopping_item_with_textureCRC $ITEM nametag_to s$GXT 
 
 038E: draw_box_position 320.0 224.0 size 640.0 448.0 RGBA 0 0 0 16
 0343: set_text_draw_linewidth 640.0
 033E: set_draw_text_position 20.0 0@ GXT s$GXT
 0343: set_text_draw_linewidth 640.0
 045A: draw_text_1number 320.0 0@ GXT 'DOLLAR' number $PPRICE
 0@ += 16.0
 end
end

:end
087C: release_shopping_data
// ...

Результат:



Неплохо! Давайте двигаться дальше. А тут нас ждут опкоды, связанные с модификаторами цен:

08C8: set_shopping_item_with_textureCRC $ITEM price_to 16000
08C9: reset_shopping_item $ITEM price

Опкод 08C8 устанавливает новую цену на выбранный товар, независимо от настроек в файле. Его можно использовать вне цикла; как только новая цена задана, она используется постоянно. Опкод 08C9, должно быть, сбрасывает цену по умолчанию, однако у меня никакой реакции не происходило (он встречается только в скрипте гардероба). Следует отметить, что новая цена не сохраняется навсегда. Как только мы используем опкод "087C", товары вновь будут иметь старые цены.

Далее рассмотрим опкод, который получает данные об экстра параметре:

0783: get_shopping_item_with_textureCRC $ITEM flag 0 store_to $EXTRA1

Мы можем получить данные об экстра параметре в любой секции, даже если она не содержит экстр. Если параметра нет, то в переменную $EXTRA1 будет записано число 0.

Здесь:
0 - номер экстра параметра
$EXTRA1 - переменная, в которую будет записано значение этого параметра

Максимальное количество экстр: 2 (значения 0 и 1 соответственно). Для типа "Weapons" нет таких параметров но, к моему удивлению, опкод достал данные об экстрах (при 0). Изначально я подумал, что это количество патронов, так как оно присутствует в секции, но результат был совсем другим: были числа, но они не соответствовали моим догадкам (ниже будет пример)!

Следующий опкод осуществляет покупку предмета:

0790: charge_money_for_shopping_item_with_textureCRC $ITEM

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

И последний опкод, который входит в "основную обойму":

0942: item_with_textureCRC $ITEM is_clothing

Эта проверка возвращает "true" в том случае, если предмет был когда-либо куплен опкодом 0790. Информация о покупке хранится всегда; в сейв-файле (или main.scm, точно не скажу).

Давайте рассмотрим пример с выбором предмета и его покупкой:

// ...

// загружаем модели оружия
075E: load_shopping_data_PRICES_subsection "ammun1" 
075D: load_shopping_data_SHOPS_subsection "Weapons"

075F: store_shopping_data_entries_number_to $MAX_ITEMS_COUNT
0A8F: $MAX_INDEX = $MAX_ITEMS_COUNT - 1 // int
03F0: enable_text_draw 1
32@ = 0

while true
wait 0 
 if
 00E1: player 0 pressed_key 15 // ~k~~VEHICLE_ENTER_EXIT~
 then
 jump @end
 end
 
 if and
 32@ > 150
 0AB0: key_pressed 38 // up
 then
 5@ -= 1 
 32@ = 0
 if
 8029: not 5@ >= 0
 then
 008B: 5@ = $MAX_INDEX // (int)
 end
 end 
 if and
 32@ > 150
 0AB0: key_pressed 40 // down
 then
 5@ += 1 
 32@ = 0
 if
 001F: 5@ > $MAX_INDEX // (int)
 then
 5@ = 0
 end
 end
 
 0@ = 20.0
 for $CURRENT_INDEX = 0 TO $MAX_INDEX 
 0760: store_shopping_data_index $CURRENT_INDEX textureCRC_to $ITEM 
 
 0761: get_shopping_item_with_textureCRC $ITEM price_to $PPRICE
 078C: get_shopping_item_with_textureCRC $ITEM nametag_to s$GXT 
 0783: get_shopping_item_with_textureCRC $ITEM flag 0 store_to $EXTRA1 
 0783: get_shopping_item_with_textureCRC $ITEM flag 1 store_to $EXTRA2

 038E: draw_box_position 320.0 224.0 size 640.0 448.0 RGBA 0 0 0 16 

 if
 0942: item_with_textureCRC $ITEM is_clothing
 then
 0343: set_text_draw_linewidth 640.0
 045A: draw_text_1number 5.0 0@ GXT 'DOLLAR' number 1 
 end
 
 if
 07D6: 5@ == $CURRENT_INDEX // @ == $ (int)
 then
 0340: set_text_draw_RGBA 0 255 0 255 
 if
 00E1: player 0 pressed_key 16 // ~k~~PED_SPRINT~
 then
 0790: charge_money_for_shopping_item_with_textureCRC $ITEM
 08C9: reset_shopping_item $ITEM price
 end 
 end
 
 0343: set_text_draw_linewidth 640.0
 033E: set_draw_text_position 20.0 0@ GXT s$GXT
 0343: set_text_draw_linewidth 640.0
 045A: draw_text_1number 320.0 0@ GXT 'DOLLAR' number $PPRICE 
 0343: set_text_draw_linewidth 640.0
 045A: draw_text_1number 460.0 0@ GXT 'DOLLAR' number $EXTRA1 
 0343: set_text_draw_linewidth 640.0
 045A: draw_text_1number 500.0 0@ GXT 'DOLLAR' number $EXTRA2
 
 0@ += 16.0
 end 
end

:end
087C: release_shopping_data
// выгружаем модели оружия
// ...

Результат:



Похожим способом делается покупка для остальных магазинов. Это вся базовая информация, которая у меня есть.


Теги: Цены, shops, prices, shopping.dat, Магазины
Вход на сайт

Поиск
Категории раздела
Мини-чат
Пожалуйста, все вопросы по скриптингу задавать на форуме!
Наш опрос
Кто из главных героев GTA 5 круче?
Всего ответов: 33
Активность на сайте
Пожертвования
Кошельки WebMoney:
U859420971000
R407741810602
Z331072372430
E314272616890
Друзья сайта
Полезные ресурсы
Статистика

Онлайн всего: 1
Гостей: 1
Пользователей: 0

Сегодня нас посетили:
wmysterio, FlameBack
Рекомендую