Modding:Añadir comportamiento a bloque

From Vintage Story Wiki
Revision as of 14:25, 15 June 2023 by Eleli (talk | contribs) (Created page with "} </syntaxhighlight>")
Other languages:

This page was last verified for Vintage Story version 1.9.


Introducción

Los comportamientos de bloque son útiles cuando se desea que diferentes bloques actúen de la misma manera, ya que se pueden adjuntar uno o más comportamientos de bloque a un número arbitrario de bloques. Puede que le interese echar un vistazo a las comportamientos de bloque existentes antes de implementar las suyas propias.

En este tutorial crearemos un nuevo comportamiento que podremos adjuntar a los bloques para hacerlos móviles haciendo clic con el botón derecho del ratón.

Configuración

Se requiere un espacio de trabajo de desarrollo. Además, necesitarás los recursos (tipo de bloque, textura y archivo lang). Se puede crear una propia o utilizar los que ya están hechos: Moving - No CS File.zip

Creación del comportamiento

Así que en primer lugar tenemos que crear el comportamiento en sí, que es una clase que extiende BlockBehavior

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

Esta clase proporciona varios métodos que podemos anular. Si utilizas Visual Studio puedes encontrar una lista completa de métodos pasando el ratón por encima de "BlockBehavior" y pulsando "F12".


El método bool OnPlayerInteract(IWorldAccessor world, IPlayer byPlayer, BlockSelection blockSel, ref EnumHandling handling) parece ideal para nuestro propósito.

¿Qué debe hacer?

  1. Calcula la nueva posición del bloque en función de la cara que mire el jugador
  2. Comprueba si el bloque se puede colocar en esta posición
  3. Retira el bloque original
  4. Coloca el nuevo bloque utilizando la posición calculada anteriormente
    public override bool OnPlayerInteract(IWorldAccessor world, IPlayer byPlayer, BlockSelection blockSel, ref EnumHandling handling)
    {
        // Encontrar la posición objetivo
        BlockPos pos = blockSel.Position.AddCopy(blockSel.Face.GetOpposite());

        // ¿Podemos colocar el bloque ahí?
        if (world.BlockAccessor.GetBlock(pos).IsReplacableBy(block))
        {
            // Elimina el bloque de la posición actual y lo coloca en la posición de destino
            world.BlockAccessor.SetBlock(0, blockSel.Position);
            world.BlockAccessor.SetBlock(block.BlockId, pos);
        }

        // Notificar al motor del juego otros comportamientos de bloque que manejamos la interacción de los jugadores con el bloque.
        // Si no fijáramos el campo de manipulación, el jugador seguiría pudiendo colocar bloques si los tiene en las manos.
        handling = EnumHandling.PreventDefault;
        return true;
    }

Registro

Para registrar el BlockBehavior tenemos que crear una clase mod, anular Start(ICoreAPI) y registrarlo con el nombre dado:

    public class MovingBlocks : ModSystem
    {

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

    }

Distribución

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.

Modding
Modding Introduction Getting Started Pack Temático
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 ItemEntityEntity BehaviorsBlockBlock BehaviorsBlock ClassesBlock EntitiesBlock Entity BehaviorsCollectible 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