diff --git a/src/main/java/westeroscraft/WesterosCraftEssentialsClient.java b/src/main/java/westeroscraft/WesterosCraftEssentialsClient.java new file mode 100644 index 0000000..33111d8 --- /dev/null +++ b/src/main/java/westeroscraft/WesterosCraftEssentialsClient.java @@ -0,0 +1,24 @@ +package westeroscraft; + +import net.fabricmc.api.ClientModInitializer; +import westeroscraft.commands.NVCommand; +import westeroscraft.commands.PTimeCommand; +import westeroscraft.commands.PWeatherCommand; + +public class WesterosCraftEssentialsClient implements ClientModInitializer { + public static WesterosCraftEssentialsClient INSTANCE; + public long time; + public boolean enabledTime = false; + + public float rainLevel; + public float thunderLevel; + public boolean enabledWeather = false; + + @Override + public void onInitializeClient() { + PTimeCommand.register(); + PWeatherCommand.register(); + NVCommand.register(); + INSTANCE = this; + } +} diff --git a/src/main/java/westeroscraft/commands/ETime.java b/src/main/java/westeroscraft/commands/ETime.java new file mode 100644 index 0000000..f72c54d --- /dev/null +++ b/src/main/java/westeroscraft/commands/ETime.java @@ -0,0 +1,18 @@ +package westeroscraft.commands; + +public enum ETime { + SUNRISE(0), + DAY(1000), + MORNING(2000), + NOON(6000), + AFTERNOON(9000), + SUNSET(12000), + NIGHT(13000), + MIDNIGHT(18000); + + public final int time; + + ETime(int i) { + this.time = i; + } +} diff --git a/src/main/java/westeroscraft/commands/EWeather.java b/src/main/java/westeroscraft/commands/EWeather.java new file mode 100644 index 0000000..dbcbc26 --- /dev/null +++ b/src/main/java/westeroscraft/commands/EWeather.java @@ -0,0 +1,12 @@ +package westeroscraft.commands; + +public enum EWeather { + CLEAR("clear"), + RAIN("rain"), + RESET("reset"), + THUNDER("thunder"); + + public final String string; + + EWeather(String w) { this.string = w; } +} diff --git a/src/main/java/westeroscraft/commands/NVCommand.java b/src/main/java/westeroscraft/commands/NVCommand.java new file mode 100644 index 0000000..2be192f --- /dev/null +++ b/src/main/java/westeroscraft/commands/NVCommand.java @@ -0,0 +1,40 @@ +package westeroscraft.commands; + +import net.fabricmc.fabric.api.client.command.v2.ClientCommandManager; +import net.fabricmc.fabric.api.client.command.v2.ClientCommandRegistrationCallback; +import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource; +import net.minecraft.client.player.LocalPlayer; +import net.minecraft.network.chat.Component; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.effect.MobEffectInstance; +import net.minecraft.world.effect.MobEffects; + +public class NVCommand { + public static void register() { + ClientCommandRegistrationCallback.EVENT.register((dispatcher, access) -> dispatcher.register(ClientCommandManager.literal("nv").executes((context) -> nightVision(context.getSource())))); + } + + public static int nightVision(FabricClientCommandSource source) { + //We check for both ServerPlayer and LocalPlayer to allow for it to be used in singleplayer. + if(source.getEntity() instanceof ServerPlayer player){ + MobEffectInstance nv = player.getEffect(MobEffects.NIGHT_VISION); + if(nv == null) { + player.addEffect(new MobEffectInstance(MobEffects.NIGHT_VISION, Integer.MAX_VALUE, 0, false, false, false)); + source.sendFeedback(Component.literal("Enabled Night Vision")); + } else { + player.removeEffect(MobEffects.NIGHT_VISION); + source.sendFeedback(Component.literal("Disabled Night Vision")); + } + } else if(source.getEntity() instanceof LocalPlayer player) { + MobEffectInstance nv = player.getEffect(MobEffects.NIGHT_VISION); + if(nv == null) { + player.addEffect(new MobEffectInstance(MobEffects.NIGHT_VISION, Integer.MAX_VALUE, 0, false, false, false)); + source.sendFeedback(Component.literal("Enabled Night Vision")); + } else { + player.removeEffect(MobEffects.NIGHT_VISION); + source.sendFeedback(Component.literal("Disabled Night Vision")); + } + } + return 1; + } +} diff --git a/src/main/java/westeroscraft/commands/PTimeCommand.java b/src/main/java/westeroscraft/commands/PTimeCommand.java new file mode 100644 index 0000000..7fbe85c --- /dev/null +++ b/src/main/java/westeroscraft/commands/PTimeCommand.java @@ -0,0 +1,57 @@ +package westeroscraft.commands; + +import com.mojang.brigadier.arguments.IntegerArgumentType; +import net.fabricmc.fabric.api.client.command.v2.ClientCommandManager; +import net.fabricmc.fabric.api.client.command.v2.ClientCommandRegistrationCallback; +import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource; +import net.minecraft.commands.arguments.TimeArgument; +import westeroscraft.WesterosCraftEssentialsClient; + +public class PTimeCommand { + public static void register() { + ClientCommandRegistrationCallback.EVENT.register((dispatcher, access) -> dispatcher.register(ClientCommandManager.literal("ptime") + .then(ClientCommandManager.literal("reset").executes((context) -> resetTime(context.getSource()))) + .then(ClientCommandManager.literal("set") + .then(ClientCommandManager.literal("normal").executes((context) -> resetTime(context.getSource()))) + .then(ClientCommandManager.literal("default").executes((context) -> resetTime(context.getSource()))) + .then(ClientCommandManager.literal("sunrise").executes((context) -> setTime(context.getSource(), ETime.SUNRISE.time, false))) + .then(ClientCommandManager.literal("day").executes((context) -> setTime(context.getSource(), ETime.DAY.time, false))) + .then(ClientCommandManager.literal("morning").executes((context) -> setTime(context.getSource(), ETime.MORNING.time, false))) + .then(ClientCommandManager.literal("noon").executes((context) -> setTime(context.getSource(), ETime.NOON.time, false))) + .then(ClientCommandManager.literal("afternoon").executes((context) -> setTime(context.getSource(), ETime.AFTERNOON.time, false))) + .then(ClientCommandManager.literal("sunset").executes((context) -> setTime(context.getSource(), ETime.SUNSET.time, false))) + .then(ClientCommandManager.literal("midnight").executes((context) -> setTime(context.getSource(), ETime.MIDNIGHT.time, false))) + .then(ClientCommandManager.argument("time", TimeArgument.time()).executes((context) -> setTime(context.getSource(), IntegerArgumentType.getInteger(context, "time"), false))) + ) + .then(ClientCommandManager.literal("setrelative") + .then(ClientCommandManager.literal("ahead") + .then(ClientCommandManager.argument("time", TimeArgument.time()).executes((context) -> setTime(context.getSource(), IntegerArgumentType.getInteger(context, "time"), true))) + ) + .then(ClientCommandManager.literal("behind") + .then(ClientCommandManager.argument("time", TimeArgument.time()).executes((context) -> setTime(context.getSource(), -IntegerArgumentType.getInteger(context, "time"), true))) + ) + ) + )); + } + + public static int resetTime(FabricClientCommandSource source) { + WesterosCraftEssentialsClient.INSTANCE.enabledTime = false; + WesterosCraftEssentialsClient.INSTANCE.time = source.getWorld().getDayTime(); + return 1; + } + + public static int setTime(FabricClientCommandSource source, long time, boolean relative) { + if(relative) { + if(WesterosCraftEssentialsClient.INSTANCE.enabledTime) { + WesterosCraftEssentialsClient.INSTANCE.time += time; + } else { + WesterosCraftEssentialsClient.INSTANCE.time = source.getWorld().getDayTime() + time; + } + } else { + WesterosCraftEssentialsClient.INSTANCE.time = time; + } + WesterosCraftEssentialsClient.INSTANCE.enabledTime = true; + return 1; + } +} + diff --git a/src/main/java/westeroscraft/commands/PWeatherCommand.java b/src/main/java/westeroscraft/commands/PWeatherCommand.java new file mode 100644 index 0000000..ff67750 --- /dev/null +++ b/src/main/java/westeroscraft/commands/PWeatherCommand.java @@ -0,0 +1,28 @@ +package westeroscraft.commands; + +import net.fabricmc.fabric.api.client.command.v2.ClientCommandManager; +import net.fabricmc.fabric.api.client.command.v2.ClientCommandRegistrationCallback; +import westeroscraft.WesterosCraftEssentialsClient; + +public class PWeatherCommand { + public static void register() { + ClientCommandRegistrationCallback.EVENT.register((dispatcher, access) -> dispatcher.register(ClientCommandManager.literal("pweather") + .then(ClientCommandManager.literal(EWeather.CLEAR.string).executes((context) -> setWeather( 0f, 0f))) + .then(ClientCommandManager.literal(EWeather.RAIN.string).executes((context) -> setWeather(1f, 0f))) + .then(ClientCommandManager.literal(EWeather.THUNDER.string).executes((context) -> setWeather(1f, 1f))) + .then(ClientCommandManager.literal(EWeather.RESET.string).executes((context) -> resetWeather())) + )); + } + + public static int resetWeather() { + WesterosCraftEssentialsClient.INSTANCE.enabledWeather = false; + return 1; + } + + public static int setWeather(float rainLevel, float thunderLevel) { + WesterosCraftEssentialsClient.INSTANCE.enabledWeather = true; + WesterosCraftEssentialsClient.INSTANCE.rainLevel = rainLevel; + WesterosCraftEssentialsClient.INSTANCE.thunderLevel = thunderLevel; + return 1; + } +} diff --git a/src/main/java/westeroscraft/mixin/ClientLevelDataMixin.java b/src/main/java/westeroscraft/mixin/ClientLevelDataMixin.java new file mode 100644 index 0000000..ec98bbb --- /dev/null +++ b/src/main/java/westeroscraft/mixin/ClientLevelDataMixin.java @@ -0,0 +1,22 @@ +package westeroscraft.mixin; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.minecraft.client.multiplayer.ClientLevel; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; +import westeroscraft.WesterosCraftEssentialsClient; + +@Mixin(ClientLevel.ClientLevelData.class) +public abstract class ClientLevelDataMixin { + + @Inject(at = @At("RETURN"), method = "getDayTime", cancellable = true) + @Environment(EnvType.CLIENT) + public void getDayTime(CallbackInfoReturnable cir) { + if(WesterosCraftEssentialsClient.INSTANCE.enabledTime) { + cir.setReturnValue(WesterosCraftEssentialsClient.INSTANCE.time); + } else cir.cancel(); + } +} diff --git a/src/main/java/westeroscraft/mixin/ClientLevelMixin.java b/src/main/java/westeroscraft/mixin/ClientLevelMixin.java new file mode 100644 index 0000000..86d9d15 --- /dev/null +++ b/src/main/java/westeroscraft/mixin/ClientLevelMixin.java @@ -0,0 +1,38 @@ +package westeroscraft.mixin; + +import net.minecraft.client.multiplayer.ClientLevel; +import net.minecraft.core.Holder; +import net.minecraft.core.RegistryAccess; +import net.minecraft.resources.ResourceKey; +import net.minecraft.util.profiling.ProfilerFiller; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.dimension.DimensionType; +import net.minecraft.world.level.storage.WritableLevelData; +import org.spongepowered.asm.mixin.Mixin; +import westeroscraft.WesterosCraftEssentialsClient; + +import java.util.function.Supplier; + +@Mixin(ClientLevel.class) +public abstract class ClientLevelMixin extends Level { + + protected ClientLevelMixin(WritableLevelData writableLevelData, ResourceKey resourceKey, RegistryAccess registryAccess, Holder holder, Supplier supplier, boolean bl, boolean bl2, long l, int i) { + super(writableLevelData, resourceKey, registryAccess, holder, supplier, bl, bl2, l, i); + } + + @Override + public float getRainLevel(float d) { + if(WesterosCraftEssentialsClient.INSTANCE.enabledWeather) { + return WesterosCraftEssentialsClient.INSTANCE.rainLevel; + } + return super.getRainLevel(d); + } + + @Override + public float getThunderLevel(float d) { + if(WesterosCraftEssentialsClient.INSTANCE.enabledWeather) { + return WesterosCraftEssentialsClient.INSTANCE.thunderLevel; + } + return super.getThunderLevel(d); + } +} diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index cb96b43..48e5627 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -1,35 +1,27 @@ -{ - "schemaVersion": 1, - "id": "westeroscraft-essentials", - "version": "${version}", - "name": "WesterosCraft Essentials", - "description": "WesterosCraftCore is a custom Fabric mod that handles various requirements for the WesterosCraft server", - "authors": [ - "geeberry", - "mikeprimm" - ], - "contact": { - "homepage": "https://westeroscraft.com/", - "sources": "https://github.com/FabricMC/fabric-example-mod" - }, - "license": "CC0-1.0", - "icon": "assets/westeroscraft-essentials/icon.png", - "environment": "*", - "entrypoints": { - "main": [ - "westeroscraft.WesterosCraftEssentials" - ], - "fabric-datagen": [ - "westeroscraft.WesterosCraftEssentialsDataGenerator" - ] - }, - "mixins": [ - "westeroscraft-essentials.mixins.json" - ], - "depends": { - "fabricloader": ">=0.18.4", - "minecraft": "~1.21.1", - "java": ">=21", - "fabric-api": "*" - } -} \ No newline at end of file +{ + "schemaVersion": 1, + "id": "westeroscraft-essentials", + "version": "${version}", + "name": "WesterosCraft Essentials", + "description": "WesterosCraftCore is a custom Fabric mod that handles various requirements for the WesterosCraft server", + "authors": ["geeberry", "mikeprimm", "earlofberkeley"], + "contact": { + "homepage": "https://westeroscraft.com/", + "sources": "https://github.com/FabricMC/fabric-example-mod" + }, + "license": "CC0-1.0", + "icon": "assets/westeroscraft-essentials/icon.png", + "environment": "*", + "entrypoints": { + "main": ["westeroscraft.WesterosCraftEssentials"], + "client": ["westeroscraft.WesterosCraftEssentialsClient"], + "fabric-datagen": ["westeroscraft.WesterosCraftEssentialsDataGenerator"] + }, + "mixins": ["westeroscraft-essentials.mixins.json"], + "depends": { + "fabricloader": ">=0.18.4", + "minecraft": "~1.21.1", + "java": ">=21", + "fabric-api": "*" + } +} diff --git a/src/main/resources/westeroscraft-essentials.mixins.json b/src/main/resources/westeroscraft-essentials.mixins.json index 4c1ff70..d78dab4 100644 --- a/src/main/resources/westeroscraft-essentials.mixins.json +++ b/src/main/resources/westeroscraft-essentials.mixins.json @@ -15,7 +15,9 @@ "DoorBlockMixin", "TrapDoorBlockMixin", "FenceGateBlockMixin", - "ServerPlayerMixin" + "ServerPlayerMixin", + "ClientLevelMixin", + "ClientLevelDataMixin" ], "injectors": { "defaultRequire": 1