Confirmedusers
409
edits
Akellagray (talk | contribs) (Created page with "== Тестирование ==") |
No edit summary |
||
(56 intermediate revisions by 5 users not shown) | |||
Line 1: | Line 1: | ||
<languages /> | <languages/> | ||
__FORCETOC__ | __FORCETOC__ | ||
{{GameVersion|1. | {{GameVersion|1.19.3}} | ||
= Введение = | = Введение = | ||
Некоторые блоки в игре имеют особое поведение, например песок, гравий могут осыпаться, это и называется поведением блока. | |||
Возможно, | Поведения блоков полезны, когда вы хотите, чтобы разные блоки действовали одинаково, поскольку вы можете прикрепить одно или несколько поведений к произвольному количеству блоков. | ||
Возможно, вам захочется взглянуть на существующие [[Block Json Properties#p_behaviors|Поведения Блоков]], прежде чем реализовывать свои собственные. | |||
В этом уроке мы создадим новое поведение(Behavior), которое можно будет прикреплять к блокам, чтобы сделать их подвижными, нажав правую кнопку мыши. | |||
== Подготовка == | |||
Этот руководство по '''code mod''' требует наличия среды разработки. Если у вас её еще нет, прочтите руководство по {{ll|Modding:Setting up your Development Environment|настройке среды для разработки}}. Кроме того, вам понадобятся активы (тип блока, текстура и lang-файл). Вы можете либо создать свой собственный, либо воспользоваться готовыми: [https://wiki.vintagestory.at/images/2/2f/Moving_-_No_CS_File.zip Moving - No CS File.zip] | |||
Итак, прежде всего нам нужно создать само поведение, которое | == Создание поведения == | ||
Итак, прежде всего нам нужно создать само поведение, которое представляет собой класс, наследующийся от BlockBehavior | |||
<syntaxhighlight lang="csharp"> | <syntaxhighlight lang="csharp"> | ||
class Moving : BlockBehavior | class Moving : BlockBehavior | ||
Line 26: | Line 28: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Этот класс предоставляет несколько методов, которые мы можем переопределить. | Этот класс предоставляет несколько методов, которые мы можем переопределить. При использовании Visual Studio вы можете найти полный список методов, наведя курсор мыши на "BlockBehavior" и нажав "F12". | ||
---- | ---- | ||
Метод <code> bool | Метод <code>bool OnBlockInteractStart(IWorldAccessor world, IPlayer byPlayer, BlockSelection blockSel, ref EnumHandling handling)</code> выглядит идеально подходящим для нашей цели. | ||
Что | Что метод должен делать? | ||
# Рассчитать новую позицию блока | # Рассчитать новую позицию для перемещения блока, основываясь на лицевой стороне блока, на которую смотрит игрок. | ||
# Проверить, можно ли | # Проверить, можно ли поместить блок в эту новую позицию. | ||
# Удалить | # Удалить блок в старой позиции. | ||
# Поместить | # Поместить блок того же типа на новую позицию. | ||
# [[Modding:Behavior_Traversal|Skip]] логика по умолчанию, которая в противном случае поместит любой удерживаемый предмет на старую позицию. | |||
<syntaxhighlight lang="c#"> | <syntaxhighlight lang="c#"> | ||
public override bool | public override bool OnBlockInteractStart(IWorldAccessor world, IPlayer byPlayer, BlockSelection blockSel, ref EnumHandling handling) | ||
{ | { | ||
// | // Найдите выбранную позицию | ||
BlockPos pos = blockSel.Position.AddCopy(blockSel.Face. | BlockPos pos = blockSel.Position.AddCopy(blockSel.Face.Opposite); | ||
// Можем ли мы разместить здесь блок? | |||
// Можем ли мы разместить блок | if (world.BlockAccessor.GetBlock(pos).IsReplacableBy(block)) | ||
if (world.BlockAccessor.GetBlock(pos).IsReplacableBy(block)) | |||
{ | { | ||
// | // Удалите блок в текущей позиции и поместите его в выбранную позицию | ||
world.BlockAccessor.SetBlock(0, blockSel.Position); | world.BlockAccessor.SetBlock(0, blockSel.Position); | ||
world.BlockAccessor.SetBlock(block.BlockId, pos); | world.BlockAccessor.SetBlock(block.BlockId, pos); | ||
} | } | ||
// Сообщите игровому движку и другим моделям поведения блоков, что мы обработали взаимодействие игрока с блоком. | |||
// | // Если бы мы не задали поле обработки, игрок все равно смог бы ставить блоки, если бы они были у него в руках. | ||
// Если бы мы не | handling = EnumHandling.PreventDefault; | ||
handling = EnumHandling.PreventDefault; | |||
return true; | return true; | ||
} | |||
</syntaxhighlight> | </syntaxhighlight> | ||
== Регистрация == | == Регистрация == | ||
Чтобы зарегистрировать BlockBehavior, нам нужно создать класс мода, | Чтобы зарегистрировать BlockBehavior, нам нужно создать класс мода, переопределив от <code>Start(ICoreAPI)</code> и зарегистрировать его с указанным именем: | ||
<syntaxhighlight lang="c#"> | <syntaxhighlight lang="c#"> | ||
Line 68: | Line 69: | ||
{ | { | ||
public override void Start(ICoreAPI api) | |||
{ | { | ||
base.Start(api); | base.Start(api); | ||
Line 74: | Line 75: | ||
} | } | ||
} | |||
</syntaxhighlight> | </syntaxhighlight> | ||
== | == Распространение == | ||
Чтобы закончить все, откройте modtools и введите <code> pack < | Чтобы закончить все, откройте modtools и введите <code>pack <your mod id></code>. Теперь вы можете взять zip-файл и поделиться им с другими людьми. | ||
* Для VS 1.9: [https://wiki.vintagestory.at/images/2/2a/Moving_v1.0.0.zip Moving_v1.0.0.zip] | * Для VS 1.9: [https://wiki.vintagestory.at/images/2/2a/Moving_v1.0.0.zip Moving_v1.0.0.zip] | ||
* Для VS 1.6: [https://wiki.vintagestory.at/images/c/cb/Moving.zip Moving.zip] | * Для VS 1.6: [https://wiki.vintagestory.at/images/c/cb/Moving.zip Moving.zip] | ||
== Тестирование == | == Тестирование == | ||
<youtube>8eVG0uQF2xs</youtube> | <youtube>8eVG0uQF2xs</youtube> | ||
= | = Расширенное Поведение = | ||
Наше созданное поведение все еще довольно простое, но возможностей гораздо больше. Поведение может иметь особые свойства, которые могут быть определены самим типом блока. | |||
== | == Пример == | ||
Поведение жидкости поддерживает некоторые особые свойства, как показано в этом примере с типом блока "Вода": | |||
<syntaxhighlight lang="json"> | <syntaxhighlight lang="json"> | ||
Line 110: | Line 111: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
== | == Разбор свойств == | ||
Для того чтобы разобраться со специальными свойствами, существует метод <code>Initialize(JsonObject)</code>. Каждый blocktype создает новый экземпляр поведения, поэтому этот метод можно использовать для разбора свойств. | |||
Итак, какие свойства мы можем добавить? | |||
* | * Толчок блока на расстояние | ||
* | * Тянуть блок, если игрок крадется | ||
Прежде всего, нам нужно переопределить метод в нашем классе поведения блока ... | |||
<syntaxhighlight lang="c#"> | <syntaxhighlight lang="c#"> | ||
Line 127: | Line 128: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Дополнительно нам нужно добавить два поля, одно для расстояния, а другое - если игрок должен потянуть за блок, когда крадется... | |||
<syntaxhighlight lang="c#"> | <syntaxhighlight lang="c#"> | ||
Line 134: | Line 135: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Теперь мы можем разобрать эти два свойства следующим образом: | |||
<syntaxhighlight lang="c#"> | <syntaxhighlight lang="c#"> | ||
Line 143: | Line 144: | ||
---- | ---- | ||
Следующее, что нам нужно изменить, - это сам метод interact, чтобы он позаботился о свойствах расстояния и притяжения... | |||
<syntaxhighlight lang="c#"> | <syntaxhighlight lang="c#"> | ||
public override bool | public override bool OnBlockInteractStart(IWorldAccessor world, IPlayer byPlayer, BlockSelection blockSel, ref EnumHandling handling) | ||
{ | { | ||
BlockPos pos = blockSel.Position.AddCopy(pull && byPlayer.WorldData.EntityControls.Sneak ? blockSel.Face : blockSel.Face. | // Найдите выбранную позицию | ||
BlockPos pos = blockSel.Position.AddCopy(pull && byPlayer.WorldData.EntityControls.Sneak ? blockSel.Face : blockSel.Face.Opposite, distance); | |||
// Можем ли мы разместить здесь блок? | |||
if (world.BlockAccessor.GetBlock(pos).IsReplacableBy(block)) | if (world.BlockAccessor.GetBlock(pos).IsReplacableBy(block)) | ||
{ | { | ||
// Удалите блок в текущей позиции и поместите его в выбранную позицию | |||
world.BlockAccessor.SetBlock(0, blockSel.Position); | world.BlockAccessor.SetBlock(0, blockSel.Position); | ||
world.BlockAccessor.SetBlock(block.BlockId, pos); | world.BlockAccessor.SetBlock(block.BlockId, pos); | ||
} | } | ||
// Сообщите игровому движку и другим моделям поведения блоков, что мы обработали взаимодействие игрока с блоком. | |||
// Если бы мы не задали поле обработки, игрок все равно смог бы ставить блоки, если бы они были у него в руках. | |||
handling = EnumHandling.PreventDefault; | handling = EnumHandling.PreventDefault; | ||
return true; | return true; | ||
Line 158: | Line 166: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
== | == Добавление другого блока == | ||
Давайте создадим еще один блок, используя это поведение, но на этот раз мы настроим некоторые дополнительные свойства ... | |||
<syntaxhighlight lang="json"> | <syntaxhighlight lang="json"> | ||
Line 174: | Line 182: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Блок будет толкать два блока вместо одного, и игрок может тянуть его, крадясь, нажимая правую кнопку мыши. | |||
= | = Скачать Мод = | ||
* | * Для VS 1.9: [https://wiki.vintagestory.at/images/7/7b/Advancedmoving_v1.0.0.zip AdvancedMoving_v1.0.0.zip] | ||
* | * Для VS 1.6: [https://wiki.vintagestory.at/images/7/72/AdvancedMoving.zip AdvancedMoving.zip] | ||
{{Navbox/modding|Vintage Story}} | {{Navbox/modding|Vintage Story}} |