Modding:Block and Item Interactions: Difference between revisions
No edit summary |
m (Added outdated tag and categories.) |
||
(21 intermediate revisions by 8 users not shown) | |||
Line 1: | Line 1: | ||
<languages/> | |||
__FORCETOC__ | |||
<translate> | |||
<!--T:1--> | |||
{{Outdated|Please note that this tutorial is candidate for a rewrite. While the particles created will work, the item used will not move due to "UsingHeldItemTransformAfter" being deprecated.}} | |||
</translate> | |||
<translate> | |||
<!--T:2--> | |||
This tutorial will introduce you into the basics of custom interactions. We will create a magic wand which will spawn particles when holding right click. | |||
</translate> | |||
<translate> | |||
= Preparations = <!--T:3--> | |||
</translate> | |||
<translate> | |||
<!--T:4--> | |||
I highly recommend to read about [[Advanced Items|The Item Class]] first. Additionally you can download the assets [https://wiki.vintagestory.at/images/4/4d/MagicWand_-_No_CS_File.zip here]. | |||
</translate> | |||
<translate> | |||
<!--T:5--> | |||
All of this should be familiar to you, creating and registering the item class ... | All of this should be familiar to you, creating and registering the item class ... | ||
</translate> | |||
<syntaxhighlight lang="c#"> | <syntaxhighlight lang="c#"> | ||
public class Magic : | public class Magic : ModSystem | ||
{ | { | ||
Line 25: | Line 43: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
== Adding particles == | <translate> | ||
== Adding particles == <!--T:6--> | |||
</translate> | |||
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 | <translate> | ||
<!--T:7--> | |||
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 set handling to <code>handled</code> ... | |||
</translate> | |||
<syntaxhighlight lang="c#"> | <syntaxhighlight lang="c#"> | ||
public override | public override void OnHeldInteractStart(ItemSlot slot, EntityAgent byEntity, BlockSelection blockSel, EntitySelection entitySel, bool firstEvent, ref EnumHandHandling handling) | ||
{ | { | ||
handling = EnumHandHandling.Handled; | |||
} | } | ||
</syntaxhighlight> | </syntaxhighlight> | ||
The method <code> | <translate> | ||
<!--T:8--> | |||
The method [[Modding:Right_click_events|<code>OnHeldInteractStep</code>]] 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 ... | |||
</translate> | |||
<syntaxhighlight lang="c#"> | <syntaxhighlight lang="c#"> | ||
public override bool | public override bool OnHeldInteractStep(float secondsUsed, ItemSlot slot, EntityAgent byEntity, BlockSelection blockSel, EntitySelection entitySel) | ||
{ | { | ||
if (byEntity.World is IClientWorldAccessor) | if (byEntity.World is IClientWorldAccessor) | ||
Line 46: | Line 72: | ||
tf.EnsureDefaultValues(); | tf.EnsureDefaultValues(); | ||
tf.Origin.Set(0, -1, 0); | |||
tf.Rotation.Z = Math.Min(30, secondsUsed * 40); | |||
byEntity.Controls.UsingHeldItemTransformAfter = tf; | |||
tf.Origin.Set(0, | |||
tf. | |||
byEntity.Controls. | |||
} | } | ||
return true; | |||
} | } | ||
</syntaxhighlight> | </syntaxhighlight> | ||
<translate> | |||
<!--T:9--> | |||
Holding rightclick ... | Holding rightclick ... | ||
<!--T:10--> | |||
[[File:Magic Stick Interact.gif|300px]] | [[File:Magic Stick Interact.gif|300px]] | ||
<!--T:11--> | |||
So let's start to mess around with particles, therefore we need a static particle type ... | So let's start to mess around with particles, therefore we need a static particle type ... | ||
</translate> | |||
<syntaxhighlight lang="c#"> | <syntaxhighlight lang="c#"> | ||
public static SimpleParticleProperties particles = new SimpleParticleProperties( | public static SimpleParticleProperties particles = new SimpleParticleProperties( | ||
1, 1, | 1, 1, | ||
ColorUtil. | ColorUtil.ColorFromRgba(220, 220, 220, 50), | ||
new Vec3d(), | new Vec3d(), | ||
new Vec3d(), | new Vec3d(), | ||
Line 81: | Line 107: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
<translate> | |||
<!--T:12--> | |||
Particles should spawn once the animation is completed. This will be the case after <code>0.6</code> seconds ... | Particles should spawn once the animation is completed. This will be the case after <code>0.6</code> seconds ... | ||
</translate> | |||
<syntaxhighlight lang="c#"> | <syntaxhighlight lang="c#"> | ||
Line 90: | Line 119: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
<translate> | |||
<!--T:13--> | |||
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 ... | 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 ... | ||
</translate> | |||
<syntaxhighlight lang="c#"> | <syntaxhighlight lang="c#"> | ||
Vec3d pos = | Vec3d pos = | ||
byEntity.Pos.XYZ.Add(0, byEntity. | byEntity.Pos.XYZ.Add(0, byEntity.LocalEyePos.Y, 0) | ||
.Ahead(1f, byEntity.Pos.Pitch, byEntity.Pos.Yaw) | .Ahead(1f, byEntity.Pos.Pitch, byEntity.Pos.Yaw) | ||
; | ; | ||
Vec3f speedVec = new Vec3d(0, 0, 0).Ahead(5, byEntity.Pos.Pitch, byEntity.Pos.Yaw).ToVec3f(); | Vec3f speedVec = new Vec3d(0, 0, 0).Ahead(5, byEntity.Pos.Pitch, byEntity.Pos.Yaw).ToVec3f(); | ||
particles. | particles.MinVelocity = speedVec; | ||
Random rand = new Random(); | Random rand = new Random(); | ||
particles. | particles.Color = ColorUtil.ColorFromRgba(rand.Next(0, 255), rand.Next(0, 255), rand.Next(0, 255), 255); | ||
particles. | particles.MinPos = pos.AddCopy(-0.05, -0.05, -0.05); | ||
particles. | particles.AddPos.Set(0.1, 0.1, 0.1); | ||
particles. | particles.MinSize = 0.1F; | ||
particles.SizeEvolve = EvolvingNatFloat.create(EnumTransformFunction.SINUS, 10); | particles.SizeEvolve = EvolvingNatFloat.create(EnumTransformFunction.SINUS, 10); | ||
byEntity.World.SpawnParticles(particles); | byEntity.World.SpawnParticles(particles); | ||
</syntaxhighlight> | </syntaxhighlight> | ||
If we put everything together the <code> | <translate> | ||
<!--T:14--> | |||
If we put everything together the <code>OnHeldInteractStep</code> method will look like this ... | |||
</translate> | |||
<syntaxhighlight lang="c#"> | <syntaxhighlight lang="c#"> | ||
public override bool | public override bool OnHeldInteractStep(float secondsUsed, ItemSlot slot, EntityAgent byEntity, BlockSelection blockSel, EntitySelection entitySel) | ||
{ | { | ||
if (byEntity.World is IClientWorldAccessor) | if (byEntity.World is IClientWorldAccessor) | ||
Line 119: | Line 154: | ||
tf.EnsureDefaultValues(); | tf.EnsureDefaultValues(); | ||
tf.Origin.Set(0, -1, 0); | |||
tf.Rotation.Z = Math.Min(30, secondsUsed * 40); | |||
byEntity.Controls.UsingHeldItemTransformAfter = tf; | |||
tf.Origin.Set(0, | |||
tf. | |||
byEntity.Controls. | |||
if (secondsUsed > 0.6) | if (secondsUsed > 0.6) | ||
{ | { | ||
Vec3d pos = | Vec3d pos = | ||
byEntity.Pos.XYZ.Add(0, byEntity. | byEntity.Pos.XYZ.Add(0, byEntity.LocalEyePos.Y, 0) | ||
.Ahead(1f, byEntity.Pos.Pitch, byEntity.Pos.Yaw) | .Ahead(1f, byEntity.Pos.Pitch, byEntity.Pos.Yaw) | ||
; | ; | ||
Vec3f speedVec = new Vec3d(0, 0, 0).Ahead(5, byEntity.Pos.Pitch, byEntity.Pos.Yaw).ToVec3f(); | Vec3f speedVec = new Vec3d(0, 0, 0).Ahead(5, byEntity.Pos.Pitch, byEntity.Pos.Yaw).ToVec3f(); | ||
particles. | particles.MinVelocity = speedVec; | ||
Random rand = new Random(); | Random rand = new Random(); | ||
particles. | particles.Color = ColorUtil.ColorFromRgba(rand.Next(0, 255), rand.Next(0, 255), rand.Next(0, 255), 255); | ||
particles. | particles.MinPos = pos.AddCopy(-0.05, -0.05, -0.05); | ||
particles. | particles.AddPos.Set(0.1, 0.1, 0.1); | ||
particles. | particles.MinSize = 0.1F; | ||
particles.SizeEvolve = EvolvingNatFloat.create(EnumTransformFunction.SINUS, 10); | particles.SizeEvolve = EvolvingNatFloat.create(EnumTransformFunction.SINUS, 10); | ||
byEntity.World.SpawnParticles(particles); | byEntity.World.SpawnParticles(particles); | ||
Line 151: | Line 180: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
== Testing == | <translate> | ||
== Testing == <!--T:15--> | |||
</translate> | |||
<translate> | |||
<!--T:16--> | |||
Now we can run our first test, doesn't it look beautiful? | Now we can run our first test, doesn't it look beautiful? | ||
</translate> | |||
<youtube>bTPXL97Gfns</youtube> | <youtube>bTPXL97Gfns</youtube> | ||
= | <translate> | ||
= Mod Download = <!--T:17--> | |||
</translate> | |||
<translate> | |||
<!--T:18--> | |||
Feel free to try it out yourself: | Feel free to try it out yourself: | ||
</translate> | |||
[ | <translate> | ||
<!--T:19--> | |||
Here is my version: | |||
* for VS v1.9: [https://wiki.vintagestory.at/images/7/72/Magicwand_vs1.9_v1.0.0.zip Magicwand_vs1.9_v1.0.0.zip] | |||
* for VS v1.8: [https://wiki.vintagestory.at/images/3/38/MagicWand.zip MagicWand.zip] | |||
</translate> | |||
{{Navbox/ | {{Navbox/codemodding}} | ||
[[Category:Modding{{#translation:}}]] | |||
[[Category:Modding:Code{{#translation:}}]] |
Latest revision as of 20:13, 22 November 2024
This page is outdated.
Reason: Please note that this tutorial is candidate for a rewrite. While the particles created will work, the item used will not move due to "UsingHeldItemTransformAfter" being deprecated.
The content on this page is not up to date with the most recent game update. If you do wish to contribute, please request wiki edit access on the Discord.
This tutorial will introduce you into the basics of custom interactions. We will create a magic wand which will 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 : ModSystem
{
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 set handling to handled
...
public override void OnHeldInteractStart(ItemSlot slot, EntityAgent byEntity, BlockSelection blockSel, EntitySelection entitySel, bool firstEvent, ref EnumHandHandling handling)
{
handling = EnumHandHandling.Handled;
}
The method OnHeldInteractStep
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 OnHeldInteractStep(float secondsUsed, ItemSlot slot, EntityAgent byEntity, BlockSelection blockSel, EntitySelection entitySel)
{
if (byEntity.World is IClientWorldAccessor)
{
ModelTransform tf = new ModelTransform();
tf.EnsureDefaultValues();
tf.Origin.Set(0, -1, 0);
tf.Rotation.Z = Math.Min(30, secondsUsed * 40);
byEntity.Controls.UsingHeldItemTransformAfter = tf;
}
return true;
}
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.ColorFromRgba(220, 220, 220, 50),
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.LocalEyePos.Y, 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.ColorFromRgba(rand.Next(0, 255), rand.Next(0, 255), rand.Next(0, 255), 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 OnHeldInteractStep
method will look like this ...
public override bool OnHeldInteractStep(float secondsUsed, ItemSlot slot, EntityAgent byEntity, BlockSelection blockSel, EntitySelection entitySel)
{
if (byEntity.World is IClientWorldAccessor)
{
ModelTransform tf = new ModelTransform();
tf.EnsureDefaultValues();
tf.Origin.Set(0, -1, 0);
tf.Rotation.Z = Math.Min(30, secondsUsed * 40);
byEntity.Controls.UsingHeldItemTransformAfter = tf;
if (secondsUsed > 0.6)
{
Vec3d pos =
byEntity.Pos.XYZ.Add(0, byEntity.LocalEyePos.Y, 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.ColorFromRgba(rand.Next(0, 255), rand.Next(0, 255), rand.Next(0, 255), 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?
Mod Download
Feel free to try it out yourself:
Here is my version:
- for VS v1.9: Magicwand_vs1.9_v1.0.0.zip
- for VS v1.8: MagicWand.zip
Code Modding | |||||||
---|---|---|---|---|---|---|---|
Basics | Code Mods • Preparing For Code Mods • Creating A Code Mod | ||||||
Tutorials |
|
||||||
Advanced | Server-Client Considerations • Setting up your Development Environment • Advanced Blocks • Advanced Items • Block and Item Interactions • Block Behavior • Block Entity • Particle Effects • World Access • Inventory Handling • Commands • GUIs • Network API • Monkey patching (Harmony) | ||||||
Data Management | VCDBS format • Savegame Moddata • ModConfig File • Chunk Moddata • Serialization Formats • TreeAttribute | ||||||
Worldgen | WorldGen API • NatFloat • EvolvingNatFloat | ||||||
Rendering | Shaders and Renderers |
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 |