Difference between revisions of "Modding:Advanced Blocks"

From Vintage Story Wiki
Jump to navigation Jump to search
(Created page with "__FORCETOC__ This tutorial requires a development environment. If you don't have one or don't know how to setup up something like that read the tutorial Setting up a dev en...")
 
Line 5: Line 5:
 
= Tramopline =
 
= Tramopline =
  
== Block Json File ==
+
== Block Assets ==
  
 +
The first thing we are going to need are the assets of the block. There is a separate tutorial covering all the stuff you need to know about [[Creating Blocks|block assets]], which you should read first if haven't already. You can download the assets (block json, texture) [http://wiki.vintagestory.at/images/c/cf/Trampoline-assets.zip here] and extract them into your assets folder inside the [[Vintagestory folder]].
 +
 +
If you want to use your own block, you have to add the class property, which should refer to the class we will register later on:
 
<syntaxhighlight lang="json">
 
<syntaxhighlight lang="json">
 
class: "trampoline",
 
class: "trampoline",
 
</syntaxhighlight>
 
</syntaxhighlight>
  
You can download the assets [http://wiki.vintagestory.at/images/c/cf/Trampoline-assets.zip here].
+
== The Block Class ==
 +
 
 +
So how can we implement a jumping functionality? First of all we need to create a new <code>*.cs</code> file in our project. I'm gonna name it <code>Trampoline.cs</code>.
 +
 
 +
=== The Mod Base ===
 +
 
 +
Now we can create a new class which extends ModBase.
 +
 
 +
<syntaxhighlight lang="c#">
 +
public class TrampolineMod : ModBase
 +
{
 +
   
 +
}
 +
</syntaxhighlight>
 +
 
 +
This class can be used to register all kinds of stuff. For now we will stick to our trampoline. Therefore we have to override the <code>Start(ICoreAPI)</code> method and register your block class.
 +
 
 +
<syntaxhighlight lang="c#">
 +
public class TrampolineMod : ModBase
 +
{
 +
    public override void Start(ICoreAPI api)
 +
    {
 +
        base.Start(api);
 +
        api.RegisterBlockClass("trampoline", typeof(TrampolineBlock));
 +
    }
 +
}
 +
</syntaxhighlight>
 +
 
 +
This should be marked as a syntax error because there is no <code>TrampolineBlock</code> class yet.
 +
 
 +
=== The Block Class ===
 +
 
 +
The next thing we have to do is to create another class, which should extend <code>Block</code>. This class must have the same name as you have implemented it before:
 +
 
 +
<syntaxhighlight lang="c#">
 +
public class TrampolineBlock : Block
 +
{
 +
 
 +
}
 +
</syntaxhighlight>
 +
 
 +
This will solve all syntax errors, but how do we implement a bouncy block? To figure out how to implement something like that, we can take a look at the [http://apidocs.vintagestory.at/Vintagestory.API/Block.htm api documentation].
 +
 
 +
This method seems to be a good way to implement a bouncy functionality: <code>void onEntityCollide(IWorldAccessor world, Entity entity, BlockPos pos, BlockFacing facing, bool isImpact)</code>
 +
 
 +
'''When should an entity bounce?'''
 +
# The entity should bounce in the moment it lands on top of the block and not if it is standing on it already. Therefore <code>isImpact</code> has to be <code>true</code>
 +
# If the entity is colliding vertically. The sides of the block shouldn't push an entity away. So the <code>axis</code> of the <code>facing</code> has to be <code>Y</code>.
 +
 
 +
'''How the we make the entity bounce?'''
 +
 
 +
We can revert its motion by doing the following:
 +
<syntaxhighlight lang="c#">
 +
entity.Pos.Motion.Y *= -0.8;
 +
</syntaxhighlight>
 +
 
 +
----
 +
 
 +
If we put everything together it should look like this:
 +
 
 +
<syntaxhighlight lang="c#">
 +
public class TrampolineBlock : Block
 +
{
 +
    public override void onEntityCollide(IWorldAccessor world, Entity entity, BlockPos pos, BlockFacing facing, bool isImpact)
 +
    {
 +
        if (isImpact && facing.Axis == EnumAxis.Y)
 +
        {
 +
            entity.Pos.Motion.Y *= -0.8;
 +
        }
 +
    }
 +
}
 +
</syntaxhighlight>
 +
 
 +
Although this code would work already, we should also add a sound to it:
 +
<syntaxhighlight lang="c#">
 +
entity.PlayEntitySound("tick", EnumAppSide.Server);
 +
</syntaxhighlight>
  
== The Block Class ==
 
  
 +
If you have done everything right, your class should look similar to this:
 
<syntaxhighlight lang="c#">
 
<syntaxhighlight lang="c#">
 
using System;
 
using System;
Line 50: Line 129:
 
}
 
}
 
