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() {
|
public WeatherCommand() {
|
||||||
super("weather");
|
super("weather");
|
||||||
|
|
||||||
var isRaining = ArgumentType.Boolean("isRaining").setDefaultValue(false);
|
|
||||||
var rainLevel = ArgumentType.Float("rainLevel").setDefaultValue(0.0f);
|
var rainLevel = ArgumentType.Float("rainLevel").setDefaultValue(0.0f);
|
||||||
var thunderLevel = ArgumentType.Float("thunderLevel").setDefaultValue(0.0f);
|
var thunderLevel = ArgumentType.Float("thunderLevel").setDefaultValue(0.0f);
|
||||||
var transitionTicks = ArgumentType.Integer("transition").setDefaultValue(0);
|
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) {
|
private void handleWeather(CommandSender source, CommandContext context) {
|
||||||
Player player = (Player) source;
|
Player player = (Player) source;
|
||||||
boolean isRaining = context.get("isRaining");
|
|
||||||
float rainLevel = context.get("rainLevel");
|
float rainLevel = context.get("rainLevel");
|
||||||
float thunderLevel = context.get("thunderLevel");
|
float thunderLevel = context.get("thunderLevel");
|
||||||
int transitionTicks = context.get("transition");
|
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;
|
private long lastTimeUpdate;
|
||||||
|
|
||||||
// Weather of the instance
|
// Weather of the instance
|
||||||
private Weather targetWeather = new Weather(false, 0, 0);
|
private Weather weather = Weather.CLEAR;
|
||||||
private Weather currentWeather = new Weather(false, 0, 0);
|
private Weather transitioningWeather = Weather.CLEAR;
|
||||||
private int remainingWeatherTransitionTicks;
|
private int remainingRainTransitionTicks;
|
||||||
|
private int remainingThunderTransitionTicks;
|
||||||
|
|
||||||
// Field for tick events
|
// Field for tick events
|
||||||
private long lastTickAge = System.currentTimeMillis();
|
private long lastTickAge = System.currentTimeMillis();
|
||||||
@ -674,11 +675,12 @@ public abstract class Instance implements Block.Getter, Block.Setter,
|
|||||||
|
|
||||||
}
|
}
|
||||||
// Weather
|
// Weather
|
||||||
if (remainingWeatherTransitionTicks > 0) {
|
if (remainingRainTransitionTicks > 0 || remainingThunderTransitionTicks > 0) {
|
||||||
Weather previousWeather = currentWeather;
|
Weather previousWeather = transitioningWeather;
|
||||||
currentWeather = transitionWeather(remainingWeatherTransitionTicks);
|
transitioningWeather = transitionWeather(remainingRainTransitionTicks, remainingThunderTransitionTicks);
|
||||||
sendWeatherPackets(previousWeather);
|
sendWeatherPackets(previousWeather);
|
||||||
remainingWeatherTransitionTicks--;
|
remainingRainTransitionTicks = Math.max(0, remainingRainTransitionTicks - 1);
|
||||||
|
remainingThunderTransitionTicks = Math.max(0, remainingThunderTransitionTicks - 1);
|
||||||
}
|
}
|
||||||
// Tick event
|
// 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() {
|
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
|
* @param transitionTicks the ticks to transition to new weather
|
||||||
*/
|
*/
|
||||||
public void setWeather(@NotNull Weather weather, int transitionTicks) {
|
public void setWeather(@NotNull Weather weather, int transitionTicks) {
|
||||||
Check.stateCondition(transitionTicks < 1, "Transition ticks cannot be lower than 1");
|
Check.stateCondition(transitionTicks < 1, "Transition ticks cannot be lower than 0");
|
||||||
targetWeather = weather;
|
this.weather = weather;
|
||||||
remainingWeatherTransitionTicks = transitionTicks;
|
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) {
|
private void sendWeatherPackets(@NotNull Weather previousWeather) {
|
||||||
if (currentWeather.isRaining() != previousWeather.isRaining()) sendGroupedPacket(currentWeather.createIsRainingPacket());
|
boolean toggledRain = (transitioningWeather.isRaining() != previousWeather.isRaining());
|
||||||
if (currentWeather.rainLevel() != previousWeather.rainLevel()) sendGroupedPacket(currentWeather.createRainLevelPacket());
|
if (toggledRain) sendGroupedPacket(transitioningWeather.createIsRainingPacket());
|
||||||
if (currentWeather.thunderLevel() != previousWeather.thunderLevel()) sendGroupedPacket(currentWeather.createThunderLevelPacket());
|
if (transitioningWeather.rainLevel() != previousWeather.rainLevel()) sendGroupedPacket(transitioningWeather.createRainLevelPacket());
|
||||||
|
if (transitioningWeather.thunderLevel() != previousWeather.thunderLevel()) sendGroupedPacket(transitioningWeather.createThunderLevelPacket());
|
||||||
}
|
}
|
||||||
|
|
||||||
private @NotNull Weather transitionWeather(int remainingTicks) {
|
private @NotNull Weather transitionWeather(int remainingRainTransitionTicks, int remainingThunderTransitionTicks) {
|
||||||
Weather target = targetWeather;
|
Weather target = weather;
|
||||||
Weather current = currentWeather;
|
Weather current = transitioningWeather;
|
||||||
if (remainingTicks <= 1) {
|
float rainLevel = current.rainLevel() + (target.rainLevel() - current.rainLevel()) * (1 / (float)Math.max(1, remainingRainTransitionTicks));
|
||||||
return new Weather(target.isRaining(), target.isRaining() ? target.rainLevel() : 0,
|
float thunderLevel = current.thunderLevel() + (target.thunderLevel() - current.thunderLevel()) * (1 / (float)Math.max(1, remainingThunderTransitionTicks));
|
||||||
target.isRaining() ? target.thunderLevel() : 0);
|
return new Weather(rainLevel, thunderLevel);
|
||||||
}
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -14,7 +14,6 @@ import java.util.List;
|
|||||||
/**
|
/**
|
||||||
* Represents the possible weather properties of an instance
|
* 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
|
* @param rainLevel a percentage between 0 and 1
|
||||||
* used to change how heavy the rain is
|
* used to change how heavy the rain is
|
||||||
* higher values darken the sky and increase rain opacity
|
* 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
|
* used to change how heavy the thunder is
|
||||||
* higher values further darken the sky
|
* 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 rainLevel} is not between 0 and 1
|
||||||
* @throws IllegalArgumentException if {@code thunderLevel} 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)
|
@Contract(pure = true)
|
||||||
public @NotNull Weather withRain(boolean isRaining) {
|
public @NotNull Weather withRainLevel(float rainLevel) {
|
||||||
return new Weather(isRaining, rainLevel, thunderLevel);
|
return new Weather(rainLevel, thunderLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Contract(pure = true)
|
/**
|
||||||
public @NotNull Weather withRainLevel(float rainLevel) {
|
* @return true if {@code rainLevel} is > 0
|
||||||
return new Weather(isRaining, rainLevel, thunderLevel);
|
*/
|
||||||
|
public boolean isRaining() {
|
||||||
|
return rainLevel > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Contract(pure = true)
|
@Contract(pure = true)
|
||||||
@ -49,7 +54,7 @@ public record Weather(boolean isRaining, float rainLevel, float thunderLevel) {
|
|||||||
|
|
||||||
@Contract(pure = true)
|
@Contract(pure = true)
|
||||||
public @NotNull Weather withThunderLevel(float thunderLevel) {
|
public @NotNull Weather withThunderLevel(float thunderLevel) {
|
||||||
return new Weather(isRaining, rainLevel, thunderLevel);
|
return new Weather(rainLevel, thunderLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Contract(pure = true)
|
@Contract(pure = true)
|
||||||
@ -58,7 +63,7 @@ public record Weather(boolean isRaining, float rainLevel, float thunderLevel) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public ChangeGameStatePacket createIsRainingPacket() {
|
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() {
|
public ChangeGameStatePacket createRainLevelPacket() {
|
||||||
|
@ -23,7 +23,7 @@ public class WeatherTest {
|
|||||||
assertEquals(0, weather.rainLevel());
|
assertEquals(0, weather.rainLevel());
|
||||||
assertEquals(0, weather.thunderLevel());
|
assertEquals(0, weather.thunderLevel());
|
||||||
|
|
||||||
instance.setWeather(new Weather(true, 1, 0.5f), 1);
|
instance.setWeather(new Weather(1, 0.5f), 1);
|
||||||
instance.tick(0);
|
instance.tick(0);
|
||||||
|
|
||||||
// Weather sent on instance join
|
// Weather sent on instance join
|
||||||
@ -45,7 +45,7 @@ public class WeatherTest {
|
|||||||
|
|
||||||
// Weather change while inside instance
|
// Weather change while inside instance
|
||||||
var tracker2 = connection.trackIncoming(ChangeGameStatePacket.class);
|
var tracker2 = connection.trackIncoming(ChangeGameStatePacket.class);
|
||||||
instance.setWeather(new Weather(false, 0, 0), 2);
|
instance.setWeather(new Weather(0, 0), 2);
|
||||||
instance.tick(0);
|
instance.tick(0);
|
||||||
state = tracker2.collect().get(0);
|
state = tracker2.collect().get(0);
|
||||||
assertEquals(ChangeGameStatePacket.Reason.RAIN_LEVEL_CHANGE, state.reason());
|
assertEquals(ChangeGameStatePacket.Reason.RAIN_LEVEL_CHANGE, state.reason());
|
||||||
|
Loading…
Reference in New Issue
Block a user