The plugin works exactly as intended, but what if we have a change of heart and begin to miss the sound of rain? Alternatively, what if our town bursts into flames and it must be extinguished quickly? We do not want to limit our power as an administrator by denying ourselves the use of the /toggledownfall
command. Next, we will listen for this command to be issued, and when it is issued, we will allow the weather to change. Ultimately, we will still be able to control the weather manually, but the weather will not start on its own.
Let's create another EventHandler method
. This time, we will listen for a console command being sent so that we can set a Boolean flag, as follows:
@EventHandler (ignoreCancelled = true, priority = EventPriority.MONITOR) public void onPlayerCommand(PlayerCommandPreprocessEvent event) { //Check if the Player is attempting to change the weather if (event.getMessage().startsWith("/toggledownfall")) { //Verify that the Player has permission to change the weather if (event.getPlayer().hasPermission("minecraft.command.toggledownfall")) { //Allow the Rain to start for this occasion denyRain = false; } } }
We will not actually be modifying this event at all. Therefore, the event priority will be set to MONITOR
. We also want to ignore canceled events. The event that we will listen for is PlayerCommandPreprocessEvent
, which will occur every time a player issues a command, whether they are for Minecraft, Bukkit, or another plugin. We only care about one command, namely /toggledownfall
. So, the first if
statement checks whether the message starts with /toggledownfall
. If it is a different command, we will ignore it. As the event name suggests, this event occurs before the command is actually executed. Therefore, we must verify that a player has the permission to run the command. The permission node for the command is minecraft.command.toggledownfall
. If these two conditions are met, then we want to allow rain to start on the next WeatherChangeEvent class
. The second EventHandler method
is completed by using the two if
statements and setting a Boolean variable to false
.
At this point, a light bulb will appear, informing you that the denyRain
symbol cannot be found. When you click on the bulb, you can select Create Field denyRain in com.codisimus.norain.NoRain
. This will automatically create a private variable called denyRain
inside the class. Note the placement of the new line of code. It is outside the existing method blocks and yet still inside the class. This is important because it defines the variable's scope. The scope of a variable is where it can be accessed. The denyRain
variable is private. Therefore, no other class, such as a class from another plugin, can modify it. However, within the NoRain
class, all the methods can access it. This is useful because if the variable was declared within the curly braces of the onPlayerCommand
method, we would not be able to see it from the onWeatherChange
method.
Now that the plugin knows when we wish to allow the rain to start, we must slightly modify the onWeatherChange
method to allow for such an exception. Currently, to cancel the event, we will call the setCancelled
method with true
as the parameter. If we were to pass false
as a parameter, then the event would not be cancelled. The denyRain
variable is equal to true
when we wish to cancel the event. Therefore, rather than passing true
or false
, we can pass the value of denyRain
. So, when denyRain
is set to false
, we will call setCancelled
using the following line of code:
event.setCancelled(false);
At the end of the onWeatherChange
method, we want to reset the value of denyRain
to true
. In this way, we can ensure that we allow the weather to change only once each time the /toggledownfall
command is issued. The final code looks like this:
package com.codisimus.norain; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerCommandPreprocessEvent; import org.bukkit.event.weather.WeatherChangeEvent; import org.bukkit.plugin.java.JavaPlugin; public class NoRain extends JavaPlugin implements Listener { //This is a variable that our two methods will use to "communicate" with each other private boolean denyRain = true; @Override public void onEnable() { //Register all of the EventHandlers within this class getServer().getPluginManager().registerEvents(this, this); } @EventHandler (ignoreCancelled = true, priority =EventPriority.LOW) public void onWeatherChange(WeatherChangeEvent event) { if (event.toWeatherState()) { //Rain is trying to turn on //Cancel the event if denyRain is set to true event.setCancelled(denyRain); } //Reset the denyRain value until next time a Player issues the /toggledownfall command denyRain = true; } @EventHandler (ignoreCancelled = true, priority =EventPriority.MONITOR) public void onPlayerCommand(PlayerCommandPreprocessEvent event) { //Check if the Player is attempting to change the weather if (event.getMessage().startsWith("/toggledownfall")) { //Verify that the Player has permission to change the weather if (event.getPlayer().hasPermission("minecraft.command.toggledownfall")) { //Allow the Rain to start for this occasion denyRain = false; } } } }
Note that when we declare the Boolean denyRain method
, we set its initial value to true
.
This completes the NoRain
plugin. Build the JAR file and test it out on your server. With this new version, you will be able to use the /toggledownfall
command to stop and start rain.
3.149.255.162