Modding:Block Entity/ru: Difference between revisions

From Vintage Story Wiki
(Created page with "Моддинг: Сущность блока")
 
No edit summary
Tags: Mobile edit Mobile web edit
 
(20 intermediate revisions by one other user not shown)
Line 4: Line 4:
= Введение =
= Введение =


<div lang="en" dir="ltr" class="mw-content-ltr">
Блочная сущность — это конструкция, которую вы можете прикрепить к существующему блоку, чтобы придать ему дополнительную функциональность. Всякий раз, когда блок должен что-то делать через регулярные промежутки времени или хранить дополнительную информацию, например содержимое блока сундука, вам нужна сущность блока. Настоятельно рекомендуется прочитать руководство по [[Modding:Asset System/ru|базовым блокам]] и [[Modding:Advanced Blocks/ru|классам блоков]], чтобы правильно понять это руководство.
A block entity is a construct that you can tack onto an existing block to give it additional functionality. Whenever a block should do something on a regular interval or store extra information, such as the contents of a chest block, you need a block entity. It's highly recommend to have read the tutorial about [[Basic Modding|Basic Blocks]] and [[Advanced Blocks|Block Class]] in order to understand this tutorial properly.
</div>


<div lang="en" dir="ltr" class="mw-content-ltr">
== Переключатель текстур ==
== The Texture Flipper ==
</div>


<div lang="en" dir="ltr" class="mw-content-ltr">
Давайте создадим блок, который меняет свою текстуру каждые 3 секунды. Он должен иметь два варианта: <code>"on"</code> и <code>"off"</code>. Кроме того, нам нужно определить класс blockentity следующим образом:
Let's create a block which switches its texture every 3 seconds. It should have two variants <code>"on"</code> and <code>"off"</code>. Additionally we need to define the blockentity class like so:
<syntaxhighlight lang="json">
<syntaxhighlight lang="json">
entityClass: "tickingcounter",
entityClass: "tickingcounter",
</syntaxhighlight>
</syntaxhighlight>
</div>


<div lang="en" dir="ltr" class="mw-content-ltr">
Вы можете загрузить ассеты [https://wiki.vintagestory.at/images/d/d4/Ticking_-_No_CS_File.zip здесь] и поместить их в папку с модами.
You can download the assets [https://wiki.vintagestory.at/images/d/d4/Ticking_-_No_CS_File.zip here] and place it in your mods directory.
</div>


<div lang="en" dir="ltr" class="mw-content-ltr">
== Сущность блока ==
== The BlockEntity ==
</div>


<div lang="en" dir="ltr" class="mw-content-ltr">
Теперь нам нужно зарегистрировать наш класс blockentity и поэтому нам нужно создать новый файл *.cs в нашем проекте. Назовем его <code>Ticking.cs</code>.
Now we need to register our blockentity class and therefore we need to create a new *.cs file in our project. Let's name it <code>Ticking.cs</code>.
</div>


<div lang="en" dir="ltr" class="mw-content-ltr">
Прежде всего вам нужно создать сам класс blockentity. Поэтому вам нужно расширить <code>BlockEntity</code>:
First of all you need to create the blockentity class itself. Therefore you need to extend <code>BlockEntity</code>:
</div>


<div lang="en" dir="ltr" class="mw-content-ltr">
<syntaxhighlight lang="c#">
<syntaxhighlight lang="c#">
     public class TickingBlockEntity : BlockEntity
     public class TickingBlockEntity : BlockEntity
Line 42: Line 27:
     }
     }
</syntaxhighlight>
</syntaxhighlight>
</div>


<div lang="en" dir="ltr" class="mw-content-ltr">
----
----
</div>


<div lang="en" dir="ltr" class="mw-content-ltr">
Этот класс должен иметь таймер, когда таймер достигает 3 секунд, он должен заменить текущий блок другим состоянием.
This class needs to have a timer, once the timer reaches 3 seconds it should replace the current block with the different state.
</div>


