aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.editorconfig7
-rw-r--r--.github/ISSUE_TEMPLATE/bug_report.md2
-rw-r--r--.github/workflows/build-docs.yml128
-rw-r--r--README.md5
-rw-r--r--Writerside/cfg/buildprofiles.xml16
-rw-r--r--Writerside/topics/config-file.md22
-rw-r--r--Writerside/topics/configuration.md2
-rw-r--r--Writerside/topics/gamerules.md15
-rw-r--r--Writerside/topics/introduction.md11
-rw-r--r--Writerside/topics/resource-pack.md49
-rw-r--r--Writerside/topics/usage.md7
-rw-r--r--build.gradle102
-rw-r--r--settings.gradle14
-rw-r--r--src/client/java/world/anhgelus/molehunt/client/MolehuntClient.java90
-rw-r--r--src/client/java/world/anhgelus/molehunt/client/mixin/NoCustomizableSkinOverlay.java16
-rw-r--r--src/client/java/world/anhgelus/molehunt/client/mixin/NoNametags.java12
-rw-r--r--src/client/java/world/anhgelus/molehunt/client/mixin/NoPlayerListHud.java10
-rw-r--r--src/client/java/world/anhgelus/molehunt/client/mixin/NoSkin.java20
-rw-r--r--src/client/resources/assets/molehunt/lang/en_us.json52
-rw-r--r--src/client/resources/assets/molehunt/lang/fr_fr.json52
-rw-r--r--src/client/resources/molehunt.client.mixins.json26
-rw-r--r--src/main/java/world/anhgelus/molehunt/Molehunt.java377
-rw-r--r--src/main/java/world/anhgelus/molehunt/config/Config.java262
-rw-r--r--src/main/java/world/anhgelus/molehunt/config/ConfigPayload.java24
-rw-r--r--src/main/java/world/anhgelus/molehunt/config/SimpleConfig.java422
-rw-r--r--src/main/java/world/anhgelus/molehunt/game/Game.java344
-rw-r--r--src/main/java/world/anhgelus/molehunt/game/GamePayload.java20
-rw-r--r--src/main/java/world/anhgelus/molehunt/mixin/NoJoinLeaveMessage.java12
-rw-r--r--src/main/java/world/anhgelus/molehunt/mixin/NoMsgCommand.java8
-rw-r--r--src/main/java/world/anhgelus/molehunt/mixin/NoPortals.java10
-rw-r--r--src/main/java/world/anhgelus/molehunt/mixin/WorldTimerAccess.java56
-rw-r--r--src/main/java/world/anhgelus/molehunt/timer/TickTask.java118
-rw-r--r--src/main/java/world/anhgelus/molehunt/timer/TimerAccess.java96
-rw-r--r--src/main/java/world/anhgelus/molehunt/utils/TimeUtils.java93
-rw-r--r--src/main/resources/fabric.mod.json69
-rw-r--r--src/main/resources/molehunt.mixins.json26
36 files changed, 1295 insertions, 1300 deletions
diff --git a/.editorconfig b/.editorconfig
index 6d4b8c2..886d72a 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -1,2 +1,7 @@
[*]
-end_of_line = crlf \ No newline at end of file
+end_of_line = lf
+indent_style = tab
+ij_smart_tabs = true
+
+[*.json]
+tab_width = 2 \ No newline at end of file
diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md
index 1d42630..4a4bc3f 100644
--- a/.github/ISSUE_TEMPLATE/bug_report.md
+++ b/.github/ISSUE_TEMPLATE/bug_report.md
@@ -12,6 +12,7 @@ assignees: ''
**To Reproduce**
<!-- Steps to reproduce the behavior. -->
+
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
@@ -24,6 +25,7 @@ assignees: ''
<!-- If applicable, add screenshots to help explain your problem. -->
**Crash reports or relevant logs**
+
```log
log here
```
diff --git a/.github/workflows/build-docs.yml b/.github/workflows/build-docs.yml
index 84f9cb0..a129e0c 100644
--- a/.github/workflows/build-docs.yml
+++ b/.github/workflows/build-docs.yml
@@ -1,80 +1,80 @@
name: Build documentation
on:
- push:
- branches: ["main"]
- workflow_dispatch:
+ push:
+ branches: [ "main" ]
+ workflow_dispatch:
permissions:
- id-token: write
- pages: write
+ id-token: write
+ pages: write
env:
- INSTANCE: 'Writerside/md'
- ARTIFACT: 'webHelpMD2-all.zip'
- DOCKER_VERSION: '241.18775'
+ INSTANCE: 'Writerside/md'
+ ARTIFACT: 'webHelpMD2-all.zip'
+ DOCKER_VERSION: '241.18775'
jobs:
- build:
- runs-on: ubuntu-latest
- steps:
- - name: Checkout repository
- uses: actions/checkout@v4
- with:
- fetch-depth: 0
+ build:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v4
+ with:
+ fetch-depth: 0
- - name: Build docs using Writerside Docker builder
- uses: JetBrains/writerside-github-action@v4
- with:
- instance: ${{ env.INSTANCE }}
- artifact: ${{ env.ARTIFACT }}
- docker-version: ${{ env.DOCKER_VERSION }}
+ - name: Build docs using Writerside Docker builder
+ uses: JetBrains/writerside-github-action@v4
+ with:
+ instance: ${{ env.INSTANCE }}
+ artifact: ${{ env.ARTIFACT }}
+ docker-version: ${{ env.DOCKER_VERSION }}
- - name: Save artifact with build results
- uses: actions/upload-artifact@v4
- with:
- name: docs
- path: |
- artifacts/${{ env.ARTIFACT }}
- artifacts/report.json
- retention-days: 7
- test:
- needs: build
- runs-on: ubuntu-latest
- steps:
- - name: Download artifacts
- uses: actions/download-artifact@v4
- with:
- name: docs
- path: artifacts
+ - name: Save artifact with build results
+ uses: actions/upload-artifact@v4
+ with:
+ name: docs
+ path: |
+ artifacts/${{ env.ARTIFACT }}
+ artifacts/report.json
+ retention-days: 7
+ test:
+ needs: build
+ runs-on: ubuntu-latest
+ steps:
+ - name: Download artifacts
+ uses: actions/download-artifact@v4
+ with:
+ name: docs
+ path: artifacts
- - name: Test documentation
- uses: JetBrains/writerside-checker-action@v1
- with:
- instance: ${{ env.INSTANCE }}
- deploy:
- environment:
- name: github-pages
- url: ${{ steps.deployment.outputs.page_url }}
- needs: [build, test]
- runs-on: ubuntu-latest
- steps:
- - name: Download artifacts
- uses: actions/download-artifact@v4
- with:
- name: docs
+ - name: Test documentation
+ uses: JetBrains/writerside-checker-action@v1
+ with:
+ instance: ${{ env.INSTANCE }}
+ deploy:
+ environment:
+ name: github-pages
+ url: ${{ steps.deployment.outputs.page_url }}
+ needs: [ build, test ]
+ runs-on: ubuntu-latest
+ steps:
+ - name: Download artifacts
+ uses: actions/download-artifact@v4
+ with:
+ name: docs
- - name: Unzip artifact
- run: unzip -O UTF-8 -qq '${{ env.ARTIFACT }}' -d dir
+ - name: Unzip artifact
+ run: unzip -O UTF-8 -qq '${{ env.ARTIFACT }}' -d dir
- - name: Setup Pages
- uses: actions/configure-pages@v4
+ - name: Setup Pages
+ uses: actions/configure-pages@v4
- - name: Package and upload Pages artifact
- uses: actions/upload-pages-artifact@v3
- with:
- path: dir
+ - name: Package and upload Pages artifact
+ uses: actions/upload-pages-artifact@v3
+ with:
+ path: dir
- - name: Deploy to GitHub Pages
- id: deployment
- uses: actions/deploy-pages@v4
+ - name: Deploy to GitHub Pages
+ id: deployment
+ uses: actions/deploy-pages@v4
diff --git a/README.md b/README.md
index 475b263..1e05f15 100644
--- a/README.md
+++ b/README.md
@@ -34,10 +34,11 @@ _Almost_ everything in the mod can configured.
## Configuration
-To change most values, you can play with the gamerules added by the mod with the
+To change most values, you can play with the gamerules added by the mod with the
`/gamerule` command. Every gamerule introduced by the mod starts with `molehunt:`.
-To dive deeper into the configuration, [an online wiki is available](https://www.anhgelus.world/molehunt/configuration.html).
+To dive deeper into the
+configuration, [an online wiki is available](https://www.anhgelus.world/molehunt/configuration.html).
## Technologies
diff --git a/Writerside/cfg/buildprofiles.xml b/Writerside/cfg/buildprofiles.xml
index 8ddb9c7..1353666 100644
--- a/Writerside/cfg/buildprofiles.xml
+++ b/Writerside/cfg/buildprofiles.xml
@@ -1,13 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE buildprofiles SYSTEM "https://resources.jetbrains.com/writerside/1.0/build-profiles.dtd">
-<buildprofiles xsi:noNamespaceSchemaLocation="https://resources.jetbrains.com/writerside/1.0/build-profiles.xsd"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+<buildprofiles xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="https://resources.jetbrains.com/writerside/1.0/build-profiles.xsd">
- <variables></variables>
- <build-profile instance="md">
- <variables>
- <noindex-content>true</noindex-content>
- </variables>
- </build-profile>
+ <variables></variables>
+ <build-profile instance="md">
+ <variables>
+ <noindex-content>true</noindex-content>
+ </variables>
+ </build-profile>
</buildprofiles>
diff --git a/Writerside/topics/config-file.md b/Writerside/topics/config-file.md
index c70e347..56d4d94 100644
--- a/Writerside/topics/config-file.md
+++ b/Writerside/topics/config-file.md
@@ -1,6 +1,6 @@
# Config file
-On top of the gamerules, you can edit a config file, named `molehunt.properties`.
+On top of the gamerules, you can edit a config file, named `molehunt.properties`.
This file is automatically generated when starting a server with the mod installed.
This file will set the default settings when creating a new world, but that's it.
@@ -11,8 +11,7 @@ different worlds.
> If you only want to change the settings on a single world, or don't want to change
> a lot, I would suggest [playing with the gamerules](gamerules.md) rather than the config
> file, as it is easier and directly in-game
-{style=note}
-
+> {style=note}
## Editing the config file
@@ -24,10 +23,10 @@ similar names, even though different). To know what each setting does, you can
check [the gamerules documention](gamerules.md).
The config syntax is very simple:
-- `name_of_the_setting = value` to set a setting to a `value`. Only one setting
- can be set on a single line
-- A line starting with a `#` is a comment, and will not be counted be the mod.
+- `name_of_the_setting = value` to set a setting to a `value`. Only one setting
+ can be set on a single line
+- A line starting with a `#` is a comment, and will not be counted be the mod.
## Troubleshooting the config file
@@ -42,6 +41,7 @@ and that the file's name is `molehunt.properties`.
### Check that you use the config file's setting names, and not the gamerule names
For example, to change the game duration in the config file:
+
```yaml
# Do this:
game_duration = 30
@@ -58,6 +58,7 @@ You can see the list of all config file setting in [the default configuration fi
A comment line starts with a `#`, not with `//` nor with anything else.
Also, you can only set one variable on one line. For exemple, this is incorrect:
+
```yaml
# This is not a valid config file
first_setting = 1 second_setting = 2
@@ -71,6 +72,7 @@ another_setting =
A boolean value (one that can either be "on or off") can be set to `true` or `false`,
nothing else.
+
```yaml
# Good
my_boolean = true
@@ -79,7 +81,7 @@ my_boolean = true
my_boolean = false
```
-Every numerical value should be integers: there are no decimal values in this mod.
+Every numerical value should be integers: there are no decimal values in this mod.
And you should not put the unit after the value (do not put `50 blocks`, but only `50`).
> If you have checked everything, and there's still a problem, don't hesitate to
@@ -87,11 +89,11 @@ And you should not put the unit after the value (do not put `50 blocks`, but onl
## Default configuration
-Here is the default configuration that is automatically generated. Every setting
+Here is the default configuration that is automatically generated. Every setting
is listed below.
-To regenerate the default configuration, you can rename, move or delete your
-current config file, and then run the server with the mod installed.
+To regenerate the default configuration, you can rename, move or delete your
+current config file, and then run the server with the mod installed.
```yaml
# Molehunt mod configuration file
diff --git a/Writerside/topics/configuration.md b/Writerside/topics/configuration.md
index a258e4f..456b982 100644
--- a/Writerside/topics/configuration.md
+++ b/Writerside/topics/configuration.md
@@ -1,7 +1,7 @@
# Configuration
_Almost_ everything in the mod can be modified. You can change the mod's behavior by
-changing custom gamerules or editing a config file.
+changing custom gamerules or editing a config file.
To change the mod's text and default skin, you can use a custom resource pack and set
it to be the default resource pack on your server.
diff --git a/Writerside/topics/gamerules.md b/Writerside/topics/gamerules.md
index 54d9290..939388e 100644
--- a/Writerside/topics/gamerules.md
+++ b/Writerside/topics/gamerules.md
@@ -1,11 +1,11 @@
# Gamerules
-To change the mods behavior, you can change your world's gamerules. Every gamerule added
+To change the mods behavior, you can change your world's gamerules. Every gamerule added
by this mod starts with the prefix `molehunt:`.
> If plan on making multiple worlds, and don't want to set the gamerules each time,
> [edit the configuration file](config-file.md).
-{style=tip}
+> {style=tip}
Here's a list of all the Molehunt gamerules.
@@ -15,16 +15,16 @@ Here's a list of all the Molehunt gamerules.
- `gameDurationMinutes`: sets the game's duration in minutes (default: `90 minutes`).
- `molePercentage`: sets the mole percentage among all players (default: `25 %`).
-- `moleCount`: the absolute mole amount. Overwrites `molePercentage`. To disable
- this setting, set it to `-1` (default: `-1`).
+- `moleCount`: the absolute mole amount. Overwrites `molePercentage`. To disable
+ this setting, set it to `-1` (default: `-1`).
- `foodOnStart`: give food on start
### Client-side settings
> These gamerules affect client-side features, but are still applied to all players.
->
+>
> Also, they will only be effective when the game starts.
-{style=note}
+> {style=note}
- `showNametags`: players' nametags are shown (default: `false`).
- `showSkins`: players' custom skin is visible. Setting this to false will
@@ -40,6 +40,7 @@ Here's a list of all the Molehunt gamerules.
- `initialWorldSize`: the world size when starting the game (default: `600 blocks`).
- `finalWorldSize`: the target world size on the end of the game (default: `100 blocks`).
-- `borderMovingStartingTimeOffsetMinutes`: the time before the world borders start to move in minutes (default: `10 minutes`).
+- `borderMovingStartingTimeOffsetMinutes`: the time before the world borders start to move in minutes (default:
+ `10 minutes`).
> Setting this to a value greater than `gameDuration` will make the borders never move.
{style=note}
diff --git a/Writerside/topics/introduction.md b/Writerside/topics/introduction.md
index e2ef02c..cb32630 100644
--- a/Writerside/topics/introduction.md
+++ b/Writerside/topics/introduction.md
@@ -2,7 +2,8 @@
[Molehunt](https://modrinth.com/mod/molehunt-mod) is a mod creating the Molehunt game in Minecraft.
You can watch this [video](https://www.youtube.com/watch?v=NJBjQ8T_1cc) to understand what it is.
-If you are speaking French, I made this [30 seconds video](https://cdn.anhgelus.world/molehunt-presentation.mp4) explaining the concept.
+If you are speaking French, I made this [30 seconds video](https://cdn.anhgelus.world/molehunt-presentation.mp4)
+explaining the concept.
## Installation
@@ -11,10 +12,10 @@ Download the mod for your version.
The mod requires [Fabric-API](https://modrinth.com/mod/fabric-api) to works.
[Simple Voice Chat](https://modrinth.com/plugin/simple-voice-chat) is highly recommended.
-> If you use Simple Voice Chat, make sure to disable private groups,
+> If you use Simple Voice Chat, make sure to disable private groups,
> as they would ruin the immersion.
-{style=tip}
+> {style=tip}
-The mod has to be installed on the server *and* on every client. The mod is required
-to be installed on clients for some client-side features (such as hiding nametags
+The mod has to be installed on the server *and* on every client. The mod is required
+to be installed on clients for some client-side features (such as hiding nametags
or changing skins).
diff --git a/Writerside/topics/resource-pack.md b/Writerside/topics/resource-pack.md
index b3bbf86..9b83906 100644
--- a/Writerside/topics/resource-pack.md
+++ b/Writerside/topics/resource-pack.md
@@ -3,14 +3,13 @@
If you want to customize visual elements of the mod, you can create
your own custom resource pack.
-Doing so will enable you to change or translate every text line used by
+Doing so will enable you to change or translate every text line used by
the mod, and also change to default skin that is applied to all players
(if the [gamerule `showSkins`](gamerules.md#client-side-settings) is set to true).
> After creating your resource pack, you can either force its use by setting it as
> the server's resource pack, or make it optional (it's purely visuals anyway!)
-{style=tip}
-
+> {style=tip}
## First steps
@@ -19,6 +18,7 @@ inside of this folder, create a file named `pack.mcmeta`. This file is very impo
the game that it is indeed a resource pack.
Now, edit the `pack.mcmeta` file with your favorite text editor, and write the following:
+
```json
{
"pack": {
@@ -28,15 +28,16 @@ Now, edit the `pack.mcmeta` file with your favorite text editor, and write the f
}
```
-> Note that the `pack_format` used here (34) corresponds to minecraft version 1.21.x. If you
-> are making the resource pack for another version, you can check which pack format to use
+> Note that the `pack_format` used here (34) corresponds to minecraft version 1.21.x. If you
+> are making the resource pack for another version, you can check which pack format to use
> [on the wiki](https://minecraft.wiki/w/Pack_format).
-{style=note}
+> {style=note}
-You can now close the `pack.mcmeta` file. Now, inside your resource pack's main folder,
-create a folder named `assets`, and inside it make another folder name `molehunt`.
+You can now close the `pack.mcmeta` file. Now, inside your resource pack's main folder,
+create a folder named `assets`, and inside it make another folder name `molehunt`.
You file tree you look like that:
+
```
๐Ÿ“ MyAwesomeResourcePack
โ”œโ”€โ”€ ๐Ÿ“„ pack.mcmeta
@@ -46,18 +47,18 @@ You file tree you look like that:
> If you want, you can also add an icon to your resource pack: just add a png file named
> `pack.png` in your resource pack's main folder.
-{style=tip}
-
+> {style=tip}
## Adding a custom skin
To add a custom skin, first you need to make one. You can either use
-your own skin, or make a new one using a minecraft skin editor (there are
+your own skin, or make a new one using a minecraft skin editor (there are
a lot online).
Then grab your skin file (make sure it's a `.png` file!), name it `skin.png`
-and put it inside a `textures` folder, inside the `molehunt` folder. It should
+and put it inside a `textures` folder, inside the `molehunt` folder. It should
look like that:
+
```
...
๐Ÿ“ assets
@@ -68,27 +69,27 @@ look like that:
Now everyone in the game will be wearing your custom skin!
-
## Changing the mod's text
Finally, if the mod's text doesn't suit you, or if you want to translate
-it to another language, you can!
+it to another language, you can!
> Note that french is already supported by default, so no need to translate
> to it.
-{style=tip}
+> {style=tip}
First, create a new folder in the `molehunt` folder named `lang`, then create
a `en_us.json` file.
> If you want to target another language, name the file according to your language
> and region. For example: `fr_fr.json` for French in France.
-{style=note}
+> {style=note}
Now copy the content of the [default `en_us.json` file](#default-en-us-json-language-file)
in you language file, and start editing the lines you want to change!
Finally, your file structure should look like that:
+
```
...
๐Ÿ“ assets
@@ -98,15 +99,16 @@ Finally, your file structure should look like that:
โ””โ”€โ”€ ๐Ÿ“„ en_pt.json
โ””โ”€โ”€ etc.
```
+
(You can have only one, or multiple language files, it doesn't matter)
-[Minecraft formatting codes](https://minecraft.wiki/w/Formatting_codes) are
+[Minecraft formatting codes](https://minecraft.wiki/w/Formatting_codes) are
supported in `titles` and `subtitles`.
-
## Final file tree, and installing your resource pack
If you followed every step of this tutorial, the final resource pack should look like this:
+
```
๐Ÿ“ MyAwesomeResourcePack
โ”œโ”€โ”€ ๐Ÿ“„ pack.mcmeta
@@ -121,21 +123,20 @@ If you followed every step of this tutorial, the final resource pack should look
โ””โ”€โ”€ etc.
```
-To install it on your client, simply put your awesome resource pack in the `resourcepacks` folder
+To install it on your client, simply put your awesome resource pack in the `resourcepacks` folder
of [your `.minecraft` folder](https://minecraft.wiki/w/.minecraft).
If you want, you can zip it to make sharing it easier, but it is not required.
-
## Default `en_us.json` language file
Here's the default `en_us.json` file. You can use it as a template to
customize the mod's text lines.
-> The weird `ยง` and the character after it corresponds to a minecraft
-> formatting code. It can change the text's color and format. You can
-> learn more [on the wiki](https://minecraft.wiki/w/Formatting_codes).
-{style=tip}
+> The weird `ยง` and the character after it corresponds to a minecraft
+> formatting code. It can change the text's color and format. You can
+> learn more [on the wiki](https://minecraft.wiki/w/Formatting_codes).
+> {style=tip}
```json
{
diff --git a/Writerside/topics/usage.md b/Writerside/topics/usage.md
index 46bc5fb..6cb1c64 100644
--- a/Writerside/topics/usage.md
+++ b/Writerside/topics/usage.md
@@ -5,23 +5,24 @@
To start a game, execute `/molehunt start` (you must be OP).
The game ends automatically if one of these two condition is met:
+
- Every alive player is a mole.
- The timer has run out.
The game does not automatically end when every mole is dead to allow for
-some funny moments. But if needed, you can stop the game early by using
+some funny moments. But if needed, you can stop the game early by using
`/molehunt stop` (you must be OP).
-
## Player commands
The mod also provide a few commands for every player.
If you forgot your role during the game, you can use `/molehunt role`
This command will also provide you with some additional information :
+
- For survivors, it will give the mole count;
- For moles and spectators, it will give the list of all moles.
To some people, the timer above you hotbar could be annoying. To hide it,
-use `/molehunt timer hide`. If you want to see it again, use
+use `/molehunt timer hide`. If you want to see it again, use
`/molehunt timer show`.
diff --git a/build.gradle b/build.gradle
index d34a196..baf537b 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,89 +1,89 @@
plugins {
- id 'fabric-loom' version '1.15-SNAPSHOT'
- id 'maven-publish'
+ id 'fabric-loom' version '1.15-SNAPSHOT'
+ id 'maven-publish'
}
version = project.mod_version
group = project.maven_group
base {
- archivesName = project.archives_base_name
+ archivesName = project.archives_base_name
}
loom {
- splitEnvironmentSourceSets()
+ splitEnvironmentSourceSets()
- mods {
- "molehunt" {
- sourceSet sourceSets.main
- sourceSet sourceSets.client
- }
- }
+ mods {
+ "molehunt" {
+ sourceSet sourceSets.main
+ sourceSet sourceSets.client
+ }
+ }
}
repositories {
- // Add repositories to retrieve artifacts from in here.
- // You should only use this when depending on other mods because
- // Loom adds the essential maven repositories to download Minecraft and libraries from automatically.
- // See https://docs.gradle.org/current/userguide/declaring_repositories.html
- // for more information about repositories.
+ // Add repositories to retrieve artifacts from in here.
+ // You should only use this when depending on other mods because
+ // Loom adds the essential maven repositories to download Minecraft and libraries from automatically.
+ // See https://docs.gradle.org/current/userguide/declaring_repositories.html
+ // for more information about repositories.
}
dependencies {
- // To change the versions see the gradle.properties file
- minecraft "com.mojang:minecraft:${project.minecraft_version}"
- mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2"
- modImplementation "net.fabricmc:fabric-loader:${project.loader_version}"
+ // To change the versions see the gradle.properties file
+ minecraft "com.mojang:minecraft:${project.minecraft_version}"
+ mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2"
+ modImplementation "net.fabricmc:fabric-loader:${project.loader_version}"
- // Fabric API. This is technically optional, but you probably want it anyway.
- modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}"
+ // Fabric API. This is technically optional, but you probably want it anyway.
+ modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}"
}
processResources {
- inputs.property "version", project.version
- inputs.property "minecraft_version", project.minecraft_version
- inputs.property "loader_version", project.loader_version
- filteringCharset "UTF-8"
+ inputs.property "version", project.version
+ inputs.property "minecraft_version", project.minecraft_version
+ inputs.property "loader_version", project.loader_version
+ filteringCharset "UTF-8"
- filesMatching("fabric.mod.json") {
- expand "version": project.version,
- "minecraft_version": project.minecraft_version,
- "loader_version": project.loader_version
- }
+ filesMatching("fabric.mod.json") {
+ expand "version": project.version,
+ "minecraft_version": project.minecraft_version,
+ "loader_version": project.loader_version
+ }
}
tasks.withType(JavaCompile).configureEach {
- it.options.release = 21
- it.options.encoding = "UTF-8"
+ it.options.release = 21
+ it.options.encoding = "UTF-8"
}
java {
- withSourcesJar()
+ withSourcesJar()
- sourceCompatibility = JavaVersion.VERSION_21
- targetCompatibility = JavaVersion.VERSION_21
+ sourceCompatibility = JavaVersion.VERSION_21
+ targetCompatibility = JavaVersion.VERSION_21
}
jar {
- from("LICENSE") {
- rename { "${it}_${inputs.properties.archivesName}"}
- }
+ from("LICENSE") {
+ rename { "${it}_${inputs.properties.archivesName}" }
+ }
}
// configure the maven publication
publishing {
- publications {
- create("mavenJava", MavenPublication) {
- artifactId = project.archives_base_name
- from components.java
- }
- }
+ publications {
+ create("mavenJava", MavenPublication) {
+ artifactId = project.archives_base_name
+ from components.java
+ }
+ }
- // See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing.
- repositories {
- // Add repositories to publish to here.
- // Notice: This block does NOT have the same function as the block in the top level.
- // The repositories here will be used for publishing your artifact, not for
- // retrieving dependencies.
- }
+ // See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing.
+ repositories {
+ // Add repositories to publish to here.
+ // Notice: This block does NOT have the same function as the block in the top level.
+ // The repositories here will be used for publishing your artifact, not for
+ // retrieving dependencies.
+ }
}
diff --git a/settings.gradle b/settings.gradle
index f91a4fe..027b233 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -1,9 +1,9 @@
pluginManagement {
- repositories {
- maven {
- name = 'Fabric'
- url = 'https://maven.fabricmc.net/'
- }
- gradlePluginPortal()
- }
+ repositories {
+ maven {
+ name = 'Fabric'
+ url = 'https://maven.fabricmc.net/'
+ }
+ gradlePluginPortal()
+ }
}
diff --git a/src/client/java/world/anhgelus/molehunt/client/MolehuntClient.java b/src/client/java/world/anhgelus/molehunt/client/MolehuntClient.java
index 03198ee..f495d40 100644
--- a/src/client/java/world/anhgelus/molehunt/client/MolehuntClient.java
+++ b/src/client/java/world/anhgelus/molehunt/client/MolehuntClient.java
@@ -9,49 +9,49 @@ import world.anhgelus.molehunt.game.GamePayload;
public class MolehuntClient implements ClientModInitializer {
- private static boolean SHOW_SKINS = false;
- private static boolean SHOW_NAMETAGS = false;
- private static boolean SHOW_TAB = false;
-
- private static boolean GAME_STARTED = false;
-
- @Override
- public void onInitializeClient() {
- ClientPlayNetworking.registerGlobalReceiver(ConfigPayload.ID, (payload, context) -> context.client().execute(() -> {
- SHOW_SKINS = payload.showSkins();
- SHOW_NAMETAGS = payload.showNametags();
- SHOW_TAB = payload.showTab();
- }));
- ClientPlayNetworking.registerGlobalReceiver(GamePayload.ID, (payload, context) -> context.client().execute(() -> GAME_STARTED = payload.gameLaunched()));
-
- // Needed because else `client.options` is null
- ClientLifecycleEvents.CLIENT_STARTED.register(client -> {
- var options = client.options;
-
- options.setPlayerModelPart(PlayerModelPart.CAPE, true);
- options.setPlayerModelPart(PlayerModelPart.HAT, true);
- options.setPlayerModelPart(PlayerModelPart.JACKET, true);
- options.setPlayerModelPart(PlayerModelPart.LEFT_SLEEVE, true);
- options.setPlayerModelPart(PlayerModelPart.RIGHT_SLEEVE, true);
- options.setPlayerModelPart(PlayerModelPart.LEFT_PANTS_LEG, true);
- options.setPlayerModelPart(PlayerModelPart.RIGHT_PANTS_LEG, true);
- });
-
- }
-
- public static boolean showSkins() {
- return SHOW_SKINS;
- }
-
- public static boolean showNameTags() {
- return SHOW_NAMETAGS;
- }
-
- public static boolean showTab() {
- return SHOW_TAB;
- }
-
- public static boolean gameStarted() {
- return GAME_STARTED;
- }
+ private static boolean SHOW_SKINS = false;
+ private static boolean SHOW_NAMETAGS = false;
+ private static boolean SHOW_TAB = false;
+
+ private static boolean GAME_STARTED = false;
+
+ public static boolean showSkins() {
+ return SHOW_SKINS;
+ }
+
+ public static boolean showNameTags() {
+ return SHOW_NAMETAGS;
+ }
+
+ public static boolean showTab() {
+ return SHOW_TAB;
+ }
+
+ public static boolean gameStarted() {
+ return GAME_STARTED;
+ }
+
+ @Override
+ public void onInitializeClient() {
+ ClientPlayNetworking.registerGlobalReceiver(ConfigPayload.ID, (payload, context) -> context.client().execute(() -> {
+ SHOW_SKINS = payload.showSkins();
+ SHOW_NAMETAGS = payload.showNametags();
+ SHOW_TAB = payload.showTab();
+ }));
+ ClientPlayNetworking.registerGlobalReceiver(GamePayload.ID, (payload, context) -> context.client().execute(() -> GAME_STARTED = payload.gameLaunched()));
+
+ // Needed because else `client.options` is null
+ ClientLifecycleEvents.CLIENT_STARTED.register(client -> {
+ var options = client.options;
+
+ options.setPlayerModelPart(PlayerModelPart.CAPE, true);
+ options.setPlayerModelPart(PlayerModelPart.HAT, true);
+ options.setPlayerModelPart(PlayerModelPart.JACKET, true);
+ options.setPlayerModelPart(PlayerModelPart.LEFT_SLEEVE, true);
+ options.setPlayerModelPart(PlayerModelPart.RIGHT_SLEEVE, true);
+ options.setPlayerModelPart(PlayerModelPart.LEFT_PANTS_LEG, true);
+ options.setPlayerModelPart(PlayerModelPart.RIGHT_PANTS_LEG, true);
+ });
+
+ }
}
diff --git a/src/client/java/world/anhgelus/molehunt/client/mixin/NoCustomizableSkinOverlay.java b/src/client/java/world/anhgelus/molehunt/client/mixin/NoCustomizableSkinOverlay.java
index c2c0ab0..f253cd8 100644
--- a/src/client/java/world/anhgelus/molehunt/client/mixin/NoCustomizableSkinOverlay.java
+++ b/src/client/java/world/anhgelus/molehunt/client/mixin/NoCustomizableSkinOverlay.java
@@ -3,7 +3,6 @@ package world.anhgelus.molehunt.client.mixin;
import net.minecraft.client.option.GameOptions;
import net.minecraft.entity.player.PlayerModelPart;
import org.spongepowered.asm.mixin.Mixin;
-import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@@ -11,14 +10,9 @@ import world.anhgelus.molehunt.client.MolehuntClient;
@Mixin(GameOptions.class)
public abstract class NoCustomizableSkinOverlay {
- @Shadow
- private void setPlayerModelPart(PlayerModelPart part, boolean enabled) {}
-
- @Inject(at = @At("HEAD"), method = "setPlayerModelPart", cancellable = true)
- public void togglePlayerModelPart(PlayerModelPart part, boolean enabled, CallbackInfo ci) {
- if (MolehuntClient.showSkins()) return;
- setPlayerModelPart(part, true);
- ((GameOptions) (Object) this).sendClientSettings();
- ci.cancel();
- }
+ @Inject(at = @At("HEAD"), method = "setPlayerModelPart", cancellable = true)
+ public void togglePlayerModelPart(PlayerModelPart part, boolean enabled, CallbackInfo ci) {
+ if (MolehuntClient.showSkins()) return;
+ ci.cancel();
+ }
}
diff --git a/src/client/java/world/anhgelus/molehunt/client/mixin/NoNametags.java b/src/client/java/world/anhgelus/molehunt/client/mixin/NoNametags.java
index 555fb00..cea817d 100644
--- a/src/client/java/world/anhgelus/molehunt/client/mixin/NoNametags.java
+++ b/src/client/java/world/anhgelus/molehunt/client/mixin/NoNametags.java
@@ -7,7 +7,6 @@ import net.minecraft.client.render.state.CameraRenderState;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityType;
-import net.minecraft.entity.player.PlayerEntity;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
@@ -16,9 +15,10 @@ import world.anhgelus.molehunt.client.MolehuntClient;
@Mixin(EntityRenderer.class)
public class NoNametags<T extends Entity, S extends EntityRenderState> {
- @Inject(at = @At("HEAD"), method = "render", cancellable = true)
- private void renderLabelOrNot(S state, MatrixStack matrices, OrderedRenderCommandQueue queue, CameraRenderState cameraState, CallbackInfo ci) {
- if (EntityType.PLAYER != state.entityType || MolehuntClient.showNameTags() || !MolehuntClient.gameStarted()) return;
- ci.cancel();
- }
+ @Inject(at = @At("HEAD"), method = "render", cancellable = true)
+ private void renderLabelOrNot(S state, MatrixStack matrices, OrderedRenderCommandQueue queue, CameraRenderState cameraState, CallbackInfo ci) {
+ if (EntityType.PLAYER != state.entityType || MolehuntClient.showNameTags() || !MolehuntClient.gameStarted())
+ return;
+ ci.cancel();
+ }
} \ No newline at end of file
diff --git a/src/client/java/world/anhgelus/molehunt/client/mixin/NoPlayerListHud.java b/src/client/java/world/anhgelus/molehunt/client/mixin/NoPlayerListHud.java
index 4473b12..d889f06 100644
--- a/src/client/java/world/anhgelus/molehunt/client/mixin/NoPlayerListHud.java
+++ b/src/client/java/world/anhgelus/molehunt/client/mixin/NoPlayerListHud.java
@@ -9,9 +9,9 @@ import world.anhgelus.molehunt.client.MolehuntClient;
@Mixin(PlayerListHud.class)
public class NoPlayerListHud {
- @Inject(at = @At("HEAD"), method = "render", cancellable = true)
- public void render(CallbackInfo ci) {
- if (MolehuntClient.showTab() || !MolehuntClient.gameStarted()) return;
- ci.cancel();
- }
+ @Inject(at = @At("HEAD"), method = "render", cancellable = true)
+ public void render(CallbackInfo ci) {
+ if (MolehuntClient.showTab() || !MolehuntClient.gameStarted()) return;
+ ci.cancel();
+ }
}
diff --git a/src/client/java/world/anhgelus/molehunt/client/mixin/NoSkin.java b/src/client/java/world/anhgelus/molehunt/client/mixin/NoSkin.java
index b6b67cc..945ef9b 100644
--- a/src/client/java/world/anhgelus/molehunt/client/mixin/NoSkin.java
+++ b/src/client/java/world/anhgelus/molehunt/client/mixin/NoSkin.java
@@ -14,14 +14,14 @@ import world.anhgelus.molehunt.client.MolehuntClient;
@Mixin(AbstractClientPlayerEntity.class)
public class NoSkin {
- @Inject(at = @At("HEAD"), method = "getSkin", cancellable = true)
- public void getSkin(CallbackInfoReturnable<SkinTextures> cir) {
- if (MolehuntClient.showSkins() || !MolehuntClient.gameStarted()) return;
- cir.setReturnValue(SkinTextures.create(
- new AssetInfo.TextureAssetInfo(Identifier.of(Molehunt.MOD_ID, "skin")),
- null,
- null,
- PlayerSkinType.WIDE
- ));
- }
+ @Inject(at = @At("HEAD"), method = "getSkin", cancellable = true)
+ public void getSkin(CallbackInfoReturnable<SkinTextures> cir) {
+ if (MolehuntClient.showSkins() || !MolehuntClient.gameStarted()) return;
+ cir.setReturnValue(SkinTextures.create(
+ new AssetInfo.TextureAssetInfo(Identifier.of(Molehunt.MOD_ID, "skin")),
+ null,
+ null,
+ PlayerSkinType.WIDE
+ ));
+ }
}
diff --git a/src/client/resources/assets/molehunt/lang/en_us.json b/src/client/resources/assets/molehunt/lang/en_us.json
index 267230a..5bbd6f5 100644
--- a/src/client/resources/assets/molehunt/lang/en_us.json
+++ b/src/client/resources/assets/molehunt/lang/en_us.json
@@ -1,28 +1,28 @@
{
- "commands.molehunt.error.game_not_started": "The Molehunt game has not been started yet.",
- "commands.molehunt.timer.show": "Showing Molehunt timer.",
- "commands.molehunt.timer.hide": "Hiding Molehunt timer.",
- "commands.molehunt.role.mole": "ยงcYou are a Mole.\nKill all the survivors before the timer runs out.",
- "commands.molehunt.role.mole.list": "ยงeThe moles are: %s",
- "commands.molehunt.role.survivor": "ยงaYou are not the Mole. \nSurvive until the timer runs out, and try to discover who's the Mole.",
- "commands.molehunt.role.survivor.mole_count": "ยงeThere are %d ยงemoles among you.",
- "commands.molehunt.stop.success": "The Molehunt game has been stopped.",
- "molehunt.game.end.suspense.title": "ยงeAnd the winners are...",
- "molehunt.game.end.winners.moles.title": "ยงcThe Moles!",
- "molehunt.game.end.winners.survivors.title": "ยงaNot the Moles!",
- "molehunt.game.end.winners.subtitle": "ยง6The Moles were %s",
- "molehunt.game.start.suspense": "ยงeYou are...",
- "molehunt.game.start.mole.title": "ยงcThe Mole!",
- "molehunt.game.start.mole.subtitle": "ยงeGet the list of moles with ยง6/molehunt roleยงe.",
- "molehunt.game.start.survivor.title": "ยงaNot the Mole!",
- "molehunt.game.start.survivor.subtitle": "ยงeTry to survive and find out who's the mole!",
- "gamerule.molehunt:gameDuration": "Molehunt: Duration of a game",
- "gamerule.molehunt:molePercentage": "Molehunt: Percentage of Mole",
- "gamerule.molehunt:moleCount": "Molehunt: Number of Mole",
- "gamerule.molehunt:showNametags": "Molehunt: Show players' nametag",
- "gamerule.molehunt:showTab": "Molehunt: Enable the tab",
- "gamerule.molehunt:showSkins": "Molehunt: Show players' skin",
- "gamerule.molehunt:initialWorldSize": "Molehunt: Initial world size",
- "gamerule.molehunt:finalWorldSize": "Molehunt: Final world size",
- "gamerule.molehunt:borderMovingStartingTimeOffsetMinutes": "Molehunt: Time before moving the borders"
+ "commands.molehunt.error.game_not_started": "The Molehunt game has not been started yet.",
+ "commands.molehunt.timer.show": "Showing Molehunt timer.",
+ "commands.molehunt.timer.hide": "Hiding Molehunt timer.",
+ "commands.molehunt.role.mole": "ยงcYou are a Mole.\nKill all the survivors before the timer runs out.",
+ "commands.molehunt.role.mole.list": "ยงeThe moles are: %s",
+ "commands.molehunt.role.survivor": "ยงaYou are not the Mole. \nSurvive until the timer runs out, and try to discover who's the Mole.",
+ "commands.molehunt.role.survivor.mole_count": "ยงeThere are %d ยงemoles among you.",
+ "commands.molehunt.stop.success": "The Molehunt game has been stopped.",
+ "molehunt.game.end.suspense.title": "ยงeAnd the winners are...",
+ "molehunt.game.end.winners.moles.title": "ยงcThe Moles!",
+ "molehunt.game.end.winners.survivors.title": "ยงaNot the Moles!",
+ "molehunt.game.end.winners.subtitle": "ยง6The Moles were %s",
+ "molehunt.game.start.suspense": "ยงeYou are...",
+ "molehunt.game.start.mole.title": "ยงcThe Mole!",
+ "molehunt.game.start.mole.subtitle": "ยงeGet the list of moles with ยง6/molehunt roleยงe.",
+ "molehunt.game.start.survivor.title": "ยงaNot the Mole!",
+ "molehunt.game.start.survivor.subtitle": "ยงeTry to survive and find out who's the mole!",
+ "gamerule.molehunt:gameDuration": "Molehunt: Duration of a game",
+ "gamerule.molehunt:molePercentage": "Molehunt: Percentage of Mole",
+ "gamerule.molehunt:moleCount": "Molehunt: Number of Mole",
+ "gamerule.molehunt:showNametags": "Molehunt: Show players' nametag",
+ "gamerule.molehunt:showTab": "Molehunt: Enable the tab",
+ "gamerule.molehunt:showSkins": "Molehunt: Show players' skin",
+ "gamerule.molehunt:initialWorldSize": "Molehunt: Initial world size",
+ "gamerule.molehunt:finalWorldSize": "Molehunt: Final world size",
+ "gamerule.molehunt:borderMovingStartingTimeOffsetMinutes": "Molehunt: Time before moving the borders"
} \ No newline at end of file
diff --git a/src/client/resources/assets/molehunt/lang/fr_fr.json b/src/client/resources/assets/molehunt/lang/fr_fr.json
index 62c10ca..cc5133d 100644
--- a/src/client/resources/assets/molehunt/lang/fr_fr.json
+++ b/src/client/resources/assets/molehunt/lang/fr_fr.json
@@ -1,28 +1,28 @@
{
- "commands.molehunt.error.game_not_started": "La partie de Molehunt n'a pas encore commencรฉ.",
- "commands.molehunt.timer.show": "Le timer est maintenant affichรฉ.",
- "commands.molehunt.timer.hide": "Le timer est maintenant cachรฉ.",
- "commands.molehunt.role.mole": "ยงcVous รชtes une taupe.\nTuez tous les survivants avant la fin de la partie..",
- "commands.molehunt.role.mole.list": "ยงeLes taupes sont : %s",
- "commands.molehunt.role.survivor": "ยงaVous n'รชtes pas la taupe. \nSurvivez jusqu'ร  la fin, et dรฉcouvrez qui sont les moles.",
- "commands.molehunt.role.survivor.mole_count": "ยงeIl y a %d ยงetaupes parmi vous.",
- "commands.molehunt.stop.success": "La partie de Molehunt a รฉtรฉ arrรชtรฉe.",
- "molehunt.game.end.suspense.title": "ยงeEt les gagnants sont...",
- "molehunt.game.end.winners.moles.title": "ยงcLes Taupes !",
- "molehunt.game.end.winners.survivors.title": "ยงaPas les Taupes !",
- "molehunt.game.end.winners.subtitle": "ยงLes Taupes sont",
- "molehunt.game.start.suspense": "ยงeVous รชtes...",
- "molehunt.game.start.mole.title": "ยงcLa Taupe !",
- "molehunt.game.start.mole.subtitle": "ยงeRรฉcupรฉrer la liste des taupes avec ยง6/molehunt moles",
- "molehunt.game.start.survivor.title": "ยงaPas la taupe!",
- "molehunt.game.start.survivor.subtitle": "ยงeEssaye de survivre et de trouver qui est la taupe !",
- "gamerule.molehunt:gameDuration": "Molehunt : Durรฉe d'une partie",
- "gamerule.molehunt:molePercentage": "Molehunt : Pourcentage de Taupes",
- "gamerule.molehunt:moleCount": "Molehunt : Nombre de Taupes",
- "gamerule.molehunt:showNametags": "Molehunt : Affiche les nametags des joueurs",
- "gamerule.molehunt:showTab": "Molehunt : Active la liste des joueurs",
- "gamerule.molehunt:showSkins": "Molehunt : Affiche les skins des joueurs",
- "gamerule.molehunt:initialWorldSize": "Molehunt : Taille initiale du monde",
- "gamerule.molehunt:finalWorldSize": "Molehunt : Taille finale du monde",
- "gamerule.molehunt:borderMovingStartingTimeOffsetMinutes": "Molehunt : Temps avant de bouger les bordures du monde"
+ "commands.molehunt.error.game_not_started": "La partie de Molehunt n'a pas encore commencรฉ.",
+ "commands.molehunt.timer.show": "Le timer est maintenant affichรฉ.",
+ "commands.molehunt.timer.hide": "Le timer est maintenant cachรฉ.",
+ "commands.molehunt.role.mole": "ยงcVous รชtes une taupe.\nTuez tous les survivants avant la fin de la partie..",
+ "commands.molehunt.role.mole.list": "ยงeLes taupes sont : %s",
+ "commands.molehunt.role.survivor": "ยงaVous n'รชtes pas la taupe. \nSurvivez jusqu'ร  la fin, et dรฉcouvrez qui sont les moles.",
+ "commands.molehunt.role.survivor.mole_count": "ยงeIl y a %d ยงetaupes parmi vous.",
+ "commands.molehunt.stop.success": "La partie de Molehunt a รฉtรฉ arrรชtรฉe.",
+ "molehunt.game.end.suspense.title": "ยงeEt les gagnants sont...",
+ "molehunt.game.end.winners.moles.title": "ยงcLes Taupes !",
+ "molehunt.game.end.winners.survivors.title": "ยงaPas les Taupes !",
+ "molehunt.game.end.winners.subtitle": "ยงLes Taupes sont",
+ "molehunt.game.start.suspense": "ยงeVous รชtes...",
+ "molehunt.game.start.mole.title": "ยงcLa Taupe !",
+ "molehunt.game.start.mole.subtitle": "ยงeRรฉcupรฉrer la liste des taupes avec ยง6/molehunt moles",
+ "molehunt.game.start.survivor.title": "ยงaPas la taupe!",
+ "molehunt.game.start.survivor.subtitle": "ยงeEssaye de survivre et de trouver qui est la taupe !",
+ "gamerule.molehunt:gameDuration": "Molehunt : Durรฉe d'une partie",
+ "gamerule.molehunt:molePercentage": "Molehunt : Pourcentage de Taupes",
+ "gamerule.molehunt:moleCount": "Molehunt : Nombre de Taupes",
+ "gamerule.molehunt:showNametags": "Molehunt : Affiche les nametags des joueurs",
+ "gamerule.molehunt:showTab": "Molehunt : Active la liste des joueurs",
+ "gamerule.molehunt:showSkins": "Molehunt : Affiche les skins des joueurs",
+ "gamerule.molehunt:initialWorldSize": "Molehunt : Taille initiale du monde",
+ "gamerule.molehunt:finalWorldSize": "Molehunt : Taille finale du monde",
+ "gamerule.molehunt:borderMovingStartingTimeOffsetMinutes": "Molehunt : Temps avant de bouger les bordures du monde"
} \ No newline at end of file
diff --git a/src/client/resources/molehunt.client.mixins.json b/src/client/resources/molehunt.client.mixins.json
index 7b9c0f4..b966891 100644
--- a/src/client/resources/molehunt.client.mixins.json
+++ b/src/client/resources/molehunt.client.mixins.json
@@ -1,15 +1,15 @@
{
- "required": true,
- "minVersion": "0.8",
- "package": "world.anhgelus.molehunt.client.mixin",
- "compatibilityLevel": "JAVA_21",
- "client": [
- "NoCustomizableSkinOverlay",
- "NoNametags",
- "NoPlayerListHud",
- "NoSkin"
- ],
- "injectors": {
- "defaultRequire": 1
- }
+ "required": true,
+ "minVersion": "0.8",
+ "package": "world.anhgelus.molehunt.client.mixin",
+ "compatibilityLevel": "JAVA_21",
+ "client": [
+ "NoCustomizableSkinOverlay",
+ "NoNametags",
+ "NoPlayerListHud",
+ "NoSkin"
+ ],
+ "injectors": {
+ "defaultRequire": 1
+ }
}
diff --git a/src/main/java/world/anhgelus/molehunt/Molehunt.java b/src/main/java/world/anhgelus/molehunt/Molehunt.java
index d5df320..6486700 100644
--- a/src/main/java/world/anhgelus/molehunt/Molehunt.java
+++ b/src/main/java/world/anhgelus/molehunt/Molehunt.java
@@ -40,199 +40,186 @@ import static net.minecraft.server.command.CommandManager.literal;
public class Molehunt implements ModInitializer {
- public static final String MOD_ID = "molehunt";
- public static final Logger LOGGER = LoggerFactory.getLogger(MOD_ID);
- public static Config CONFIG;
-
- public static final SimpleConfig CONFIG_FILE = Config.configFile(MOD_ID);
-
- public static final GameRule<Integer> GAME_DURATION = GameRuleBuilder
- .forInteger(CONFIG_FILE.getOrDefault("game_duration", 90))
- .category(GameRuleCategory.MISC)
- .buildAndRegister(Identifier.of(MOD_ID, "gameDurationMinutes"));
-
- public static final GameRule<Integer> MOLE_PERCENTAGE = GameRuleBuilder
- .forInteger(CONFIG_FILE.getOrDefault("mole_percentage", 25))
- .range(0, 100)
- .category(GameRuleCategory.MISC)
- .buildAndRegister(Identifier.of(MOD_ID, "molePercentage"));
-
- public static final GameRule<Integer> MOLE_COUNT = GameRuleBuilder
- .forInteger(CONFIG_FILE.getOrDefault("mole_count", -1))
- .category(GameRuleCategory.MISC)
- .buildAndRegister(Identifier.of(MOD_ID, "moleCount"));
-
- public static final GameRule<Boolean> SHOW_NAMETAGS = GameRuleBuilder
- .forBoolean(CONFIG_FILE.getOrDefault("show_nametags", false))
- .category(GameRuleCategory.MISC)
- .buildAndRegister(Identifier.of(MOD_ID, "showNametags"));
-
- public static final GameRule<Boolean> SHOW_TAB = GameRuleBuilder
- .forBoolean(CONFIG_FILE.getOrDefault("show_tab", false))
- .category(GameRuleCategory.MISC)
- .buildAndRegister(Identifier.of(MOD_ID, "showTab"));
-
- public static final GameRule<Boolean> SHOW_SKINS = GameRuleBuilder
- .forBoolean(CONFIG_FILE.getOrDefault("show_skins", false))
- .category(GameRuleCategory.MISC)
- .buildAndRegister(Identifier.of(MOD_ID, "showSkins"));
-
- public static final GameRule<Integer> INITIAL_WORLD_SIZE = GameRuleBuilder
- .forInteger(CONFIG_FILE.getOrDefault("initial_world_size", 600))
- .minValue(0)
- .category(GameRuleCategory.MISC)
- .buildAndRegister(Identifier.of(MOD_ID, "initialWorldSize"));
-
- public static final GameRule<Integer> FINAL_WORLD_SIZE = GameRuleBuilder
- .forInteger(CONFIG_FILE.getOrDefault("final_world_size", 100))
- .minValue(0)
- .category(GameRuleCategory.MISC)
- .buildAndRegister(Identifier.of(MOD_ID, "finalWorldSize"));
-
- public static final GameRule<Integer> MOVING_STARTING_TIME_OFFSET = GameRuleBuilder
- .forInteger(CONFIG_FILE.getOrDefault("border_moving_starting_time_offset", 30))
- .minValue(0)
- .category(GameRuleCategory.MISC)
- .buildAndRegister(Identifier.of(MOD_ID, "borderMovingStartingTimeOffsetMinutes"));
-
- public static final GameRule<Boolean> ENABLE_PORTALS = GameRuleBuilder
- .forBoolean(CONFIG_FILE.getOrDefault("enable_portals", false))
- .category(GameRuleCategory.MISC)
- .buildAndRegister(Identifier.of(MOD_ID, "enablePortals"));
-
- public static final GameRule<Boolean> FOOD_ON_START = GameRuleBuilder
- .forBoolean(CONFIG_FILE.getOrDefault("food_on_start", true))
- .category(GameRuleCategory.MISC)
- .buildAndRegister(Identifier.of(MOD_ID, "foodOnStart"));
-
- public Game game;
-
- public static HashMap<UUID, Boolean> timerVisibility = new HashMap<>();
-
- private static <T> void sendConfigPayload(T v, MinecraftServer server) {
- if (CONFIG == null) return;
- CONFIG.sendConfigPayload();
- }
-
- static {
- GameRuleEvents.changeCallback(SHOW_NAMETAGS).register(Molehunt::sendConfigPayload);
- GameRuleEvents.changeCallback(SHOW_TAB).register(Molehunt::sendConfigPayload);
- GameRuleEvents.changeCallback(SHOW_SKINS).register(Molehunt::sendConfigPayload);
- }
-
- @Override
- public void onInitialize() {
- LOGGER.info("Initializing Molehunt");
-
- final var command = literal("molehunt");
- command.then(literal("start")
- .requires(CommandManager.requirePermissionLevel(CommandManager.GAMEMASTERS_CHECK))
- .executes(context -> {
- game = new Game(context.getSource().getServer());
- game.start();
- return Command.SINGLE_SUCCESS;
- }));
- command.then(literal("timer").requires(ServerCommandSource::isExecutedByPlayer).then(
- literal("show").executes(context -> {
- var player = context.getSource().getPlayer();
- assert player != null;
-
- timerVisibility.put(player.getUuid(), true);
- context.getSource().sendFeedback(() -> Text.translatable("commands.molehunt.timer.show"), false);
-
- if (game == null || !game.started()) {
- player.networkHandler.sendPacket(new OverlayMessageS2CPacket(
- Text.translatable("commands.molehunt.error.game_not_started").formatted(Formatting.RED)
- ));
- } else {
- player.networkHandler.sendPacket(new OverlayMessageS2CPacket(Text.of(game.getRemainingText())));
- }
-
- return Command.SINGLE_SUCCESS;
- })
- ).then(
- literal("hide").executes(context -> {
- var player = context.getSource().getPlayer();
- assert player != null;
-
- timerVisibility.put(player.getUuid(), false);
- context.getSource().sendFeedback(() -> Text.translatable("commands.molehunt.timer.hide"), false);
- return Command.SINGLE_SUCCESS;
- })
- ));
- command.then(literal("role")
- .requires(ServerCommandSource::isExecutedByPlayer)
- .executes(context -> {
- if (game == null || !game.started()) {
- throw (new SimpleCommandExceptionType(Text.translatable("commands.molehunt.error.game_not_started"))).create();
- }
-
- final var source = context.getSource();
- final var player = source.getPlayer();
- assert player != null;
-
- if (game.isMole(player)) {
- source.sendFeedback(
- () -> Text.translatable("commands.molehunt.role.mole")
- .append("\n\n")
- .append(Text.translatable("commands.molehunt.role.mole.list", game.getMolesAsString())),
- false);
- } else if (player.isSpectator()) {
- source.sendFeedback(
- () -> Text.translatable("commands.molehunt.role.survivor.mole_count", game.getMoles().size()),
- false);
- } else {
- source.sendFeedback(
- () -> Text.translatable("commands.molehunt.role.survivor")
- .append("\n\n")
- .append(Text.translatable("commands.molehunt.role.survivor.mole_count", game.getMoles().size())),
- false);
- }
-
- return Command.SINGLE_SUCCESS;
- }));
- command.then(literal("stop")
- .requires(CommandManager.requirePermissionLevel(CommandManager.GAMEMASTERS_CHECK))
- .executes(context -> {
- if (game == null || !game.started()) {
- throw (new SimpleCommandExceptionType(Text.translatable("commands.molehunt.error.game_not_started"))).create();
- }
-
- game.stop();
-
- return Command.SINGLE_SUCCESS;
- }));
-
- ServerLifecycleEvents.SERVER_STARTED.register(server -> CONFIG = new Config(server));
-
- CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> dispatcher.register(command));
-
- ServerMessageEvents.ALLOW_CHAT_MESSAGE.register((message, sender, params) -> false);
-
- ServerLivingEntityEvents.AFTER_DEATH.register((entity, damageSource) -> {
- if (!(entity instanceof ServerPlayerEntity) || game == null) return;
- if (!game.started()) return;
- if (game.wonByMoles()) game.end();
- });
-
- ServerPlayerEvents.AFTER_RESPAWN.register((oldPlayer, newPlayer, alive) -> {
- if (game == null) return;
- if (!game.started()) return;
- newPlayer.changeGameMode(GameMode.SPECTATOR);
- });
-
- ServerPlayConnectionEvents.JOIN.register((handler, sender, server) -> {
- ServerPlayNetworking.send(
- handler.player,
- new ConfigPayload(CONFIG.nametagsEnabled(), CONFIG.skinsEnabled(), CONFIG.tabEnabled())
- );
- ServerPlayNetworking.send(
- handler.player,
- new GamePayload(game != null && game.started())
- );
- });
-
- PayloadTypeRegistry.playS2C().register(ConfigPayload.ID, ConfigPayload.CODEC);
- PayloadTypeRegistry.playS2C().register(GamePayload.ID, GamePayload.CODEC);
- }
+ public static final String MOD_ID = "molehunt";
+ public static final Logger LOGGER = LoggerFactory.getLogger(MOD_ID);
+ public static final SimpleConfig CONFIG_FILE = Config.configFile(MOD_ID);
+ public static final GameRule<Integer> GAME_DURATION = GameRuleBuilder
+ .forInteger(CONFIG_FILE.getOrDefault("game_duration", 90))
+ .category(GameRuleCategory.MISC)
+ .buildAndRegister(Identifier.of(MOD_ID, "gameDurationMinutes"));
+ public static final GameRule<Integer> MOLE_PERCENTAGE = GameRuleBuilder
+ .forInteger(CONFIG_FILE.getOrDefault("mole_percentage", 25))
+ .range(0, 100)
+ .category(GameRuleCategory.MISC)
+ .buildAndRegister(Identifier.of(MOD_ID, "molePercentage"));
+ public static final GameRule<Integer> MOLE_COUNT = GameRuleBuilder
+ .forInteger(CONFIG_FILE.getOrDefault("mole_count", -1))
+ .category(GameRuleCategory.MISC)
+ .buildAndRegister(Identifier.of(MOD_ID, "moleCount"));
+ public static final GameRule<Boolean> SHOW_NAMETAGS = GameRuleBuilder
+ .forBoolean(CONFIG_FILE.getOrDefault("show_nametags", false))
+ .category(GameRuleCategory.MISC)
+ .buildAndRegister(Identifier.of(MOD_ID, "showNametags"));
+ public static final GameRule<Boolean> SHOW_TAB = GameRuleBuilder
+ .forBoolean(CONFIG_FILE.getOrDefault("show_tab", false))
+ .category(GameRuleCategory.MISC)
+ .buildAndRegister(Identifier.of(MOD_ID, "showTab"));
+ public static final GameRule<Boolean> SHOW_SKINS = GameRuleBuilder
+ .forBoolean(CONFIG_FILE.getOrDefault("show_skins", false))
+ .category(GameRuleCategory.MISC)
+ .buildAndRegister(Identifier.of(MOD_ID, "showSkins"));
+ public static final GameRule<Integer> INITIAL_WORLD_SIZE = GameRuleBuilder
+ .forInteger(CONFIG_FILE.getOrDefault("initial_world_size", 600))
+ .minValue(0)
+ .category(GameRuleCategory.MISC)
+ .buildAndRegister(Identifier.of(MOD_ID, "initialWorldSize"));
+ public static final GameRule<Integer> FINAL_WORLD_SIZE = GameRuleBuilder
+ .forInteger(CONFIG_FILE.getOrDefault("final_world_size", 100))
+ .minValue(0)
+ .category(GameRuleCategory.MISC)
+ .buildAndRegister(Identifier.of(MOD_ID, "finalWorldSize"));
+ public static final GameRule<Integer> MOVING_STARTING_TIME_OFFSET = GameRuleBuilder
+ .forInteger(CONFIG_FILE.getOrDefault("border_moving_starting_time_offset", 30))
+ .minValue(0)
+ .category(GameRuleCategory.MISC)
+ .buildAndRegister(Identifier.of(MOD_ID, "borderMovingStartingTimeOffsetMinutes"));
+ public static final GameRule<Boolean> ENABLE_PORTALS = GameRuleBuilder
+ .forBoolean(CONFIG_FILE.getOrDefault("enable_portals", false))
+ .category(GameRuleCategory.MISC)
+ .buildAndRegister(Identifier.of(MOD_ID, "enablePortals"));
+ public static final GameRule<Boolean> FOOD_ON_START = GameRuleBuilder
+ .forBoolean(CONFIG_FILE.getOrDefault("food_on_start", true))
+ .category(GameRuleCategory.MISC)
+ .buildAndRegister(Identifier.of(MOD_ID, "foodOnStart"));
+ public static Config CONFIG;
+ public static HashMap<UUID, Boolean> timerVisibility = new HashMap<>();
+
+ static {
+ GameRuleEvents.changeCallback(SHOW_NAMETAGS).register(Molehunt::sendConfigPayload);
+ GameRuleEvents.changeCallback(SHOW_TAB).register(Molehunt::sendConfigPayload);
+ GameRuleEvents.changeCallback(SHOW_SKINS).register(Molehunt::sendConfigPayload);
+ }
+
+ public Game game;
+
+ private static <T> void sendConfigPayload(T v, MinecraftServer server) {
+ if (CONFIG == null) return;
+ CONFIG.sendConfigPayload();
+ }
+
+ @Override
+ public void onInitialize() {
+ LOGGER.info("Initializing Molehunt");
+
+ final var command = literal("molehunt");
+ command.then(literal("start")
+ .requires(CommandManager.requirePermissionLevel(CommandManager.GAMEMASTERS_CHECK))
+ .executes(context -> {
+ game = new Game(context.getSource().getServer());
+ game.start();
+ return Command.SINGLE_SUCCESS;
+ }));
+ command.then(literal("timer").requires(ServerCommandSource::isExecutedByPlayer).then(
+ literal("show").executes(context -> {
+ var player = context.getSource().getPlayer();
+ assert player != null;
+
+ timerVisibility.put(player.getUuid(), true);
+ context.getSource().sendFeedback(() -> Text.translatable("commands.molehunt.timer.show"), false);
+
+ if (game == null || !game.started()) {
+ player.networkHandler.sendPacket(new OverlayMessageS2CPacket(
+ Text.translatable("commands.molehunt.error.game_not_started").formatted(Formatting.RED)
+ ));
+ } else {
+ player.networkHandler.sendPacket(new OverlayMessageS2CPacket(Text.of(game.getRemainingText())));
+ }
+
+ return Command.SINGLE_SUCCESS;
+ })
+ ).then(
+ literal("hide").executes(context -> {
+ var player = context.getSource().getPlayer();
+ assert player != null;
+
+ timerVisibility.put(player.getUuid(), false);
+ context.getSource().sendFeedback(() -> Text.translatable("commands.molehunt.timer.hide"), false);
+ return Command.SINGLE_SUCCESS;
+ })
+ ));
+ command.then(literal("role")
+ .requires(ServerCommandSource::isExecutedByPlayer)
+ .executes(context -> {
+ if (game == null || !game.started()) {
+ throw (new SimpleCommandExceptionType(Text.translatable("commands.molehunt.error.game_not_started"))).create();
+ }
+
+ final var source = context.getSource();
+ final var player = source.getPlayer();
+ assert player != null;
+
+ if (game.isMole(player)) {
+ source.sendFeedback(
+ () -> Text.translatable("commands.molehunt.role.mole")
+ .append("\n\n")
+ .append(Text.translatable("commands.molehunt.role.mole.list", game.getMolesAsString())),
+ false);
+ } else if (player.isSpectator()) {
+ source.sendFeedback(
+ () -> Text.translatable("commands.molehunt.role.survivor.mole_count", game.getMoles().size()),
+ false);
+ } else {
+ source.sendFeedback(
+ () -> Text.translatable("commands.molehunt.role.survivor")
+ .append("\n\n")
+ .append(Text.translatable("commands.molehunt.role.survivor.mole_count", game.getMoles().size())),
+ false);
+ }
+
+ return Command.SINGLE_SUCCESS;
+ }));
+ command.then(literal("stop")
+ .requires(CommandManager.requirePermissionLevel(CommandManager.GAMEMASTERS_CHECK))
+ .executes(context -> {
+ if (game == null || !game.started()) {
+ throw (new SimpleCommandExceptionType(Text.translatable("commands.molehunt.error.game_not_started"))).create();
+ }
+
+ game.stop();
+
+ return Command.SINGLE_SUCCESS;
+ }));
+
+ ServerLifecycleEvents.SERVER_STARTED.register(server -> CONFIG = new Config(server));
+
+ CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> dispatcher.register(command));
+
+ ServerMessageEvents.ALLOW_CHAT_MESSAGE.register((message, sender, params) -> false);
+
+ ServerLivingEntityEvents.AFTER_DEATH.register((entity, damageSource) -> {
+ if (!(entity instanceof ServerPlayerEntity) || game == null) return;
+ if (!game.started()) return;
+ if (game.wonByMoles()) game.end();
+ });
+
+ ServerPlayerEvents.AFTER_RESPAWN.register((oldPlayer, newPlayer, alive) -> {
+ if (game == null) return;
+ if (!game.started()) return;
+ newPlayer.changeGameMode(GameMode.SPECTATOR);
+ });
+
+ ServerPlayConnectionEvents.JOIN.register((handler, sender, server) -> {
+ ServerPlayNetworking.send(
+ handler.player,
+ new ConfigPayload(CONFIG.nametagsEnabled(), CONFIG.skinsEnabled(), CONFIG.tabEnabled())
+ );
+ ServerPlayNetworking.send(
+ handler.player,
+ new GamePayload(game != null && game.started())
+ );
+ });
+
+ PayloadTypeRegistry.playS2C().register(ConfigPayload.ID, ConfigPayload.CODEC);
+ PayloadTypeRegistry.playS2C().register(GamePayload.ID, GamePayload.CODEC);
+ }
}
diff --git a/src/main/java/world/anhgelus/molehunt/config/Config.java b/src/main/java/world/anhgelus/molehunt/config/Config.java
index 08c3850..d65b569 100644
--- a/src/main/java/world/anhgelus/molehunt/config/Config.java
+++ b/src/main/java/world/anhgelus/molehunt/config/Config.java
@@ -6,135 +6,135 @@ import world.anhgelus.molehunt.Molehunt;
public class Config {
- private final MinecraftServer server;
-
- public Config(MinecraftServer server) {
- this.server = server;
-
- sendConfigPayload(nametagsEnabled(), skinsEnabled(), tabEnabled());
- }
-
- public void sendConfigPayload() {
- final var payload = new ConfigPayload(nametagsEnabled(), skinsEnabled(), tabEnabled());
- server.getPlayerManager().getPlayerList().forEach(p -> ServerPlayNetworking.send(p, payload));
- }
-
- public void sendConfigPayload(boolean showNametags, boolean showSkins, boolean showTab) {
- final var payload = new ConfigPayload(showNametags, showSkins, showTab);
- server.getPlayerManager().getPlayerList().forEach(p -> ServerPlayNetworking.send(p, payload));
- }
-
- public int getGameDuration() {
- return server.getOverworld().getGameRules().getValue(Molehunt.GAME_DURATION);
- }
-
- public int getMolePercentage() {
- return server.getOverworld().getGameRules().getValue(Molehunt.MOLE_PERCENTAGE);
- }
-
- public int getMoleCount() {
- return server.getOverworld().getGameRules().getValue(Molehunt.MOLE_COUNT);
- }
-
- public boolean nametagsEnabled() {
- return server.getOverworld().getGameRules().getValue(Molehunt.SHOW_NAMETAGS);
- }
-
- public boolean skinsEnabled() {
- return server.getOverworld().getGameRules().getValue(Molehunt.SHOW_SKINS);
- }
-
- public boolean tabEnabled() {
- return server.getOverworld().getGameRules().getValue(Molehunt.SHOW_TAB);
- }
-
- public int getInitialWorldSize() {
- return server.getOverworld().getGameRules().getValue(Molehunt.INITIAL_WORLD_SIZE);
- }
-
- public int getFinalWorldSize() {
- return server.getOverworld().getGameRules().getValue(Molehunt.FINAL_WORLD_SIZE);
- }
-
- public int getBorderShrinkingStartingTimeOffset() {
- return server.getOverworld().getGameRules().getValue(Molehunt.MOVING_STARTING_TIME_OFFSET);
- }
-
- public boolean portalsEnabled() {
- return server.getOverworld().getGameRules().getValue(Molehunt.ENABLE_PORTALS);
- }
-
- public boolean foodOnStart() {
- return server.getOverworld().getGameRules().getValue(Molehunt.FOOD_ON_START);
- }
-
- public static SimpleConfig configFile(String fileName) {
- return SimpleConfig.of(fileName).provider(Config::defaultConfig).request();
- }
-
- private static String defaultConfig(String s) {
- return """
- # Molehunt mod configuration file
- # To regenerate the default configuration, delete, move or rename this file.
-
- # Game settings
-
- # The duration of a molehunt game, in minutes.
- # Default: 90 minutes (1 hour 30 minutes).
- game_duration = 90
-
- # Mole percentage.
- # For example, a mole percentage of 25% will get 1 mole every 4 players.
- # Default: 25 %.
- mole_percentage = 25
-
- # Mole count (absolute).
- # This setting will overwrite the mole_percentage setting.
- # If set below 0, this setting is disabled.
- # Default: -1.
- mole_count = -1
-
- # Give food on start
- # Default: true
- food_on_start = true
-
-
- # Client-side settings (applies to all players)
-
- # Show nametags
- # Default: false
- show_nametags = false
-
- # Show skins
- # Default: false
- show_skins = false
-
- # Show tab
- # Default: false
- show_tab = false
-
-
- # World border settings
-
- # Initial world size (in blocks).
- # Default: 600 blocks.
- initial_world_size = 600
-
- # Final world size (in blocks).
- # Default: 100 blocks.
- final_world_size = 100
-
- # Moving starting time offset (in minutes)
- # The time before starting to move the world borders.
- # If this value is greater than the game duration, borders will never move.
- # Default: 30 minutes.
- border_moving_starting_time_offset = 30
-
- # Other
-
- # Enable portals (nether, end, end gateway).
- # Default: false.
- enable_portals = false
- """;
- }
+ private final MinecraftServer server;
+
+ public Config(MinecraftServer server) {
+ this.server = server;
+
+ sendConfigPayload(nametagsEnabled(), skinsEnabled(), tabEnabled());
+ }
+
+ public static SimpleConfig configFile(String fileName) {
+ return SimpleConfig.of(fileName).provider(Config::defaultConfig).request();
+ }
+
+ private static String defaultConfig(String s) {
+ return """
+ # Molehunt mod configuration file
+ # To regenerate the default configuration, delete, move or rename this file.
+
+ # Game settings
+
+ # The duration of a molehunt game, in minutes.
+ # Default: 90 minutes (1 hour 30 minutes).
+ game_duration = 90
+
+ # Mole percentage.
+ # For example, a mole percentage of 25% will get 1 mole every 4 players.
+ # Default: 25 %.
+ mole_percentage = 25
+
+ # Mole count (absolute).
+ # This setting will overwrite the mole_percentage setting.
+ # If set below 0, this setting is disabled.
+ # Default: -1.
+ mole_count = -1
+
+ # Give food on start
+ # Default: true
+ food_on_start = true
+
+
+ # Client-side settings (applies to all players)
+
+ # Show nametags
+ # Default: false
+ show_nametags = false
+
+ # Show skins
+ # Default: false
+ show_skins = false
+
+ # Show tab
+ # Default: false
+ show_tab = false
+
+
+ # World border settings
+
+ # Initial world size (in blocks).
+ # Default: 600 blocks.
+ initial_world_size = 600
+
+ # Final world size (in blocks).
+ # Default: 100 blocks.
+ final_world_size = 100
+
+ # Moving starting time offset (in minutes)
+ # The time before starting to move the world borders.
+ # If this value is greater than the game duration, borders will never move.
+ # Default: 30 minutes.
+ border_moving_starting_time_offset = 30
+
+ # Other
+
+ # Enable portals (nether, end, end gateway).
+ # Default: false.
+ enable_portals = false
+ """;
+ }
+
+ public void sendConfigPayload() {
+ final var payload = new ConfigPayload(nametagsEnabled(), skinsEnabled(), tabEnabled());
+ server.getPlayerManager().getPlayerList().forEach(p -> ServerPlayNetworking.send(p, payload));
+ }
+
+ public void sendConfigPayload(boolean showNametags, boolean showSkins, boolean showTab) {
+ final var payload = new ConfigPayload(showNametags, showSkins, showTab);
+ server.getPlayerManager().getPlayerList().forEach(p -> ServerPlayNetworking.send(p, payload));
+ }
+
+ public int getGameDuration() {
+ return server.getOverworld().getGameRules().getValue(Molehunt.GAME_DURATION);
+ }
+
+ public int getMolePercentage() {
+ return server.getOverworld().getGameRules().getValue(Molehunt.MOLE_PERCENTAGE);
+ }
+
+ public int getMoleCount() {
+ return server.getOverworld().getGameRules().getValue(Molehunt.MOLE_COUNT);
+ }
+
+ public boolean nametagsEnabled() {
+ return server.getOverworld().getGameRules().getValue(Molehunt.SHOW_NAMETAGS);
+ }
+
+ public boolean skinsEnabled() {
+ return server.getOverworld().getGameRules().getValue(Molehunt.SHOW_SKINS);
+ }
+
+ public boolean tabEnabled() {
+ return server.getOverworld().getGameRules().getValue(Molehunt.SHOW_TAB);
+ }
+
+ public int getInitialWorldSize() {
+ return server.getOverworld().getGameRules().getValue(Molehunt.INITIAL_WORLD_SIZE);
+ }
+
+ public int getFinalWorldSize() {
+ return server.getOverworld().getGameRules().getValue(Molehunt.FINAL_WORLD_SIZE);
+ }
+
+ public int getBorderShrinkingStartingTimeOffset() {
+ return server.getOverworld().getGameRules().getValue(Molehunt.MOVING_STARTING_TIME_OFFSET);
+ }
+
+ public boolean portalsEnabled() {
+ return server.getOverworld().getGameRules().getValue(Molehunt.ENABLE_PORTALS);
+ }
+
+ public boolean foodOnStart() {
+ return server.getOverworld().getGameRules().getValue(Molehunt.FOOD_ON_START);
+ }
}
diff --git a/src/main/java/world/anhgelus/molehunt/config/ConfigPayload.java b/src/main/java/world/anhgelus/molehunt/config/ConfigPayload.java
index b43bd1b..f33e2c5 100644
--- a/src/main/java/world/anhgelus/molehunt/config/ConfigPayload.java
+++ b/src/main/java/world/anhgelus/molehunt/config/ConfigPayload.java
@@ -8,18 +8,18 @@ import net.minecraft.util.Identifier;
import world.anhgelus.molehunt.Molehunt;
public record ConfigPayload(boolean showNametags, boolean showSkins, boolean showTab) implements CustomPayload {
- public static final Identifier CONFIG_PACKET_ID = Identifier.of(Molehunt.MOD_ID, "config");
+ public static final Identifier CONFIG_PACKET_ID = Identifier.of(Molehunt.MOD_ID, "config");
- public static final CustomPayload.Id<ConfigPayload> ID = new CustomPayload.Id<>(CONFIG_PACKET_ID);
- public static final PacketCodec<RegistryByteBuf, ConfigPayload> CODEC = PacketCodec.tuple(
- PacketCodecs.BOOLEAN, ConfigPayload::showNametags,
- PacketCodecs.BOOLEAN, ConfigPayload::showSkins,
- PacketCodecs.BOOLEAN, ConfigPayload::showTab,
- ConfigPayload::new
- );
+ public static final CustomPayload.Id<ConfigPayload> ID = new CustomPayload.Id<>(CONFIG_PACKET_ID);
+ public static final PacketCodec<RegistryByteBuf, ConfigPayload> CODEC = PacketCodec.tuple(
+ PacketCodecs.BOOLEAN, ConfigPayload::showNametags,
+ PacketCodecs.BOOLEAN, ConfigPayload::showSkins,
+ PacketCodecs.BOOLEAN, ConfigPayload::showTab,
+ ConfigPayload::new
+ );
- @Override
- public Id<? extends CustomPayload> getId() {
- return ID;
- }
+ @Override
+ public Id<? extends CustomPayload> getId() {
+ return ID;
+ }
}
diff --git a/src/main/java/world/anhgelus/molehunt/config/SimpleConfig.java b/src/main/java/world/anhgelus/molehunt/config/SimpleConfig.java
index 2b65829..6b7060a 100644
--- a/src/main/java/world/anhgelus/molehunt/config/SimpleConfig.java
+++ b/src/main/java/world/anhgelus/molehunt/config/SimpleConfig.java
@@ -38,216 +38,216 @@ import java.util.Scanner;
public class SimpleConfig {
- private static final Logger LOGGER = LogManager.getLogger("SimpleConfig");
- private final HashMap<String, String> config = new HashMap<>();
- private final ConfigRequest request;
- private boolean broken = false;
-
- public interface DefaultConfig {
- String get( String namespace );
-
- static String empty( String namespace ) {
- return "";
- }
- }
-
- public static class ConfigRequest {
-
- private final File file;
- private final String filename;
- private DefaultConfig provider;
-
- private ConfigRequest(File file, String filename ) {
- this.file = file;
- this.filename = filename;
- this.provider = DefaultConfig::empty;
- }
-
- /**
- * Sets the default config provider, used to generate the
- * config if it's missing.
- *
- * @param provider default config provider
- * @return current config request object
- * @see DefaultConfig
- */
- public ConfigRequest provider( DefaultConfig provider ) {
- this.provider = provider;
- return this;
- }
-
- /**
- * Loads the config from the filesystem.
- *
- * @return config object
- * @see SimpleConfig
- */
- public SimpleConfig request() {
- return new SimpleConfig( this );
- }
-
- private String getConfig() {
- return provider.get( filename ) + "\n";
- }
-
- }
-
- /**
- * Creates new config request object, ideally `namespace`
- * should be the name of the mod id of the requesting mod
- *
- * @param filename - name of the config file
- * @return new config request object
- */
- public static ConfigRequest of( String filename ) {
- Path path = FabricLoader.getInstance().getConfigDir();
- return new ConfigRequest( path.resolve( filename + ".properties" ).toFile(), filename );
- }
-
- private void createConfig() throws IOException {
-
- // try creating missing files
- request.file.getParentFile().mkdirs();
- Files.createFile( request.file.toPath() );
-
- // write default config data
- PrintWriter writer = new PrintWriter(request.file, StandardCharsets.UTF_8);
- writer.write( request.getConfig() );
- writer.close();
-
- }
-
- private void loadConfig() throws IOException {
- Scanner reader = new Scanner( request.file );
- for( int line = 1; reader.hasNextLine(); line ++ ) {
- parseConfigEntry( reader.nextLine(), line );
- }
- }
-
- private void parseConfigEntry( String entry, int line ) {
- if( !entry.isEmpty() && !entry.startsWith( "#" ) ) {
- String[] parts = entry.split("=", 2);
- if( parts.length == 2 ) {
- config.put( parts[0].stripTrailing(), parts[1].strip() );
- }else{
- throw new RuntimeException("Syntax error in config file on line " + line + "!");
- }
- }
- }
-
- private SimpleConfig( ConfigRequest request ) {
- this.request = request;
- String identifier = "Config '" + request.filename + "'";
-
- if( !request.file.exists() ) {
- LOGGER.info("{} is missing, generating default one...", identifier);
-
- try {
- createConfig();
- } catch (IOException e) {
- LOGGER.error("{} failed to generate!", identifier);
- LOGGER.trace( e );
- broken = true;
- }
- }
-
- if( !broken ) {
- try {
- loadConfig();
- } catch (Exception e) {
- LOGGER.error("{} failed to load!", identifier);
- LOGGER.trace( e );
- broken = true;
- }
- }
-
- }
-
- /**
- * Queries a value from config, returns `null` if the
- * key does not exist.
- *
- * @return value corresponding to the given key
- * @see SimpleConfig#getOrDefault
- */
- @Deprecated
- public String get( String key ) {
- return config.get( key );
- }
-
- /**
- * Returns string value from config corresponding to the given
- * key, or the default string if the key is missing.
- *
- * @return value corresponding to the given key, or the default value
- */
- public String getOrDefault( String key, String def ) {
- String val = get(key);
- return val == null ? def : val;
- }
-
- /**
- * Returns integer value from config corresponding to the given
- * key, or the default integer if the key is missing or invalid.
- *
- * @return value corresponding to the given key, or the default value
- */
- public int getOrDefault( String key, int def ) {
- try {
- return Integer.parseInt( get(key) );
- } catch (Exception e) {
- return def;
- }
- }
-
- /**
- * Returns boolean value from config corresponding to the given
- * key, or the default boolean if the key is missing.
- *
- * @return value corresponding to the given key, or the default value
- */
- public boolean getOrDefault( String key, boolean def ) {
- String val = get(key);
- if( val != null ) {
- return val.equalsIgnoreCase("true");
- }
-
- return def;
- }
-
- /**
- * Returns double value from config corresponding to the given
- * key, or the default string if the key is missing or invalid.
- *
- * @return value corresponding to the given key, or the default value
- */
- public double getOrDefault( String key, double def ) {
- try {
- return Double.parseDouble( get(key) );
- } catch (Exception e) {
- return def;
- }
- }
-
- /**
- * If any error occurred during loading or reading from the config
- * a 'broken' flag is set, indicating that the config's state
- * is undefined and should be discarded using `delete()`
- *
- * @return the 'broken' flag of the configuration
- */
- public boolean isBroken() {
- return broken;
- }
-
- /**
- * deletes the config file from the filesystem
- *
- * @return true if the operation was successful
- */
- public boolean delete() {
- LOGGER.warn("Config '{}' was removed from existence! Restart the game to regenerate it.", request.filename);
- return request.file.delete();
- }
+ private static final Logger LOGGER = LogManager.getLogger("SimpleConfig");
+ private final HashMap<String, String> config = new HashMap<>();
+ private final ConfigRequest request;
+ private boolean broken = false;
+
+ private SimpleConfig(ConfigRequest request) {
+ this.request = request;
+ String identifier = "Config '" + request.filename + "'";
+
+ if (!request.file.exists()) {
+ LOGGER.info("{} is missing, generating default one...", identifier);
+
+ try {
+ createConfig();
+ } catch (IOException e) {
+ LOGGER.error("{} failed to generate!", identifier);
+ LOGGER.trace(e);
+ broken = true;
+ }
+ }
+
+ if (!broken) {
+ try {
+ loadConfig();
+ } catch (Exception e) {
+ LOGGER.error("{} failed to load!", identifier);
+ LOGGER.trace(e);
+ broken = true;
+ }
+ }
+
+ }
+
+ /**
+ * Creates new config request object, ideally `namespace`
+ * should be the name of the mod id of the requesting mod
+ *
+ * @param filename - name of the config file
+ * @return new config request object
+ */
+ public static ConfigRequest of(String filename) {
+ Path path = FabricLoader.getInstance().getConfigDir();
+ return new ConfigRequest(path.resolve(filename + ".properties").toFile(), filename);
+ }
+
+ private void createConfig() throws IOException {
+
+ // try creating missing files
+ request.file.getParentFile().mkdirs();
+ Files.createFile(request.file.toPath());
+
+ // write default config data
+ PrintWriter writer = new PrintWriter(request.file, StandardCharsets.UTF_8);
+ writer.write(request.getConfig());
+ writer.close();
+
+ }
+
+ private void loadConfig() throws IOException {
+ Scanner reader = new Scanner(request.file);
+ for (int line = 1; reader.hasNextLine(); line++) {
+ parseConfigEntry(reader.nextLine(), line);
+ }
+ }
+
+ private void parseConfigEntry(String entry, int line) {
+ if (!entry.isEmpty() && !entry.startsWith("#")) {
+ String[] parts = entry.split("=", 2);
+ if (parts.length == 2) {
+ config.put(parts[0].stripTrailing(), parts[1].strip());
+ } else {
+ throw new RuntimeException("Syntax error in config file on line " + line + "!");
+ }
+ }
+ }
+
+ /**
+ * Queries a value from config, returns `null` if the
+ * key does not exist.
+ *
+ * @return value corresponding to the given key
+ * @see SimpleConfig#getOrDefault
+ */
+ @Deprecated
+ public String get(String key) {
+ return config.get(key);
+ }
+
+ /**
+ * Returns string value from config corresponding to the given
+ * key, or the default string if the key is missing.
+ *
+ * @return value corresponding to the given key, or the default value
+ */
+ public String getOrDefault(String key, String def) {
+ String val = get(key);
+ return val == null ? def : val;
+ }
+
+ /**
+ * Returns integer value from config corresponding to the given
+ * key, or the default integer if the key is missing or invalid.
+ *
+ * @return value corresponding to the given key, or the default value
+ */
+ public int getOrDefault(String key, int def) {
+ try {
+ return Integer.parseInt(get(key));
+ } catch (Exception e) {
+ return def;
+ }
+ }
+
+ /**
+ * Returns boolean value from config corresponding to the given
+ * key, or the default boolean if the key is missing.
+ *
+ * @return value corresponding to the given key, or the default value
+ */
+ public boolean getOrDefault(String key, boolean def) {
+ String val = get(key);
+ if (val != null) {
+ return val.equalsIgnoreCase("true");
+ }
+
+ return def;
+ }
+
+ /**
+ * Returns double value from config corresponding to the given
+ * key, or the default string if the key is missing or invalid.
+ *
+ * @return value corresponding to the given key, or the default value
+ */
+ public double getOrDefault(String key, double def) {
+ try {
+ return Double.parseDouble(get(key));
+ } catch (Exception e) {
+ return def;
+ }
+ }
+
+ /**
+ * If any error occurred during loading or reading from the config
+ * a 'broken' flag is set, indicating that the config's state
+ * is undefined and should be discarded using `delete()`
+ *
+ * @return the 'broken' flag of the configuration
+ */
+ public boolean isBroken() {
+ return broken;
+ }
+
+ /**
+ * deletes the config file from the filesystem
+ *
+ * @return true if the operation was successful
+ */
+ public boolean delete() {
+ LOGGER.warn("Config '{}' was removed from existence! Restart the game to regenerate it.", request.filename);
+ return request.file.delete();
+ }
+
+ public interface DefaultConfig {
+ static String empty(String namespace) {
+ return "";
+ }
+
+ String get(String namespace);
+ }
+
+ public static class ConfigRequest {
+
+ private final File file;
+ private final String filename;
+ private DefaultConfig provider;
+
+ private ConfigRequest(File file, String filename) {
+ this.file = file;
+ this.filename = filename;
+ this.provider = DefaultConfig::empty;
+ }
+
+ /**
+ * Sets the default config provider, used to generate the
+ * config if it's missing.
+ *
+ * @param provider default config provider
+ * @return current config request object
+ * @see DefaultConfig
+ */
+ public ConfigRequest provider(DefaultConfig provider) {
+ this.provider = provider;
+ return this;
+ }
+
+ /**
+ * Loads the config from the filesystem.
+ *
+ * @return config object
+ * @see SimpleConfig
+ */
+ public SimpleConfig request() {
+ return new SimpleConfig(this);
+ }
+
+ private String getConfig() {
+ return provider.get(filename) + "\n";
+ }
+
+ }
} \ No newline at end of file
diff --git a/src/main/java/world/anhgelus/molehunt/game/Game.java b/src/main/java/world/anhgelus/molehunt/game/Game.java
index 4f3234c..35c45fa 100644
--- a/src/main/java/world/anhgelus/molehunt/game/Game.java
+++ b/src/main/java/world/anhgelus/molehunt/game/Game.java
@@ -25,176 +25,176 @@ import java.util.stream.Collectors;
public class Game {
- public final int defaultTime = Molehunt.CONFIG.getGameDuration() * 60;
- private final MinecraftServer server;
- private final List<UUID> moles = new ArrayList<>();
- private final TitleFadeS2CPacket timing = new TitleFadeS2CPacket(20, 40, 20);
- private int remaining = defaultTime;
- private boolean started = false;
-
- public Game(MinecraftServer server) {
- this.server = server;
- }
-
- public void start() {
- final int n = Molehunt.CONFIG.getMoleCount() < 0
- ? Math.floorDiv(server.getCurrentPlayerCount(), Math.floorDiv(100, Molehunt.CONFIG.getMolePercentage()))
- : Molehunt.CONFIG.getMoleCount();
-
- final var playerManager = server.getPlayerManager();
-
- final var players = new ArrayList<>(playerManager.getPlayerList());
- for (int i = 0; i < n && !players.isEmpty(); i++) {
- final var r = ThreadLocalRandom.current().nextInt(0, players.size());
- final var mole = players.get(r);
- if (mole == null) throw new IllegalStateException("Mole is null!");
- moles.add(mole.getUuid());
- players.remove(r);
- }
-
- final var gamerules = server.getOverworld().getGameRules();
- // immutable gamerules
- gamerules.setValue(GameRules.SHOW_DEATH_MESSAGES, false, server);
- gamerules.setValue(GameRules.ANNOUNCE_ADVANCEMENTS, false, server);
- // gamerules for the start
- gamerules.setValue(GameRules.DO_IMMEDIATE_RESPAWN, true, server);
-
- final var timer = TimerAccess.getTimerFromOverworld(server);
-
- final var worldBorder = server.getOverworld().getWorldBorder();
- worldBorder.setSize(Molehunt.CONFIG.getInitialWorldSize());
- if (Molehunt.CONFIG.getBorderShrinkingStartingTimeOffset() < Molehunt.CONFIG.getGameDuration()) {
- timer.dds_runTask(new TickTask(() -> worldBorder.interpolateSize(
- Molehunt.CONFIG.getInitialWorldSize(),
- Molehunt.CONFIG.getFinalWorldSize(),
- (Molehunt.CONFIG.getGameDuration() - Molehunt.CONFIG.getBorderShrinkingStartingTimeOffset()) * 60 * 20L,
- 0L
- ), Molehunt.CONFIG.getBorderShrinkingStartingTimeOffset() * 60 * 20L));
- }
-
- final var title = new TitleS2CPacket(Text.translatable("molehunt.game.start.suspense"));
- playerManager.getPlayerList().forEach(p -> {
- p.getInventory().clear();
- p.kill(p.getEntityWorld());
- p.networkHandler.sendPacket(timing);
- p.networkHandler.sendPacket(title);
- p.changeGameMode(GameMode.SURVIVAL);
- if (Molehunt.CONFIG.foodOnStart()) p.giveItemStack(new ItemStack(Items.COOKED_BEEF, 64));
- });
-
- server.setDefaultGameMode(GameMode.SPECTATOR);
-
- timer.dds_runTask(new TickTask(() -> {
- playerManager.getPlayerList().forEach(p -> {
- p.networkHandler.sendPacket(timing);
- if (moles.contains(p.getUuid())) {
- p.networkHandler.sendPacket(new TitleS2CPacket(Text.translatable("molehunt.game.start.mole.title")));
- p.networkHandler.sendPacket(new SubtitleS2CPacket(Text.translatable("molehunt.game.start.mole.subtitle")));
- } else {
- p.networkHandler.sendPacket(new TitleS2CPacket(Text.translatable("molehunt.game.start.survivor.title")));
- p.networkHandler.sendPacket(new SubtitleS2CPacket(Text.translatable("molehunt.game.start.survivor.subtitle")));
- }
- // reset health and food level
- p.setHealth(p.getMaxHealth());
- p.getHungerManager().setFoodLevel(20);
- p.getHungerManager().setSaturationLevel(5.0f);
- });
- // reset gamerules after the start
- gamerules.setValue(GameRules.DO_IMMEDIATE_RESPAWN, false, server);
- // reset time and weather
- server.getOverworld().setTimeOfDay(0);
- server.getOverworld().resetWeather();
- changeState(true);
- timer.dds_runTask(new TickTask(() -> {
- remaining--;
- playerManager.getPlayerList().forEach(player -> {
- if (Molehunt.timerVisibility.getOrDefault(player.getUuid(), true)) {
- player.networkHandler.sendPacket(new OverlayMessageS2CPacket(Text.of(getRemainingText())));
- }
- });
- playerManager.sendToAll(timing);
- if (remaining == 0) end();
- }, 5 * 20, 20));
- }, 4 * 20));
- }
-
- public void stop() {
- server.getPlayerManager().broadcast(Text.translatable("commands.molehunt.stop.success"), false);
- end();
- }
-
- public void end() {
- final var timer = TimerAccess.getTimerFromOverworld(server);
- timer.dds_cancel();
-
- final var worldBorder = server.getOverworld().getWorldBorder();
- // Stops the border shrinking.
- worldBorder.setSize(worldBorder.getSize());
-
- changeState(false);
- final var pm = server.getPlayerManager();
- final var winnerSuspense = new TitleS2CPacket(Text.translatable("molehunt.game.end.suspense.title"));
- pm.getPlayerList().forEach(p -> {
- p.networkHandler.sendPacket(timing);
- p.networkHandler.sendPacket(winnerSuspense);
- p.changeGameMode(GameMode.CREATIVE);
- });
- timer.dds_runTask(new TickTask(() -> {
- TitleS2CPacket winner;
- if (wonByMoles()) {
- winner = new TitleS2CPacket(Text.translatable("molehunt.game.end.winners.moles.title"));
- } else {
- winner = new TitleS2CPacket(Text.translatable("molehunt.game.end.winners.survivors.title"));
- }
- pm.sendToAll(new SubtitleS2CPacket(Text.translatable("molehunt.game.end.winners.subtitle", getMolesAsString())));
- pm.sendToAll(winner);
- pm.sendToAll(timing);
- moles.clear();
- }, 4 * 20));
- }
-
- public Text getRemainingText() {
- return Text.of("ยงc" + TimeUtils.generateShortString(remaining));
- }
-
- public List<ServerPlayerEntity> getMoles() {
- return moles.stream()
- .map(uuid -> server.getPlayerManager().getPlayer(uuid))
- .filter(Objects::nonNull)
- .filter(p -> !p.isSpectator())
- .toList();
- }
-
- public String getMolesAsString() {
- return getMoles().stream()
- .map(PlayerEntity::getDisplayName)
- .filter(Objects::nonNull)
- .map(Object::toString)
- .collect(Collectors.joining(", "));
- }
-
- public boolean isMole(ServerPlayerEntity player) {
- return moles.contains(player.getUuid());
- }
-
- public boolean wonByMoles() {
- return new HashSet<>(moles).containsAll(
- server.getPlayerManager()
- .getPlayerList()
- .stream()
- .filter(p -> !p.isSpectator() && !p.isCreative())
- .map(Entity::getUuid)
- .toList()
- );
- }
-
- public boolean started() {
- return started;
- }
-
- private void changeState(boolean hasStarted) {
- started = hasStarted;
- final var payload = new GamePayload(hasStarted);
- server.getPlayerManager().getPlayerList().forEach(p -> ServerPlayNetworking.send(p, payload));
- }
+ public final int defaultTime = Molehunt.CONFIG.getGameDuration() * 60;
+ private final MinecraftServer server;
+ private final List<UUID> moles = new ArrayList<>();
+ private final TitleFadeS2CPacket timing = new TitleFadeS2CPacket(20, 40, 20);
+ private int remaining = defaultTime;
+ private boolean started = false;
+
+ public Game(MinecraftServer server) {
+ this.server = server;
+ }
+
+ public void start() {
+ final int n = Molehunt.CONFIG.getMoleCount() < 0
+ ? Math.floorDiv(server.getCurrentPlayerCount(), Math.floorDiv(100, Molehunt.CONFIG.getMolePercentage()))
+ : Molehunt.CONFIG.getMoleCount();
+
+ final var playerManager = server.getPlayerManager();
+
+ final var players = new ArrayList<>(playerManager.getPlayerList());
+ for (int i = 0; i < n && !players.isEmpty(); i++) {
+ final var r = ThreadLocalRandom.current().nextInt(0, players.size());
+ final var mole = players.get(r);
+ if (mole == null) throw new IllegalStateException("Mole is null!");
+ moles.add(mole.getUuid());
+ players.remove(r);
+ }
+
+ final var gamerules = server.getOverworld().getGameRules();
+ // immutable gamerules
+ gamerules.setValue(GameRules.SHOW_DEATH_MESSAGES, false, server);
+ gamerules.setValue(GameRules.ANNOUNCE_ADVANCEMENTS, false, server);
+ // gamerules for the start
+ gamerules.setValue(GameRules.DO_IMMEDIATE_RESPAWN, true, server);
+
+ final var timer = TimerAccess.getTimerFromOverworld(server);
+
+ final var worldBorder = server.getOverworld().getWorldBorder();
+ worldBorder.setSize(Molehunt.CONFIG.getInitialWorldSize());
+ if (Molehunt.CONFIG.getBorderShrinkingStartingTimeOffset() < Molehunt.CONFIG.getGameDuration()) {
+ timer.dds_runTask(new TickTask(() -> worldBorder.interpolateSize(
+ Molehunt.CONFIG.getInitialWorldSize(),
+ Molehunt.CONFIG.getFinalWorldSize(),
+ (Molehunt.CONFIG.getGameDuration() - Molehunt.CONFIG.getBorderShrinkingStartingTimeOffset()) * 60 * 20L,
+ 0L
+ ), Molehunt.CONFIG.getBorderShrinkingStartingTimeOffset() * 60 * 20L));
+ }
+
+ final var title = new TitleS2CPacket(Text.translatable("molehunt.game.start.suspense"));
+ playerManager.getPlayerList().forEach(p -> {
+ p.getInventory().clear();
+ p.kill(p.getEntityWorld());
+ p.networkHandler.sendPacket(timing);
+ p.networkHandler.sendPacket(title);
+ p.changeGameMode(GameMode.SURVIVAL);
+ if (Molehunt.CONFIG.foodOnStart()) p.giveItemStack(new ItemStack(Items.COOKED_BEEF, 64));
+ });
+
+ server.setDefaultGameMode(GameMode.SPECTATOR);
+
+ timer.dds_runTask(new TickTask(() -> {
+ playerManager.getPlayerList().forEach(p -> {
+ p.networkHandler.sendPacket(timing);
+ if (moles.contains(p.getUuid())) {
+ p.networkHandler.sendPacket(new TitleS2CPacket(Text.translatable("molehunt.game.start.mole.title")));
+ p.networkHandler.sendPacket(new SubtitleS2CPacket(Text.translatable("molehunt.game.start.mole.subtitle")));
+ } else {
+ p.networkHandler.sendPacket(new TitleS2CPacket(Text.translatable("molehunt.game.start.survivor.title")));
+ p.networkHandler.sendPacket(new SubtitleS2CPacket(Text.translatable("molehunt.game.start.survivor.subtitle")));
+ }
+ // reset health and food level
+ p.setHealth(p.getMaxHealth());
+ p.getHungerManager().setFoodLevel(20);
+ p.getHungerManager().setSaturationLevel(5.0f);
+ });
+ // reset gamerules after the start
+ gamerules.setValue(GameRules.DO_IMMEDIATE_RESPAWN, false, server);
+ // reset time and weather
+ server.getOverworld().setTimeOfDay(0);
+ server.getOverworld().resetWeather();
+ changeState(true);
+ timer.dds_runTask(new TickTask(() -> {
+ remaining--;
+ playerManager.getPlayerList().forEach(player -> {
+ if (Molehunt.timerVisibility.getOrDefault(player.getUuid(), true)) {
+ player.networkHandler.sendPacket(new OverlayMessageS2CPacket(Text.of(getRemainingText())));
+ }
+ });
+ playerManager.sendToAll(timing);
+ if (remaining == 0) end();
+ }, 5 * 20, 20));
+ }, 4 * 20));
+ }
+
+ public void stop() {
+ server.getPlayerManager().broadcast(Text.translatable("commands.molehunt.stop.success"), false);
+ end();
+ }
+
+ public void end() {
+ final var timer = TimerAccess.getTimerFromOverworld(server);
+ timer.dds_cancel();
+
+ final var worldBorder = server.getOverworld().getWorldBorder();
+ // Stops the border shrinking.
+ worldBorder.setSize(worldBorder.getSize());
+
+ changeState(false);
+ final var pm = server.getPlayerManager();
+ final var winnerSuspense = new TitleS2CPacket(Text.translatable("molehunt.game.end.suspense.title"));
+ pm.getPlayerList().forEach(p -> {
+ p.networkHandler.sendPacket(timing);
+ p.networkHandler.sendPacket(winnerSuspense);
+ p.changeGameMode(GameMode.CREATIVE);
+ });
+ timer.dds_runTask(new TickTask(() -> {
+ TitleS2CPacket winner;
+ if (wonByMoles()) {
+ winner = new TitleS2CPacket(Text.translatable("molehunt.game.end.winners.moles.title"));
+ } else {
+ winner = new TitleS2CPacket(Text.translatable("molehunt.game.end.winners.survivors.title"));
+ }
+ pm.sendToAll(new SubtitleS2CPacket(Text.translatable("molehunt.game.end.winners.subtitle", getMolesAsString())));
+ pm.sendToAll(winner);
+ pm.sendToAll(timing);
+ moles.clear();
+ }, 4 * 20));
+ }
+
+ public Text getRemainingText() {
+ return Text.of("ยงc" + TimeUtils.generateShortString(remaining));
+ }
+
+ public List<ServerPlayerEntity> getMoles() {
+ return moles.stream()
+ .map(uuid -> server.getPlayerManager().getPlayer(uuid))
+ .filter(Objects::nonNull)
+ .filter(p -> !p.isSpectator())
+ .toList();
+ }
+
+ public String getMolesAsString() {
+ return getMoles().stream()
+ .map(PlayerEntity::getDisplayName)
+ .filter(Objects::nonNull)
+ .map(Object::toString)
+ .collect(Collectors.joining(", "));
+ }
+
+ public boolean isMole(ServerPlayerEntity player) {
+ return moles.contains(player.getUuid());
+ }
+
+ public boolean wonByMoles() {
+ return new HashSet<>(moles).containsAll(
+ server.getPlayerManager()
+ .getPlayerList()
+ .stream()
+ .filter(p -> !p.isSpectator() && !p.isCreative())
+ .map(Entity::getUuid)
+ .toList()
+ );
+ }
+
+ public boolean started() {
+ return started;
+ }
+
+ private void changeState(boolean hasStarted) {
+ started = hasStarted;
+ final var payload = new GamePayload(hasStarted);
+ server.getPlayerManager().getPlayerList().forEach(p -> ServerPlayNetworking.send(p, payload));
+ }
}
diff --git a/src/main/java/world/anhgelus/molehunt/game/GamePayload.java b/src/main/java/world/anhgelus/molehunt/game/GamePayload.java
index 66e3209..1532fa9 100644
--- a/src/main/java/world/anhgelus/molehunt/game/GamePayload.java
+++ b/src/main/java/world/anhgelus/molehunt/game/GamePayload.java
@@ -8,16 +8,16 @@ import net.minecraft.util.Identifier;
import world.anhgelus.molehunt.Molehunt;
public record GamePayload(boolean gameLaunched) implements CustomPayload {
- public static final Identifier GAME_PACKET_ID = Identifier.of(Molehunt.MOD_ID, "game");
+ public static final Identifier GAME_PACKET_ID = Identifier.of(Molehunt.MOD_ID, "game");
- public static final CustomPayload.Id<GamePayload> ID = new CustomPayload.Id<>(GAME_PACKET_ID);
- public static final PacketCodec<RegistryByteBuf, GamePayload> CODEC = PacketCodec.tuple(
- PacketCodecs.BOOLEAN, GamePayload::gameLaunched,
- GamePayload::new
- );
+ public static final CustomPayload.Id<GamePayload> ID = new CustomPayload.Id<>(GAME_PACKET_ID);
+ public static final PacketCodec<RegistryByteBuf, GamePayload> CODEC = PacketCodec.tuple(
+ PacketCodecs.BOOLEAN, GamePayload::gameLaunched,
+ GamePayload::new
+ );
- @Override
- public Id<? extends CustomPayload> getId() {
- return ID;
- }
+ @Override
+ public Id<? extends CustomPayload> getId() {
+ return ID;
+ }
}
diff --git a/src/main/java/world/anhgelus/molehunt/mixin/NoJoinLeaveMessage.java b/src/main/java/world/anhgelus/molehunt/mixin/NoJoinLeaveMessage.java
index a82a21e..0dfd624 100644
--- a/src/main/java/world/anhgelus/molehunt/mixin/NoJoinLeaveMessage.java
+++ b/src/main/java/world/anhgelus/molehunt/mixin/NoJoinLeaveMessage.java
@@ -9,10 +9,10 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(PlayerManager.class)
public class NoJoinLeaveMessage {
- @Inject(at = @At("HEAD"), method = "broadcast*", cancellable = true)
- public void broadcastNoJoinLeaveMessage(Text message, boolean overlay, CallbackInfo ci) {
- final var content = message.getContent().toString();
- if (content.startsWith("translation{key='multiplayer.player.joined")) ci.cancel();
- else if (content.startsWith("translation{key='multiplayer.player.left")) ci.cancel();
- }
+ @Inject(at = @At("HEAD"), method = "broadcast*", cancellable = true)
+ public void broadcastNoJoinLeaveMessage(Text message, boolean overlay, CallbackInfo ci) {
+ final var content = message.getContent().toString();
+ if (content.startsWith("translation{key='multiplayer.player.joined")) ci.cancel();
+ else if (content.startsWith("translation{key='multiplayer.player.left")) ci.cancel();
+ }
}
diff --git a/src/main/java/world/anhgelus/molehunt/mixin/NoMsgCommand.java b/src/main/java/world/anhgelus/molehunt/mixin/NoMsgCommand.java
index 2727143..f698f1c 100644
--- a/src/main/java/world/anhgelus/molehunt/mixin/NoMsgCommand.java
+++ b/src/main/java/world/anhgelus/molehunt/mixin/NoMsgCommand.java
@@ -10,8 +10,8 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(MessageCommand.class)
public class NoMsgCommand {
- @Inject(at = @At("HEAD"), method = "register", cancellable = true)
- private static void register(CommandDispatcher<ServerCommandSource> dispatcher, CallbackInfo ci) {
- ci.cancel();
- }
+ @Inject(at = @At("HEAD"), method = "register", cancellable = true)
+ private static void register(CommandDispatcher<ServerCommandSource> dispatcher, CallbackInfo ci) {
+ ci.cancel();
+ }
}
diff --git a/src/main/java/world/anhgelus/molehunt/mixin/NoPortals.java b/src/main/java/world/anhgelus/molehunt/mixin/NoPortals.java
index a71e6d1..2648f25 100644
--- a/src/main/java/world/anhgelus/molehunt/mixin/NoPortals.java
+++ b/src/main/java/world/anhgelus/molehunt/mixin/NoPortals.java
@@ -11,9 +11,9 @@ import world.anhgelus.molehunt.Molehunt;
@Mixin(PortalManager.class)
public class NoPortals {
- @Inject(at = @At("HEAD"), method = "tick", cancellable = true)
- public void disableTick(ServerWorld world, Entity entity, boolean canUsePortals, CallbackInfoReturnable<Boolean> cir) {
- if (Molehunt.CONFIG == null || Molehunt.CONFIG.portalsEnabled()) return;
- cir.setReturnValue(false);
- }
+ @Inject(at = @At("HEAD"), method = "tick", cancellable = true)
+ public void disableTick(ServerWorld world, Entity entity, boolean canUsePortals, CallbackInfoReturnable<Boolean> cir) {
+ if (Molehunt.CONFIG == null || Molehunt.CONFIG.portalsEnabled()) return;
+ cir.setReturnValue(false);
+ }
}
diff --git a/src/main/java/world/anhgelus/molehunt/mixin/WorldTimerAccess.java b/src/main/java/world/anhgelus/molehunt/mixin/WorldTimerAccess.java
index cd8a1b4..1e0ba12 100644
--- a/src/main/java/world/anhgelus/molehunt/mixin/WorldTimerAccess.java
+++ b/src/main/java/world/anhgelus/molehunt/mixin/WorldTimerAccess.java
@@ -14,32 +14,32 @@ import java.util.function.BooleanSupplier;
@Mixin(ServerWorld.class)
public class WorldTimerAccess implements TimerAccess {
- @Unique
- private final List<TickTask> tasks = new ArrayList<>();
-
- @Unique
- private final List<TimerAccess.TickTask> tasksToAdd = new ArrayList<>();
-
- @Inject(method = "tick", at = @At("TAIL"))
- private void onTick(BooleanSupplier shouldKeepTicking, CallbackInfo ci) {
- tasks.stream().filter(TickTask::isRunning).forEach(TickTask::tick);
- tasks.addAll(tasksToAdd);
- tasksToAdd.clear();
- }
-
- @Override
- public void dds_runTask(TimerAccess.TickTask task) {
- tasksToAdd.add(task);
- }
-
- @Override
- public void dds_cancel() {
- tasks.stream().filter(TickTask::isRunning).forEach(TickTask::cancel);
- tasks.clear();
- }
-
- @Override
- public List<TickTask> dds_getTasks() {
- return tasks.stream().filter(TickTask::isRunning).toList();
- }
+ @Unique
+ private final List<TickTask> tasks = new ArrayList<>();
+
+ @Unique
+ private final List<TimerAccess.TickTask> tasksToAdd = new ArrayList<>();
+
+ @Inject(method = "tick", at = @At("TAIL"))
+ private void onTick(BooleanSupplier shouldKeepTicking, CallbackInfo ci) {
+ tasks.stream().filter(TickTask::isRunning).forEach(TickTask::tick);
+ tasks.addAll(tasksToAdd);
+ tasksToAdd.clear();
+ }
+
+ @Override
+ public void dds_runTask(TimerAccess.TickTask task) {
+ tasksToAdd.add(task);
+ }
+
+ @Override
+ public void dds_cancel() {
+ tasks.stream().filter(TickTask::isRunning).forEach(TickTask::cancel);
+ tasks.clear();
+ }
+
+ @Override
+ public List<TickTask> dds_getTasks() {
+ return tasks.stream().filter(TickTask::isRunning).toList();
+ }
} \ No newline at end of file
diff --git a/src/main/java/world/anhgelus/molehunt/timer/TickTask.java b/src/main/java/world/anhgelus/molehunt/timer/TickTask.java
index 8c74b89..1cc83e2 100644
--- a/src/main/java/world/anhgelus/molehunt/timer/TickTask.java
+++ b/src/main/java/world/anhgelus/molehunt/timer/TickTask.java
@@ -4,69 +4,69 @@ package world.anhgelus.molehunt.timer;
* Represents a complete task called each tick
*/
public class TickTask implements TimerAccess.TickTask {
- public final long ticksDelay;
- public final long ticksRepeat;
- public final boolean repeating;
- public final TimerAccess.Task task;
- private boolean cancelled = false;
- private long currentTicking;
+ public final long ticksDelay;
+ public final long ticksRepeat;
+ public final boolean repeating;
+ public final TimerAccess.Task task;
+ private boolean cancelled = false;
+ private long currentTicking;
- /**
- * Create a new repeating TickTask
- *
- * @param task Task to run after the delay or the repeat time
- * @param ticksDelay Delay before the first task's run
- * @param ticksRepeat Repeat each tick (if the repeat is 0, it will repeat each tick, if it is below 0, it will not repeat)
- * @throws IllegalArgumentException if ticksDelay is below 0
- */
- public TickTask(TimerAccess.Task task, long ticksDelay, long ticksRepeat) {
- if (ticksDelay < 0) throw new IllegalArgumentException("Ticks delay must be non-negative");
- this.ticksDelay = ticksDelay;
- this.ticksRepeat = ticksRepeat;
- this.task = task;
- repeating = ticksRepeat >= 0;
- currentTicking = ticksDelay;
- }
+ /**
+ * Create a new repeating TickTask
+ *
+ * @param task Task to run after the delay or the repeat time
+ * @param ticksDelay Delay before the first task's run
+ * @param ticksRepeat Repeat each tick (if the repeat is 0, it will repeat each tick, if it is below 0, it will not repeat)
+ * @throws IllegalArgumentException if ticksDelay is below 0
+ */
+ public TickTask(TimerAccess.Task task, long ticksDelay, long ticksRepeat) {
+ if (ticksDelay < 0) throw new IllegalArgumentException("Ticks delay must be non-negative");
+ this.ticksDelay = ticksDelay;
+ this.ticksRepeat = ticksRepeat;
+ this.task = task;
+ repeating = ticksRepeat >= 0;
+ currentTicking = ticksDelay;
+ }
- /**
- * Create a new delayed TickTask
- *
- * @param task Task to run after the delay or the repeat time
- * @param ticksDelay Delay before the first task's run
- * @throws IllegalArgumentException if ticksDelay or if ticksRepeat is below 0
- */
- public TickTask(TimerAccess.Task task, long ticksDelay) {
- if (ticksDelay < 0) throw new IllegalArgumentException("Ticks delay must be non-negative");
- this.ticksDelay = ticksDelay;
- this.ticksRepeat = -1;
- this.task = task;
- repeating = false;
- currentTicking = ticksDelay;
- }
+ /**
+ * Create a new delayed TickTask
+ *
+ * @param task Task to run after the delay or the repeat time
+ * @param ticksDelay Delay before the first task's run
+ * @throws IllegalArgumentException if ticksDelay or if ticksRepeat is below 0
+ */
+ public TickTask(TimerAccess.Task task, long ticksDelay) {
+ if (ticksDelay < 0) throw new IllegalArgumentException("Ticks delay must be non-negative");
+ this.ticksDelay = ticksDelay;
+ this.ticksRepeat = -1;
+ this.task = task;
+ repeating = false;
+ currentTicking = ticksDelay;
+ }
- public void tick() {
- if (--currentTicking > 0) return;
- task.run();
- if (repeating) {
- currentTicking = ticksRepeat;
- } else {
- cancel();
- }
- }
+ public void tick() {
+ if (--currentTicking > 0) return;
+ task.run();
+ if (repeating) {
+ currentTicking = ticksRepeat;
+ } else {
+ cancel();
+ }
+ }
- public long cancel() {
- if (cancelled) throw new IllegalStateException("Task already cancelled");
- cancelled = true;
- return currentTicking;
- }
+ public long cancel() {
+ if (cancelled) throw new IllegalStateException("Task already cancelled");
+ cancelled = true;
+ return currentTicking;
+ }
- public boolean isRunning() {
- return !cancelled;
- }
+ public boolean isRunning() {
+ return !cancelled;
+ }
- @Override
- public long getTickingBeforeRun() {
- if (cancelled) return -1;
- return currentTicking;
- }
+ @Override
+ public long getTickingBeforeRun() {
+ if (cancelled) return -1;
+ return currentTicking;
+ }
} \ No newline at end of file
diff --git a/src/main/java/world/anhgelus/molehunt/timer/TimerAccess.java b/src/main/java/world/anhgelus/molehunt/timer/TimerAccess.java
index 2e02b12..32ee611 100644
--- a/src/main/java/world/anhgelus/molehunt/timer/TimerAccess.java
+++ b/src/main/java/world/anhgelus/molehunt/timer/TimerAccess.java
@@ -6,60 +6,60 @@ import net.minecraft.world.World;
import java.util.List;
public interface TimerAccess {
- /**
- * Get the timer linked to the overworld
- *
- * @param server Current server
- * @return TimerAccess linked to the overworld
- */
- static TimerAccess getTimerFromOverworld(MinecraftServer server) {
- final var timer = (TimerAccess) server.getWorld(World.OVERWORLD);
- if (timer == null)
- throw new NullPointerException("Impossible to get TimerAccess from the overworld (it is null)");
- return timer;
- }
+ /**
+ * Get the timer linked to the overworld
+ *
+ * @param server Current server
+ * @return TimerAccess linked to the overworld
+ */
+ static TimerAccess getTimerFromOverworld(MinecraftServer server) {
+ final var timer = (TimerAccess) server.getWorld(World.OVERWORLD);
+ if (timer == null)
+ throw new NullPointerException("Impossible to get TimerAccess from the overworld (it is null)");
+ return timer;
+ }
- /**
- * Run a task (called each tick ticked)
- *
- * @param task Task to run
- */
- void dds_runTask(TimerAccess.TickTask task);
+ /**
+ * Run a task (called each tick ticked)
+ *
+ * @param task Task to run
+ */
+ void dds_runTask(TimerAccess.TickTask task);
- void dds_cancel();
+ void dds_cancel();
- /**
- * @return All non-cancelled tasks
- */
- List<TickTask> dds_getTasks();
+ /**
+ * @return All non-cancelled tasks
+ */
+ List<TickTask> dds_getTasks();
- interface TickTask {
- /**
- * Tick the task
- */
- void tick();
+ interface TickTask {
+ /**
+ * Tick the task
+ */
+ void tick();
- /**
- * Cancel the task
- *
- * @return the remaining ticks before the run of the Task
- * @throws IllegalStateException if the task is already cancelled
- */
- long cancel();
+ /**
+ * Cancel the task
+ *
+ * @return the remaining ticks before the run of the Task
+ * @throws IllegalStateException if the task is already cancelled
+ */
+ long cancel();
- boolean isRunning();
+ boolean isRunning();
- /**
- * @return the number of ticks before run of the task (if the task is cancelled, returns -1)
- */
- long getTickingBeforeRun();
- }
+ /**
+ * @return the number of ticks before run of the task (if the task is cancelled, returns -1)
+ */
+ long getTickingBeforeRun();
+ }
- /**
- * Represents a task to run after ticking
- */
- @FunctionalInterface
- interface Task {
- void run();
- }
+ /**
+ * Represents a task to run after ticking
+ */
+ @FunctionalInterface
+ interface Task {
+ void run();
+ }
}
diff --git a/src/main/java/world/anhgelus/molehunt/utils/TimeUtils.java b/src/main/java/world/anhgelus/molehunt/utils/TimeUtils.java
index 2b96606..952f2d2 100644
--- a/src/main/java/world/anhgelus/molehunt/utils/TimeUtils.java
+++ b/src/main/java/world/anhgelus/molehunt/utils/TimeUtils.java
@@ -2,50 +2,51 @@ package world.anhgelus.molehunt.utils;
public class TimeUtils {
- private record Time(long hours, long minutes, long seconds) {}
-
- public static String generateString(long time) {
- final var pt = generateTime(time);
-
- StringBuilder sb = new StringBuilder();
- if (pt.hours != 0) {
- sb.append(pt.hours).append(" hours ");
- }
- if (pt.minutes != 0 || pt.hours != 0) {
- sb.append(pt.minutes).append(" minutes ");
- }
- sb.append(pt.seconds).append(" seconds");
-
- return sb.toString();
- }
-
- public static String generateShortString(long time) {
- final var pt = generateTime(time);
-
- return padLeft(pt.hours) + ":" +
- padLeft(pt.minutes) + ":" +
- padLeft(pt.seconds);
- }
-
- private static Time generateTime(long time) {
- long hours = 0;
- if (time > 3600) {
- hours = Math.floorDiv(time, 3600);
- }
- long minutes = 0;
- if (hours != 0 || time > 60) {
- minutes = Math.floorDiv(time - hours * 3600, 60);
- }
- long seconds = (long) Math.floor(time - hours * 3600 - minutes * 60);
- return new Time(hours, minutes, seconds);
- }
-
- private static String padLeft(long n) {
- if (n < 10 && n != 0) {
- return "0" + Math.round(n);
- } else if (n == 0) {
- return "00";
- }
- return Long.toString(Math.round(n));
- }
+ public static String generateString(long time) {
+ final var pt = generateTime(time);
+
+ StringBuilder sb = new StringBuilder();
+ if (pt.hours != 0) {
+ sb.append(pt.hours).append(" hours ");
+ }
+ if (pt.minutes != 0 || pt.hours != 0) {
+ sb.append(pt.minutes).append(" minutes ");
+ }
+ sb.append(pt.seconds).append(" seconds");
+
+ return sb.toString();
+ }
+
+ public static String generateShortString(long time) {
+ final var pt = generateTime(time);
+
+ return padLeft(pt.hours) + ":" +
+ padLeft(pt.minutes) + ":" +
+ padLeft(pt.seconds);
+ }
+
+ private static Time generateTime(long time) {
+ long hours = 0;
+ if (time > 3600) {
+ hours = Math.floorDiv(time, 3600);
+ }
+ long minutes = 0;
+ if (hours != 0 || time > 60) {
+ minutes = Math.floorDiv(time - hours * 3600, 60);
+ }
+ long seconds = (long) Math.floor(time - hours * 3600 - minutes * 60);
+ return new Time(hours, minutes, seconds);
+ }
+
+ private static String padLeft(long n) {
+ if (n < 10 && n != 0) {
+ return "0" + Math.round(n);
+ } else if (n == 0) {
+ return "00";
+ }
+ return Long.toString(Math.round(n));
+ }
+
+ private record Time(long hours, long minutes, long seconds) {
+ }
}
diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json
index 09a65fe..43d56c8 100644
--- a/src/main/resources/fabric.mod.json
+++ b/src/main/resources/fabric.mod.json
@@ -1,37 +1,36 @@
{
- "schemaVersion": 1,
- "id": "molehunt",
- "version": "${version}",
- "name": "Molehunt",
- "description": "Molehunt mod",
- "authors": [
- "Anhgelus Morhtuuzh"
- ],
- "contact": {},
- "license": "AGPL-3.0",
- "icon": "assets/molehunt/icon.png",
- "environment": "*",
- "entrypoints": {
- "client": [
- "world.anhgelus.molehunt.client.MolehuntClient"
- ],
- "server": [
-
- ],
- "main": [
- "world.anhgelus.molehunt.Molehunt"
- ]
- },
- "mixins": [
- "molehunt.mixins.json",
- {
- "config": "molehunt.client.mixins.json",
- "environment": "client"
- }
- ],
- "depends": {
- "fabricloader": ">=${loader_version}",
- "fabric-api": "*",
- "minecraft": "${minecraft_version}"
- }
+ "schemaVersion": 1,
+ "id": "molehunt",
+ "version": "${version}",
+ "name": "Molehunt",
+ "description": "Molehunt mod",
+ "authors": [
+ "Anhgelus Morhtuuzh"
+ ],
+ "contact": {},
+ "license": "AGPL-3.0",
+ "icon": "assets/molehunt/icon.png",
+ "environment": "*",
+ "entrypoints": {
+ "client": [
+ "world.anhgelus.molehunt.client.MolehuntClient"
+ ],
+ "server": [
+ ],
+ "main": [
+ "world.anhgelus.molehunt.Molehunt"
+ ]
+ },
+ "mixins": [
+ "molehunt.mixins.json",
+ {
+ "config": "molehunt.client.mixins.json",
+ "environment": "client"
+ }
+ ],
+ "depends": {
+ "fabricloader": ">=${loader_version}",
+ "fabric-api": "*",
+ "minecraft": "${minecraft_version}"
+ }
}
diff --git a/src/main/resources/molehunt.mixins.json b/src/main/resources/molehunt.mixins.json
index 2dc5bb9..8013886 100644
--- a/src/main/resources/molehunt.mixins.json
+++ b/src/main/resources/molehunt.mixins.json
@@ -1,15 +1,15 @@
{
- "required": true,
- "minVersion": "0.8",
- "package": "world.anhgelus.molehunt.mixin",
- "compatibilityLevel": "JAVA_21",
- "mixins": [
- "NoJoinLeaveMessage",
- "NoMsgCommand",
- "NoPortals",
- "WorldTimerAccess"
- ],
- "injectors": {
- "defaultRequire": 1
- }
+ "required": true,
+ "minVersion": "0.8",
+ "package": "world.anhgelus.molehunt.mixin",
+ "compatibilityLevel": "JAVA_21",
+ "mixins": [
+ "NoJoinLeaveMessage",
+ "NoMsgCommand",
+ "NoPortals",
+ "WorldTimerAccess"
+ ],
+ "injectors": {
+ "defaultRequire": 1
+ }
}