</syntaxhighlight>
 
</syntaxhighlight>
 +
 +
Of course you can download the file directly [http://wiki.vintagestory.at/images/8/8a/Trampoline.cs Trampoline.cs].
  
 
== Testing ==
 
== Testing ==
 +
 +
<youtube>Kg8J_rNOweU</youtube>
  
 
== Distributing a mod ==
 
== Distributing a mod ==

Revision as of 13:39, 29 March 2017


This tutorial requires a development environment. If you don't have one or don't know how to setup up something like that read the tutorial Setting up a dev environment.

Tramopline

Block Assets

The first thing we are going to need are the assets of the block. There is a separate tutorial covering all the stuff you need to know about block assets, which you should read first if haven't already. You can download the assets (block json, texture) here and extract them into your assets folder inside the Vintagestory folder.

If you want to use your own block, you have to add the class property, which should refer to the class we will register later on:

	class: "trampoline",

The Block Class

So how can we implement a jumping functionality? First of all we need to create a new *.cs file in our project. I'm gonna name it Trampoline.cs.

The Mod Base

Now we can create a new class which extends ModBase.

public class TrampolineMod : ModBase
{
    
}

This class can be used to register all kinds of stuff. For now we will stick to our trampoline. Therefore we have to override the Start(ICoreAPI) method and register your block class.

public class TrampolineMod : ModBase
{
    public override void Start(ICoreAPI api)
    {
        base.Start(api);
        api.RegisterBlockClass("trampoline", typeof(TrampolineBlock));
    }
}

This should be marked as a syntax error because there is no TrampolineBlock class yet.

The Block Class

The next thing we have to do is to create another class, which should extend Block. This class must have the same name as you have implemented it before:

public class TrampolineBlock : Block
{

}

This will solve all syntax errors, but how do we implement a bouncy block? To figure out how to implement something like that, we can take a look at the api documentation.

This method seems to be a good way to implement a bouncy functionality: void onEntityCollide(IWorldAccessor world, Entity entity, BlockPos pos, BlockFacing facing, bool isImpact)

When should an entity bounce?

  1. The entity should bounce in the moment it lands on top of the block and not if it is standing on it already. Therefore isImpact has to be true
  2. If the entity is colliding vertically. The sides of the block shouldn't push an entity away. So the axis of the facing has to be Y.

How the we make the entity bounce?

We can revert its motion by doing the following:

entity.Pos.Motion.Y *= -0.8;

If we put everything together it should look like this:

public class TrampolineBlock : Block
{
    public override void onEntityCollide(IWorldAccessor world, Entity entity, BlockPos pos, BlockFacing facing, bool isImpact)
    {
        if (isImpact && facing.Axis == EnumAxis.Y)
        {
            entity.Pos.Motion.Y *= -0.8;
        }
    }
}

Although this code would work already, we should also add a sound to it:

entity.PlayEntitySound("tick", EnumAppSide.Server);


If you have done everything right, your class should look similar to this:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Vintagestory.API;
using Vintagestory.API.Common;
using Vintagestory.API.Common.Entities;
using Vintagestory.API.MathTools;

namespace VSExampleMods
{
    public class TrampolineMod : ModBase
    {
        public override void Start(ICoreAPI api)
        {
            base.Start(api);
            api.RegisterBlockClass("trampoline", typeof(TrampolineBlock));
        }
    }

    public class TrampolineBlock : Block
    {
        public override void onEntityCollide(IWorldAccessor world, Entity entity, BlockPos pos, BlockFacing facing, bool isImpact)
        {
            if (isImpact && facing.Axis == EnumAxis.Y)
            {
                entity.PlayEntitySound("tick", EnumAppSide.Server);
                entity.Pos.Motion.Y *= -0.8;
            }
        }
    }
}

Of course you can download the file directly Trampoline.cs.

Testing

Distributing a mod