<div lang="en" dir="ltr" class="mw-content-ltr">
Чтобы создать таймер, нам нужно зарегистрировать прослушиватель тиков. Поэтому нам нужно переопределить <code>Initialize(ICoreAPI)</code>:
In order to create a timer we need to register a tick listener. Therefore we need to override <code>Initialize(ICoreAPI)</code>:
</div>


<div lang="en" dir="ltr" class="mw-content-ltr">
<syntaxhighlight lang="c#">
<syntaxhighlight lang="c#">
         public override void Initialize(ICoreAPI api)
         public override void Initialize(ICoreAPI api)
Line 63: Line 40:
         }
         }
</syntaxhighlight>
</syntaxhighlight>
</div>


<div lang="en" dir="ltr" class="mw-content-ltr">
добавить счетчик (который должен увеличиваться за тик)...
add a counter (which should increase per tick) ...
</div>


<div lang="en" dir="ltr" class="mw-content-ltr">
<syntaxhighlight lang="c#">
<syntaxhighlight lang="c#">
         public float timer;
         public float timer;
</syntaxhighlight>
</syntaxhighlight>
</div>


<div lang="en" dir="ltr" class="mw-content-ltr">
... и собственно метод тиканья...
... and the actual ticking method ...
</div>


<div lang="en" dir="ltr" class="mw-content-ltr">
<syntaxhighlight lang="c#">
<syntaxhighlight lang="c#">
         public void OnGameTick(float dt)
         public void OnGameTick(float dt)
Line 86: Line 55:
         }
         }
</syntaxhighlight>
</syntaxhighlight>
</div>


<div lang="en" dir="ltr" class="mw-content-ltr">
Чтобы зарегистрировать метод тиканья, мы можем использовать <code>RegisterGameTickListener</code> в <code>Initialize</code>.
To register the ticking method we can use <code>RegisterGameTickListener</code> in <code>Initialize</code>
</div>


<div lang="en" dir="ltr" class="mw-content-ltr">
<syntaxhighlight lang="c#">
<syntaxhighlight lang="c#">
         public override void Initialize(ICoreAPI api)
         public override void Initialize(ICoreAPI api)
Line 100: Line 65:
         }
         }
</syntaxhighlight>
</syntaxhighlight>
</div>


<div lang="en" dir="ltr" class="mw-content-ltr">
Сам таймер должен увеличиваться на dt, разницу во времени в секундах между текущим тиком и предыдущим тиком. Он тикает примерно каждые 50 мс или реже, если игра медленная. Поэтому, если таймер больше 3, он должен заменить блок:
The timer itself should increment by dt, the time difference in seconds between the current tick and the previous tick. It ticks about every 50ms or less often if the game is slow. So if the timer is greater than 3, it should replace the block:
</div>


<div lang="en" dir="ltr" class="mw-content-ltr">
<syntaxhighlight lang="c#">
<syntaxhighlight lang="c#">
         public void OnGameTick(float dt)
         public void OnGameTick(float dt)
Line 122: Line 83:
                     block = Api.World.GetBlock(block.CodeWithParts("on"));
                     block = Api.World.GetBlock(block.CodeWithParts("on"));
                 }
                 }
</div>


                 <div lang="en" dir="ltr" class="mw-content-ltr">
                 Api.World.BlockAccessor.SetBlock(block.BlockId, Pos);
Api.World.BlockAccessor.SetBlock(block.BlockId, Pos);
             }
             }
         }
         }
</syntaxhighlight>
</syntaxhighlight>
</div>


<div lang="en" dir="ltr" class="mw-content-ltr">
----
----
</div>


<div lang="en" dir="ltr" class="mw-content-ltr">
Кроме того, нам нужно сохранить текущее время:
Furthermore we need to save the current time:
</div>


