Amazon Ad

Wednesday, May 24, 2017

Custom Commands

I decided to do a tutorial on commands since there aren't really any tutorials on commands these days. So without further-a-do, let's get to it.

Remember at part two of setting up with IntelliJ while we were creating the proxies, we created two extra methods called "serverStarting(event)" and "serverStopping(event)"? Well, it's now time to utilize them...well...one of them at least! We are going to need to use the "serverStarting(event)" method to register a command to the logical server. So we need to create that same method in our main mod class, annotate it with "@Mod.EventHandler" and pass in "FMLServerStartingEvent" into it. It's going to contain a method we need in order to register our command. (Doing this for "serverStopping(event)" is optional since we are currently not using it).


Now we need to go into our CommonProxy class and register our yet to be created command.


Now we need to create a new class called CommandTutorial and we will put it in a new package called "command". This class needs to inherit from CommandBase, which is a base template for all commands in Minecraft. You will be prompted to override a few methods: "getName()", "getUsage(sender)", and "execute(server, sender, args[]) throws CommandException". For the "getName()" we are going to return the name of our command, which is going to give our command the "/<name_here> <args_1> [args_2] ... [args_8]" look, and the args[] is everything typed after the name of the command separated by spaces. So for the tutorial we should give our command the name "tut", for simplicity and consistency. The "getUsage(sender)" method is returned to us when we try to get the usage for that command. The "execute(server, sender, args[]) throws CommandException" is what we want to happen after the player presses enter with our command entered in. So we are going to specify that.in our "execute()" comand.

First, we need to get the world of the command sender. The command sender is whomever is sending it, the player practically, and get's the entity world out of it. Then we need to check if we are on the client side or on server side. Again, using world.isRemote to check that means that returning true is on the client logical side and returning false means server logical side. We should also print depending on which side we are on just in case we missed something.



Now we need to specify what we want to happen if we are processing on the server logical side. We are going to make a test command that will give us our custom blocks and items specifically. So we will need to get the player that is sending the command. Luckily, we don't need to do any witchcraft to pull that off, cause CommandBase has a method for getting the player; two methods, in fact. We are going to need to use one of them. There is "getPlayer(server, player, name)" and there is "getCommandSenderAsPlayer(sender)" which returns the player that is sending the command. We need that one. So let's create a new EntityPlayerMP object called "player" and initialize it to "getCommandSenderAsPlayer(sender)" and pass in "sender" as an argument. Now let's move on to the part of deciding what block or item to give to the player.

In order to tell Minecraft what block or item to give to the player, we need to test if the command looks like this:

/tut get <item:block>

So we need to see if the command sender has typed in "get" as the first argument.


Now if this is true, then we need to see if the command argument after that matches with any of our items/blocks unlocalized names.



Now we need to give the player the items or blocks requested. We need to create a new ItemStack with each of these items/blocks in it. There are two methods that we can use called "getBlockFromText(sender, name)" and "getItemFromText(sender, name)". We can use these when creating the itemstacks of the blocks/items. We give it a string and it matches the string with an unlocalized name of an item or block (depending on the method specified) and returns the item or block that it finds. Then, we can put it in the player's inventory by using a method in the "player.inventory" called "addStackToInventory(stack)". We need to do this for each item and block.


Let's print something to the screen whenever the command is successful!


Now we can test the mod and type in the command and see what it gives us!


It works for the item, and it also works for the blocks. Congrats! You just created a working command!

3 comments:

  1. "Not processing on client side!"
    "Processing on server side!"
    Um, aren't those the same thing?

    ReplyDelete