Строка 4: |
Строка 4: |
| | | |
| ==Источник== | | ==Источник== |
− | Данные расписания хранятся в <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>. |
| | | |
| ===Расписание в браке=== | | ===Расписание в браке=== |
Строка 46: |
Строка 46: |
| ! Описание | | ! Описание |
| |- | | |- |
− | | <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> |
| |} | | |} |
| | | |
Строка 64: |
Строка 64: |
| ! Описание | | ! Описание |
| |- | | |- |
− | | <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" |
Строка 115: |
Строка 115: |
| ! Описание | | ! Описание |
| |- | | |- |
− | | <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" |
Строка 142: |
Строка 142: |
| ! Описание | | ! Описание |
| |- | | |- |
− | | <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". |
| |} | | |} |
| | | |