Creating a Custom Weather (0.7 - 0.8)[programming]

How's custom weather defined?/What it is?

When you say custom weather, it's understood( at least by ProperWeather) as an event, which modifies current weather conditions in some world and occurs with some probability.

[programming]

This section is about creating a custom weather using a plugin. As of 0.7 release, you can use YAML file to create a weather.

Let's get started!

To implement a class, we should know what we're doing, so I paste Weather class here, so you'll know what to implement:

package sk.tomsik68.pw.api;

import java.util.UUID;

import sk.tomsik68.pw.config.WeatherDescription;
import sk.tomsik68.pw.plugin.ProperWeather;

public abstract class Weather implements Cloneable{
	private UUID worldID;
	protected final WeatherDescription wd;
	public Weather(WeatherDescription wd, UUID world){
		worldID = world;
		this.wd = wd;
	}
	public final WeatherController getController(){
		return ProperWeather.instance().getWeatherSystem().getWeatherController(worldID);
	}
	public final boolean canBeStarted(Integer previousID){
		return wd.canBeAfter(previousID);
	}
	
	public final int getRandomTimeProbability(){
		return wd.getRandomTimeProbability();
	}

	public final int getProbability(){
		return wd.getProbability();
	}
	
	public abstract void initWeather();

	public abstract void onRandomTime();

	public final int getMaxDuration(){
		return wd.getMaxDuration();
		
	}
	//for defining default values for variables
	public abstract int getDefMaxDuration();
	public abstract String[] getDefCantBeAfter();
	public abstract int getDefRandomTimeProbability();
	public abstract int getDefProbability();
	public final String getName() {
		return wd.getName();
	}
	
}

Implementation of Weather method by method

canBeStarted(int previousID)

public boolean canBeStarted(int previousID);

This method tells weather system, whether this weather can be started after different weather. Usage Example: Storm must logically begin after rain. Why ID? Because I find really stupid to save objects of type Weather. Weather is an event, neither a save structure, so I've decided to make ID for each weather. Example implementation: Let's say your weather can only be started after Meteorite Storm.

public boolean canBeStarted(int previousID){
    return previousID == 4;
}

getDefRandomTimeProbability()

public int getDefRandomTimeProbability();

A random time??? Yes. Random time. Random time is used for any further sub-events occured while your weather is running. Example Usage: You don't want to see lightning or meteor every second. Ok and what should be returned here? The plugin is expecting number in range 0 - 100 ( %s ) Example Implementation:

public int getDefRandomTimeProbability(){
    return 50;
}

And what do you do if you aren't sure about %s? Just use enum sk.tomsik68.pw.api.EWeatherRarity to help you, like this:

public int getDefRandomTimeProbability(){
    return EWeatherRarity.Normal.getApart();
}

getDefProbability(WeatherSystem ws)

This tells the system default probability of weather initialisation. Example Usages: Some weather can be more rare than others, I don't want meteors to destroy my house ;) Example Implementation:

public int getDefProbability(){
    return EWeatherRarity.Normal.getApart();
}

initWeather()

Your weather was chosen by system( or user ;) ) to run. You need to start the basic conditions of your weather. Example Usages: Change sky color, Start raining, Allow Thunders,... Example Implementation:

    public void initWeather(){
          WeatherController wc = getController();
          wc.clear();
          wc.allowThundering();
          wc.setSkyColor(java.awt.Color.BLACK);
    }

onRandomTime()

Here we get to previously mentioned random time. Example Usages: Thundering, Falling Meteorite, Spawning Custom Entities,... Example Implementation(with thunders):

public void onRandomTime() {
		WeatherController controller = getController();
		World world = controller.getWorld();
		Random rand = new Random(world.getSeed() * world.getFullTime());
		for(Chunk chunk : world.getLoadedChunks()){
			for(int x = chunk.getX();x<x+16;x++){
				for(int z = chunk.getZ();z<z+16;z++){
					if(rand.nextInt(0x186a0) == 0 && world.getHighestBlockAt(x, z).getType() != Material.SAND){
						controller.strike(x, world.getHighestBlockYAt(x, z), z);
					}
				}
			}
		}
	}

How to register weather?

So far, we've implemented our weather, but that's not enought, because ProperWeather can't find it itself, so registration is needed. Luckily, I've made the registration simple:

WeatherManager.register(MyWeather.class);

Let's add the code into main skeleton:

import sk.tomsik68.pw.WeatherManager
import sk.tomsik68.pw.plugin.ProperWeather;
public void setupBridge() {
		Plugin test = getServer().getPluginManager().getPlugin("ProperWeather");
		if (test != null && test instanceof ProperWeather) {
			ProperWeather pw = (ProperWeather) test;
			System.out.println("[MyPlugin] Hooked into ProperWeather");
                        //MyWeather is the Weather implementation you've just created
			WeatherManager.register(MyWeather.class);
		}
	}

Cheers!

You've just made your first (and hopefully not last) Weather for Minecraft! Now go ahead, compile it and try it. If you've got any questions, suggestions or anything to tell me, just PM me or comment ProperWeather.


Comments

Posts Quoted:
Reply
Clear All Quotes