This page is a tutorial about how to create a simple staff mod using StaffModLib.
Introduction
In this tutorial, you will learn how to create a simple staff mod only in code using StaffModLib and Bukkit. Let's begin !
The library may contain several implementation for different API. The one which is used here is the Bukkit one.
Step 1 : Initializing manager
First of all, you have to create a new instance of the BukkitStaffModManager class. This class has for goal to handle all the players which are in staff mod and will be required when we'll create our staff mod.
So, let's create an instance of this class. In this tutorial, we'll store it in the main class of our plugin.
publicclassStaffModLibExampleextendsJavaPlugin {privateBukkitStaffModManager manager; @OverridepublicvoidonEnable() {// Creating a new BukkitStaffModManager instance which will// be used by all the staff mods.this.manager=newBukkitStaffModManager(this); }}
Step 2 : Creating a staff mod
Now, let's create our first staff mod. To begin, you have to create a new class that extends the SimpleBukkitStaffMod class. It is an implementation of the StaffMod interface and it provides the basics to create your staff mod.
A constructor that takes as parameter an instance of the BukkitStaffModManager class is also needed. Furthermore, a plugin instance we'll be used to handle item listeners so we need to pass it too as a parameter of the constructor.
Before continuing the creation of our staff mod, we would like to save and clear the current player's state to restore it later. Indeed, the process of setting a player in staff mod will modify his inventory and you may also want to clear some states or to keep others to restore them when the staff mod we'll be disabled.
To do that, we have to use the PlayerDataHandler interface. You can click on the page below to see how to use it and to get more information about it.
So, let's create a createPlayerData() method which will handle the creation of PlayerDataHandler object. We'll use it later by adding code when enabling and disabling the staff mod.
privatePlayerDataHandlercreatePlayerData() {// This method has for goal to create a PlayerData object// which will store player state before enabling the staff mod.List<DataHandler<Player>> data =Arrays.asList(newInventoryDataHandler(),// Storing inventory information.newPotionDataHandler(),// Storing potion effects information.newGameModeDataHandler(),// Storing current game mode.newHealthDataHandler(),// Storing health information.newFoodDataHandler()// Storing food information. );returnnewPlayerDataHandler(data);}
Now, write the following code in the enable(Player holder) and the disable(Player holder) methods.
@Overridepublicvoidenable(Player holder) {// Saving player data.this.handler=this.createPlayerData();this.handler.save(holder);this.handler.clear(holder); super.enable(holder);}@Overridepublicvoiddisable(Player holder) {// Restoring player data.this.handler.clear(holder);this.handler.restore(holder);this.handler=null; // Avoiding reuse. super.disable(holder);}
Step 4 : Creating items
Now, let's create our items. In this tutorial, we'll only create an item that simulates a freeze system. So, to do that, you must first create a new class that inherits from the BukkitStaffModItem class. Now, redefine the require method and implement a constructor that takes a player instance and a plugin instance as parameter. You should have something like this:
Now, let's create the item which will be given to the player by implementing the body of the getItemStack() method.
@OverridepublicItemStackgetItem() {ItemStack item =newItemStack(Material.BLAZE_ROD);ItemMeta meta =item.getItemMeta();meta.setDisplayName("§eFreeze");item.setItemMeta(meta);return item;}
Handling events
In this part, we'll handle the events related to the freeze item that we're currently creating. So, to do that, we'll create an internal class that implements the Listener interface and we'll add methods to handle the events related to the freeze system.
// This class will handle the event related with the item.privateclassItemListenerimplementsListener { @EventHandlerpublicvoidonItemUseOnEntity(ItemUseOnEntityEvent event) {Player player =event.getPlayer();// Necessary. Checking that the holder of the items and the player// associated with the event are the sames.if(!player.equals(getHolder())) return;// Necessary. Checking that the current item and the items associated// with the event are the sames.if(!event.getStaffModItem().equals(FreezeItem.this)) return;Entity entity =event.getEntity();// If the entity isn't a Player, return.if(!(entity instanceof Player)) return;Player target = (Player) entity;// Note that in this example, only messages are sent.// You should create by yourself the freeze logic.player.sendMessage(String.format("%s is now frozen.",target.getName()));target.sendMessage(String.format("You have been frozen by %s.",player.getName()));// Cancelling the interaction.event.setCancelled(true); } @EventHandlerpublicvoidonItemUse(ItemUseEvent event) {event.setCancelled(true);event.getPlayer().updateInventory(); // Preventing display bugs. } @EventHandlerpublicvoidonItemUseOnBlock(ItemUseOnBlockEvent event) {event.setCancelled(true);event.getPlayer().updateInventory(); // Preventing display bugs. }}
You can see that I'm using a custom event called ItemUseOnEntityEvent. If you want to learn more about it and the other custom events provided by the library, you can click on the page below.
Now, let's handle this listener by overriding the onRegister() and the onUnregister() methods of the FreezeItem class. Before doing that, don't forget to create an instance variable which will store our listener instance and which will allow us to unregister the listener when the item will be unregistered.
privateListener listener;// ...@OverridepublicvoidonRegister() {// Registering our listener. Don't forget to store it into an instance variable// to allow to unregister it later.this.listener=newItemListener();Bukkit.getPluginManager().registerEvents(this.listener,this.plugin);}@OverridepublicvoidonUnregister() {// Unregistering the listener.HandlerList.unregisterAll(this.listener);}// ...
Final result
You can see the whole class below. Now, you have to follow the previously mentioned steps and adapt them to each item that you want to create.
publicclassFreezeItemextendsBukkitStaffModItem {privatefinalPlayer holder;privatefinalPlugin plugin;privateListener listener;publicFreezeItem(Player holder,Plugin plugin) {this.holder= holder;this.plugin= plugin; } @OverridepublicvoidonRegister() {this.listener=newItemListener();Bukkit.getPluginManager().registerEvents(this.listener,this.plugin); } @OverridepublicvoidonUnregister() {HandlerList.unregisterAll(this.listener); } @OverridepublicItemStackgetItem() {ItemStack item =newItemStack(Material.BLAZE_ROD);ItemMeta meta =item.getItemMeta();meta.setDisplayName("§eFreeze");item.setItemMeta(meta);return item; }privateclassItemListenerimplementsListener { @EventHandlerpublicvoidonItemUseOnEntity(ItemUseOnEntityEvent event) {Player player =event.getPlayer();if(!player.equals(getHolder())) return;if(!event.getStaffModItem().equals(FreezeItem.this)) return;Entity entity =event.getEntity();if(!(entity instanceof Player)) return;Player target = (Player) entity;player.sendMessage(String.format("%s is now frozen.",target.getName()));target.sendMessage(String.format("You have been frozen by %s.",player.getName()));event.setCancelled(true); } @EventHandlerpublicvoidonItemUse(ItemUseEvent event) {event.setCancelled(true);event.getPlayer().updateInventory(); } @EventHandlerpublicvoidonItemUseOnBlock(ItemUseOnBlockEvent event) {event.setCancelled(true);event.getPlayer().updateInventory(); } }}
Step 5 : Registering the items
Now, we'll register the item that has been previously created into our staff mod. To share responsibilities between the methods, we'll create a registerItems(Player player) method which will handle items registration. So, open your SimpleStaffMod class and write the following code.
publicvoidregisterItems(Player player) {// Declaring the item.StaffModItem freezeItem =newFreezeItem(player,this.plugin);// Setting its slot.freezeItem.setSlot(0);// Registering it. super.registerItem(freezeItem);}
Note that the slot of the item must be a number between 0 and 8.
And then, add call this method into the enable(Player holder) method:
@Overridepublicvoidenable(Player holder) {// Registering items.this.registerItems(holder);// Some code...}
In the two examples below, we'll suppose that we have access to instances of the Plugin and the BukkitStaffModManager classes. We'll also suppose that we have access to an instance of the Player class. First of all, we'll see how to enable the staff mod for a player.
Now, you know how to create your own staff mod very easily. In the next tutorials, we'll see how to create more advanced staff mods like a configurable or a pageable staff mod.