From 8b107c3a9a19ae78f38b1d9337b6823ba76a781b Mon Sep 17 00:00:00 2001 From: Moulberry Date: Thu, 21 Sep 2023 18:13:57 +0800 Subject: [PATCH] Add weather world properties --- .../java/com/moulberry/axiom/AxiomPaper.java | 17 +++++++- .../WorldPropertyWidgetType.java | 15 +++++++ .../server/ServerWorldPropertiesRegistry.java | 40 +++++++++++++++++-- .../server/ServerWorldProperty.java | 7 ++-- 4 files changed, 72 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/moulberry/axiom/AxiomPaper.java b/src/main/java/com/moulberry/axiom/AxiomPaper.java index 2046acb..8cf5dd2 100644 --- a/src/main/java/com/moulberry/axiom/AxiomPaper.java +++ b/src/main/java/com/moulberry/axiom/AxiomPaper.java @@ -11,6 +11,7 @@ import com.moulberry.axiom.world_properties.server.ServerWorldProperty; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import io.papermc.paper.event.player.PlayerFailMoveEvent; +import io.papermc.paper.event.world.WorldGameRuleChangeEvent; import io.papermc.paper.network.ChannelInitializeListener; import io.papermc.paper.network.ChannelInitializeListenerHolder; import net.kyori.adventure.key.Key; @@ -21,6 +22,7 @@ import net.minecraft.network.protocol.Packet; import net.minecraft.network.protocol.PacketFlow; import net.minecraft.network.protocol.game.ServerboundCustomPayloadPacket; import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.level.GameRules; import org.bukkit.*; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; @@ -163,8 +165,21 @@ public class AxiomPaper extends JavaPlugin implements Listener { }, 20); // Why does this need to be delayed? } + @EventHandler + public void onGameRuleChanged(WorldGameRuleChangeEvent event) { + if (event.getGameRule() == GameRule.DO_WEATHER_CYCLE) { + ServerWorldPropertiesRegistry properties = getWorldProperties(event.getWorld()); + if (properties != null) { + ServerWorldProperty property = properties.getById(new ResourceLocation("axiom:pause_weather")); + if (property != null) { + ((ServerWorldProperty)property).setValue(event.getWorld(), Boolean.valueOf(event.getValue())); + } + } + } + } + private ServerWorldPropertiesRegistry createWorldProperties(World world) { - ServerWorldPropertiesRegistry registry = new ServerWorldPropertiesRegistry(); + ServerWorldPropertiesRegistry registry = new ServerWorldPropertiesRegistry(world); AxiomCreateWorldPropertiesEvent createEvent = new AxiomCreateWorldPropertiesEvent(world, registry); Bukkit.getPluginManager().callEvent(createEvent); diff --git a/src/main/java/com/moulberry/axiom/world_properties/WorldPropertyWidgetType.java b/src/main/java/com/moulberry/axiom/world_properties/WorldPropertyWidgetType.java index 5ae502b..547aefb 100644 --- a/src/main/java/com/moulberry/axiom/world_properties/WorldPropertyWidgetType.java +++ b/src/main/java/com/moulberry/axiom/world_properties/WorldPropertyWidgetType.java @@ -4,6 +4,8 @@ import net.minecraft.network.FriendlyByteBuf; import net.minecraft.resources.ResourceLocation; import net.minecraft.util.Unit; +import java.util.List; + public interface WorldPropertyWidgetType { WorldPropertyDataType dataType(); @@ -72,4 +74,17 @@ public interface WorldPropertyWidgetType { } }; + record ButtonArray(List otherButtons) implements WorldPropertyWidgetType { + @Override + public WorldPropertyDataType dataType() { + return WorldPropertyDataType.INTEGER; + } + + @Override + public void write(FriendlyByteBuf friendlyByteBuf) { + friendlyByteBuf.writeVarInt(5); + friendlyByteBuf.writeCollection(this.otherButtons, FriendlyByteBuf::writeUtf); + } + } + } diff --git a/src/main/java/com/moulberry/axiom/world_properties/server/ServerWorldPropertiesRegistry.java b/src/main/java/com/moulberry/axiom/world_properties/server/ServerWorldPropertiesRegistry.java index e353970..3044d9a 100644 --- a/src/main/java/com/moulberry/axiom/world_properties/server/ServerWorldPropertiesRegistry.java +++ b/src/main/java/com/moulberry/axiom/world_properties/server/ServerWorldPropertiesRegistry.java @@ -6,6 +6,9 @@ import io.netty.buffer.Unpooled; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.level.GameRules; +import org.bukkit.World; +import org.bukkit.craftbukkit.v1_20_R1.CraftWorld; import org.bukkit.entity.Player; import org.bukkit.plugin.Plugin; @@ -19,8 +22,8 @@ public class ServerWorldPropertiesRegistry { private final LinkedHashMap>> propertyList = new LinkedHashMap<>(); private final Map> propertyMap = new HashMap<>(); - public ServerWorldPropertiesRegistry() { - this.registerDefault(); + public ServerWorldPropertiesRegistry(World world) { + this.registerDefault(world); } public ServerWorldProperty getById(ResourceLocation resourceLocation) { @@ -53,7 +56,10 @@ public class ServerWorldPropertiesRegistry { buf.accessByteBufWithCorrectSize()); } - public void registerDefault() { + public void registerDefault(World world) { + ServerLevel serverLevel = ((CraftWorld)world).getHandle(); + GameRules gameRules = serverLevel.getGameRules(); + // Time WorldPropertyCategory timeCategory = new WorldPropertyCategory("axiom.editorui.window.world_properties.time", true); @@ -63,6 +69,34 @@ public class ServerWorldPropertiesRegistry { ); this.addCategory(timeCategory, List.of(time)); + + // Weather + WorldPropertyCategory weatherCategory = new WorldPropertyCategory("axiom.editorui.window.world_properties.weather", + true); + + ServerWorldProperty pauseWeather = new ServerWorldProperty<>(new ResourceLocation("axiom:pause_weather"), + "axiom.editorui.window.world_properties.pause_weather", + true, WorldPropertyWidgetType.CHECKBOX, !gameRules.getRule(GameRules.RULE_WEATHER_CYCLE).get(), bool -> { + gameRules.getRule(GameRules.RULE_WEATHER_CYCLE).set(!bool, serverLevel); + return false; + }); + + ServerWorldProperty weatherType = new ServerWorldProperty<>(new ResourceLocation("axiom:weather_type"), + "axiom.editorui.window.world_properties.clear_weather", + true, new WorldPropertyWidgetType.ButtonArray( + List.of("axiom.editorui.window.world_properties.rain_weather", "axiom.editorui.window.world_properties.thunder_weather") + ), 0, index -> { + if (index == 0) { + serverLevel.setWeatherParameters(ServerLevel.RAIN_DELAY.sample(serverLevel.random), 0, false, false); + } else if (index == 1) { + serverLevel.setWeatherParameters(0, ServerLevel.RAIN_DURATION.sample(serverLevel.random), true, false); + } else if (index == 2) { + serverLevel.setWeatherParameters(0, ServerLevel.THUNDER_DURATION.sample(serverLevel.random), true, true); + } + return false; + }); + + this.addCategory(weatherCategory, List.of(pauseWeather, weatherType)); } } diff --git a/src/main/java/com/moulberry/axiom/world_properties/server/ServerWorldProperty.java b/src/main/java/com/moulberry/axiom/world_properties/server/ServerWorldProperty.java index cafc6df..9027af9 100644 --- a/src/main/java/com/moulberry/axiom/world_properties/server/ServerWorldProperty.java +++ b/src/main/java/com/moulberry/axiom/world_properties/server/ServerWorldProperty.java @@ -1,7 +1,6 @@ package com.moulberry.axiom.world_properties.server; import com.moulberry.axiom.AxiomPaper; -import com.moulberry.axiom.world_properties.WorldPropertyCategory; import com.moulberry.axiom.world_properties.WorldPropertyDataType; import com.moulberry.axiom.world_properties.WorldPropertyWidgetType; import io.netty.buffer.Unpooled; @@ -51,8 +50,10 @@ public class ServerWorldProperty { } public void setValue(World world, T value) { - this.value = value; - this.sync(world); + if (!value.equals(this.value)) { + this.value = value; + this.sync(world); + } } public void sync(World world) {