Modding:Commands: Difference between revisions

From Vintage Story Wiki
m (add tvar tag)
m (Updated navbox to new code navbox.)
 
(3 intermediate revisions by 2 users not shown)
Line 1: Line 1:
<languages/>
<languages/>
{{GameVersion|1.15}}
{{GameVersion|1.19.3}}
<translate>
<translate>
<!--T:1-->
<!--T:1-->
Line 8: Line 8:


<!--T:3-->
<!--T:3-->
The idea is to add a command which makes it easier for your mates to locate you. Therefore we will spawn some particles alongside a playing sound, so others can see and hear where you are at the moment.
The idea is to add a command which makes it easier for your friends to locate you. Therefore we will spawn some particles alongside a playing sound, so others can see and hear where you are at the moment.


<!--T:4-->
== Implementation == <!--T:7-->
You can download the required assets [https://wiki.vintagestory.at/images/1/16/Here_Assets.zip here]. Just extract them in your mods directory and you are good to go.
As always, we need to create a class extending <code>ModSystem</code>:
 
== Implementation == <!--T:5-->
 
<!--T:6-->
First of all you need to add another mod to your workspace. I will use the modid <tvar|1><code>here</code></>, so I will type in <tvar|2><code>add here</code></> in modtools to create a new mod. Additionally I will create <tvar|3><code>Command.cs</code></> in the <tvar|4><code>src</code></> directory.
 
<!--T:7-->
As always we need to create a class extending <tvar|5><code>ModSystem</code></>:
<tvar|6>
<syntaxhighlight lang="c#">
<syntaxhighlight lang="c#">
public class CommandMod : ModSystem
public class CommandMod : ModSystem
Line 28: Line 19:
}
}
</syntaxhighlight>
</syntaxhighlight>
</>


<!--T:9-->
<!--T:9-->
Commands are processed by the server, so our mod only needs to load on the server's side:
We will be creating a server-side command, so our mod only needs to load on the server's side:
<tvar|7>
<syntaxhighlight lang="c#">
<syntaxhighlight lang="c#">
         public override bool ShouldLoad(EnumAppSide side)
         public override bool ShouldLoad(EnumAppSide side)
Line 39: Line 28:
         }
         }
</syntaxhighlight>
</syntaxhighlight>
</>


<!--T:10-->
<!--T:10-->
Now we need to register the command itself:
Now we need to create the command itself:
<tvar|8>
<syntaxhighlight lang="c#">
<syntaxhighlight lang="c#">
         public override void StartServerSide(ICoreServerAPI api)
         public override void StartServerSide(ICoreServerAPI api)
         {
         {
             base.StartServerSide(api);
             base.StartServerSide(api);
             api.RegisterCommand("here", "spawns particles around the player", "",
            AssetLocation sound = new AssetLocation("here", "sounds/partyhorn");
                (IServerPlayer player, int groupId, CmdArgs args) =>
             api.ChatCommands.Create("here")
                    {
            .WithDescription("spawns particles around the player")
 
            .RequiresPrivilege(Privilege.chat)
                    <!--T:11-->
            .RequiresPlayer();
}, Privilege.chat);
         }
         }
</syntaxhighlight>
</syntaxhighlight>
</>


<!--T:12-->
<!--T:12-->
This command can be used by any player who is allowed to send a message (by default everyone). When a player types in <tvar|9><code>/here</code></>, the command will be executed. Now we the only thing missing is the actual code to spawn particles and to play the sound.
This command can be used by any player who is allowed to send a message (by default everyone). When a player types in <code>/here</code>, the command will be executed. Now we the only thing missing is the actual code to spawn particles and to play the sound.