<div lang="en" dir="ltr" class="mw-content-ltr">
<syntaxhighlight lang="c#">
<syntaxhighlight lang="c#">
         public override void ToTreeAttributes(ITreeAttribute tree)
         public override void ToTreeAttributes(ITreeAttribute tree)
Line 146: Line 99:
             tree.SetFloat("timer", timer);
             tree.SetFloat("timer", timer);
         }
         }
</div>


         <div lang="en" dir="ltr" class="mw-content-ltr">
         public override void FromTreeAttributes(ITreeAttribute tree, IWorldAccessor worldForResolving)
public override void FromTreeAttributes(ITreeAttribute tree, IWorldAccessor worldForResolving)
         {
         {
             base.FromTreeAttributes(tree, worldForResolving);
             base.FromTreeAttributes(tree, worldForResolving);
             timer = tree.GetFloat("timer");
             timer = tree.GetFloat("timer");
         }
         }
</div>


<div lang="en" dir="ltr" class="mw-content-ltr">
</syntaxhighlight>
</syntaxhighlight>
</div>


<div lang="en" dir="ltr" class="mw-content-ltr">
== Регистрация объекта блока ==
== Registering the Block Entity ==
</div>


<div lang="en" dir="ltr" class="mw-content-ltr">
Регистрация класса блочной сущности довольно проста (скорее похожа на регистрацию блочного класса). Вам нужен класс мода и переопределить <code>Start(ICoreAPI)</code>:
Registering the blockentity class is rather simple (rather similar to registering a block class). You need a mod class and override <code>Start(ICoreAPI)</code>:
</div>


<div lang="en" dir="ltr" class="mw-content-ltr">
<syntaxhighlight lang="c#">
<syntaxhighlight lang="c#">
     public class Ticking : ModSystem
     public class Ticking : ModSystem
     {
     {
</div>


         <div lang="en" dir="ltr" class="mw-content-ltr">
         public override void Start(ICoreAPI api)
public override void Start(ICoreAPI api)
         {
         {
             base.Start(api);
             base.Start(api);
             api.RegisterBlockEntityClass("tickingcounter", typeof(TickingBlockEntity));
             api.RegisterBlockEntityClass("tickingcounter", typeof(TickingBlockEntity));
         }
         }
</div>


     <div lang="en" dir="ltr" class="mw-content-ltr">
     }
}
</syntaxhighlight>
</syntaxhighlight>
</div>


<div lang="en" dir="ltr" class="mw-content-ltr">
== Тестирование ==
== Testing ==
</div>


<div lang="en" dir="ltr" class="mw-content-ltr">
Теперь все готово для запуска первого теста:
Now everything is ready to run the first test:
</div>


<div lang="en" dir="ltr" class="mw-content-ltr">
<youtube>QQUibC4H9TI</youtube>
<youtube>QQUibC4H9TI</youtube>
</div>


<div lang="en" dir="ltr" class="mw-content-ltr">
== Распространение ==
== Distribution ==
</div>


<div lang="en" dir="ltr" class="mw-content-ltr">
Чтобы все закончить, откройте modtools и введите <code>pack <your mod id></code>. Теперь вы можете взять zip-файл и поделиться им с другими людьми. Он будет работать так же, как и обычные моды, вы можете установить его, скопировав в папку с модами.
In order to finish everything, open the modtools and type in <code>pack <your mod id></code>. Now you can take the zip file and share it with other people. It will work in the same way as ordinary mods, you can install it by copying it into the mods folder.
</div>


