Modding:Block and Item Interactions
This tutorial should introduce you into the basics of custom interactions. We will create a magic wand which should spawn particles when holding right click.
Preparations
I highly recommend to read about The Item Class first. Additionally you can download the assets here.
All of this should be familiar to you, creating and registering the item class ...
public class Magic : ModBase
{
public override void Start(ICoreAPI api)
{
base.Start(api);
api.RegisterItemClass("ItemMagicWand", typeof(ItemMagicWand));
}
}
public class ItemMagicWand : Item
{
}
Adding particles
Now we need to implement the interact function. First of all we need to specify that the player can "use" this tool, therefore we need to return true
...
public override bool OnBeginInteract(IItemSlot slot, IEntityAgent byEntity, BlockSelection blockSel, EntitySelection entitySel)
{
return true;
}
The method OnInteracting
allows us to spawn particles per tick while the player is using the item, but it would be better to implement an animation first. Particles should spawn after the animation is done ...
public override bool OnInteracting(float secondsUsed, IItemSlot slot, IEntityAgent byEntity, BlockSelection blockSel, EntitySelection entitySel)
{
if (byEntity.World is IClientWorldAccessor)
{
ModelTransform tf = new ModelTransform();
tf.EnsureDefaultValues();
float speed = 5 + 20 * Math.Max(0, secondsUsed - 0.25f);
float start = secondsUsed * 120;
float rotationZ = Math.Max(-110, start - Math.Max(0, secondsUsed - 0.25f) * 90 * speed);
tf.Origin.Set(0, 2f, 0);
tf.Translation.Set(0, Math.Max(-1f, -5 * Math.Max(0, secondsUsed - 0.25f)), 0);
tf.Rotation.Z = rotationZ;
byEntity.Controls.UsingHeldItemTransform = tf;
}
}
Holding rightclick ...
So let's start to mess around with particles, therefore we need a static particle type ...
public static SimpleParticleProperties particles = new SimpleParticleProperties(
1, 1,
ColorUtil.ColorFromArgb(50, 220, 220, 220),
new Vec3d(),
new Vec3d(),
new Vec3f(-0.25f, 0.1f, -0.25f),
new Vec3f(0.25f, 0.1f, 0.25f),
1.5f,
-0.075f,
0.25f,
0.25f,
EnumParticleModel.Quad
);
Particles should spawn once the animation is completed. This will be the case after 0.6
seconds ...
if (secondsUsed > 0.6)
{
//Spawn particles
}
I suggest to read the tutorial about Simple Particles first. This code will spawn particles in front of the player with a randomized color and a sinus evolving size ...
Vec3d pos =
byEntity.Pos.XYZ.Add(0, byEntity.EyeHeight(), 0)
.Ahead(1f, byEntity.Pos.Pitch, byEntity.Pos.Yaw)
;
Vec3f speedVec = new Vec3d(0, 0, 0).Ahead(5, byEntity.Pos.Pitch, byEntity.Pos.Yaw).ToVec3f();
particles.minVelocity = speedVec;
Random rand = new Random();
particles.color = ColorUtil.ToRGBABytes(ColorUtil.ColorFromArgb(255, rand.Next(0, 255), rand.Next(0, 255), rand.Next(0, 255)));
particles.minPos = pos.AddCopy(-0.05, -0.05, -0.05);
particles.addPos.Set(0.1, 0.1, 0.1);
particles.minSize = 0.1F;
particles.SizeEvolve = EvolvingNatFloat.create(EnumTransformFunction.SINUS, 10);
byEntity.World.SpawnParticles(particles);
If we put everything together the OnInteracting
method will look like this ...
public override bool OnInteracting(float secondsUsed, IItemSlot slot, IEntityAgent byEntity, BlockSelection blockSel, EntitySelection entitySel)
{
if (byEntity.World is IClientWorldAccessor)
{
ModelTransform tf = new ModelTransform();
tf.EnsureDefaultValues();
float speed = 5 + 20 * Math.Max(0, secondsUsed - 0.25f);
float start = secondsUsed * 120;
float rotationZ = Math.Max(-110, start - Math.Max(0, secondsUsed - 0.25f) * 90 * speed);
tf.Origin.Set(0, 2f, 0);
tf.Translation.Set(0, Math.Max(-1f, -5 * Math.Max(0, secondsUsed - 0.25f)), 0);
tf.Rotation.Z = rotationZ;
byEntity.Controls.UsingHeldItemTransform = tf;
if (secondsUsed > 0.6)
{
Vec3d pos =
byEntity.Pos.XYZ.Add(0, byEntity.EyeHeight(), 0)
.Ahead(1f, byEntity.Pos.Pitch, byEntity.Pos.Yaw)
;
Vec3f speedVec = new Vec3d(0, 0, 0).Ahead(5, byEntity.Pos.Pitch, byEntity.Pos.Yaw).ToVec3f();
particles.minVelocity = speedVec;
Random rand = new Random();
particles.color = ColorUtil.ToRGBABytes(ColorUtil.ColorFromArgb(255, rand.Next(0, 255), rand.Next(0, 255), rand.Next(0, 255)));
particles.minPos = pos.AddCopy(-0.05, -0.05, -0.05);
particles.addPos.Set(0.1, 0.1, 0.1);
particles.minSize = 0.1F;
particles.SizeEvolve = EvolvingNatFloat.create(EnumTransformFunction.SINUS, 10);
byEntity.World.SpawnParticles(particles);
}
}
return true;
}
Testing
Now we can run our first test, doesn't it look beautiful?
Download
Feel free to try it out yourself:
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 • Theme Pack |
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 | Item • Entity • Entity Behaviors • Block • Block Behaviors • Block Classes • Block Entities • Block Entity Behaviors • Collectible Behaviors • World properties |
Workflows & Infrastructure | Modding Efficiency Tips • Mod-engine compatibility • Mod Extensibility • VS Engine |
Additional Resources | Community Resources • Modding API Updates • Programming Languages • List of server commands • List of client commands • Client startup parameters • Server startup parameters Example Mods • API Docs • GitHub Repository |