====== Моды ======

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

Официальные моды можно найти в самой игре. В главном меню сверху есть вкладка **Моды**.

===== Источники =====

По-умолчанию у вас должно быть 3 источника модов: **Локальные моды**, **Моды для патронов** и **Official**.
  * Локальные моды - Это моды, которые уже установлены
  * Моды для патронов - Официальные источник модов, доступный только патронам.
  * Official - Официальный источник модов, доступный всем.

==== Список источников ====

  * Официальные моды: http://mods.kunoichi-trainer.ninja/official/manifest.json
  * Переводы игры: http://mods.kunoichi-trainer.ninja/translations/manifest.json
  * Моды для разработчиков модов: https://bitbucket.org/dinaki/dev-mods/raw/master/manifest.json


[[ru:mods:create_source|Как создать свой источник]]

===== Моды =====

==== Как установить официальный мод ====

  - Зайдите в игру
  - Сверху выберите вкладку **Моды**
  - Выберите источник модов. Например, Official.
  - Выберите мод.
  - Нажмите кнопку **Установить**.
  - Перезагрузите игру.

==== Как установить сторонний мод ====
  - Распакуйте архив с модом в папку с модами. См. [[#где_хранятся_моды|где находится папка с модами]].

==== Где хранятся моды ====
По-умолчанию, моды находятся в папке ''Kunoichi Trainer/mods''. Папки ''mods'' может не быть. В таком случае её нужно создать вручную.

Так же в настройках игры, если пролистать в самый низ, можно указать другой путь до папки с модами.

==== Как отключить мод ====
  - Откройте главное меню.
  - Выберите источник **Локальные моды**.
  - Выберите мод.
  - Нажмите **Отключить**.

-------

Каждый мод должен находится в отдельной папке, которая называется так же, как и id мода.

В папке мода должен быть файл ''manifest.json''. В этом файле должна быть такая же информация, что и в источнике, кроме поля ''file_name''.

=== Пример ===

<code javascript>
{
    "id": "mod-id",
    "name": "Название мода",
    "version": "1.0",
    "description": "Описание мода",
    "game_version": "0.16"
}
</code>

==== Скрипты ====
Файлы с кодом должны иметь формат **.rpym**, либо **.rpymc**. Это тоже самое, что и **.rpy** и **.rpyc**. Не знаете про .rpy и .rpyc? Смотрите [[https://www.renpy.org/doc/html/language_basics.html#files|документацию RenPy]].

Вы пишите код мода в файлах .rpym, при запуске игры они будут скомпилированы в .rpymc.

Файлы могут лежать просто в папке, либо в **.rpa** архиве.

==== Как заменить изображение из игры ====

Для этого необходимо в ''manifest.json'' добавить новый параметр ''merge_folders'', который является массивом строк.
В этом параметре указывается список папок, файлы из которых будут распознаваться игрой, как будто они были  в самой игре изначально.

Чтобы изменить изображение в игре, нужно знать расположение оригинального изображения. В папке, указанной в параметре ''merge_folders'', нужно разместить новое изображение по такому же пути, что и оригинальное изображение.

=== Пример ===

Простой мод, который заменяет фон комнаты, в которой игрок появляется в самом начале игры.

Оригинальный фон хранится по такому пути:
<code>
images/bg/beginning_room.webp
</code>

Структура папок мода:
<code>
 mods
└───mod-id
│   │   manifest.json
│   └───my_folder
│       └───images
│           └───bg
│               └───beginning_room.webp

</code>

Где ''mod-id/my_folder/images/bg/beginning_room.webp'' - это новое изображение, на которое хотим заменить оригинальное.

Содержимое файла ''manifest.json'':
<code javascript>
{
    "id": "mod-id",
    "name": "Название мода",
    "version": "1.0",
    "description": "Описание мода",
    "game_version": "0.16",
    "merge_folders": ["my_folder"]
}
</code>

Это всё, что нужно, чтобы заменить изображение.

==== Как взаимодействовать с игровыми событиями ====
Для этого необходимо создать класс (в файле **.rpym**), наследующий класс ''Module'' и подписаться на нужные события. См. [[ru:mods:events|Список событий]]

Например, модуль, который реагирует на изменение времени суток и смену локации.
<code python>
init python:
    # У каждого модуля должно быть уникальное название и id
    class DemoModule(Module):
        id="demo"
        subscribe_on_events=["time_update", "change_location"]

        def on_event(self, event):
            if event.type == "time_update":
                if event.is_morning:
                    renpy.notify("Наступило утро")
                elif event.is_evening:
                    renpy.notify("Наступил вечер")
            elif event.type == "change_location":
                renpy.notify("Новая локация: " + event.new_location.id)

</code>

==== Как добавить предмет в магазин ====
Для этого, нужно создать переменную от класса [[ru:mods:classes#item|Item]], если это просто предмет, или от класса [[ru:mods:classes#outfit|Outfit]], если это элемент одежды.

  * Желательно, чтобы название переменной начиналось с ''item_''.
  * Название предмета должно быть уникальным и не должно повторятся.

=== Примеры ===

Добавление обычного предмета в магазин Тен-Тен.

<code python>
init python:
  item_pen = Item(
    name=__("Ручка"),
    cost=5,
    icon="my_mod_folder/pen.webp",
    descr=__("Ручка с чернилами."),
    shop="tenten",
  )
</code>

Добавление одежды в магазин Тен-Тен.

<code python>
init python:
  item_ino_my_new_costume = Outfit(
    name=__("Новый костюм для Ино"),
    cost=100,
    descr=__("Описание предмета"),
    char="Ino",
    lust=10,
    layer="costume",
    val="my_new_costume",
    shop="tenten",
    ptr=False,
    icon=KTCharInventoryPreview(
      char_name="ino",
      layers=ino_preview_layers + [("costume", "my_new_costume")],
      crop=ino_costume_inv_preview
    ),
  )
</code>

Структура папок мода:
<code>
mods
└───mod-id
│   │   manifest.json
│   │   item.rpym
│   └───merge_folder
│       └───images
│           └───characters
│               └───ino
│                   └───costume
│                       └───my_new_costume.webp

</code>

При таком подходе предмет будет в магазине, только если начать новую игру. Чтобы добавить предмет в магазин, если игрок загружает уже существующее сохранение надо использовать [[ru:mods:classes#module|Module]]. См. [[ru:mods#как_взаимодействовать_с_игровыми_событиями|Как взаимодействовать с игровыми событиями]] и [[ru:mods:events#game_loaded|событие game_loaded]].

Получится что-то вроде такого:
<code python>
def on_event(self, event):
  if event.type == "game_loaded" and not inv_shop.has_item(item_my_item):
    inv_shop.add(item_my_item)
</code>

===== Игровые переменные =====
==== Время суток ====
<code python>
if game.time.is_morning:
    "Сейчас день"
elif game.time.is_evening:
    "Сейчас вечер"

$ game.time.set_morning()
"Сейчас точно день"
$ game.time.set_evening()
"Сейчас точно вечер"

$ game.time.next_cycle()
"Если был день, сейчас вечер. Если был вечер, сейчас день и счетчик дней увеличился."

$ game.time.next_day()
"Сейчас точно день и счетчик дней увеличился на 1."

$ game.time.skip_days(10)
"Счетчик дней увеличился на 10."
</code>