mirror of
https://github.com/Minestom/Minestom.git
synced 2025-02-06 15:31:43 +01:00
feat: vanilla style Instance#setWeather method overload, weather api improvements (#2064)
* feat: weather update * chore: Weather#createIsRainingPacket use isRaining
This commit is contained in:
parent
9f72bf4c44
commit
dc17d171ce
@ -11,19 +11,17 @@ public class WeatherCommand extends Command {
|
||||
public WeatherCommand() {
|
||||
super("weather");
|
||||
|
||||
var isRaining = ArgumentType.Boolean("isRaining").setDefaultValue(false);
|
||||
var rainLevel = ArgumentType.Float("rainLevel").setDefaultValue(0.0f);
|
||||
var thunderLevel = ArgumentType.Float("thunderLevel").setDefaultValue(0.0f);
|
||||
var transitionTicks = ArgumentType.Integer("transition").setDefaultValue(0);
|
||||
addSyntax(this::handleWeather, isRaining, rainLevel, thunderLevel, transitionTicks);
|
||||
addSyntax(this::handleWeather, rainLevel, thunderLevel, transitionTicks);
|
||||
}
|
||||
|
||||
private void handleWeather(CommandSender source, CommandContext context) {
|
||||
Player player = (Player) source;
|
||||
boolean isRaining = context.get("isRaining");
|
||||
float rainLevel = context.get("rainLevel");
|
||||
float thunderLevel = context.get("thunderLevel");
|
||||
int transitionTicks = context.get("transition");
|
||||
player.getInstance().setWeather(new Weather(isRaining, rainLevel, thunderLevel), transitionTicks);
|
||||
player.getInstance().setWeather(new Weather(rainLevel, thunderLevel), transitionTicks);
|
||||
}
|
||||
}
|
||||
|
@ -84,9 +84,10 @@ public abstract class Instance implements Block.Getter, Block.Setter,
|
||||
private long lastTimeUpdate;
|
||||
|
||||
// Weather of the instance
|
||||
private Weather targetWeather = new Weather(false, 0, 0);
|
||||
private Weather currentWeather = new Weather(false, 0, 0);
|
||||
private int remainingWeatherTransitionTicks;
|
||||
private Weather weather = Weather.CLEAR;
|
||||
private Weather transitioningWeather = Weather.CLEAR;
|
||||
private int remainingRainTransitionTicks;
|
||||
private int remainingThunderTransitionTicks;
|
||||
|
||||
// Field for tick events
|
||||
private long lastTickAge = System.currentTimeMillis();
|
||||
@ -674,11 +675,12 @@ public abstract class Instance implements Block.Getter, Block.Setter,
|
||||
|
||||
}
|
||||
// Weather
|
||||
if (remainingWeatherTransitionTicks > 0) {
|
||||
Weather previousWeather = currentWeather;
|
||||
currentWeather = transitionWeather(remainingWeatherTransitionTicks);
|
||||
if (remainingRainTransitionTicks > 0 || remainingThunderTransitionTicks > 0) {
|
||||
Weather previousWeather = transitioningWeather;
|
||||
transitioningWeather = transitionWeather(remainingRainTransitionTicks, remainingThunderTransitionTicks);
|
||||
sendWeatherPackets(previousWeather);
|
||||
remainingWeatherTransitionTicks--;
|
||||
remainingRainTransitionTicks = Math.max(0, remainingRainTransitionTicks - 1);
|
||||
remainingThunderTransitionTicks = Math.max(0, remainingThunderTransitionTicks - 1);
|
||||
}
|
||||
// Tick event
|
||||
{
|
||||
@ -691,12 +693,12 @@ public abstract class Instance implements Block.Getter, Block.Setter,
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the current weather on this instance
|
||||
* Gets the weather of this instance
|
||||
*
|
||||
* @return the current weather
|
||||
* @return the instance weather
|
||||
*/
|
||||
public @NotNull Weather getWeather() {
|
||||
return currentWeather;
|
||||
return weather;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -706,27 +708,36 @@ public abstract class Instance implements Block.Getter, Block.Setter,
|
||||
* @param transitionTicks the ticks to transition to new weather
|
||||
*/
|
||||
public void setWeather(@NotNull Weather weather, int transitionTicks) {
|
||||
Check.stateCondition(transitionTicks < 1, "Transition ticks cannot be lower than 1");
|
||||
targetWeather = weather;
|
||||
remainingWeatherTransitionTicks = transitionTicks;
|
||||
Check.stateCondition(transitionTicks < 1, "Transition ticks cannot be lower than 0");
|
||||
this.weather = weather;
|
||||
remainingRainTransitionTicks = transitionTicks;
|
||||
remainingThunderTransitionTicks = transitionTicks;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the weather of this instance with a fixed transition
|
||||
*
|
||||
* @param weather the new weather
|
||||
*/
|
||||
public void setWeather(@NotNull Weather weather) {
|
||||
this.weather = weather;
|
||||
remainingRainTransitionTicks = (int) Math.max(1, Math.abs((this.weather.rainLevel() - transitioningWeather.rainLevel()) / 0.01));
|
||||
remainingThunderTransitionTicks = (int) Math.max(1, Math.abs((this.weather.thunderLevel() - transitioningWeather.thunderLevel()) / 0.01));
|
||||
}
|
||||
|
||||
private void sendWeatherPackets(@NotNull Weather previousWeather) {
|
||||
if (currentWeather.isRaining() != previousWeather.isRaining()) sendGroupedPacket(currentWeather.createIsRainingPacket());
|
||||
if (currentWeather.rainLevel() != previousWeather.rainLevel()) sendGroupedPacket(currentWeather.createRainLevelPacket());
|
||||
if (currentWeather.thunderLevel() != previousWeather.thunderLevel()) sendGroupedPacket(currentWeather.createThunderLevelPacket());
|
||||
boolean toggledRain = (transitioningWeather.isRaining() != previousWeather.isRaining());
|
||||
if (toggledRain) sendGroupedPacket(transitioningWeather.createIsRainingPacket());
|
||||
if (transitioningWeather.rainLevel() != previousWeather.rainLevel()) sendGroupedPacket(transitioningWeather.createRainLevelPacket());
|
||||
if (transitioningWeather.thunderLevel() != previousWeather.thunderLevel()) sendGroupedPacket(transitioningWeather.createThunderLevelPacket());
|
||||
}
|
||||
|
||||
private @NotNull Weather transitionWeather(int remainingTicks) {
|
||||
Weather target = targetWeather;
|
||||
Weather current = currentWeather;
|
||||
if (remainingTicks <= 1) {
|
||||
return new Weather(target.isRaining(), target.isRaining() ? target.rainLevel() : 0,
|
||||
target.isRaining() ? target.thunderLevel() : 0);
|
||||
}
|
||||
float rainLevel = current.rainLevel() + (target.rainLevel() - current.rainLevel()) * (1 / (float)remainingTicks);
|
||||
float thunderLevel = current.thunderLevel() + (target.thunderLevel() - current.thunderLevel()) * (1 / (float)remainingTicks);
|
||||
return new Weather(rainLevel > 0, rainLevel, thunderLevel);
|
||||
private @NotNull Weather transitionWeather(int remainingRainTransitionTicks, int remainingThunderTransitionTicks) {
|
||||
Weather target = weather;
|
||||
Weather current = transitioningWeather;
|
||||
float rainLevel = current.rainLevel() + (target.rainLevel() - current.rainLevel()) * (1 / (float)Math.max(1, remainingRainTransitionTicks));
|
||||
float thunderLevel = current.thunderLevel() + (target.thunderLevel() - current.thunderLevel()) * (1 / (float)Math.max(1, remainingThunderTransitionTicks));
|
||||
return new Weather(rainLevel, thunderLevel);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -14,7 +14,6 @@ import java.util.List;
|
||||
/**
|
||||
* Represents the possible weather properties of an instance
|
||||
*
|
||||
* @param isRaining true if the instance is raining, otherwise false
|
||||
* @param rainLevel a percentage between 0 and 1
|
||||
* used to change how heavy the rain is
|
||||
* higher values darken the sky and increase rain opacity
|
||||
@ -22,7 +21,11 @@ import java.util.List;
|
||||
* used to change how heavy the thunder is
|
||||
* higher values further darken the sky
|
||||
*/
|
||||
public record Weather(boolean isRaining, float rainLevel, float thunderLevel) {
|
||||
public record Weather(float rainLevel, float thunderLevel) {
|
||||
public static final Weather CLEAR = new Weather(0, 0);
|
||||
public static final Weather RAIN = new Weather(1, 0);
|
||||
public static final Weather THUNDER = new Weather(1, 1);
|
||||
|
||||
/**
|
||||
* @throws IllegalArgumentException if {@code rainLevel} is not between 0 and 1
|
||||
* @throws IllegalArgumentException if {@code thunderLevel} is not between 0 and 1
|
||||
@ -33,13 +36,15 @@ public record Weather(boolean isRaining, float rainLevel, float thunderLevel) {
|
||||
}
|
||||
|
||||
@Contract(pure = true)
|
||||
public @NotNull Weather withRain(boolean isRaining) {
|
||||
return new Weather(isRaining, rainLevel, thunderLevel);
|
||||
public @NotNull Weather withRainLevel(float rainLevel) {
|
||||
return new Weather(rainLevel, thunderLevel);
|
||||
}
|
||||
|
||||
@Contract(pure = true)
|
||||
public @NotNull Weather withRainLevel(float rainLevel) {
|
||||
return new Weather(isRaining, rainLevel, thunderLevel);
|
||||
/**
|
||||
* @return true if {@code rainLevel} is > 0
|
||||
*/
|
||||
public boolean isRaining() {
|
||||
return rainLevel > 0;
|
||||
}
|
||||
|
||||
@Contract(pure = true)
|
||||
@ -49,7 +54,7 @@ public record Weather(boolean isRaining, float rainLevel, float thunderLevel) {
|
||||
|
||||
@Contract(pure = true)
|
||||
public @NotNull Weather withThunderLevel(float thunderLevel) {
|
||||
return new Weather(isRaining, rainLevel, thunderLevel);
|
||||
return new Weather(rainLevel, thunderLevel);
|
||||
}
|
||||
|
||||
@Contract(pure = true)
|
||||
@ -58,7 +63,7 @@ public record Weather(boolean isRaining, float rainLevel, float thunderLevel) {
|
||||
}
|
||||
|
||||
public ChangeGameStatePacket createIsRainingPacket() {
|
||||
return new ChangeGameStatePacket(isRaining ? ChangeGameStatePacket.Reason.BEGIN_RAINING : ChangeGameStatePacket.Reason.END_RAINING, 0);
|
||||
return new ChangeGameStatePacket(isRaining() ? ChangeGameStatePacket.Reason.BEGIN_RAINING : ChangeGameStatePacket.Reason.END_RAINING, 0);
|
||||
}
|
||||
|
||||
public ChangeGameStatePacket createRainLevelPacket() {
|
||||
|
@ -23,7 +23,7 @@ public class WeatherTest {
|
||||
assertEquals(0, weather.rainLevel());
|
||||
assertEquals(0, weather.thunderLevel());
|
||||
|
||||
instance.setWeather(new Weather(true, 1, 0.5f), 1);
|
||||
instance.setWeather(new Weather(1, 0.5f), 1);
|
||||
instance.tick(0);
|
||||
|
||||
// Weather sent on instance join
|
||||
@ -45,7 +45,7 @@ public class WeatherTest {
|
||||
|
||||
// Weather change while inside instance
|
||||
var tracker2 = connection.trackIncoming(ChangeGameStatePacket.class);
|
||||
instance.setWeather(new Weather(false, 0, 0), 2);
|
||||
instance.setWeather(new Weather(0, 0), 2);
|
||||
instance.tick(0);
|
||||
state = tracker2.collect().get(0);
|
||||
assertEquals(ChangeGameStatePacket.Reason.RAIN_LEVEL_CHANGE, state.reason());
|
||||
|
Loading…
Reference in New Issue
Block a user