Изменения

Перейти к навигации Перейти к поиску
м
Замена текста — «tt>» на «samp>»
Строка 1: Строка 1:  
← [[Модификации:Индекс|Индекс]]
 
← [[Модификации:Индекс|Индекс]]
{{Переведите}}
+
 
 
На этой странице объясняется, как игра хранит и анализирует данные расписания NPC, которые определяют, куда отправляются NPC и что они делают, когда попадают туда. Это расширенное руководство для разработчиков модов.
 
На этой странице объясняется, как игра хранит и анализирует данные расписания NPC, которые определяют, куда отправляются NPC и что они делают, когда попадают туда. Это расширенное руководство для разработчиков модов.
    
==Источник==
 
==Источник==
Данные расписания хранятся в <tt>Content/Characters/schedules/*.xnb</tt> (один файл на персонажа), которые могут быть [[Модификации:Редактирование_XNB_файлов#Распаковывание и упаковывание ресурсов|распакованы для редактирования]]. Вот исходные данные по Абигейл по состоянию на {{version|1.5.1}} для примера:
+
Данные расписания хранятся в <samp>Content/Characters/schedules/*.xnb</samp> (один файл на персонажа), которые могут быть [[Модификации:Редактирование_XNB_файлов#Распаковывание и упаковывание ресурсов|распакованы для редактирования]]. Вот исходные данные по Абигейл по состоянию на {{version|1.5.1}} для примера:
    
{{collapse|Данные|content=<syntaxhighlight lang="json">
 
{{collapse|Данные|content=<syntaxhighlight lang="json">
Строка 35: Строка 35:     
Примечание:
 
Примечание:
* Большинство текстов чувствительны к регистру (т.е. <tt>Mon</tt> '''не''' тоже самое, что <tt>mon</tt>).
+
* Большинство текстов чувствительны к регистру (т.е. <samp>Mon</samp> '''не''' тоже самое, что <samp>mon</samp>).
* Логика игры для ключей расписания находится в <tt>NPC::getSchedule</tt>.
+
* Логика игры для ключей расписания находится в <samp>NPC::getSchedule</samp>.
    
===Расписание в браке===
 
===Расписание в браке===
 
Они применяются, если NPC женат на игроке (не обязательно главном). '''Женатые NPC не используют никаких других расписаний.'''
 
Они применяются, если NPC женат на игроке (не обязательно главном). '''Женатые NPC не используют никаких других расписаний.'''
   −
{| class="wikitable"
+
{|class="wikitable"
 
|-
 
|-
 
! Синтаксис
 
! Синтаксис
 
! Описание
 
! Описание
 
|-
 
|-
| <tt>marriage_{{t|season}}_{{t|day of month}}</tt>
+
| <samp>marriage_{{t|season}}_{{t|day of month}}</samp>
| Применяется в указанную дату.<br /><small>Пример: <tt>marriage_spring_26</tt></small>
+
| Применяется в указанную дату.<br /><small>Пример: <samp>marriage_spring_26</samp></small>
 
|-
 
|-
| <tt>marriageJob</tt>
+
| <samp>marriageJob</samp>
 
| Используется Харви во вторник/четверг, Мару во вторник/четверг, Пенни во вторник/среду/пятницу.
 
| Используется Харви во вторник/четверг, Мару во вторник/четверг, Пенни во вторник/среду/пятницу.
 
|-
 
|-
| <tt>marriage_{{t|day of week}}</tt>
+
| <samp>marriage_{{t|day of week}}</samp>
| Применяется в указанный день недели, когда нет дождя.<br /><small>Пример: <tt>marriage_Mon</tt></small>
+
| Применяется в указанный день недели, когда нет дождя.<br /><small>Пример: <samp>marriage_Mon</samp></small>
 
|}
 
|}
   Строка 59: Строка 59:  
Такие расписания применяются к любому NPC, не состоящему в браке. Если ни один из этих ключей не совпадает, у персонажа не будет расписания на этот день.
 
Такие расписания применяются к любому NPC, не состоящему в браке. Если ни один из этих ключей не совпадает, у персонажа не будет расписания на этот день.
   −
{| class="wikitable"
+
{|class="wikitable"
 
|-
 
|-
 
! Синтаксис
 
! Синтаксис
 
! Описание
 
! Описание
 
|-
 
|-
| <tt>{{t|season}}_{{t|day of month}}</tt>
+
| <samp>{{t|season}}_{{t|day of month}}</samp>
| Применяется в указанную дату.<br /><small>Пример: <tt>spring_15</tt></small>
+
| Применяется в указанную дату.<br /><small>Пример: <samp>spring_15</samp></small>
 
|-
 
|-
| <tt>{{t|day of month}}_{{t|hearts}}</tt>
+
| <samp>{{t|day of month}}_{{t|hearts}}</samp>
| Применяется в указанный день месяца, если у ''любого'' игрока есть по крайней мере столько [[Дружба|сердец]] с NPC. Если применяется несколько расписаний, используется то, у которого наибольшее число сердец.<br /><small>Пример: <tt>11_6</tt></small>
+
| Применяется в указанный день месяца, если у ''любого'' игрока есть по крайней мере столько [[Дружба|сердец]] с NPC. Если применяется несколько расписаний, используется то, у которого наибольшее число сердец.<br /><small>Пример: <samp>11_6</samp></small>
 
|-
 
|-
| <tt>{{t|day of month}}</tt>
+
| <samp>{{t|day of month}}</samp>
| Применяется в указанный день месяца.<br /><small>Пример: <tt>16</tt></small>
+
| Применяется в указанный день месяца.<br /><small>Пример: <samp>16</samp></small>
 
|-
 
|-
| <tt>bus</tt>
+
| <samp>bus</samp>
 
| Для [[Пэм]], применяется только если автобус отремонтирован.
 
| Для [[Пэм]], применяется только если автобус отремонтирован.
 
|-
 
|-
| <tt>rain2</tt>
+
| <samp>rain2</samp>
 
| 50% шанс в дождливый день.
 
| 50% шанс в дождливый день.
 
|-
 
|-
| <tt>rain</tt>
+
| <samp>rain</samp>
 
| Применяется в дождливые дни.
 
| Применяется в дождливые дни.
 
|-
 
|-
| <tt>{{t|season}}_{{t|day of week}}_{{t|hearts}}</tt>
+
| <samp>{{t|season}}_{{t|day of week}}_{{t|hearts}}</samp>
| Применяется в указанный сезон и день недели, если у ''любого'' игрока есть по крайней мере столько [[Дружба|сердец]] с NPC. Если применяется несколько расписаний, используется то, у которого наибольшее число сердец.<br /><small>Пример: <tt>spring_Mon_6</tt></small>
+
| Применяется в указанный сезон и день недели, если у ''любого'' игрока есть по крайней мере столько [[Дружба|сердец]] с NPC. Если применяется несколько расписаний, используется то, у которого наибольшее число сердец.<br /><small>Пример: <samp>spring_Mon_6</samp></small>
 
|-
 
|-
| <tt>{{t|season}}_{{t|day of week}}</tt>
+
| <samp>{{t|season}}_{{t|day of week}}</samp>
| Применяется в указанный сезон и день недели.<br /><small>Пример: <tt>spring_Mon</tt></small>
+
| Применяется в указанный сезон и день недели.<br /><small>Пример: <samp>spring_Mon</samp></small>
 
|-
 
|-
| <tt>{{t|day of week}}</tt>
+
| <samp>{{t|day of week}}</samp>
| Применяется в указанный день недели.<br /><small>Пример: <tt>Mon</tt></small>
+
| Применяется в указанный день недели.<br /><small>Пример: <samp>Mon</samp></small>
 
|-
 
|-
| <tt>{{t|season}}</tt>
+
| <samp>{{t|season}}</samp>
| Применяется в указанный сезон.<br /><small>Пример: <tt>spring</tt></small>
+
| Применяется в указанный сезон.<br /><small>Пример: <samp>spring</samp></small>
 
|-
 
|-
| <tt>spring_{{t|day of week}}</tt>
+
| <samp>spring_{{t|day of week}}</samp>
| Применяется (в любое время года) в указанный день недели.<br /><small>Пример: <tt>spring_Mon</tt></small>
+
| Применяется (в любое время года) в указанный день недели.<br /><small>Пример: <samp>spring_Mon</samp></small>
 
|-
 
|-
| <tt>{{t|season}}_{{t|day of week}}_{{t|hearts}}</tt>
+
| <samp>{{t|season}}_{{t|day of week}}_{{t|hearts}}</samp>
| Применяется в указанный сезон, если у ''любого'' игрока есть по крайней мере столько [[Дружба|сердец]] с NPC. Если применяется несколько расписаний, используется то, у которого наибольшее число сердец.<br /><small>Пример: <tt>spring_Mon_6</tt></small>
+
| Применяется в указанный сезон, если у ''любого'' игрока есть по крайней мере столько [[Дружба|сердец]] с NPC. Если применяется несколько расписаний, используется то, у которого наибольшее число сердец.<br /><small>Пример: <samp>spring_Mon_6</samp></small>
 
|-
 
|-
| <tt>spring</tt>
+
| <samp>spring</samp>
 
| Применяется всегда
 
| Применяется всегда
 
|}
 
|}
Строка 108: Строка 108:     
===Начальные команды===
 
===Начальные команды===
Сценарий может содержать одну начальную команду в качестве первого поля в сценарии перед первым <tt>/</tt>. Команда <tt>GOTO</tt> также может появиться в следующих двух полях после <tt>MAIL</tt> или в следующем поле после <tt>NOT</tt>.
+
Сценарий может содержать одну начальную команду в качестве первого поля в сценарии перед первым <samp>/</samp>. Команда <samp>GOTO</samp> также может появиться в следующих двух полях после <samp>MAIL</samp> или в следующем поле после <samp>NOT</samp>.
   −
{| class="wikitable"
+
{|class="wikitable"
 
|-
 
|-
 
! Команда
 
! Команда
 
! Описание
 
! Описание
 
|-
 
|-
| <tt>GOTO {{t|key}}</tt>
+
| <samp>GOTO {{t|key}}</samp>
| (Примечание: эта строка применяется только в том случае, если <tt>GOTO</tt> является первой командой. Если это не так, смотри <tt>GOTO</tt> ниже.)<br />Завершите текущий сценарий и вместо этого загрузите расписание с заданным ключом. Если ключ "сезон", вместо него используется текущее название сезона. Если расписание не существует или не может быть проанализировано, вместо него будет использоваться расписание <tt>spring</tt>.<br /><small>Пример: <tt>GOTO spring</tt></small>
+
| (Примечание: эта строка применяется только в том случае, если <samp>GOTO</samp> является первой командой. Если это не так, смотри <samp>GOTO</samp> ниже.)<br />Завершите текущий сценарий и вместо этого загрузите расписание с заданным ключом. Если ключ "сезон", вместо него используется текущее название сезона. Если расписание не существует или не может быть проанализировано, вместо него будет использоваться расписание <samp>spring</samp>.<br /><small>Пример: <samp>GOTO spring</samp></small>
 
|-
 
|-
| <tt>NOT friendship {{t|npc name}} {{t|hearts}}</tt>
+
| <samp>NOT friendship {{t|npc name}} {{t|hearts}}</samp>
| Завершите текущий сценарий, если ''любого'' игрока ''есть'' как минимум {{t|hearts}} [[Дружба|сердечек]] с любым из указанных NPC (можно перечислить несколько). Если сценарий завершен, то вместо этого используется расписание <tt>spring</tt>. <br /><small>Например: <tt>NOT friendship Sebastian 6 Abigail 3</tt> (сценарий заканчивается, если у любого игрока 6+ сердец с Себастианом и/или 3+ сердца с Абигейл).</small>
+
| Завершите текущий сценарий, если ''любого'' игрока ''есть'' как минимум {{t|hearts}} [[Дружба|сердечек]] с любым из указанных NPC (можно перечислить несколько). Если сценарий завершен, то вместо этого используется расписание <samp>spring</samp>. <br /><small>Например: <samp>NOT friendship Sebastian 6 Abigail 3</samp> (сценарий заканчивается, если у любого игрока 6+ сердец с Себастианом и/или 3+ сердца с Абигейл).</small>
 
|-
 
|-
| <tt>NOT</tt>
+
| <samp>NOT</samp>
| Команда игнорируется, если следующее слово не <tt>friendship</tt>.
+
| Команда игнорируется, если следующее слово не <samp>friendship</samp>.
 
|-
 
|-
| <tt>MAIL {{t|letter ID}}</tt>
+
| <samp>MAIL {{t|letter ID}}</samp>
| Запускает следующую команду, если игрок ''не'' получил письмо с ID или ID состояния мира (смотри <tt>HasFlag</tt> в [https://github.com/Pathoschild/StardewMods/tree/develop/ContentPatcher документации Content Patcher]); остальное продолжается из команды после этого.<br /><small>Например: <tt>MAIL ccVault/GOTO spring/GOTO summer</tt> (запускает <tt>GOTO spring</tt> если автобус отремонтирован, или <tt>GOTO summer</tt> если это не так; не ограничиваясь командой <tt>GOTO</tt>).</small>
+
| Запускает следующую команду, если игрок ''не'' получил письмо с ID или ID состояния мира (смотри <samp>HasFlag</samp> в [https://github.com/Pathoschild/StardewMods/tree/develop/ContentPatcher документации Content Patcher]); остальное продолжается из команды после этого.<br /><small>Например: <samp>MAIL ccVault/GOTO spring/GOTO summer</samp> (запускает <samp>GOTO spring</samp> если автобус отремонтирован, или <samp>GOTO summer</samp> если это не так; не ограничиваясь командой <samp>GOTO</samp>).</small>
 
|-
 
|-
| <tt>GOTO {{t|key}}</tt>
+
| <samp>GOTO {{t|key}}</samp>
| (Примечание: эта строка применяется только в том случае, если <tt>GOTO</tt> стоит после <tt>NOT</tt> или <tt>MAIL</tt>. Если это не так, смотрите <tt>GOTO</tt> выше.)<br />Завершите текущий сценарий и вместо этого загрузите расписание с заданным ключом. Если ключ "сезон", вместо него используется название текущего сезона. Если ключ = "NO_SCHEDULE", то у NPC нет расписания на день. Если расписание не существует или не может быть проанализировано, игра вылетает (или покажет ошибку при игре с SMAPI).<br /><small>Например: <tt>GOTO NO_SCHEDULE</tt></small>
+
| (Примечание: эта строка применяется только в том случае, если <samp>GOTO</samp> стоит после <samp>NOT</samp> или <samp>MAIL</samp>. Если это не так, смотрите <samp>GOTO</samp> выше.)<br />Завершите текущий сценарий и вместо этого загрузите расписание с заданным ключом. Если ключ "сезон", вместо него используется название текущего сезона. Если ключ = "NO_SCHEDULE", то у NPC нет расписания на день. Если расписание не существует или не может быть проанализировано, игра вылетает (или покажет ошибку при игре с SMAPI).<br /><small>Например: <samp>GOTO NO_SCHEDULE</samp></small>
 
|}
 
|}
    
===Пункты расписания===
 
===Пункты расписания===
 
Остальная часть сценария расписания состоит из записей, разделенных косой чертой, каждая из которых содержит поля, разделенные пробелами, в которых указывается время начала, пункт назначения и действие, которое выполнит NPC, когда достигнет место назначения:
 
Остальная часть сценария расписания состоит из записей, разделенных косой чертой, каждая из которых содержит поля, разделенные пробелами, в которых указывается время начала, пункт назначения и действие, которое выполнит NPC, когда достигнет место назначения:
: <tt>{{t|time}} {{o|location}} {{t|tileX}} {{t|tileY}} {{o|facingDirection}} {{o|animation}} {{o|dialogue}}</tt>
+
: <samp>{{t|time}} {{o|location}} {{t|tileX}} {{t|tileY}} {{o|facingDirection}} {{o|animation}} {{o|dialogue}}</samp>
   −
Если поле <tt>location</tt> опущено, остальные поля анализируются как обычно. Другие необязательные поля должны быть в последовательном порядке (например, вы можете пропустить <tt>animation</tt> и <tt>dialogue</tt>, но не можете пропустить <tt>facingDirection</tt> а затем укажите <tt>animation</tt> и <tt>dialogue</tt>). Исключением является <tt>dialogue</tt>. <tt>dialogue</tt> может быть указан без <tt>animation</tt>.
+
Если поле <samp>location</samp> опущено, остальные поля анализируются как обычно. Другие необязательные поля должны быть в последовательном порядке (например, вы можете пропустить <samp>animation</samp> и <samp>dialogue</samp>, но не можете пропустить <samp>facingDirection</samp> а затем укажите <samp>animation</samp> и <samp>dialogue</samp>). Исключением является <samp>dialogue</samp>. <samp>dialogue</samp> может быть указан без <samp>animation</samp>.
   −
{| class="wikitable"
+
{|class="wikitable"
 
|-
 
|-
 
! Поле
 
! Поле
 
! Описание
 
! Описание
 
|-
 
|-
| <tt>time</tt>
+
| <samp>time</samp>
| Время, в которое начинается событие расписания, по времени (24-часовой формат, без двоеточия). Времени может предшествовать один символ '<tt>a</tt>', чтобы указать, что событие должно завершиться (то есть NPC должен прибыть в пункт назначения) в заданное время. В этом случае игра рассчитает, когда должно начаться событие. Однако событие никогда не начнется раньше времени, указанного для предыдущего события.
+
| Время, в которое начинается событие расписания, по времени (24-часовой формат, без двоеточия). Времени может предшествовать один символ '<samp>a</samp>', чтобы указать, что событие должно завершиться (то есть NPC должен прибыть в пункт назначения) в заданное время. В этом случае игра рассчитает, когда должно начаться событие. Однако событие никогда не начнется раньше времени, указанного для предыдущего события.
    
В неизмененной игре это используется только для синхронизации расписаний Эмили и Сэнди на 15 число осени.
 
В неизмененной игре это используется только для синхронизации расписаний Эмили и Сэнди на 15 число осени.
 
|-
 
|-
| <tt>location</tt>
+
| <samp>location</samp>
| <p>''(необязательное)'' Название местоположения, к которому должен идти NPC. Если этот параметр опущен, по умолчанию используется [[Автобусная остановка]] (если замужем за игроком) или их местоположение по умолчанию.</p><p>'''Примечание:''' в игре есть специальная логика для открываемых локаций. Если это JojaMart/Железная дорога, и она еще недоступна, игра получает место назначения для замены с первой записи в <tt>{{t|location}}_Replacement</tt> расписание, если доступно; в противном случае он переключается на расписание <tt>default</tt>, если доступно, в противном случае <tt>spring</tt>. Если это общественный центр, и он еще недоступен, игра переключается на расписание <tt>default</tt>, если доступно, в противном случае <tt>spring</tt>.</p>
+
| <p>''(необязательное)'' Название местоположения, к которому должен идти NPC. Если этот параметр опущен, по умолчанию используется [[Автобусная остановка]] (если замужем за игроком) или их местоположение по умолчанию.</p><p>'''Примечание:''' в игре есть специальная логика для открываемых локаций. Если это JojaMart/Железная дорога, и она еще недоступна, игра получает место назначения для замены с первой записи в <samp>{{t|location}}_Replacement</samp> расписание, если доступно; в противном случае он переключается на расписание <samp>default</samp>, если доступно, в противном случае <samp>spring</samp>. Если это общественный центр, и он еще недоступен, игра переключается на расписание <samp>default</samp>, если доступно, в противном случае <samp>spring</samp>.</p>
 
|-
 
|-
| <tt>tileX</tt><br /><tt>tileY</tt>
+
| <samp>tileX</samp><br /><samp>tileY</samp>
 
| X и Y [[Модификации:Моддер_гайд/Основы_игры#Тайлы|координаты тайлов]] NPC должен идти навстречу.
 
| X и Y [[Модификации:Моддер_гайд/Основы_игры#Тайлы|координаты тайлов]] NPC должен идти навстречу.
 
|-
 
|-
| <tt>facingDirection</tt>
+
| <samp>facingDirection</samp>
 
| ''(необязательное)'' Направление, в котором нужно двигаться после достижения пункта назначения. Возможными значениями являются 0 (вверх), 1 (вправо), 2 (вниз), и 3 (влево). По умолчанию вниз.
 
| ''(необязательное)'' Направление, в котором нужно двигаться после достижения пункта назначения. Возможными значениями являются 0 (вверх), 1 (вправо), 2 (вниз), и 3 (влево). По умолчанию вниз.
 
|-
 
|-
| <tt>animation</tt>
+
| <samp>animation</samp>
| ''(необязательное)'' Анимация, которая будет воспроизводиться, когда NPC достигнет места назначения. Это должен быть ключ, который появляется в файле <tt>Content/Data/animationDescriptions.xnb</tt>. Каждая ключевая запись состоит из трех частей: предварительная анимация/циклическая анимация/пост-анимация. Цифры на них относятся к [[Модификации:О_NPC#Спрайты|спрайтам]]. Предварительная анимация будет воспроизводиться после прибытия в пункт расписания. Затем анимация цикла будет повторяться до конца запланированного времени. Наконец, пост-анимация будет воспроизведена перед переходом к следующему пункту расписания. Обратите внимание, что каждый кадр составляет около 120 мс, поэтому дубликаты кадра используются для получения желаемой анимации.
+
| ''(необязательное)'' Анимация, которая будет воспроизводиться, когда NPC достигнет места назначения. Это должен быть ключ, который появляется в файле <samp>Content/Data/animationDescriptions.xnb</samp>. Каждая ключевая запись состоит из трех частей: предварительная анимация/циклическая анимация/пост-анимация. Цифры на них относятся к [[Модификации:О_NPC#Спрайты|спрайтам]]. Предварительная анимация будет воспроизводиться после прибытия в пункт расписания. Затем анимация цикла будет повторяться до конца запланированного времени. Наконец, пост-анимация будет воспроизведена перед переходом к следующему пункту расписания. Обратите внимание, что каждый кадр составляет около 120 мс, поэтому дубликаты кадра используются для получения желаемой анимации.
 
|-
 
|-
| <tt>dialogue</tt>
+
| <samp>dialogue</samp>
| <p>''(необязательное)'' Диалог, который должен использовать NPC, когда они доберутся до места назначения. Это должно быть [Модификации:Моддер гайд/APIs/Контентt|наименование]] и ключ ввода в этом формате (включая цитаты): <tt>"assetName:key"</tt>. Любые косые черты в имени ресурса должны быть двойными обратными косыми чертами (<tt>\\</tt>). Формат ключа ввода не имеет значения, он просто должен соответствовать одному из файла.</p><p>Например, <tt>"Strings\\schedules\\Abigail:Sun.000"</tt> открыть "open the file at <tt>Strings\schedules\Abigail.xnb</tt> и получить текст <tt>Sun.000</tt> key".
+
| <p>''(необязательное)'' Диалог, который должен использовать NPC, когда они доберутся до места назначения. Это должно быть [Модификации:Моддер гайд/APIs/Контентt|наименование]] и ключ ввода в этом формате (включая цитаты): <samp>"assetName:key"</samp>. Любые косые черты в имени ресурса должны быть двойными обратными косыми чертами (<samp>\\</samp>). Формат ключа ввода не имеет значения, он просто должен соответствовать одному из файла.</p><p>Например, <samp>"Strings\\schedules\\Abigail:Sun.000"</samp> открыть "open the file at <samp>Strings\schedules\Abigail.xnb</samp> и получить текст <samp>Sun.000</samp> key".
 
|}
 
|}
  

Навигация