<!--T:13-->
<!--T:13-->
<tvar|10>
<syntaxhighlight lang="c#">
<syntaxhighlight lang="c#">
         public override void StartServerSide(ICoreServerAPI api)
         public override void StartServerSide(ICoreServerAPI api)
         {
         {
             base.StartServerSide(api);
             base.StartServerSide(api);
             AssetLocation sound = new AssetLocation("here", "sounds/partyhorn"); // Create sound location
             AssetLocation sound = new AssetLocation("here", "sounds/partyhorn");
             api.RegisterCommand("here", "spawns particles around the player", "",
             api.ChatCommands.Create("here")
                (IServerPlayer player, int groupId, CmdArgs args) =>
            .WithDescription("spawns particles around the player")
                    {
            .RequiresPrivilege(Privilege.chat)
                        EntityPlayer byEntity = player.Entity;
            .RequiresPlayer()
                        byEntity.World.PlaySoundAt(sound, byEntity); // Play sound
            .HandleWith((args) =>
 
            {
                        <!--T:14-->
                var byEntity = args.Caller.Entity;
Vec3d pos = byEntity.Pos.XYZ.Add(0, byEntity.EyeHeight, 0); // Setting up position to spawn particles
                byEntity.World.PlaySoundAt(sound, byEntity);
                        Random rand = new Random();
                Vec3d pos = byEntity.Pos.XYZ.Add(0, byEntity.LocalEyePos.Y, 0);
                        for (int i = 0; i < 100; i++) // Spawn 100 particles
                Random rand = new Random();
                        {
                for (int i = 0; i < 100; i++)
                            Vec3d realPos = pos.AddCopy(-0.1 + rand.NextDouble() * 0.2, 0, -0.1 + rand.NextDouble() * 0.2);
                {
                            Vec3f velocity = new Vec3f(-0.2F + (float) rand.NextDouble() * 0.4F, 0.4F + (float) rand.NextDouble() * 2F, -0.2F + (float) rand.NextDouble() * 0.4F);
                    Vec3d realPos = pos.AddCopy(-0.1 + rand.NextDouble() * 0.2, 0, -0.1 + rand.NextDouble() * 0.2);
                            byEntity.World.SpawnParticles(1, ColorUtil.ColorFromRgba(255, rand.Next(0, 255), rand.Next(0, 255), rand.Next(0, 255)),
                    Vec3f velocity = new Vec3f(-0.2F + (float)rand.NextDouble() * 0.4F, 0.4F + (float)rand.NextDouble() * 2F, -0.2F + (float)rand.NextDouble() * 0.4F);
                                realPos, realPos,
                    byEntity.World.SpawnParticles(1, ColorUtil.ToRgba(255, rand.Next(0, 255), rand.Next(0, 255), rand.Next(0, 255)),
                                velocity, velocity, (float) rand.NextDouble()*1 + 1, 0.01F,
                        realPos, realPos,
                                1, EnumParticleModel.Cube);
                        velocity, velocity, (float)rand.NextDouble() * 1 + 1, 0.01F,
                        }
                        1, EnumParticleModel.Cube);
                    }, Privilege.chat);
                }
                return TextCommandResult.Success();
            });
         }
         }
</syntaxhighlight>
</syntaxhighlight>
</>


<!--T:15-->
<!--T:15-->
Line 101: Line 86:
<!--T:18-->
<!--T:18-->
<youtube>XjHMtl6rSF4</youtube>
<youtube>XjHMtl6rSF4</youtube>
== Download == <!--T:19-->
<!--T:20-->
Feel free to try it out yourself:
<!--T:21-->
[https://wiki.vintagestory.at/images/5/5f/Here_v1.1.zip Here_v1.1.zip]
</translate>
</translate>
{{Navbox/modding|Vintage Story}}
{{Navbox/codemodding}}

Latest revision as of 17:04, 27 March 2024

Other languages:

This page was last verified for Vintage Story version 1.19.3.

Ever wanted to know how to add a command to the game? If yes, this is the right place to get an answer.

Preparations

The idea is to add a command which makes it easier for your friends to locate you. Therefore we will spawn some particles alongside a playing sound, so others can see and hear where you are at the moment.

Implementation

As always, we need to create a class extending ModSystem:

public class CommandMod : ModSystem
{

}

We will be creating a server-side command, so our mod only needs to load on the server's side:

        public override bool ShouldLoad(EnumAppSide side)
        {
            return side == EnumAppSide.Server;
        }

Now we need to create the command itself:

        public override void StartServerSide(ICoreServerAPI api)
        {
            base.StartServerSide(api);
            AssetLocation sound = new AssetLocation("here", "sounds/partyhorn");
            api.ChatCommands.Create("here")
            .WithDescription("spawns particles around the player")
            .RequiresPrivilege(Privilege.chat)
            .RequiresPlayer();
        }

This command can be used by any player who is allowed to send a message (by default everyone). When a player types in /here, the command will be executed. Now we the only thing missing is the actual code to spawn particles and to play the sound.

        public override void StartServerSide(ICoreServerAPI api)
        {
            base.StartServerSide(api);
            AssetLocation sound = new AssetLocation("here", "sounds/partyhorn");
            api.ChatCommands.Create("here")
            .WithDescription("spawns particles around the player")
            .RequiresPrivilege(Privilege.chat)
            .RequiresPlayer()
            .HandleWith((args) =>
            {
                var byEntity = args.Caller.Entity;
                byEntity.World.PlaySoundAt(sound, byEntity);
                Vec3d pos = byEntity.Pos.XYZ.Add(0, byEntity.LocalEyePos.Y, 0);
                Random rand = new Random();
                for (int i = 0; i < 100; i++)
                {
                    Vec3d realPos = pos.AddCopy(-0.1 + rand.NextDouble() * 0.2, 0, -0.1 + rand.NextDouble() * 0.2);
                    Vec3f velocity = new Vec3f(-0.2F + (float)rand.NextDouble() * 0.4F, 0.4F + (float)rand.NextDouble() * 2F, -0.2F + (float)rand.NextDouble() * 0.4F);
                    byEntity.World.SpawnParticles(1, ColorUtil.ToRgba(255, rand.Next(0, 255), rand.Next(0, 255), rand.Next(0, 255)),
                        realPos, realPos,
                        velocity, velocity, (float)rand.NextDouble() * 1 + 1, 0.01F,
                        1, EnumParticleModel.Cube);
                }
                return TextCommandResult.Success();
            });
        }

If you want to learn more about how to use particles you can check out this tutorial.

Testing

Finally, we are ready to run our first test:

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