Modding:Block and Item Interactions: Difference between revisions

From Vintage Story Wiki
(Created page with "Custom collectible, will be available soon.")
 
No edit summary
Line 1: Line 1:
Custom collectible, will be available soon.
Custom collectible, will be available soon.
== Preparations ==
I highly recommend to read about [[Advanced Items|The Item Class]] first. Additionally you can download the assets [http://wiki.vintagestory.at/images/4/4d/MagicWand_-_No_CS_File.zip here].
Furthermore we need to create and register the item class ...
<syntaxhighlight lang="c#">
    public class Magic : ModBase
    {
        public override void Start(ICoreAPI api)
        {
            base.Start(api);
            api.RegisterItemClass("ItemMagicWand", typeof(ItemMagicWand));
        }
    }
    public class ItemMagicWand : Item
    {
       
    }
</syntaxhighlight>
== Adding particles ==
Now we need to implement the actual spawning function. First of all we need to specify that the player can "use" this tool, therefore we return <code>true</code> ...
<syntaxhighlight lang="c#">
        public override bool OnBeginInteract(IItemSlot slot, IEntityAgent byEntity, BlockSelection blockSel, EntitySelection entitySel)
        {
            return true;
        }
</syntaxhighlight>
The <code>OnInteracting</code> allows is to do something per tick while the player is using the item ...
<syntaxhighlight lang="c#">
        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;
            }
        }
</syntaxhighlight>
Holding rightclick ...
[[File:Magic Stick Interact.gif|300px]]
So let's mess around with particles. This will create a static particle type ...
<syntaxhighlight lang="c#">
        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
                );
</syntaxhighlight>
Particles should spawn once the stick animation is completed. This will be the case after <code>0.6</code> seconds ...
<syntaxhighlight lang="c#">
                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);
                }
</syntaxhighlight>
If we put everything together the <code>OnInteracting</code> method will look like this ...
<syntaxhighlight lang="c#">
        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;
        }
</syntaxhighlight>
You can read more about particles and how to use them [[Simple Particles|here]].
== Testing ==
<youtube>bTPXL97Gfns</youtube>
== Download ==

Revision as of 12:07, 21 November 2017

Custom collectible, will be available soon.

Preparations

I highly recommend to read about The Item Class first. Additionally you can download the assets here.

Furthermore we need to create and register 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 actual spawning function. First of all we need to specify that the player can "use" this tool, therefore we return true ...

        public override bool OnBeginInteract(IItemSlot slot, IEntityAgent byEntity, BlockSelection blockSel, EntitySelection entitySel)
        {
            return true;
        }

The OnInteracting allows is to do something per tick while the player is using the item ...

        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 ...

Magic Stick Interact.gif

So let's mess around with particles. This will create 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 stick animation is completed. This will be the case after 0.6 seconds ...

                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);
                }

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;
        }

You can read more about particles and how to use them here.

Testing

Download