Modding:Adding Block Behavior/ru: Difference between revisions

From Vintage Story Wiki
(Created page with "Что это должно сделать?")
(Created page with "# Рассчитать новую позицию блока в зависимости от стороны, в которую смотрит игрок # Проверить, м...")
Line 34: Line 34:
Что это должно сделать?
Что это должно сделать?


# Calculate the new position of the block depending on the face the player is looking at
# Рассчитать новую позицию блока в зависимости от стороны, в которую смотрит игрок
# Check if the block can be placed at this position
# Проверить, можно ли разместить блок в этой позиции
# Remove the original block
# Удалить оригинальный блок
# Place the new block using the previously calculated position
# Поместить новый блок, используя ранее рассчитанную позицию


<syntaxhighlight lang="c#">
<syntaxhighlight lang="c#">

Revision as of 12:35, 14 May 2020

Other languages:

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


Введение

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

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

Настройка

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

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

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

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

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


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

Что это должно сделать?

  1. Рассчитать новую позицию блока в зависимости от стороны, в которую смотрит игрок
  2. Проверить, можно ли разместить блок в этой позиции
  3. Удалить оригинальный блок
  4. Поместить новый блок, используя ранее рассчитанную позицию
    public override bool OnPlayerInteract(IWorldAccessor world, IPlayer byPlayer, BlockSelection blockSel, ref EnumHandling handling)
    {
        // Find the target position
        BlockPos pos = blockSel.Position.AddCopy(blockSel.Face.GetOpposite());

        // Can we place the block there?
        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(block.BlockId, pos);
        }

        // Notify the game engine other block behaviors that we handled the players interaction with the block.
        // If we would not set the handling field the player would still be able to place blocks if he has them in hands.
        handling = EnumHandling.PreventDefault;
        return true;
    }

Register

In order the register the BlockBehavior we need to create a mod class, override Start(ICoreAPI) and register it with the given name:

    public class MovingBlocks : ModSystem
    {

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

    }

Distribution

In order to finish everything, open the modtools and type in pack <your mod id>. Now you can take the zip file and share it with other people.

Testing

Advanced Behavior

Our behavior is still rather simple, but there are a lot more possibilities. A behavior can have special properties, which can be defined by the blocktype itself.

Example

The behavior liquid supports some special properties as shown in this example of the water blocktype:

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

Parsing properties

In order to take care of special properties there is a method called Initialize(JsonObject). Each blocktype creates a new instance of the behavior, so the method can be used to parse the properties.

So what kind of properties could we add?

  • push distance
  • pull block if player is sneaking

First of all, we need to override the method in our block behavior class ...

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

Additionally we need to add two fields, one for the distance and another one if the player should pull the block while sneaking ...

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

Now we can parse the two properties like so:

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

The next thing we need to change is the interact method itself, so that it takes care of the distance and the pull properties ...

        public override bool OnPlayerInteract(IWorldAccessor world, IPlayer byPlayer, BlockSelection blockSel, ref EnumHandling handling)
        {
            BlockPos pos = blockSel.Position.AddCopy(pull && byPlayer.WorldData.EntityControls.Sneak ? blockSel.Face : blockSel.Face.GetOpposite(), 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;
        }

Adding another block

Let's create another block using this behavior, but this time we will configure some additional properties ...

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

The block will be pushed two blocks instead of one and the player can pull it by sneaking while right clicking.

Mod Download


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.