<div lang="en" dir="ltr" class="mw-content-ltr">
= Скачать мод =
= Mod Download =
* для VS 1.12 (только исходник): [https://github.com/anegostudios/vsmodexamples/tree/ac7eeaed597b8a25dcfc2366b9c51cd92850d2b9/Mods/Ticking GitHub]
* for VS 1.12 (Source only): [https://github.com/anegostudios/vsmodexamples/tree/ac7eeaed597b8a25dcfc2366b9c51cd92850d2b9/Mods/Ticking GitHub]
* для VS 1.9: [https://wiki.vintagestory.at/images/8/80/Ticking_v1.0.0.zip Ticking_v1.0.0.zip]
* for VS 1.9: [https://wiki.vintagestory.at/images/8/80/Ticking_v1.0.0.zip Ticking_v1.0.0.zip]
* для VS 1.6: [https://wiki.vintagestory.at/images/6/65/Ticking.zip Ticking.zip]
* for VS 1.6: [https://wiki.vintagestory.at/images/6/65/Ticking.zip Ticking.zip]
</div>




{{Navbox/modding|Vintage Story}}
{{Navbox/modding|Vintage Story}}

Latest revision as of 11:15, 8 December 2023

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

Other languages:

Введение

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

Переключатель текстур

Давайте создадим блок, который меняет свою текстуру каждые 3 секунды. Он должен иметь два варианта: "on" и "off". Кроме того, нам нужно определить класс blockentity следующим образом:

	entityClass: "tickingcounter",

Вы можете загрузить ассеты здесь и поместить их в папку с модами.

Сущность блока

Теперь нам нужно зарегистрировать наш класс blockentity и поэтому нам нужно создать новый файл *.cs в нашем проекте. Назовем его Ticking.cs.

Прежде всего вам нужно создать сам класс blockentity. Поэтому вам нужно расширить BlockEntity:

    public class TickingBlockEntity : BlockEntity
    {
    
    }

Этот класс должен иметь таймер, когда таймер достигает 3 секунд, он должен заменить текущий блок другим состоянием.

Чтобы создать таймер, нам нужно зарегистрировать прослушиватель тиков. Поэтому нам нужно переопределить Initialize(ICoreAPI):

        public override void Initialize(ICoreAPI api)
        {
            base.Initialize(api);
        }

добавить счетчик (который должен увеличиваться за тик)...

        public float timer;

... и собственно метод тиканья...

        public void OnGameTick(float dt)
        {
        
        }

Чтобы зарегистрировать метод тиканья, мы можем использовать RegisterGameTickListener в Initialize.

        public override void Initialize(ICoreAPI api)
        {
            base.Initialize(api);
            RegisterGameTickListener(OnGameTick, 50);
        }

Сам таймер должен увеличиваться на dt, разницу во времени в секундах между текущим тиком и предыдущим тиком. Он тикает примерно каждые 50 мс или реже, если игра медленная. Поэтому, если таймер больше 3, он должен заменить блок:

        public void OnGameTick(float dt)
        {
            timer += dt;
            if(timer >= 3)
            {
                Block block = Api.World.BlockAccessor.GetBlock(Pos);
                if (block.Code.Path.EndsWith("-on"))
                {
                    block = Api.World.GetBlock(block.CodeWithParts("off"));
                }
                else
                {
                    block = Api.World.GetBlock(block.CodeWithParts("on"));
                }

                Api.World.BlockAccessor.SetBlock(block.BlockId, Pos);
            }
        }

Кроме того, нам нужно сохранить текущее время:

        public override void ToTreeAttributes(ITreeAttribute tree)
        {
            base.ToTreeAttributes(tree);
            tree.SetFloat("timer", timer);
        }

        public override void FromTreeAttributes(ITreeAttribute tree, IWorldAccessor worldForResolving)
        {
            base.FromTreeAttributes(tree, worldForResolving);
            timer = tree.GetFloat("timer");
        }

Регистрация объекта блока

Регистрация класса блочной сущности довольно проста (скорее похожа на регистрацию блочного класса). Вам нужен класс мода и переопределить Start(ICoreAPI):

    public class Ticking : ModSystem
    {

        public override void Start(ICoreAPI api)
        {
            base.Start(api);
            api.RegisterBlockEntityClass("tickingcounter", typeof(TickingBlockEntity));
        }

    }

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

Теперь все готово для запуска первого теста:

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

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

Скачать мод


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