Modding:Adding Block Behavior/ru: Difference between revisions

From Vintage Story Wiki
(Created page with "* Для 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/Adva...")
No edit summary
 
(41 intermediate revisions by 5 users not shown)
Line 1: Line 1:
<languages />
<languages/>
__FORCETOC__
__FORCETOC__
{{GameVersion|1.9}}
{{GameVersion|1.19.3}}


= Введение =
= Введение =
Поведение блоков довольно полезно, если вы хотите, чтобы разные блоки действовали одинаково, поскольку вы можете прикрепить к произвольному количеству блоков одно или несколько поведений.
Некоторые блоки в игре имеют особое поведение, например песок, гравий могут осыпаться, это и называется поведением блока.
Возможно, вы захотите взглянуть на существующие [[Block Json Properties # p_behaviors | block behaviors]] перед реализацией своего собственного.
Поведения блоков полезны, когда вы хотите, чтобы разные блоки действовали одинаково, поскольку вы можете прикрепить одно или несколько поведений к произвольному количеству блоков.
Возможно, вам захочется взглянуть на существующие [[Block Json Properties#p_behaviors|Поведения Блоков]], прежде чем реализовывать свои собственные.


В этом уроке мы создадим новое поведение, которое мы можем прикрепить к блокам, чтобы сделать их подвижными, щелкнув по ним правой кнопкой мыши.


== Настройка ==
В этом уроке мы создадим новое поведение(Behavior), которое можно будет прикреплять к блокам, чтобы сделать их подвижными, нажав правую кнопку мыши.


Требуется ознакомится со статьёй - [[Настройка среды для разработки]]. Кроме того, вам понадобятся ресурсы (тип блока, текстура и файл lang). Вы можете создать свои собственные или использовать готовые: [https://wiki.vintagestory.at/images/2/2f/Moving_-_No_CS_File.zip Moving - No CS File.zip]
== Подготовка ==


== Создание поведения ==
Этот руководство по '''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
== Создание поведения ==
 
Итак, прежде всего нам нужно создать само поведение, которое представляет собой класс, наследующийся от BlockBehavior
<syntaxhighlight lang="csharp">
<syntaxhighlight lang="csharp">
class Moving : BlockBehavior
class Moving : BlockBehavior
Line 26: Line 28:
</syntaxhighlight>
</syntaxhighlight>


Этот класс предоставляет несколько методов, которые мы можем переопределить. Когда вы используете Visual Studio, вы можете найти полный список методов, наведя курсор мыши на «BlockBehavior» и нажав «F12».
Этот класс предоставляет несколько методов, которые мы можем переопределить. При использовании Visual Studio вы можете найти полный список методов, наведя курсор мыши на "BlockBehavior" и нажав "F12".


----
----


Метод <code> bool OnPlayerInteract (IWorldAccessor world, IPlayer byPlayer, BlockSelection blockSel, ref EnumHandling handling) </code> выглядит идеально подходящим для наших целей.
Метод <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 OnPlayerInteract(IWorldAccessor world, IPlayer byPlayer, BlockSelection blockSel, ref EnumHandling handling)
     public override bool OnBlockInteractStart(IWorldAccessor world, IPlayer byPlayer, BlockSelection blockSel, ref EnumHandling handling)
     {
     {
         // Находим целевую позицию
         // Найдите выбранную позицию
         BlockPos pos = blockSel.Position.AddCopy(blockSel.Face.GetOpposite());
         BlockPos pos = blockSel.Position.AddCopy(blockSel.Face.Opposite);
 
         // Можем ли мы разместить здесь блок?
         // Можем ли мы разместить блок там?
        if (world.BlockAccessor.GetBlock(pos).IsReplacableBy(block))
if (world.BlockAccessor.GetBlock(pos).IsReplacableBy(block))
         {
         {
             // Remove the block at the current position and place it at the target position
             // Удалите блок в текущей позиции и поместите его в выбранную позицию
             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, нам нужно создать класс мода, переопределить <code> Start (ICoreAPI) </code> и зарегистрировать его с заданным именем:
Чтобы зарегистрировать BlockBehavior, нам нужно создать класс мода, переопределив от <code>Start(ICoreAPI)</code> и зарегистрировать его с указанным именем:


<syntaxhighlight lang="c#">
<syntaxhighlight lang="c#">
Line 68: Line 69:
     {
     {


        public override void Start(ICoreAPI api)
public override void Start(ICoreAPI api)
         {
         {
             base.Start(api);
             base.Start(api);
Line 74: Line 75:
         }
         }


    }
}
</syntaxhighlight>
</syntaxhighlight>


== Распределение ==
== Распространение ==  


Чтобы закончить все, откройте modtools и введите <code> pack <ваш mod id> </ code>. Теперь вы можете взять zip-файл и поделиться им с другими людьми.
Чтобы закончить все, откройте 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>. Каждый тип блока создает новый экземпляр поведения, поэтому метод может использоваться для анализа свойств.
Для того чтобы разобраться со специальными свойствами, существует метод <code>Initialize(JsonObject)</code>. Каждый blocktype создает новый экземпляр поведения, поэтому этот метод можно использовать для разбора свойств.


Итак, какие свойства мы можем добавить?
Итак, какие свойства мы можем добавить?
* толчок расстояние
* Толчок блока на расстояние
* собрать блок, если игрок крадется
* Тянуть блок, если игрок крадется


Прежде всего, нам нужно переопределить метод в нашем классе поведения блока ...
Прежде всего, нам нужно переопределить метод в нашем классе поведения блока ...
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#">
        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.Opposite, distance);
 
            // Можем ли мы разместить здесь блок?
            if (world.BlockAccessor.GetBlock(pos).IsReplacableBy(block))
            {
                // Удалите блок в текущей позиции и поместите его в выбранную позицию
                world.BlockAccessor.SetBlock(0, blockSel.Position);
                world.BlockAccessor.SetBlock(block.BlockId, pos);
            }
 
            // Сообщите игровому движку и другим моделям поведения блоков, что мы обработали взаимодействие игрока с блоком.
            // Если бы мы не задали поле обработки, игрок все равно смог бы ставить блоки, если бы они были у него в руках.
            handling = EnumHandling.PreventDefault;
            return true;
        }
</syntaxhighlight>


== Добавление другого блока ==
== Добавление другого блока ==  


Давайте создадим еще один блок, используя это поведение, но на этот раз мы настроим некоторые дополнительные свойства ...
Давайте создадим еще один блок, используя это поведение, но на этот раз мы настроим некоторые дополнительные свойства ...
Line 161: Line 182:
</syntaxhighlight>
</syntaxhighlight>


The block will be pushed two blocks instead of one and the player can pull it by sneaking while right clicking.
Блок будет толкать два блока вместо одного, и игрок может тянуть его, крадясь, нажимая правую кнопку мыши.


= Загрузка мода =
= Скачать Мод =  


* Для VS 1.9: [https://wiki.vintagestory.at/images/7/7b/Advancedmoving_v1.0.0.zip AdvancedMoving_v1.0.0.zip]
* Для VS 1.9: [https://wiki.vintagestory.at/images/7/7b/Advancedmoving_v1.0.0.zip AdvancedMoving_v1.0.0.zip]

Latest revision as of 20:24, 25 March 2024

Other languages:

Эта страница проверялась в последний раз для версии Vintage Story 1.19.3.


Введение

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


В этом уроке мы создадим новое поведение(Behavior), которое можно будет прикреплять к блокам, чтобы сделать их подвижными, нажав правую кнопку мыши.

Подготовка

Этот руководство по code mod требует наличия среды разработки. Если у вас её еще нет, прочтите руководство по настройке среды для разработки . Кроме того, вам понадобятся активы (тип блока, текстура и lang-файл). Вы можете либо создать свой собственный, либо воспользоваться готовыми: Moving - No CS File.zip

Создание поведения

Итак, прежде всего нам нужно создать само поведение, которое представляет собой класс, наследующийся от BlockBehavior

class Moving : BlockBehavior
{
    public Moving(Block block) : base(block)
    {
        
    } 
}

Этот класс предоставляет несколько методов, которые мы можем переопределить. При использовании Visual Studio вы можете найти полный список методов, наведя курсор мыши на "BlockBehavior" и нажав "F12".


Метод bool OnBlockInteractStart(IWorldAccessor world, IPlayer byPlayer, BlockSelection blockSel, ref EnumHandling handling) выглядит идеально подходящим для нашей цели.

Что метод должен делать?

  1. Рассчитать новую позицию для перемещения блока, основываясь на лицевой стороне блока, на которую смотрит игрок.
  2. Проверить, можно ли поместить блок в эту новую позицию.
  3. Удалить блок в старой позиции.
  4. Поместить блок того же типа на новую позицию.
  5. Skip логика по умолчанию, которая в противном случае поместит любой удерживаемый предмет на старую позицию.
    public override bool OnBlockInteractStart(IWorldAccessor world, IPlayer byPlayer, BlockSelection blockSel, ref EnumHandling handling)
    {
        // Найдите выбранную позицию
        BlockPos pos = blockSel.Position.AddCopy(blockSel.Face.Opposite);
        // Можем ли мы разместить здесь блок?
        if (world.BlockAccessor.GetBlock(pos).IsReplacableBy(block))
        {
            // Удалите блок в текущей позиции и поместите его в выбранную позицию
            world.BlockAccessor.SetBlock(0, blockSel.Position);
            world.BlockAccessor.SetBlock(block.BlockId, pos);
        }
        // Сообщите игровому движку и другим моделям поведения блоков, что мы обработали взаимодействие игрока с блоком.
        // Если бы мы не задали поле обработки, игрок все равно смог бы ставить блоки, если бы они были у него в руках.
        handling = EnumHandling.PreventDefault;
        return true;
    }

Регистрация

Чтобы зарегистрировать BlockBehavior, нам нужно создать класс мода, переопределив от Start(ICoreAPI) и зарегистрировать его с указанным именем:

    public class MovingBlocks : ModSystem
    {

public override void Start(ICoreAPI api)
        {
            base.Start(api);
            api.RegisterBlockBehaviorClass("Moving", typeof(Moving));
        }

}

Распространение

Чтобы закончить все, откройте modtools и введите pack <your mod id>. Теперь вы можете взять zip-файл и поделиться им с другими людьми.

Тестирование

Расширенное Поведение

Наше созданное поведение все еще довольно простое, но возможностей гораздо больше. Поведение может иметь особые свойства, которые могут быть определены самим типом блока.

Пример

Поведение жидкости поддерживает некоторые особые свойства, как показано в этом примере с типом блока "Вода":

	behaviors: [
		{
			name: "FiniteSpreadingLiquid", 
			properties:
			{
				spreadDelay: 150, 
				liquidCollisionSound: "hotmetal", 
				sourceReplacementCode: "obsidian", 
				flowingReplacementCode: "basalt"
			}
		}
	],

Разбор свойств

Для того чтобы разобраться со специальными свойствами, существует метод Initialize(JsonObject). Каждый blocktype создает новый экземпляр поведения, поэтому этот метод можно использовать для разбора свойств.

Итак, какие свойства мы можем добавить?

  • Толчок блока на расстояние
  • Тянуть блок, если игрок крадется

Прежде всего, нам нужно переопределить метод в нашем классе поведения блока ...

        public override void Initialize(JsonObject properties)
        {
            base.Initialize(properties);
        }

Дополнительно нам нужно добавить два поля, одно для расстояния, а другое - если игрок должен потянуть за блок, когда крадется...

        public int distance = 1;
        public bool pull = false;

Теперь мы можем разобрать эти два свойства следующим образом:

        distance = properties["distance"].AsInt(1);
        pull = properties["pull"].AsBool(false);

Следующее, что нам нужно изменить, - это сам метод interact, чтобы он позаботился о свойствах расстояния и притяжения...

        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.Opposite, distance);

            // Можем ли мы разместить здесь блок?
            if (world.BlockAccessor.GetBlock(pos).IsReplacableBy(block))
            {
                // Удалите блок в текущей позиции и поместите его в выбранную позицию
                world.BlockAccessor.SetBlock(0, blockSel.Position);
                world.BlockAccessor.SetBlock(block.BlockId, pos);
            }

            // Сообщите игровому движку и другим моделям поведения блоков, что мы обработали взаимодействие игрока с блоком.
            // Если бы мы не задали поле обработки, игрок все равно смог бы ставить блоки, если бы они были у него в руках.
            handling = EnumHandling.PreventDefault;
            return true;
        }

Добавление другого блока

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

	behaviors: [
		{
			name: "Moving",
			properties: {
				"distance": 2,
				"pull": true
			}
		}
	],

Блок будет толкать два блока вместо одного, и игрок может тянуть его, крадясь, нажимая правую кнопку мыши.

Скачать Мод


Icon Sign.png

Wondering where some links have gone?
The modding navbox is going through some changes! Check out Navigation Box Updates for more info and help finding specific pages.

Modding
Modding Introduction Getting Started Пакет тем
Content Modding Content Mods Developing a Content Mod Basic Tutorials Intermediate Tutorials Advanced Tutorials Content Mod Concepts
Code Modding Code Mods Setting up your Development Environment
Property Overview ItemEntityBlockBlock BehaviorsBlock ClassesBlock EntitiesBlock Entity BehaviorsWorld properties
Workflows & Infrastructure Modding Efficiency TipsMod-engine compatibilityMod ExtensibilityVS Engine
Additional Resources Community Resources Modding API Updates Programming Languages List of server commandsList of client commandsClient startup parametersServer startup parameters
Example ModsAPI DocsGitHub Repository