Compare commits

...

92 commits

Author SHA1 Message Date
cecf687c7e Update README.md 2024-10-15 15:49:05 +09:00
82039dcfd2 Update FAQ.md 2024-10-15 15:35:38 +09:00
8d18405a61 Update Reproducibility.md and Changelog.md 2024-10-15 15:01:07 +09:00
a88d812bb3 Update FAQ.md
Info related to client-config.
2024-10-15 12:02:14 +09:00
6afd7115c2 Minor update to FAQ.md 2024-10-15 11:34:42 +09:00
2e40c403cd Update Reproducibility.md 2024-10-15 11:23:05 +09:00
b9d128a647 Version NeoForge-1.26.0
All checks were successful
Build TurnBasedMC and create Release / check-release-exists (push) Successful in 0s
Build TurnBasedMC and create Release / build-and-create-release (push) Successful in 3m24s
2024-10-15 10:55:03 +09:00
606d5cf575 Minor tweak to action/workflow release build 2024-10-15 10:54:26 +09:00
25e503ddfa Update Changelog.md 2024-10-15 10:52:55 +09:00
3f36931e0e Add new mobs to config list, bump config version 2024-10-15 10:52:22 +09:00
b18b159259 Update README.md 2024-10-14 21:37:40 +09:00
e2f474564d Fix accidental version 1.27, fix client-config 2024-10-14 21:34:47 +09:00
ddcfa9190f Neoforge 21.1.69
TODO:
    Fix client-config not persisting/saving.
    Add new mobs to the list in the server-side config.
2024-10-14 19:27:38 +09:00
ecebdc91fa Update workflow/action 2024-06-15 11:36:06 +09:00
0d79d88474 Change action runner for tags/releases 2024-03-21 16:16:18 +09:00
3f8a12a4ad Change action runner for tags/releases 2024-03-21 13:19:18 +09:00
c0e70007f7 Fix "hover text" info for options in cli conf gui 2024-02-02 13:43:48 +09:00
6c2265f184 Update Changelog.md 2024-02-01 16:55:42 +09:00
3f7c922c5d Add cli opt for music vol affected by master vol 2024-02-01 16:54:34 +09:00
03ea6d3bc9 Update Changelog.md 2024-02-01 16:14:47 +09:00
6b21afdce9 Refactor ClientConfig GUI, reformat file
Also refactor how "minimum silly percentage" is handled (the minimum
percentage of "silly mobs" to play silly music in battle for).
2024-02-01 15:55:58 +09:00
c8066e2550 Fix value formatting for sliders in client config 2024-02-01 14:19:27 +09:00
b0a58384f3 Update README.md 2024-01-31 18:23:50 +09:00
caa90f7fa6 Bump version to 1.26.0 2024-01-31 18:23:26 +09:00
7ba0b7b307 Update Changelog.md 2024-01-31 18:20:57 +09:00
83b7e99cee Impl. GUI to set client config, /tbm-client-edit 2024-01-31 18:18:55 +09:00
c0fddb6955 Allow changing client config in settings
Client config is no longer stored in TBM_Config.toml.
2024-01-31 14:06:23 +09:00
aac4f9b6aa Bump NeoForge version to 20.4.146-beta 2024-01-31 12:03:45 +09:00
18b4fac876 Version 1.25.3 2024-01-31 11:58:13 +09:00
86cbc5e7ba Fix volume handling of battle/silly music 2024-01-31 11:57:52 +09:00
bba99d4e6a Update README.md 2024-01-30 11:14:01 +09:00
356502f722 Action: Check if release exists before releasing 2024-01-22 18:29:29 +09:00
75976c8d9a Enable "any_archLinux" act runner for building jar 2024-01-20 20:01:54 +09:00
62774b0b0c Fix Reproducibility.md
All checks were successful
Build TurnBasedMC and create Release / build-and-create-release (push) Successful in 6m57s
2024-01-17 14:51:42 +09:00
846840c3a7 Update README.md 2024-01-17 14:48:56 +09:00
43bb0c7059 Fix version in main mod class 2024-01-17 14:48:37 +09:00
288ed1cfd6 Update Reproducibility.md
Some checks failed
Build TurnBasedMC and create Release / build-and-create-release (push) Has been cancelled
2024-01-17 14:44:12 +09:00
b8a32a490e Update Changelog.md 2024-01-17 14:43:21 +09:00
ae3cbfe4f6 Bump version to 1.25.2, cleanup of gradle stuff 2024-01-17 14:42:55 +09:00
9a481f95d0 Update Changelog.md 2024-01-17 14:30:19 +09:00
24a29eaba6 Update Reproducibility.md 2024-01-17 14:29:31 +09:00
9fab572800 Fix usage of throwable potions in battle
Add (experimental) "right-click" support for items when "Use" is invoked
on an item in battle.
2024-01-17 14:29:19 +09:00
6f0c223c9d Update FAQ.md 2024-01-17 13:43:24 +09:00
17c39a5329 Update README.md 2024-01-17 13:38:59 +09:00
4879aaefd1 Update README.md 2024-01-17 13:35:09 +09:00
46f8e22c8b Update Changelog.md, Reproducibility.md 2024-01-16 22:20:09 +09:00
54afb08263 Update Reproducibility.md
All checks were successful
Build TurnBasedMC and create Release / build-and-create-release (push) Successful in 5m57s
2024-01-16 17:29:55 +09:00
2616e73407 Update Changelog.md 2024-01-16 17:24:22 +09:00
edc3246bd1 Minor fixes to ItemSelectionButton 2024-01-16 17:10:24 +09:00
b1b8451331 Update .gitignore 2024-01-16 16:58:48 +09:00
f635badfe1 Bump version to 1.25.1 2024-01-16 16:58:39 +09:00
fb2c4cd13c Update code for NeoForge 20.4.108-beta 2024-01-16 16:55:13 +09:00
830f4255bb Update Changelog.md 2024-01-16 14:15:29 +09:00
490518a58a Add "icon" for mod 2024-01-16 14:15:13 +09:00
e3ba1abdae Remove unused mcmod.info file 2024-01-16 14:14:45 +09:00
d564756c42 "Pin" j-ogg-vorbis version 2024-01-11 16:30:58 +09:00
64a7fb263f Tweak to forgejo action/workflow 2024-01-10 11:56:54 +09:00
52b1b5ee05 Minor tweak to FAQ.md 2024-01-09 11:16:06 +09:00
2e71ea97ad Minor fix to build-jar action/workflow 2024-01-08 18:34:00 +09:00
f9178777ee Update README.md 2024-01-08 18:24:39 +09:00
9d4cd5c4e7 Update LICENSE year 2024-01-08 18:20:57 +09:00
85c4588470 Update FAQ.md 2024-01-08 17:31:03 +09:00
7770698947 Update README.md 2024-01-08 17:27:45 +09:00
a3d4ae74ef Add FAQ.md 2024-01-08 17:25:43 +09:00
f56891e1d0 Update Reproducibility.md
All checks were successful
Build TurnBasedMC and create Release / build-and-store-artifact (push) Successful in 8m22s
2024-01-08 15:41:33 +09:00
d58ef1585a Update README.md 2024-01-08 15:37:48 +09:00
2cbad47b33 Update Changelog.md 2024-01-08 15:34:40 +09:00
d57f18d6c2 Add support for ogg-vorbis audio files 2024-01-08 15:19:42 +09:00
c0bbf92efc Bump version, add j-ogg-vorbis dependency
Updated README.md, Reproducibility.md, etc.
2024-01-08 15:19:31 +09:00
5708e46118 Tweak to build jar release action
All checks were successful
Build TurnBasedMC and store Artifact / build-and-store-artifact (push) Successful in 6m4s
2024-01-06 14:57:13 +09:00
edf2d3926d Minor fix to build-jar action 2024-01-06 14:31:29 +09:00
3caf1d31bf Make release on tag with build artifact 2024-01-06 14:23:37 +09:00
01bf977fd6 Change build action to build tags only 2024-01-05 20:28:13 +09:00
75b710c3d4 Re-attempt build jar action
All checks were successful
Build TurnBasedMC and store Artifact / build-and-store-artifact (push) Successful in 5m36s
2024-01-05 20:18:53 +09:00
0c5e823839 Fix builds changing MANIFEST based on project dir 2024-01-05 20:17:39 +09:00
c8e405f685 Remove build action for neoforge for now 2024-01-05 18:43:27 +09:00
29d45ea0f9 Attempt to reduce memory usage on neoforge build
Some checks failed
Build TurnBasedMC and store Artifact / build-and-store-artifact (push) Failing after 3m2s
2024-01-05 17:34:17 +09:00
63fb52e75f Fix artifact name of neoforge build action
Some checks are pending
Build TurnBasedMC and store Artifact / build-and-store-artifact (push) Waiting to run
2024-01-05 16:34:31 +09:00
4881f056f5 Output sha256sum of jars in action 2024-01-05 16:32:18 +09:00
3cc138dd47 Change repo clone dir name in action 2024-01-05 16:32:05 +09:00
8d15bbb593 Add forgejo build action for NeoForge branch
Some checks failed
Build TurnBasedMC and store Artifact / build-and-store-artifact (push) Failing after 20m33s
2024-01-05 15:46:40 +09:00
36b25b7d07 Fix newline for download links list 2024-01-01 12:37:45 +09:00
4801558716 Add modrinth.com link to README.md 2024-01-01 12:35:58 +09:00
69b72cadd8 Update README.md
Remove reference to `shadow` in README.md since jarJar is being used
instead for NeoForge builds.
2023-12-30 16:27:51 +09:00
f245947686 Update Reproducibility.md 2023-12-30 14:01:30 +09:00
08b8c7d412 Update README.md
Reorder `Reproducibility` to be under `Building`.
2023-12-30 13:50:34 +09:00
8e3b028f6c Update Reproducibility.md 2023-12-30 12:35:32 +09:00
7c4d4b6eb8 Update README.md, add Reproducibility.md 2023-12-30 12:24:26 +09:00
02684bfbad Update README.md 2023-12-30 11:58:11 +09:00
b00f500e36 Fix version in mcmod.info 2023-12-29 17:28:09 +09:00
a1de902d69 Update Changelog.md 2023-12-29 17:26:14 +09:00
c9bf87271d Update to NeoForge 20.2.88 2023-12-29 17:20:14 +09:00
49 changed files with 2202 additions and 1028 deletions

View file

@ -0,0 +1,50 @@
name: Build TurnBasedMC and create Release
on:
push:
tags:
- '*'
jobs:
check-release-exists:
runs-on: any_archLinux
outputs:
status: ${{ steps.release_exists_check.outputs.http_code }}
steps:
- name: Check if release already exists
id: release_exists_check
run: |
curl -X GET "https://git.seodisparate.com/api/v1/repos/stephenseo/TurnBasedMinecraftMod/releases/tags/${GITHUB_REF_NAME}" \
-H 'accept: application/json' -o release_check_resp.json 2>/dev/null \
-w '%{http_code}\n' | sed 's/^\([0-9]\+\)/http_code=\1/' >> "$GITHUB_OUTPUT"
build-and-create-release:
needs: check-release-exists
if: ${{ needs.check-release-exists.outputs.status == '404' }}
runs-on: highmem_self
steps:
- run: git clone --depth=1 --no-single-branch https://git.seodisparate.com/stephenseo/TurnBasedMinecraftMod.git TurnBasedMinecraftMod
- run: cd TurnBasedMinecraftMod && git checkout ${GITHUB_REF_NAME}
- run: cd TurnBasedMinecraftMod && sed -i '/org.gradle.jvmargs/s/Xmx[0-9]\+[mMgG]/Xmx1024m/' gradle.properties && echo 'neogradle.subsystems.decompiler.maxThreads=1' >> gradle.properties
- run: cd TurnBasedMinecraftMod && ./gradlew --console=plain build
- run: cd TurnBasedMinecraftMod/build/libs && find . -type f -regex '.*all.jar$' -exec sha256sum '{}' ';' -exec bash -c 'sha256sum {} >> sha256sums.txt' ';' && java --version >> javaVersion.txt && javac --version >> javaVersion.txt
- name: Create release and attach jar
run: |
curl --fail-with-body -X 'POST' \
"https://git.seodisparate.com/api/v1/repos/stephenseo/TurnBasedMinecraftMod/releases" \
-H 'accept: application/json' \
-H "Authorization: token ${GITHUB_TOKEN}" \
-H 'Content-Type: application/json' \
-d "{
\"name\": \"TurnBasedMinecraftMod version ${GITHUB_REF_NAME}\",
\"body\": \"See the [Changelog](https://git.seodisparate.com/stephenseo/TurnBasedMinecraftMod/src/branch/neoforge/Changelog.md)
$(java --version | sed -n '1p;2,$s/^/ /p')
$(javac --version)
$(find TurnBasedMinecraftMod/build/libs -regex '.*all.jar$' -exec sha256sum '{}' ';')\",
\"tag_name\": \"${GITHUB_REF_NAME}\"
}" > response.json \
&& curl --fail-with-body -X 'POST' \
"https://git.seodisparate.com/api/v1/repos/stephenseo/TurnBasedMinecraftMod/releases/$(jq .id < response.json)/assets" \
-H 'accept: application/json' \
-H "Authorization: token ${GITHUB_TOKEN}" \
-H 'Content-Type: multipart/form-data' \
-F "attachment=@$(find TurnBasedMinecraftMod/build/libs -regex '.*all.jar$');type=application/java-archive" > response2.json

1
.gitignore vendored
View file

@ -22,3 +22,4 @@ eclipse
run run
logs/ logs/
runs/

View file

@ -1,5 +1,102 @@
# Upcoming changes # Upcoming changes
# Version Forge-1.26.0
Port to Forge 52.0.21 (Minecraft 1.21.1).
Client-config available via `/tbm-client-edit` (same as NeoForge), but there is
no way to access it via the mod-list (unlike NeoForge). Removed from file
holding server-side config (same as NeoForge).
Add option in client-config to set battle/silly music volume, and an option for
whether or not battle/silly music volume is affected by global music volume
setting and whether or not it is affected by master volume setting.
Proper volume handling (like in the NeoForge branch).
Added Armadillo, Bogged, and Breeze to mob list in config.
# Version NeoForge-1.26.0
Make it possible to open the client-config from the Mod-list GUI.
Port to NeoForge 21.1.69 (Minecraft 1.21.1).
Fix volume handling of battle/silly music. (Previous implementation did not
properly reduce volume based on Minecraft's "music volume" setting.)
Move client-config to NeoForge's configuration.
Add GUI to edit client-config that can be opened with /tbm-client-edit command.
Add option in client-config to set battle/silly music volume, and an option for
whether or not battle/silly music volume is affected by global music volume
setting and whether or not it is affected by master volume setting.
Added Armadillo, Bogged, and Breeze to mob list in config.
# Version NeoForge-1.25.2
Fix invalid use of throwable potions. (Previously, the Player would "drink"
splash/lingering potions when used.) Now, if a splash/lingering potion is
"Use"d in battle, it will be thrown.
Add experimental support for "right-click" of arbitrary items on hotbar when
"Use" is used in battle.
# Version Forge-1.25.2
Fix invalid use of throwable potions. (Previously, the Player would "drink"
splash/lingering potions when used.) Now, if a splash/lingering potion is
"Use"d in battle, it will be thrown.
Add experimental support for "right-click" of arbitrary items on hotbar when
"Use" is used in battle.
# Version Forge-1.25.1
Add icon for mod in Mod list description.
Update for Forge 49.0.19.
Works on Forge Minecraft 1.20.4.
# Version NeoForge-1.25.1
Add icon for mod in Mod list description.
Update for NeoForge 20.4.108-beta.
Works on NeoForge Minecraft 1.20.4.
# Version NeoForge-1.25.0
Add new dependency `j-ogg-vorbis`.
Implement playing Vorbis encoded .ogg files for battle/silly music.
# Version Forge-1.25.0
Remove usage of "shadow jar" in build.gradle, and use jarJar instead.
Add new dependency `j-ogg-vorbis`.
Implement playing Vorbis encoded .ogg files for battle/silly music.
# Version NeoForge-1.24.0
Update to NeoForge 1.20.2-20.2.88.
Allow use of Crossbows in battle (it should behave identically to Bows).
# Version Forge-1.24.0
Update to Forge 1.20.2-48.1.0.
The `master` branch of this repository will track the build for Minecraft Forge.
The `neoforge` branch of this repo. will track the build for NeoForge.
Allow use of Crossbows in battle (it should behave identically to Bows).
# Version 1.23.1 # Version 1.23.1
More robust handling of disallowed Damage Sources in battle (via config). More robust handling of disallowed Damage Sources in battle (via config).

92
FAQ.md Normal file
View file

@ -0,0 +1,92 @@
## How do I use this mod to have turn-based-battle with any mob (including mobs from other mods)?
To have turn-based-battle with a mob, it must have a config entry in the server
config. This can either be done manually or be [done in-game via a
command](https://www.youtube.com/watch?v=MK648OVHddE).
## Is it possible to have a mob's config applied to any mob with a specific name?
Yes, [this video explains this feature](https://www.youtube.com/watch?v=9lBETQFMd3A).
## Can the mod play music while a battle is happening?
Yes, you have to put the music (`.wav`, `.ogg`, or `.mp3`) in
`.minecraft/config/TurnBasedMinecraft/Music/battle` and
`.minecraft/config/TurnBasedMinecraft/Music/silly` . Note that `.wav`, `.ogg`,
and `.mp3` music files are supported, but `.mid` files are disabled due to lack
of volume control with the default Java library api. The config file can be
edited to change what categories of entities trigger what type of music, but
generally "passive" mobs trigger the "silly" music and everything else triggers
"battle" music. Note that the default server config has turn-based-battle
disabled for "passive" mobs.
**Note that while .ogg Vorbis files are supported, .ogg Opus files are NOT
supported.**
**It is recommended to use .ogg Vorbis files instead of .mp3 files.**
One can use FFmpeg to convert music files into .ogg Vorbis:
ffmpeg -i <music_file_to_convert> -map a:0 -c:a libvorbis output.ogg
## Why can't the mod play my mp3 files?
The third-party-library used to load mp3 files seems to have issues with
loading any mp3 file that isn't "barebones". Try removing the metadata of the
mp3 file. I've found that using mp3s without album art embedded in it seems to
work.
**It is recommended to use .ogg Vorbis files instead of .mp3 files.**
## How do I configure battle music?
There is a way to edit client-config that deals with music settings, like what
mob groups trigger battle/silly music and volume. This menu can be opened in two
ways.
- Run the command `/tbm-client-edit` to open the menu.
- Open the Mod list from the options screen, click on TBMM on the left column
and click on "Config". (Note that this way of opening the client-config-gui
is unavailable on Forge, and is only available on NeoForge.)
Note that "Accept" must be clicked on to save the client-config.
## Why do passive mobs don't start turn-based battle?
By default, the `passive` category is set to "ignore turn-based-battle" in the
server config. Use `/tbm-server-edit` to change this. (Click on
`ignore_battle_types` which should be dark-green. A list of "categories" will
appear at the bottom of the text. Click on `passive` to remove the "passive"
category.)
![Screenshot one of two showing how to unset passive category from ignore battle types list](https://seodisparate.com/static/uploads/TBMM_ignore_battle_types_screenshot0.png)
![Screenshot two of two showing how to unset passive category from ignore battle types list](https://seodisparate.com/static/uploads/TBMM_ignore_battle_types_screenshot1.png)
Alternatively, edit the [server config](https://github.com/Stephen-Seo/TurnBasedMinecraftMod/blob/ad78063a16c768f660dd086cba857a3be43a84b2/src/main/resources/assets/com_burnedkirby_turnbasedminecraft/TBM_Config.toml#L46)
and remove "passive" from the ignore\_battle\_types list.
## Why is the mod's config file missing?
The mod needs to be run once to generate the default config file and
directories for battle music. After running it once, you can now close
Minecraft and edit the config found at
`.minecraft/config/TurnBasedMinecraft/TBM_Config.toml` Note that some options
only apply to the server and some only to the client, as specified in the
config. This means that server config must be changed on the server side for it
to take effect (local singleplayer will use all of the local config, but
multiplayer setups will require the server config to be changed on the server
side). [You can edit the server-side config in game via the "/tbm-server-edit"
command](https://youtu.be/9xkbHNWkcIY).
## I updated the mod, but now my config changes are back to default, what happened?
Sometimes, I add new mob entries to the config, and increment the version
number of the config. When the server/client starts, it checks the default
config's version number with the existing config's version number. If the
existing config is determined to be outdated, then it is renamed to a different
name (which usually includes the date/time of when it was renamed), and the new
default config is placed in its place. There is a config option to prevent this
from happening, but it is strongly recommended to not disable this since this
will cause updates to the config to never be placed in the mod's config
directory. If you have changes you want to keep, but the mod renamed the
original config, you will have to edit the `TBM_Config.toml` to have the
changes you want from the renamed older config file.

View file

@ -1,6 +1,6 @@
MIT License MIT License
Copyright (c) 2018-2023 Stephen Seo Copyright (c) 2018-2024 Stephen Seo
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View file

@ -8,9 +8,14 @@ Precompiled jars are available here:
https://seodisparate.com/static/tbm_releases/ https://seodisparate.com/static/tbm_releases/
https://burnedkirby.com/tbmm_downloads/ https://burnedkirby.com/tbmm_downloads/
https://www.curseforge.com/minecraft/mc-mods/turnbasedminecraft/files https://www.curseforge.com/minecraft/mc-mods/turnbasedminecraft/files
https://modrinth.com/mod/turnbasedmc
https://git.seodisparate.com/stephenseo/TurnBasedMinecraftMod/releases
(Once modrinth.com has approved this mod, the modrinth page of this mod will be # Forge or NeoForge
linked here.)
The `forge` branch tracks the version of the mod for Minecraft Forge.
The `neoforge` branch tracks the version of the mod for Minecraft NeoForge.
# What changed in what version # What changed in what version
@ -32,7 +37,9 @@ usually because a new entry has been added, the existing config is renamed to a
a timestamp in the filename of when it was replaced. One can set a config option in the a timestamp in the filename of when it was replaced. One can set a config option in the
config to prevent it being overwritten if necessary. config to prevent it being overwritten if necessary.
Some options in the config file only affect the Server, and some only affect the Client. Some options in the config file only affect the Server, and ~~some only affect the Client~~.
Client config has been moved to a
[separate system provided by NeoForge](https://github.com/Stephen-Seo/TurnBasedMinecraftMod/blob/neoforge/FAQ.md#how-do-i-configure-battle-music).
When playing multiplayer, some configuration of the config on the server may be needed. When playing multiplayer, some configuration of the config on the server may be needed.
# Features # Features
@ -41,14 +48,19 @@ When playing multiplayer, some configuration of the config on the server may be
between them between them
- Supports use of the vanilla Minecraft bow and arrows (have bow selected when - Supports use of the vanilla Minecraft bow and arrows (have bow selected when
in battle) in battle)
- Supports custom battle music to be played when fighting enemies. (They must be - Supports custom battle music to be played when fighting enemies. (They must
placed in `.minecraft/config/TurnBasedMinecraft/Music/battle` or be placed in `.minecraft/config/TurnBasedMinecraft/Music/battle` or
`.minecraft/config/TurnBasedMinecraft/Music/silly`. Client-side config determines `.minecraft/config/TurnBasedMinecraft/Music/silly`. Client-side config
which song plays in battle for the client. only `.wav`, ~~`.mid`~~, and `.mp3` files determines which song plays in battle for the client. only `.wav`,
supported. ~~Only `.mid` files are not affected by volume options (master and ~~`.mid`~~, `.mp3`, and `.ogg` files supported. ~~Only `.mid` files are not
music sliders))~~ Midi file playback has been disabled for now due to lack of volume affected by volume options (master and music sliders))~~ Midi file playback
control issues. MP3 file playback sometimes fails, but seems to work better when the has been disabled for now due to lack of volume control issues. MP3 file
file is as "barebones" as possible (no album art metadata in the file). playback sometimes fails, but seems to work better when the file is as
"barebones" as possible (no album art metadata in the file).
- It is recommended to use `.ogg` files for music.
- Note that ogg Vorbis is supported, and NOT ogg Opus.
- One can convert to ogg Vorbis with ffmpeg like this: `ffmpeg -i
<my_music_file_to_convert> -map a:0 -c:a libvorbis output.ogg`.
- Config allows limiting number of combatants in turn-based battle. - Config allows limiting number of combatants in turn-based battle.
- Config can be modified (server-side) to add entries of mobs from other mods. - Config can be modified (server-side) to add entries of mobs from other mods.
(by default an unknown mob cannot enter turn-based battle, so the config must be (by default an unknown mob cannot enter turn-based battle, so the config must be
@ -61,16 +73,27 @@ configured for them.)
# Building # Building
Simply invoke `./gradlew build` in the mod directory and after some time the Simply invoke `./gradlew build` in the mod directory and after some time the
finished jar will be saved at "build/libs/TurnBasedMinecraft-1.23.1.jar" finished jar will be saved at
`build/libs/TurnBasedMinecraft-NeoForge-1.26.0-all.jar`
# Reproducibility
This mod should support reproducible builds. See `Reproducibility.md` to see
more details.
# Other notes # Other notes
This mod uses [shadow](https://github.com/johnrengelman/shadow) which is This mod uses [j-ogg-vorbis](https://github.com/stephengold/j-ogg-all)
licenced under the [Apache License 2.0](https://github.com/johnrengelman/shadow/blob/master/LICENSE). available from [http://www.j-ogg.de](http://www.j-ogg.de) and copyrighted by
Tor-Einar Jarnbjo.
This mod also uses [JavaMP3](https://github.com/kevinstadler/JavaMP3) This mod also uses [JavaMP3](https://github.com/kevinstadler/JavaMP3)
which is licensed under the [MIT License](https://github.com/kevinstadler/JavaMP3/blob/master/LICENSE). which is licensed under the [MIT License](https://github.com/kevinstadler/JavaMP3/blob/master/LICENSE).
# Frequently Asked Questions
[See the FAQ page.](https://github.com/Stephen-Seo/TurnBasedMinecraftMod/blob/master/FAQ.md)
# Related Videos # Related Videos
[See related videos here](https://burnedkirby.com/posts/tbmm/) [See related videos here](https://burnedkirby.com/posts/tbmm/)

135
Reproducibility.md Normal file
View file

@ -0,0 +1,135 @@
# Reproducibility
Starting with version 1.24.0 of this mod, this file will list what version of
Java was used to compile the jars. In theory, using the same version of Java
should result in an identical jar due to reproducible builds.
## Forge 1.26.0
$ java --version
openjdk 21.0.4 2024-07-16
OpenJDK Runtime Environment (build 21.0.4+7)
OpenJDK 64-Bit Server VM (build 21.0.4+7, mixed mode, sharing)
$ javac --version
javac 21.0.4
$ sha256sum build/libs/TurnBasedMinecraft-Forge-1.26.0-all.jar
9a3bb24fef9348e620ab5bcc120d83e11c5289a046561fb4ef91d0ccade9b271 build/libs/TurnBasedMinecraft-Forge-1.26.0-all.jar
## NeoForge 1.26.0
$ java --version
openjdk 21.0.4 2024-07-16
OpenJDK Runtime Environment (build 21.0.4+7)
OpenJDK 64-Bit Server VM (build 21.0.4+7, mixed mode, sharing)
$ javac --version
javac 21.0.4
$ sha256sum build/libs/TurnBasedMinecraft-NeoForge-1.26.0-all.jar
a13e93df640eb3ce5577521421e760aa5d808d34d5cef9c5415ae7a699173ea9 build/libs/TurnBasedMinecraft-NeoForge-1.26.0-all.jar
## NeoForge 1.25.2
$ java --version
openjdk 17.0.10 2024-01-16
OpenJDK Runtime Environment (build 17.0.10+7)
OpenJDK 64-Bit Server VM (build 17.0.10+7, mixed mode)
$ javac --version
javac 17.0.10
$ sha256sum build/libs/TurnBasedMinecraft-NeoForge-1.25.2-all.jar
c59533059eb322a616f38ab40ccbc7d4d6c1667a651328a4c6eb187fe16d7a6f build/libs/TurnBasedMinecraft-NeoForge-1.25.2-all.jar
## Forge 1.25.2
$ java --version
openjdk 17.0.10 2024-01-16
OpenJDK Runtime Environment (build 17.0.10+7)
OpenJDK 64-Bit Server VM (build 17.0.10+7, mixed mode)
$ javac --version
javac 17.0.10
$ sha256sum build/libs/TurnBasedMinecraft-Forge-1.25.2-all.jar
00bc7958431e161b0a512ce32b41c1a97516b00e109195294ee18d4abf58dc26 build/libs/TurnBasedMinecraft-Forge-1.25.2-all.jar
## Forge 1.25.1
$ java --version
openjdk 17.0.9 2023-10-17
OpenJDK Runtime Environment (build 17.0.9+8)
OpenJDK 64-Bit Server VM (build 17.0.9+8, mixed mode)
$ javac --version
javac 17.0.9
$ sha256sum build/libs/TurnBasedMinecraft-Forge-1.25.1-all.jar
33711947eed8b24fa7fd65d36ecdb6ed78e144af8d7fff6e1bfa304cfe4a1d3d build/libs/TurnBasedMinecraft-Forge-1.25.1-all.jar
## NeoForge 1.25.1
$ java --version
openjdk 17.0.9 2023-10-17
OpenJDK Runtime Environment (build 17.0.9+8)
OpenJDK 64-Bit Server VM (build 17.0.9+8, mixed mode)
$ javac --version
javac 17.0.9
$ sha256sum build/libs/TurnBasedMinecraft-NeoForge-1.25.1-all.jar
b0ec086c356c4d3662dcea4bdd9aeb2b0786e4ef40e061599e81b529746e01ea build/libs/TurnBasedMinecraft-NeoForge-1.25.1-all.jar
## NeoForge 1.25.0
$ java --version
openjdk 17.0.9 2023-10-17
OpenJDK Runtime Environment (build 17.0.9+8)
OpenJDK 64-Bit Server VM (build 17.0.9+8, mixed mode)
$ javac --version
javac 17.0.9
$ sha256sum build/libs/TurnBasedMinecraft-NeoForge-1.25.0-all.jar
0e5eacc8aefd3b1a1c8e6c9657108172934fae2e727547ca7c12f9ff79ce4e8e build/libs/TurnBasedMinecraft-NeoForge-1.25.0-all.jar
## Forge 1.25.0
$ java --version
openjdk 17.0.9 2023-10-17
OpenJDK Runtime Environment (build 17.0.9+8)
OpenJDK 64-Bit Server VM (build 17.0.9+8, mixed mode)
$ javac --version
javac 17.0.9
$ sha256sum build/libs/TurnBasedMinecraft-Forge-1.25.0-all.jar
51ef854552b180df68969f4cec6fdc8716ef519b947948b9e5f4ce9953d00162 build/libs/TurnBasedMinecraft-Forge-1.25.0-all.jar
## NeoForge 1.24.0
$ java --version
openjdk 17.0.9 2023-10-17
OpenJDK Runtime Environment (build 17.0.9+8)
OpenJDK 64-Bit Server VM (build 17.0.9+8, mixed mode)
$ javac --version
javac 17.0.9
$ sha256sum build/libs/TurnBasedMinecraft-NeoForge-1.24.0-all.jar
584935b6e928ad141a55e4d1a21944cebff5152396782085d145bbe34c29286c build/libs/TurnBasedMinecraft-NeoForge-1.24.0-all.jar
## Forge 1.24.0
$ java --version
openjdk 17.0.9 2023-10-17
OpenJDK Runtime Environment (build 17.0.9+8)
OpenJDK 64-Bit Server VM (build 17.0.9+8, mixed mode)
$ javac --version
javac 17.0.9
$ sha256sum build/libs/TurnBasedMinecraft-Forge-1.24.0.jar
e17c370cdf347b053c7f55091afed77564dcd8f419615bd6ca87babe10329c07 build/libs/TurnBasedMinecraft-Forge-1.24.0.jar

View file

@ -1,119 +1,106 @@
plugins { plugins {
id 'eclipse' id 'java-library'
id 'idea'
id 'maven-publish' id 'maven-publish'
id 'net.minecraftforge.gradle' version '[6.0,6.2)' id 'net.neoforged.moddev' version '1.0.20'
id 'com.github.johnrengelman.shadow' version '8.1.1'
} }
version = "1.23.1" tasks.named('wrapper', Wrapper).configure {
group = "com.burnedkirby.TurnBasedMinecraft" // Define wrapper values here so as to not have to always do so when updating gradlew.properties.
archivesBaseName = "TurnBasedMinecraft" // Switching this to Wrapper.DistributionType.ALL will download the full gradle sources that comes with
// documentation attached on cursor hover of gradle classes and methods. However, this comes with increased
// file size for Gradle. If you do switch this to ALL, run the Gradle wrapper task twice afterwards.
// (Verify by checking gradle/wrapper/gradle-wrapper.properties to see if distributionUrl now points to `-all`)
distributionType = Wrapper.DistributionType.BIN
}
java.toolchain.languageVersion = JavaLanguageVersion.of(17) version = mod_version
group = mod_group_id
repositories {
mavenLocal()
flatDir {
dir 'libs'
}
}
base {
archivesName = "TurnBasedMinecraft-NeoForge"
}
// Mojang ships Java 21 to end users starting in 1.20.5, so mods should target Java 21.
java.toolchain.languageVersion = JavaLanguageVersion.of(21)
println('Java: ' + System.getProperty('java.version') + ' JVM: ' + System.getProperty('java.vm.version') + '(' + System.getProperty('java.vendor') + ') Arch: ' + System.getProperty('os.arch')) println('Java: ' + System.getProperty('java.version') + ' JVM: ' + System.getProperty('java.vm.version') + '(' + System.getProperty('java.vendor') + ') Arch: ' + System.getProperty('os.arch'))
minecraft { neoForge {
// The mappings can be changed at any time, and must be in the following format. // Specify the version of NeoForge to use.
// snapshot_YYYYMMDD Snapshot are built nightly. version = project.neo_version
// stable_# Stables are built at the discretion of the MCP team.
// Use non-default mappings at your own risk. they may not always work.
// Simply re-run your setup task after changing the mappings to update your workspace.
mappings channel: mapping_channel, version: mapping_version
// makeObfSourceJar = false // an Srg named sources jar is made by default. uncomment this to disable.
// accessTransformer = file('src/main/resources/META-INF/accesstransformer.cfg') parchment {
mappingsVersion = project.parchment_mappings_version
minecraftVersion = project.parchment_minecraft_version
}
// This property allows configuring Gradle's ProcessResources task(s) to run on IDE output locations before launching the game. // This line is optional. Access Transformers are automatically detected
// It is REQUIRED to be set to true for this template to function. // accessTransformers = project.files('src/main/resources/META-INF/accesstransformer.cfg')
// See https://docs.gradle.org/current/dsl/org.gradle.language.jvm.tasks.ProcessResources.html
copyIdeResources = true
// Default run configurations. // Default run configurations.
// These can be tweaked, removed, or duplicated as needed. // These can be tweaked, removed, or duplicated as needed.
runs { runs {
client { client {
workingDirectory project.file('run') client()
// Recommended logging data for a userdev environment
property 'forge.logging.markers', 'REGISTRIES'
// Recommended logging level for the console
property 'forge.logging.console.level', 'debug'
// Comma-separated list of namespaces to load gametests from. Empty = all namespaces. // Comma-separated list of namespaces to load gametests from. Empty = all namespaces.
property 'forge.enabledGameTestNamespaces', 'TurnBasedMinecraftMod' systemProperty 'neoforge.enabledGameTestNamespaces', project.mod_id
mods {
TurnBasedMinecraftMod {
source sourceSets.main
}
}
} }
server { server {
workingDirectory project.file('run') server()
programArgument '--nogui'
// Recommended logging data for a userdev environment systemProperty 'neoforge.enabledGameTestNamespaces', project.mod_id
property 'forge.logging.markers', 'REGISTRIES'
// Recommended logging level for the console
property 'forge.logging.console.level', 'debug'
// Comma-separated list of namespaces to load gametests from. Empty = all namespaces.
property 'forge.enabledGameTestNamespaces', 'TurnBasedMinecraftMod'
mods {
TurnBasedMinecraftMod {
source sourceSets.main
}
}
} }
// This run config launches GameTestServer and runs all registered gametests, then exits. // This run config launches GameTestServer and runs all registered gametests, then exits.
// By default, the server will crash when no gametests are provided. // By default, the server will crash when no gametests are provided.
// The gametest system is also enabled by default for other run configs under the /test command. // The gametest system is also enabled by default for other run configs under the /test command.
gameTestServer { gameTestServer {
workingDirectory project.file('run') type = "gameTestServer"
systemProperty 'neoforge.enabledGameTestNamespaces', project.mod_id
}
data {
data()
// example of overriding the workingDirectory set in configureEach above, uncomment if you want to use it
// gameDirectory = project.file('run-data')
// Specify the modid for data generation, where to output the resulting resource, and where to look for existing resources.
programArguments.addAll '--mod', project.mod_id, '--all', '--output', file('src/generated/resources/').getAbsolutePath(), '--existing', file('src/main/resources/').getAbsolutePath()
}
// applies to all the run configs above
configureEach {
// Recommended logging data for a userdev environment // Recommended logging data for a userdev environment
// The markers can be added/remove as needed separated by commas. // The markers can be added/remove as needed separated by commas.
// "SCAN": For mods scan. // "SCAN": For mods scan.
// "REGISTRIES": For firing of registry events. // "REGISTRIES": For firing of registry events.
// "REGISTRYDUMP": For getting the contents of all registries. // "REGISTRYDUMP": For getting the contents of all registries.
property 'forge.logging.markers', 'REGISTRIES' systemProperty 'forge.logging.markers', 'REGISTRIES'
// Recommended logging level for the console // Recommended logging level for the console
// You can set various levels here. // You can set various levels here.
// Please read: https://stackoverflow.com/questions/2031163/when-to-use-the-different-log-levels // Please read: https://stackoverflow.com/questions/2031163/when-to-use-the-different-log-levels
property 'forge.logging.console.level', 'debug' logLevel = org.slf4j.event.Level.DEBUG
}
// Comma-separated list of namespaces to load gametests from. Empty = all namespaces. }
property 'forge.enabledGameTestNamespaces', 'TurnBasedMinecraftMod'
mods { mods {
TurnBasedMinecraftMod { // define mod <-> source bindings
source sourceSets.main // these are used to tell the game which sources are for which mod
} // mostly optional in a single mod project
} // but multi mod projects should define one per mod
} "${mod_id}" {
sourceSet(sourceSets.main)
data {
workingDirectory project.file('run')
// Recommended logging data for a userdev environment
property 'forge.logging.markers', 'REGISTRIES'
// Recommended logging level for the console
property 'forge.logging.console.level', 'debug'
args '--mod', 'TurnBasedMinecraftMod', '--all', '--output', file('src/generated/resources/'), '--existing', file('src/main/resources')
mods {
TurnBasedMinecraftMod {
source sourceSets.main
}
}
} }
} }
} }
@ -121,126 +108,118 @@ minecraft {
// Include resources generated by data generators. // Include resources generated by data generators.
sourceSets.main.resources { srcDir 'src/generated/resources' } sourceSets.main.resources { srcDir 'src/generated/resources' }
//repositories { // Sets up a dependency configuration called 'localRuntime'.
// // Put repositories for dependencies here // This configuration should be used instead of 'runtimeOnly' to declare
// // ForgeGradle automatically adds the Forge maven and Maven Central for you // a dependency that will be present for runtime testing but that is
// // "optional", meaning it will not be pulled by dependents of this mod.
// // If you have mod jar dependencies in ./libs, you can declare them as a repository like so:
// // flatDir {
// // dir 'libs'
// // }
// mavenCentral()
// jcenter()
//
// dependencies {
// classpath 'com.github.jengelman.gradle.plugins:shadow:4.0.4'
// }
//}
apply plugin: 'com.github.johnrengelman.shadow'
configurations { configurations {
shade runtimeClasspath.extendsFrom localRuntime
impelmentation.extendsFrom shade
} }
dependencies { dependencies {
// Specify the version of Minecraft to use, If this is any group other then 'net.minecraft' it is assumed // Example optional mod dependency with JEI
// that the dep is a ForgeGradle 'patcher' dependency. And it's patches will be applied. // The JEI API is declared for compile time use, while the full JEI artifact is used at runtime
// The userdev artifact is a special name and will get all sorts of transformations applied to it. // compileOnly "mezz.jei:jei-${mc_version}-common-api:${jei_version}"
minecraft "net.minecraftforge:forge:${minecraft_version}-${forge_version}" // compileOnly "mezz.jei:jei-${mc_version}-neoforge-api:${jei_version}"
// We add the full version to localRuntime, not runtimeOnly, so that we do not publish a dependency on it
// localRuntime "mezz.jei:jei-${mc_version}-neoforge:${jei_version}"
// Real mod deobf dependency examples - these get remapped to your current mappings // Example mod dependency using a mod jar from ./libs with a flat dir repository
// compileOnly fg.deobf("mezz.jei:jei-${mc_version}:${jei_version}:api") // Adds JEI API as a compile dependency // This maps to ./libs/coolmod-${mc_version}-${coolmod_version}.jar
// runtimeOnly fg.deobf("mezz.jei:jei-${mc_version}:${jei_version}") // Adds the full JEI mod as a runtime dependency // The group id is ignored when searching -- in this case, it is "blank"
// implementation fg.deobf("com.tterrag.registrate:Registrate:MC${mc_version}-${registrate_version}") // Adds registrate as a dependency // implementation "blank:coolmod-${mc_version}:${coolmod_version}"
// Examples using mod jars from ./libs // Example mod dependency using a file as dependency
// implementation fg.deobf("blank:coolmod-${mc_version}:${coolmod_version}") // implementation files("libs/coolmod-${mc_version}-${coolmod_version}.jar")
// For more info... // Example project dependency using a sister or child project:
// implementation project(":myproject")
// For more info:
// http://www.gradle.org/docs/current/userguide/artifact_dependencies_tutorial.html // http://www.gradle.org/docs/current/userguide/artifact_dependencies_tutorial.html
// http://www.gradle.org/docs/current/userguide/dependency_management.html // http://www.gradle.org/docs/current/userguide/dependency_management.html
implementation files('libs/javamp3-1.0.3.jar')
shade files('libs/javamp3-1.0.3.jar')
// implementation "net.neoforged:neoforge:${neo_version}"
// implementation files('libs/javamp3-1.0.3.jar')
implementation 'fr.delthas:javamp3:1.0.3'
implementation 'com.github.stephengold:j-ogg-vorbis:1.0.4'
jarJar(implementation("fr.delthas:javamp3")) {
version {
strictly '[1.0.0,2.0.0)'
prefer '1.0.3'
}
}
jarJar(implementation("com.github.stephengold:j-ogg-vorbis")) {
version {
strictly '[1.0.4,2.0.0)'
prefer '1.0.4'
}
}
} }
// This block of code expands all declared replace properties in the specified resource targets. // This block of code expands all declared replace properties in the specified resource targets.
// A missing property will result in an error. Properties are expanded using ${} Groovy notation. // A missing property will result in an error. Properties are expanded using ${} Groovy notation.
// When "copyIdeResources" is enabled, this will also run before the game launches in IDE environments. var generateModMetadata = tasks.register("generateModMetadata", ProcessResources) {
// See https://docs.gradle.org/current/dsl/org.gradle.language.jvm.tasks.ProcessResources.html
tasks.named('processResources', ProcessResources).configure {
var replaceProperties = [ var replaceProperties = [
minecraft_version: minecraft_version, minecraft_version_range: minecraft_version_range, minecraft_version : minecraft_version,
forge_version: forge_version, forge_version_range: forge_version_range, minecraft_version_range: minecraft_version_range,
loader_version_range: loader_version_range, neo_version : neo_version,
mod_id: mod_id, mod_name: mod_name, mod_license: mod_license, mod_version: mod_version, neo_version_range : neo_version_range,
mod_authors: mod_authors, mod_description: mod_description, loader_version_range : loader_version_range,
mod_id : mod_id,
mod_name : mod_name,
mod_license : mod_license,
mod_version : mod_version,
mod_authors : mod_authors,
mod_description : mod_description
] ]
inputs.properties replaceProperties inputs.properties replaceProperties
expand replaceProperties
filesMatching(['META-INF/mods.toml', 'pack.mcmeta']) { from "src/main/templates"
expand replaceProperties + [project: project] into "build/generated/sources/modMetadata"
}
} }
// Include the output of "generateModMetadata" as an input directory for the build
// this works with both building through Gradle and the IDE.
sourceSets.main.resources.srcDir generateModMetadata
// To avoid having to run "generateModMetadata" manually, make it run on every project reload
neoForge.ideSyncTask generateModMetadata
// Example for how to get properties into the manifest for reading by the runtime.. // Example for how to get properties into the manifest for reading by the runtime..
jar { jar {
archiveClassifier = 'slim' archiveClassifier = 'all'
manifest { manifest {
attributes([ attributes([
"Specification-Title": "TurnBasedMinecraftMod", "Specification-Title": "TurnBasedMinecraftMod",
"Specification-Vendor": "TurnBasedMinecraftMod_BK", "Specification-Vendor": "TurnBasedMinecraftMod_BK",
"Specification-Version": "1", // We are version 1 of ourselves "Specification-Version": "1", // We are version 1 of ourselves
"Implementation-Title": project.name, "Implementation-Title": "TurnBasedMinecraftMod",
"Implementation-Version": "${version}", "Implementation-Version": "${version}",
"Implementation-Vendor" :"TurnBasedMinecraftMod_BK", "Implementation-Vendor" :"TurnBasedMinecraftMod_BK",
// Do not place timestamp for the sake of reproducible builds // Do not place timestamp for the sake of reproducible builds
// "Implementation-Timestamp": new Date().format("yyyy-MM-dd'T'HH:mm:ssZ"), // "Implementation-Timestamp": new Date().format("yyyy-MM-dd'T'HH:mm:ssZ"),
// "ContainedDeps": "javamp3-1.0.3.jar"
]) ])
} }
} }
shadowJar {
archiveClassifier = ''
//project.configurations.shadow.setTransitive(true);
configurations = [project.configurations.shade]
relocate 'fr.delthas', 'com.burnedkirby.tbm_repack.fr.delthas'
finalizedBy 'reobfShadowJar'
}
assemble.dependsOn shadowJar
reobf {
shadowJar {} // reobfuscate the shadowed jar
}
// Reproducible Builds // Reproducible Builds
tasks.withType(AbstractArchiveTask).configureEach { tasks.withType(AbstractArchiveTask).configureEach {
preserveFileTimestamps = false preserveFileTimestamps = false
reproducibleFileOrder = true reproducibleFileOrder = true
} }
// Example configuration to allow publishing using the maven-publish task tasks.withType(JavaCompile).configureEach {
// we define a custom artifact that is sourced from the reobfJar output task options.encoding = 'UTF-8' // Use the UTF-8 charset for Java compilation
// and then declare that to be published }
// Note you'll need to add a repository here
//def reobfFile = file("$buildDir/reobfJar/output.jar") // IDEA no longer automatically downloads sources/javadoc jars for dependencies, so we need to explicitly enable the behavior.
//def reobfArtifact = artifacts.add('default', reobfFile) { idea {
// type 'jar' module {
// builtBy 'reobfJar' downloadSources = true
//} downloadJavadoc = true
//publishing { }
// publications { }
// mavenJava(MavenPublication) {
// artifact reobfArtifact
// }
// }
// repositories {
// maven {
// url "file:///${project.projectDir}/mcmodsrepo"
// }
// }
//}

View file

@ -1,38 +1,31 @@
org.gradle.jvmargs=-Xmx4096m # Sets default memory used for gradle commands. Can be overridden by user or command line properties.
org.gradle.jvmargs=-Xmx1G
org.gradle.daemon=false org.gradle.daemon=false
org.gradle.parallel=true
org.gradle.caching=true
org.gradle.configuration-cache=true
## Environment Properties #read more on this at https://github.com/neoforged/ModDevGradle?tab=readme-ov-file#better-minecraft-parameter-names--javadoc-parchment
# you can also find the latest versions at: https://parchmentmc.org/docs/getting-started
parchment_minecraft_version=1.21
parchment_mappings_version=2024.07.28
# Environment Properties
# You can find the latest versions here: https://projects.neoforged.net/neoforged/neoforge
# The Minecraft version must agree with the Neo version to get a valid artifact
minecraft_version=1.21.1
# The Minecraft version must agree with the Forge version to get a valid artifact
minecraft_version=1.20.1
# The Minecraft version range can use any release version of Minecraft as bounds. # The Minecraft version range can use any release version of Minecraft as bounds.
# Snapshots, pre-releases, and release candidates are not guaranteed to sort properly # Snapshots, pre-releases, and release candidates are not guaranteed to sort properly
# as they do not follow standard versioning conventions. # as they do not follow standard versioning conventions.
minecraft_version_range=[1.20.1,1.21) minecraft_version_range=[1.21.1, 1.22)
# The Forge version must agree with the Minecraft version to get a valid artifact
forge_version=47.1.0 # The Neo version must agree with the Minecraft version to get a valid artifact
# The Forge version range can use any version of Forge as bounds or match the loader version range neo_version=21.1.69
forge_version_range=[47,) # The Neo version range can use any version of Neo as bounds
# The loader version range can only use the major version of Forge/FML as bounds neo_version_range=[21.1.0,)
loader_version_range=[47,) # The loader version range can only use the major version of FML as bounds
# The mapping channel to use for mappings. loader_version_range=[4,)
# The default set of supported mapping channels are ["official", "snapshot", "snapshot_nodoc", "stable", "stable_nodoc"].
# Additional mapping channels can be registered through the "channelProviders" extension in a Gradle plugin.
#
# | Channel | Version | |
# |-----------|----------------------|--------------------------------------------------------------------------------|
# | official | MCVersion | Official field/method names from Mojang mapping files |
# | parchment | YYYY.MM.DD-MCVersion | Open community-sourced parameter names and javadocs layered on top of official |
#
# You must be aware of the Mojang license when using the 'official' or 'parchment' mappings.
# See more information here: https://github.com/MinecraftForge/MCPConfig/blob/master/Mojang.md
#
# Parchment is an unofficial project maintained by ParchmentMC, separate from Minecraft Forge.
# Additional setup is needed to use their mappings, see https://parchmentmc.org/docs/getting-started
mapping_channel=official
# The mapping version to query from the mapping channel.
# This must match the format required by the mapping channel.
mapping_version=1.20.1
## Mod Properties ## Mod Properties
@ -44,11 +37,11 @@ mod_name=TurnBasedMinecraftMod
# The license of the mod. Review your options at https://choosealicense.com/. All Rights Reserved is the default. # The license of the mod. Review your options at https://choosealicense.com/. All Rights Reserved is the default.
mod_license=MIT mod_license=MIT
# The mod version. See https://semver.org/ # The mod version. See https://semver.org/
mod_version=1.23.1 mod_version=1.26.0
# The group ID for the mod. It is only important when publishing as an artifact to a Maven repository. # The group ID for the mod. It is only important when publishing as an artifact to a Maven repository.
# This should match the base package used for the mod sources. # This should match the base package used for the mod sources.
# See https://maven.apache.org/guides/mini/guide-naming-conventions.html # See https://maven.apache.org/guides/mini/guide-naming-conventions.html
#mod_group_id=com.example.examplemod mod_group_id=com.burnedkirby.TurnBasedMinecraft
# The authors of the mod. This is a simple text string that is used for display purposes in the mod list. # The authors of the mod. This is a simple text string that is used for display purposes in the mod list.
mod_authors=BurnedKirby a.k.a. Stephen Seo mod_authors=BurnedKirby a.k.a. Stephen Seo
# The description of the mod. This is a simple multiline text string that is used for display purposes in the mod list. # The description of the mod. This is a simple multiline text string that is used for display purposes in the mod list.

Binary file not shown.

View file

@ -1,6 +1,7 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.1.1-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip
networkTimeout=10000 networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists

27
gradlew vendored
View file

@ -15,6 +15,8 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
# #
# SPDX-License-Identifier: Apache-2.0
#
############################################################################## ##############################################################################
# #
@ -55,7 +57,7 @@
# Darwin, MinGW, and NonStop. # Darwin, MinGW, and NonStop.
# #
# (3) This script is generated from the Groovy template # (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project. # within the Gradle project.
# #
# You can find Gradle at https://github.com/gradle/gradle/. # You can find Gradle at https://github.com/gradle/gradle/.
@ -83,7 +85,9 @@ done
# This is normally unused # This is normally unused
# shellcheck disable=SC2034 # shellcheck disable=SC2034
APP_BASE_NAME=${0##*/} APP_BASE_NAME=${0##*/}
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s
' "$PWD" ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value. # Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum MAX_FD=maximum
@ -130,10 +134,13 @@ location of your Java installation."
fi fi
else else
JAVACMD=java JAVACMD=java
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. if ! command -v java >/dev/null 2>&1
then
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the Please set the JAVA_HOME variable in your environment to match the
location of your Java installation." location of your Java installation."
fi
fi fi
# Increase the maximum file descriptors if we can. # Increase the maximum file descriptors if we can.
@ -141,7 +148,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #( case $MAX_FD in #(
max*) max*)
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC3045 # shellcheck disable=SC2039,SC3045
MAX_FD=$( ulimit -H -n ) || MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit" warn "Could not query maximum file descriptor limit"
esac esac
@ -149,7 +156,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
'' | soft) :;; #( '' | soft) :;; #(
*) *)
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC3045 # shellcheck disable=SC2039,SC3045
ulimit -n "$MAX_FD" || ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD" warn "Could not set maximum file descriptor limit to $MAX_FD"
esac esac
@ -198,11 +205,11 @@ fi
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Collect all arguments for the java command; # Collect all arguments for the java command:
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of # * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
# shell script including quotes and variable substitutions, so put them in # and any embedded shellness will be escaped.
# double quotes to make sure that they get re-expanded; and # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
# * put everything else in single quotes, so that it's not re-expanded. # treated as '${Hostname}' itself on the command line.
set -- \ set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \ "-Dorg.gradle.appname=$APP_BASE_NAME" \

22
gradlew.bat vendored
View file

@ -13,6 +13,8 @@
@rem See the License for the specific language governing permissions and @rem See the License for the specific language governing permissions and
@rem limitations under the License. @rem limitations under the License.
@rem @rem
@rem SPDX-License-Identifier: Apache-2.0
@rem
@if "%DEBUG%"=="" @echo off @if "%DEBUG%"=="" @echo off
@rem ########################################################################## @rem ##########################################################################
@ -43,11 +45,11 @@ set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1 %JAVA_EXE% -version >NUL 2>&1
if %ERRORLEVEL% equ 0 goto execute if %ERRORLEVEL% equ 0 goto execute
echo. echo. 1>&2
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
echo. echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. echo location of your Java installation. 1>&2
goto fail goto fail
@ -57,11 +59,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute if exist "%JAVA_EXE%" goto execute
echo. echo. 1>&2
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
echo. echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. echo location of your Java installation. 1>&2
goto fail goto fail

View file

@ -1,9 +1,9 @@
pluginManagement { pluginManagement {
repositories { repositories {
mavenLocal()
gradlePluginPortal() gradlePluginPortal()
maven { maven {
name = 'MinecraftForge' url = 'https://maven.neoforged.net/releases'
url = 'https://maven.minecraftforge.net/'
} }
jcenter() jcenter()
mavenCentral() mavenCentral()
@ -11,5 +11,5 @@ pluginManagement {
} }
plugins { plugins {
id 'org.gradle.toolchains.foojay-resolver-convention' version '0.5.0' id 'org.gradle.toolchains.foojay-resolver-convention' version '0.8.0'
} }

View file

@ -5,13 +5,13 @@ import com.burnedkirby.TurnBasedMinecraft.common.Combatant;
import com.burnedkirby.TurnBasedMinecraft.common.Config; import com.burnedkirby.TurnBasedMinecraft.common.Config;
import com.burnedkirby.TurnBasedMinecraft.common.TurnBasedMinecraftMod; import com.burnedkirby.TurnBasedMinecraft.common.TurnBasedMinecraftMod;
import com.burnedkirby.TurnBasedMinecraft.common.networking.PacketBattleDecision; import com.burnedkirby.TurnBasedMinecraft.common.networking.PacketBattleDecision;
import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.gui.components.AbstractButton; import net.minecraft.client.gui.components.AbstractButton;
import net.minecraft.client.gui.components.Button; import net.minecraft.client.gui.components.Button;
import net.minecraft.client.gui.screens.Screen; import net.minecraft.client.gui.screens.Screen;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.neoforged.neoforge.network.PacketDistributor;
import java.util.ConcurrentModificationException; import java.util.ConcurrentModificationException;
import java.util.HashMap; import java.util.HashMap;
@ -150,11 +150,11 @@ public class BattleGui extends Screen {
.getSideAEntrySet()) { .getSideAEntrySet()) {
if (e.getValue().entity != null) { if (e.getValue().entity != null) {
addRenderableWidget(new EntitySelectionButton(width / 4 - 60, y, 120, 20, e.getValue().entity.getDisplayName(), e.getKey(), true, (button) -> { addRenderableWidget(new EntitySelectionButton(width / 4 - 60, y, 120, 20, e.getValue().entity.getDisplayName(), e.getKey(), true, (button) -> {
buttonActionEvent(button, ButtonAction.ATTACK_TARGET); entityButtonActionEvent(button, ButtonAction.ATTACK_TARGET);
})); }));
} else { } else {
addRenderableWidget(new EntitySelectionButton(width / 4 - 60, y, 120, 20, "Unknown", e.getKey(), true, (button) -> { addRenderableWidget(new EntitySelectionButton(width / 4 - 60, y, 120, 20, "Unknown", e.getKey(), true, (button) -> {
buttonActionEvent(button, ButtonAction.ATTACK_TARGET); entityButtonActionEvent(button, ButtonAction.ATTACK_TARGET);
})); }));
} }
y += 20; y += 20;
@ -168,11 +168,11 @@ public class BattleGui extends Screen {
.getSideBEntrySet()) { .getSideBEntrySet()) {
if (e.getValue().entity != null) { if (e.getValue().entity != null) {
addRenderableWidget(new EntitySelectionButton(width * 3 / 4 - 60, y, 120, 20, e.getValue().entity.getDisplayName(), e.getKey(), false, (button) -> { addRenderableWidget(new EntitySelectionButton(width * 3 / 4 - 60, y, 120, 20, e.getValue().entity.getDisplayName(), e.getKey(), false, (button) -> {
buttonActionEvent(button, ButtonAction.ATTACK_TARGET); entityButtonActionEvent(button, ButtonAction.ATTACK_TARGET);
})); }));
} else { } else {
addRenderableWidget(new EntitySelectionButton(width * 3 / 4 - 60, y, 120, 20, "Unknown", e.getKey(), false, (button) -> { addRenderableWidget(new EntitySelectionButton(width * 3 / 4 - 60, y, 120, 20, "Unknown", e.getKey(), false, (button) -> {
buttonActionEvent(button, ButtonAction.ATTACK_TARGET); entityButtonActionEvent(button, ButtonAction.ATTACK_TARGET);
})); }));
} }
y += 20; y += 20;
@ -202,8 +202,8 @@ public class BattleGui extends Screen {
case SWITCH_ITEM: case SWITCH_ITEM:
info = "To which item will you switch to?"; info = "To which item will you switch to?";
for (int i = 0; i < 9; ++i) { for (int i = 0; i < 9; ++i) {
addRenderableWidget(new ItemSelectionButton(width / 2 - 88 + i * 20, height - 19, 16, 16, "", i, (button) -> { addRenderableWidget(new ItemSelectionButton(width / 2 - 88 + i * 20, height - 19, 16, 16, i, (button) -> {
buttonActionEvent(button, ButtonAction.DO_ITEM_SWITCH); itemButtonActionEvent(button, ButtonAction.DO_ITEM_SWITCH);
})); }));
} }
addRenderableWidget(Button.builder(Component.literal("Cancel"), (button) -> { addRenderableWidget(Button.builder(Component.literal("Cancel"), (button) -> {
@ -213,8 +213,8 @@ public class BattleGui extends Screen {
case USE_ITEM: case USE_ITEM:
info = "Which item will you use?"; info = "Which item will you use?";
for (int i = 0; i < 9; ++i) { for (int i = 0; i < 9; ++i) {
addRenderableWidget(new ItemSelectionButton(width / 2 - 88 + i * 20, height - 19, 16, 16, "", i, (button) -> { addRenderableWidget(new ItemSelectionButton(width / 2 - 88 + i * 20, height - 19, 16, 16, i, (button) -> {
buttonActionEvent(button, ButtonAction.DO_USE_ITEM); itemButtonActionEvent(button, ButtonAction.DO_USE_ITEM);
})); }));
} }
addRenderableWidget(Button.builder(Component.literal("Cancel"), (button) -> { addRenderableWidget(Button.builder(Component.literal("Cancel"), (button) -> {
@ -275,27 +275,21 @@ public class BattleGui extends Screen {
setState(MenuState.ATTACK_TARGET); setState(MenuState.ATTACK_TARGET);
break; break;
case DEFEND: case DEFEND:
TurnBasedMinecraftMod.getHandler().sendToServer(new PacketBattleDecision( PacketDistributor.sendToServer(new PacketBattleDecision(
TurnBasedMinecraftMod.proxy.getLocalBattle().getId(), Battle.Decision.DEFEND, 0)); TurnBasedMinecraftMod.proxy.getLocalBattle().getId(), Battle.Decision.DEFEND.getValue(), 0));
setState(MenuState.WAITING); setState(MenuState.WAITING);
break; break;
case ITEM: case ITEM:
setState(MenuState.ITEM_ACTION); setState(MenuState.ITEM_ACTION);
break; break;
case FLEE: case FLEE:
TurnBasedMinecraftMod.getHandler().sendToServer(new PacketBattleDecision( PacketDistributor.sendToServer(new PacketBattleDecision(
TurnBasedMinecraftMod.proxy.getLocalBattle().getId(), Battle.Decision.FLEE, 0)); TurnBasedMinecraftMod.proxy.getLocalBattle().getId(), Battle.Decision.FLEE.getValue(), 0));
setState(MenuState.WAITING); setState(MenuState.WAITING);
break; break;
case ATTACK_TARGET: case ATTACK_TARGET:
if (button instanceof EntitySelectionButton) { // Invalid, but set menu to main menu anyways.
TurnBasedMinecraftMod.getHandler()
.sendToServer(new PacketBattleDecision(TurnBasedMinecraftMod.proxy.getLocalBattle().getId(),
Battle.Decision.ATTACK, ((EntitySelectionButton) button).getID()));
setState(MenuState.WAITING);
} else {
setState(MenuState.MAIN_MENU); setState(MenuState.MAIN_MENU);
}
break; break;
case SWITCH_HELD_ITEM: case SWITCH_HELD_ITEM:
setState(MenuState.SWITCH_ITEM); setState(MenuState.SWITCH_ITEM);
@ -307,27 +301,46 @@ public class BattleGui extends Screen {
setState(MenuState.MAIN_MENU); setState(MenuState.MAIN_MENU);
break; break;
case DO_ITEM_SWITCH: case DO_ITEM_SWITCH:
if (button instanceof ItemSelectionButton) { // Invalid, but set menu to main menu anyways.
TurnBasedMinecraftMod.getHandler()
.sendToServer(new PacketBattleDecision(TurnBasedMinecraftMod.proxy.getLocalBattle().getId(),
Battle.Decision.SWITCH_ITEM, ((ItemSelectionButton) button).getID()));
if (((ItemSelectionButton) button).getID() >= 0 && ((ItemSelectionButton) button).getID() < 9) {
Minecraft.getInstance().player.getInventory().selected = ((ItemSelectionButton) button).getID();
}
setState(MenuState.WAITING);
} else {
setState(MenuState.MAIN_MENU); setState(MenuState.MAIN_MENU);
}
break; break;
case DO_USE_ITEM: case DO_USE_ITEM:
if (button instanceof ItemSelectionButton) { // Invalid, but set menu to main menu anyways.
TurnBasedMinecraftMod.getHandler() setState(MenuState.MAIN_MENU);
.sendToServer(new PacketBattleDecision(TurnBasedMinecraftMod.proxy.getLocalBattle().getId(), break;
Battle.Decision.USE_ITEM, ((ItemSelectionButton) button).getID())); }
}
protected void entityButtonActionEvent(EntitySelectionButton button, ButtonAction action) {
if (action.equals(ButtonAction.ATTACK_TARGET)) {
PacketDistributor.sendToServer(
new PacketBattleDecision(TurnBasedMinecraftMod.proxy.getLocalBattle().getId(),
Battle.Decision.ATTACK.getValue(), ((EntitySelectionButton) button).getID()));
setState(MenuState.WAITING); setState(MenuState.WAITING);
} else { } else {
setState(MenuState.MAIN_MENU); setState(MenuState.MAIN_MENU);
} }
}
protected void itemButtonActionEvent(ItemSelectionButton button, ButtonAction action) {
switch (action) {
case DO_ITEM_SWITCH:
PacketDistributor.sendToServer(
new PacketBattleDecision(TurnBasedMinecraftMod.proxy.getLocalBattle().getId(),
Battle.Decision.SWITCH_ITEM.getValue(), button.getID()));
if (button.getID() >= 0 && button.getID() < 9) {
Minecraft.getInstance().player.getInventory().selected = button.getID();
}
setState(MenuState.WAITING);
break;
case DO_USE_ITEM:
PacketDistributor.sendToServer(
new PacketBattleDecision(TurnBasedMinecraftMod.proxy.getLocalBattle().getId(),
Battle.Decision.USE_ITEM.getValue(), button.getID()));
setState(MenuState.WAITING);
break;
default:
setState(MenuState.MAIN_MENU);
break; break;
} }
} }
@ -368,4 +381,9 @@ public class BattleGui extends Screen {
public void setTurnTimerMax(int timerMax) { public void setTurnTimerMax(int timerMax) {
this.timerMax = timerMax; this.timerMax = timerMax;
} }
@Override
public void renderBackground(GuiGraphics p_283688_, int p_296369_, int p_296477_, float p_294317_) {
// Prevent graying of background.
}
} }

View file

@ -1,6 +1,7 @@
package com.burnedkirby.TurnBasedMinecraft.client; package com.burnedkirby.TurnBasedMinecraft.client;
import com.burnedkirby.TurnBasedMinecraft.common.TurnBasedMinecraftMod; import com.burnedkirby.TurnBasedMinecraft.common.TurnBasedMinecraftMod;
import de.jarnbjo.vorbis.VorbisAudioFileReader;
import fr.delthas.javamp3.Sound; import fr.delthas.javamp3.Sound;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
@ -28,7 +29,9 @@ public class BattleMusic
private boolean playingIsSilly; private boolean playingIsSilly;
private boolean isPlaying; private boolean isPlaying;
private Thread mp3StreamThread; private Thread mp3StreamThread;
private Thread oggVorbisStreamThread;
private MP3Streamer mp3StreamRunnable; private MP3Streamer mp3StreamRunnable;
private OGGVorbisStreamer oggVorbisStreamRunnable;
public BattleMusic(Logger logger) public BattleMusic(Logger logger)
{ {
@ -81,7 +84,7 @@ public class BattleMusic
} }
String ext = name.substring(extIndex + 1).toLowerCase(); String ext = name.substring(extIndex + 1).toLowerCase();
// return ext.equals("mid") || ext.equals("wav") || ext.equals("mp3"); // return ext.equals("mid") || ext.equals("wav") || ext.equals("mp3");
return ext.equals("wav") || ext.equals("mp3"); // midi disabled return ext.equals("wav") || ext.equals("mp3") || ext.equals("ogg"); // midi disabled
} }
}); });
for(File f : battleFiles) for(File f : battleFiles)
@ -101,7 +104,7 @@ public class BattleMusic
} }
String ext = name.substring(extIndex + 1).toLowerCase(); String ext = name.substring(extIndex + 1).toLowerCase();
// return ext.equals("mid") || ext.equals("wav") || ext.equals("mp3"); // return ext.equals("mid") || ext.equals("wav") || ext.equals("mp3");
return ext.equals("wav") || ext.equals("mp3"); // midi disabled return ext.equals("wav") || ext.equals("mp3") || ext.equals("ogg"); // midi disabled
} }
}); });
for(File f : sillyFiles) for(File f : sillyFiles)
@ -256,7 +259,7 @@ public class BattleMusic
// set volume // set volume
FloatControl gainControl = (FloatControl) clip.getControl(FloatControl.Type.MASTER_GAIN); FloatControl gainControl = (FloatControl) clip.getControl(FloatControl.Type.MASTER_GAIN);
gainControl.setValue(volume * 20.0f - 20.0f); // in decibels gainControl.setValue(BattleMusic.percentageToDecibels(volume));
clip.loop(Clip.LOOP_CONTINUOUSLY); clip.loop(Clip.LOOP_CONTINUOUSLY);
clip.start(); clip.start();
@ -303,6 +306,39 @@ public class BattleMusic
return; return;
} }
} }
else if (suffix.equals("ogg")) {
if(sequencer != null && sequencer.isRunning())
{
sequencer.stop();
}
if(clip != null && clip.isActive())
{
clip.stop();
clip.close();
}
if(mp3StreamThread != null && mp3StreamThread.isAlive())
{
mp3StreamRunnable.setKeepPlaying(false);
try { mp3StreamThread.join(); } catch (Throwable t) { /* ignored */ }
}
try {
if (oggVorbisStreamRunnable == null) {
oggVorbisStreamRunnable = new OGGVorbisStreamer(next, logger, volume);
} else {
oggVorbisStreamRunnable.setOggVorbisFile(next);
oggVorbisStreamRunnable.setVolume(volume);
}
oggVorbisStreamThread = new Thread(oggVorbisStreamRunnable);
oggVorbisStreamThread.start();
logger.info("Started playing OggVorbis " + next.getName());
} catch (Throwable t) {
logger.error("Failed to play battle music (ogg)");
t.printStackTrace();
return;
}
}
} }
} }
@ -320,6 +356,10 @@ public class BattleMusic
mp3StreamRunnable.setKeepPlaying(false); mp3StreamRunnable.setKeepPlaying(false);
try { mp3StreamThread.join(); } catch (Throwable t) { /* ignored */ } try { mp3StreamThread.join(); } catch (Throwable t) { /* ignored */ }
} }
if (oggVorbisStreamThread != null && oggVorbisStreamThread.isAlive()) {
oggVorbisStreamRunnable.setKeepPlaying(false);
try { oggVorbisStreamThread.join(); } catch (Throwable t) { /* ignored */ }
}
if(resumeMCSounds) if(resumeMCSounds)
{ {
Minecraft.getInstance().getSoundManager().resume(); Minecraft.getInstance().getSoundManager().resume();
@ -347,6 +387,17 @@ public class BattleMusic
return !sillyMusic.isEmpty(); return !sillyMusic.isEmpty();
} }
/// Percentage must be between 0 and 1.
public static float percentageToDecibels(float percentage) {
if (percentage > 1.0F) {
return 0.0F;
} else if (percentage <= 0.0F) {
return Float.NEGATIVE_INFINITY;
} else {
return (float) (Math.log10(percentage) * 20.0);
}
}
private class MP3Streamer implements Runnable private class MP3Streamer implements Runnable
{ {
private AtomicBoolean keepPlaying; private AtomicBoolean keepPlaying;
@ -398,7 +449,7 @@ public class BattleMusic
sdl.open(audioFormat); sdl.open(audioFormat);
{ {
FloatControl volumeControl = (FloatControl) sdl.getControl(FloatControl.Type.MASTER_GAIN); FloatControl volumeControl = (FloatControl) sdl.getControl(FloatControl.Type.MASTER_GAIN);
volumeControl.setValue(volume * 20.0f - 20.0f); // in decibels volumeControl.setValue(BattleMusic.percentageToDecibels(volume));
} }
ByteArrayOutputStream baos = new ByteArrayOutputStream(); ByteArrayOutputStream baos = new ByteArrayOutputStream();
@ -454,4 +505,93 @@ public class BattleMusic
} }
} }
} }
private class OGGVorbisStreamer implements Runnable {
private AtomicBoolean keepPlaying;
private File oggVorbisFile;
private Logger logger;
private float volume;
public OGGVorbisStreamer(File oggVorbisFile, Logger logger, float volume) {
keepPlaying = new AtomicBoolean(true);
this.oggVorbisFile = oggVorbisFile;
this.logger = logger;
this.volume = volume;
if (this.volume > 1.0F) {
this.volume = 1.0F;
} else if (this.volume < 0.0F) {
this.volume = 0.0F;
}
}
public void setKeepPlaying(boolean playing) {
keepPlaying.set(playing);
}
public void setOggVorbisFile(File oggVorbisFile) {
this.oggVorbisFile = oggVorbisFile;
}
public void setVolume(float volume) {
this.volume = volume;
}
@Override
public void run() {
keepPlaying.set(true);
SourceDataLine sdl = null;
try {
VorbisAudioFileReader reader = new VorbisAudioFileReader();
AudioFormat audioFormat = reader.getAudioFileFormat(oggVorbisFile).getFormat();
sdl = AudioSystem.getSourceDataLine(audioFormat);
sdl.open(audioFormat);
{
FloatControl volumeControl = (FloatControl) sdl.getControl(FloatControl.Type.MASTER_GAIN);
volumeControl.setValue(BattleMusic.percentageToDecibels(volume));
}
AudioInputStream ais = reader.getAudioInputStream(oggVorbisFile);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] cached = null;
int cachedOffset = 0;
int cachedSize = 0;
byte[] buf = new byte[4096];
sdl.start();
int read = ais.read(buf);
while (keepPlaying.get()) {
if (baos != null) {
if (read != -1) {
sdl.write(buf, 0, read);
baos.write(buf, 0, read);
read = ais.read(buf);
} else {
ais.close();
ais = null;
cached = baos.toByteArray();
baos = null;
}
} else {
cachedSize = cached.length - cachedOffset;
if (cachedSize > 4096) {
cachedSize = 4096;
}
sdl.write(cached, cachedOffset, cachedSize);
cachedOffset += cachedSize;
if (cachedOffset >= cached.length) {
cachedOffset = 0;
}
}
}
} catch (Throwable t) {
logger.error("Stream play oggVorbis", t);
}
if (sdl != null) {
sdl.stop();
sdl.flush();
sdl.close();
}
}
}
} }

View file

@ -0,0 +1,68 @@
package com.burnedkirby.TurnBasedMinecraft.client;
import com.burnedkirby.TurnBasedMinecraft.common.TurnBasedMinecraftMod;
import net.neoforged.neoforge.common.ModConfigSpec;
import org.apache.commons.lang3.tuple.Pair;
import java.util.ArrayList;
import java.util.List;
public class ClientConfig {
public static final ClientConfig CLIENT;
public static final ModConfigSpec CLIENT_SPEC;
static {
Pair<ClientConfig, ModConfigSpec> pair =
new ModConfigSpec.Builder().configure(ClientConfig::new);
CLIENT = pair.getKey();
CLIENT_SPEC = pair.getValue();
}
public final ModConfigSpec.ConfigValue<List<? extends String>> battleMusicList;
public final ModConfigSpec.ConfigValue<List<? extends String>> sillyMusicList;
public final ModConfigSpec.DoubleValue sillyMusicThreshold;
public final ModConfigSpec.BooleanValue volumeAffectedByMasterVolume;
public final ModConfigSpec.BooleanValue volumeAffectedByMusicVolume;
public final ModConfigSpec.DoubleValue musicVolume;
ClientConfig(ModConfigSpec.Builder builder) {
//builder.push("music");
List<String> battleMusicList = new ArrayList<String>(8);
battleMusicList.add("monster");
battleMusicList.add("animal");
battleMusicList.add("boss");
battleMusicList.add("player");
this.battleMusicList = builder.comment("What categories of mobs that play \"battle\" music")
.translation(TurnBasedMinecraftMod.MODID + ".clientconfig.battle_music_list")
.defineList("battleMusicList", battleMusicList, (v) -> v instanceof String);
List<String> sillyMusicList = new ArrayList<String>(4);
sillyMusicList.add("passive");
this.sillyMusicList = builder.comment("What categories of mobs that play \"silly\" music")
.translation(TurnBasedMinecraftMod.MODID + ".clientconfig.silly_music_list")
.defineList("sillyMusicList", sillyMusicList, (v) -> true);
this.sillyMusicThreshold =
builder.comment("Minimum percentage of silly entities in battle to use silly music")
.translation(TurnBasedMinecraftMod.MODID + ".clientconfig.silly_percentage")
.defineInRange("sillyMusicThreshold", 0.4, 0.0, 1.0);
this.volumeAffectedByMasterVolume = builder.comment(
"If \"true\", music volume will be affected by global Master volume setting")
.translation(TurnBasedMinecraftMod.MODID + ".clientconfig.volume_affected_by_master")
.define("volumeAffectedByMasterVolume", true);
this.volumeAffectedByMusicVolume = builder.comment(
"If \"true\", music volume will be affected by global Music volume setting")
.translation(TurnBasedMinecraftMod.MODID + ".clientconfig.volume_affected_by_volume")
.define("volumeAffectedByMusicVolume", true);
this.musicVolume =
builder.comment("Volume of battle/silly music as a percentage between 0.0 and 1.0")
.translation(TurnBasedMinecraftMod.MODID + ".clientconfig.music_volume")
.defineInRange("musicVolume", 0.7, 0.0, 1.0);
//builder.pop();
}
}

View file

@ -0,0 +1,264 @@
package com.burnedkirby.TurnBasedMinecraft.client;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.gui.components.*;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.network.chat.Component;
import net.neoforged.fml.ModContainer;
import java.util.ArrayList;
import java.util.List;
public class ClientConfigGui extends net.minecraft.client.gui.screens.Screen {
private final int widget_height = 20;
private boolean dirtyFlag;
private boolean accepted;
private EditBox battleListEditBox = null;
private EditBox sillyListEditBox = null;
private SliderPercentage sillyMusicThresholdSlider = null;
private Checkbox affectedByMasterVolCheckbox = null;
private Checkbox affectedByMusicVolCheckbox = null;
private SliderPercentage volumeSlider = null;
public ClientConfigGui(ModContainer container, Screen parent) {
super(Component.literal("TurnBasedMC Client Config"));
dirtyFlag = true;
accepted = false;
}
public void onDirty() {
clearWidgets();
// Initialize GUI elements.
int widget_x_offset = 5;
int widget_width = this.width / 2 - widget_x_offset * 2;
int top_offset = 5;
addRenderableWidget(
new StringWidget(this.width / 2 - widget_width + widget_x_offset, top_offset,
widget_width, widget_height, Component.literal("Battle Music Categories"),
font));
if (battleListEditBox == null) {
battleListEditBox =
new EditBox(font, this.width / 2 + widget_x_offset, top_offset, widget_width,
widget_height, Component.literal("Battle Music Categories Edit Box"));
} else {
battleListEditBox.setPosition(this.width / 2 + widget_x_offset, top_offset);
battleListEditBox.setSize(widget_width, widget_height);
}
String tempString = "";
for (String category : ClientConfig.CLIENT.battleMusicList.get()) {
if (tempString.isEmpty()) {
tempString = category;
} else {
tempString += "," + category;
}
}
battleListEditBox.setMaxLength(128);
battleListEditBox.setValue(tempString);
addRenderableWidget(battleListEditBox);
top_offset += widget_height;
addRenderableWidget(
new StringWidget(this.width / 2 - widget_width + widget_x_offset, top_offset,
widget_width, widget_height, Component.literal("Silly Music Categories"),
font));
if (sillyListEditBox == null) {
sillyListEditBox =
new EditBox(font, this.width / 2 + widget_x_offset, top_offset, widget_width,
widget_height, Component.literal("Silly Music Categories Edit Box"));
} else {
sillyListEditBox.setPosition(this.width / 2 + widget_x_offset, top_offset);
sillyListEditBox.setSize(widget_width, widget_height);
}
tempString = "";
for (String category : ClientConfig.CLIENT.sillyMusicList.get()) {
if (tempString.isEmpty()) {
tempString = category;
} else {
tempString += "," + category;
}
}
sillyListEditBox.setMaxLength(128);
sillyListEditBox.setValue(tempString);
addRenderableWidget(sillyListEditBox);
top_offset += widget_height;
StringWidget stringWidget =
new StringWidget(this.width / 2 - widget_width + widget_x_offset, top_offset,
widget_width, widget_height, Component.literal("Silly Music Threshold"), font);
stringWidget.setTooltip(Tooltip.create(
Component.literal("Ratio of minimum of silly mobs in battle to play silly music")));
addRenderableWidget(stringWidget);
if (sillyMusicThresholdSlider == null) {
sillyMusicThresholdSlider =
new SliderPercentage(this.width / 2 + widget_x_offset, top_offset, widget_width,
widget_height, Component.literal("Silly Music Threshold: " +
String.format("%.1f%%", ClientConfig.CLIENT.sillyMusicThreshold.get() * 100.0)),
ClientConfig.CLIENT.sillyMusicThreshold.get(), "Silly Music Threshold: ");
} else {
sillyMusicThresholdSlider.setPosition(this.width / 2 + widget_x_offset, top_offset);
sillyMusicThresholdSlider.setSize(widget_width, widget_height);
}
addRenderableWidget(sillyMusicThresholdSlider);
top_offset += widget_height;
stringWidget =
new StringWidget(this.width / 2 - widget_width + widget_x_offset, top_offset,
widget_width, widget_height, Component.literal("Affected by Master Vol."),
font);
stringWidget.setTooltip(Tooltip.create(
Component.literal("If enabled, volume is affected by global master volume.")));
addRenderableWidget(stringWidget);
if (affectedByMasterVolCheckbox == null) {
affectedByMasterVolCheckbox = Checkbox.builder(Component.literal(""), font)
.pos(this.width / 2 + widget_x_offset, top_offset).build();
} else {
affectedByMasterVolCheckbox.setPosition(this.width / 2 + widget_x_offset,
top_offset);
}
if ((ClientConfig.CLIENT.volumeAffectedByMasterVolume.get() &&
!affectedByMasterVolCheckbox.selected()) ||
(!ClientConfig.CLIENT.volumeAffectedByMasterVolume.get() &&
affectedByMasterVolCheckbox.selected())) {
affectedByMasterVolCheckbox.onPress();
}
addRenderableWidget(affectedByMasterVolCheckbox);
top_offset += widget_height;
stringWidget =
new StringWidget(this.width / 2 - widget_width + widget_x_offset, top_offset,
widget_width, widget_height, Component.literal("Affected by Music Vol."), font);
stringWidget.setTooltip(Tooltip.create(
Component.literal("If enabled, volume is affected by global music volume.")));
addRenderableWidget(stringWidget);
if (affectedByMusicVolCheckbox == null) {
affectedByMusicVolCheckbox = Checkbox.builder(Component.literal(""), font)
.pos(this.width / 2 + widget_x_offset, top_offset).build();
} else {
affectedByMusicVolCheckbox.setPosition(this.width / 2 + widget_x_offset,
top_offset);
}
if ((ClientConfig.CLIENT.volumeAffectedByMusicVolume.get() &&
!affectedByMusicVolCheckbox.selected()) ||
(!ClientConfig.CLIENT.volumeAffectedByMusicVolume.get() &&
affectedByMusicVolCheckbox.selected())) {
affectedByMusicVolCheckbox.onPress();
}
addRenderableWidget(affectedByMusicVolCheckbox);
top_offset += widget_height;
stringWidget =
new StringWidget(this.width / 2 - widget_width + widget_x_offset, top_offset,
widget_width, widget_height, Component.literal("Music Volume"), font);
stringWidget.setTooltip(
Tooltip.create(Component.literal("Volume of battle/silly music")));
addRenderableWidget(stringWidget);
if (volumeSlider == null) {
volumeSlider =
new SliderPercentage(this.width / 2 + widget_x_offset, top_offset, widget_width,
widget_height, Component.literal(
"Volume: " + String.format("%.1f%%", ClientConfig.CLIENT.musicVolume.get() * 100.0)),
ClientConfig.CLIENT.musicVolume.get(), "Volume: ");
} else {
volumeSlider.setPosition(this.width / 2 + widget_x_offset, top_offset);
volumeSlider.setSize(widget_width, widget_height);
}
addRenderableWidget(volumeSlider);
addRenderableWidget(Button.builder(Component.literal("Cancel"),
(b) -> Minecraft.getInstance().setScreen(null))
.bounds(this.width / 2 - widget_width + widget_x_offset,
this.height - widget_height, widget_width, widget_height).build());
addRenderableWidget(Button.builder(Component.literal("Accept"), (b) -> {
accepted = true;
}).bounds(this.width / 2 + widget_x_offset, this.height - widget_height, widget_width,
widget_height).build());
dirtyFlag = false;
}
private void doAccepted() {
String temp = battleListEditBox.getValue();
{
List<String> battleList = new ArrayList<String>();
for (String category : temp.split(",")) {
battleList.add(category.strip());
}
ClientConfig.CLIENT.battleMusicList.set(battleList);
}
temp = sillyListEditBox.getValue();
{
List<String> sillyList = new ArrayList<String>();
for (String category : temp.split(",")) {
sillyList.add(category.strip());
}
ClientConfig.CLIENT.sillyMusicList.set(sillyList);
}
ClientConfig.CLIENT.sillyMusicThreshold.set(sillyMusicThresholdSlider.percentage);
ClientConfig.CLIENT.volumeAffectedByMasterVolume.set(affectedByMasterVolCheckbox.selected());
ClientConfig.CLIENT.volumeAffectedByMusicVolume.set(affectedByMusicVolCheckbox.selected());
ClientConfig.CLIENT.musicVolume.set(volumeSlider.percentage);
ClientConfig.CLIENT_SPEC.save();
}
@Override
public boolean isPauseScreen() {
return true;
}
@Override
public void render(GuiGraphics pGuiGraphics, int pMouseX, int pMouseY, float pPartialTick) {
if (accepted) {
doAccepted();
Minecraft.getInstance().setScreen(null);
return;
}
if (dirtyFlag) {
onDirty();
}
super.render(pGuiGraphics, pMouseX, pMouseY, pPartialTick);
}
@Override
public void resize(Minecraft pMinecraft, int pWidth, int pHeight) {
dirtyFlag = true;
super.resize(pMinecraft, pWidth, pHeight);
}
private static class SliderPercentage extends AbstractSliderButton {
private final String messagePrefix;
private double percentage;
public SliderPercentage(int x, int y, int width, int height, Component message, double percentage, String messagePrefix) {
super(x, y, width, height, message, percentage);
this.percentage = percentage;
this.messagePrefix = messagePrefix;
}
@Override
protected void updateMessage() {
setMessage(
Component.literal(messagePrefix + String.format("%.1f%%", percentage * 100.0)));
}
@Override
protected void applyValue() {
percentage = value;
}
}
}

View file

@ -15,9 +15,7 @@ import net.minecraft.resources.ResourceKey;
import net.minecraft.sounds.SoundSource; import net.minecraft.sounds.SoundSource;
import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import net.minecraftforge.network.NetworkEvent; import net.neoforged.neoforge.network.handling.IPayloadContext;
import java.util.function.Supplier;
public class ClientProxy extends CommonProxy { public class ClientProxy extends CommonProxy {
private BattleGui battleGui = null; private BattleGui battleGui = null;
@ -96,13 +94,27 @@ public class ClientProxy extends CommonProxy {
@Override @Override
public void playBattleMusic() { public void playBattleMusic() {
Options gs = Minecraft.getInstance().options; Options gs = Minecraft.getInstance().options;
battleMusic.playBattle(gs.getSoundSourceVolume(SoundSource.MUSIC) * gs.getSoundSourceVolume(SoundSource.MASTER)); float volume = ClientConfig.CLIENT.musicVolume.get().floatValue();
if (ClientConfig.CLIENT.volumeAffectedByMasterVolume.get()) {
volume *= gs.getSoundSourceVolume(SoundSource.MASTER);
}
if (ClientConfig.CLIENT.volumeAffectedByMusicVolume.get()) {
volume *= gs.getSoundSourceVolume(SoundSource.MUSIC);
}
battleMusic.playBattle(volume);
} }
@Override @Override
public void playSillyMusic() { public void playSillyMusic() {
Options gs = Minecraft.getInstance().options; Options gs = Minecraft.getInstance().options;
battleMusic.playSilly(gs.getSoundSourceVolume(SoundSource.MUSIC) * gs.getSoundSourceVolume(SoundSource.MASTER)); float volume = ClientConfig.CLIENT.musicVolume.get().floatValue();
if (ClientConfig.CLIENT.volumeAffectedByMasterVolume.get()) {
volume *= gs.getSoundSourceVolume(SoundSource.MASTER);
}
if (ClientConfig.CLIENT.volumeAffectedByMusicVolume.get()) {
volume *= gs.getSoundSourceVolume(SoundSource.MUSIC);
}
battleMusic.playSilly(volume);
} }
@Override @Override
@ -118,9 +130,9 @@ public class ClientProxy extends CommonProxy {
if (localBattle == null) { if (localBattle == null) {
return; return;
} }
if (type == null || type.isEmpty() || getConfig().isBattleMusicType(type)) { if (type == null || type.isEmpty() || ClientConfig.CLIENT.battleMusicList.get().contains(type)) {
++battleMusicCount; ++battleMusicCount;
} else if (getConfig().isSillyMusicType(type)) { } else if (ClientConfig.CLIENT.sillyMusicList.get().contains(type)) {
++sillyMusicCount; ++sillyMusicCount;
} else { } else {
++battleMusicCount; ++battleMusicCount;
@ -134,9 +146,9 @@ public class ClientProxy extends CommonProxy {
battleMusicCount = 0; battleMusicCount = 0;
sillyMusicCount = 0; sillyMusicCount = 0;
return; return;
} else if (type == null || type.isEmpty() || getConfig().isBattleMusicType(type)) { } else if (type == null || type.isEmpty() || ClientConfig.CLIENT.battleMusicList.get().contains(type)) {
--battleMusicCount; --battleMusicCount;
} else if (getConfig().isSillyMusicType(type)) { } else if (ClientConfig.CLIENT.sillyMusicList.get().contains(type)) {
--sillyMusicCount; --sillyMusicCount;
} else { } else {
--battleMusicCount; --battleMusicCount;
@ -178,16 +190,16 @@ public class ClientProxy extends CommonProxy {
return; return;
} }
float percentage = 0.0f; double percentage = 0.0;
if (sillyMusicCount == 0 && battleMusicCount == 0) { if (sillyMusicCount == 0 && battleMusicCount == 0) {
percentage = 0.0f; percentage = 0.0;
} else if (battleMusicCount == 0) { } else if (battleMusicCount == 0) {
percentage = 100.0f; percentage = 1.0;
} else { } else {
percentage = 100.0f * (float) sillyMusicCount / (float) (sillyMusicCount + battleMusicCount); percentage = (double) sillyMusicCount / (double) (sillyMusicCount + battleMusicCount);
} }
if (percentage >= (float) getConfig().getSillyMusicThreshold()) { if (percentage >= ClientConfig.CLIENT.sillyMusicThreshold.get()) {
if (battleMusic.isPlaying()) { if (battleMusic.isPlaying()) {
if (!battleMusic.isPlayingSilly() && battleMusic.hasSillyMusic()) { if (!battleMusic.isPlayingSilly() && battleMusic.hasSillyMusic()) {
stopMusic(false); stopMusic(false);
@ -224,7 +236,7 @@ public class ClientProxy extends CommonProxy {
} }
@Override @Override
public <MSG> void handlePacket(MSG msg, Supplier<NetworkEvent.Context> ctx) { public <MSG> void handlePacket(final MSG msg, final IPayloadContext ctx) {
if (msg.getClass() == PacketBattleMessage.class) { if (msg.getClass() == PacketBattleMessage.class) {
PacketBattleMessage pkt = (PacketBattleMessage) msg; PacketBattleMessage pkt = (PacketBattleMessage) msg;
Entity fromEntity = getEntity(pkt.getEntityIDFrom(), pkt.getDimension()); Entity fromEntity = getEntity(pkt.getEntityIDFrom(), pkt.getDimension());
@ -435,6 +447,11 @@ public class ClientProxy extends CommonProxy {
parentComponent.getSiblings().add(message); parentComponent.getSiblings().add(message);
TurnBasedMinecraftMod.proxy.displayComponent(parentComponent); TurnBasedMinecraftMod.proxy.displayComponent(parentComponent);
} }
case CROSSBOW_NO_AMMO: {
parentComponent.getSiblings().add(from);
parentComponent.getSiblings().add(Component.literal(" tried to use their crossbow but ran out of ammo!"));
TurnBasedMinecraftMod.proxy.displayComponent(parentComponent);
}
break; break;
} }
} else if (msg.getClass() == PacketGeneralMessage.class) { } else if (msg.getClass() == PacketGeneralMessage.class) {
@ -1456,4 +1473,9 @@ public class ClientProxy extends CommonProxy {
} }
} }
} }
@Override
public void showClientConfigGui() {
Minecraft.getInstance().setScreen(new ClientConfigGui(null, null));
}
} }

View file

@ -1,34 +1,49 @@
package com.burnedkirby.TurnBasedMinecraft.client; package com.burnedkirby.TurnBasedMinecraft.client;
import com.burnedkirby.TurnBasedMinecraft.common.CommonProxy;
import com.burnedkirby.TurnBasedMinecraft.common.TurnBasedMinecraftMod; import com.burnedkirby.TurnBasedMinecraft.common.TurnBasedMinecraftMod;
import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.gui.components.AbstractButton; import net.minecraft.client.gui.components.Button;
import net.minecraft.client.gui.components.Renderable;
import net.minecraft.client.gui.components.events.GuiEventListener;
import net.minecraft.client.gui.narration.NarratableEntry;
import net.minecraft.client.gui.narration.NarratedElementType; import net.minecraft.client.gui.narration.NarratedElementType;
import net.minecraft.client.gui.narration.NarrationElementOutput; import net.minecraft.client.gui.narration.NarrationElementOutput;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.LivingEntity;
public class EntitySelectionButton extends AbstractButton { public class EntitySelectionButton implements Renderable, GuiEventListener, NarratableEntry {
TBMButtonPress onPress; private int x;
private int y;
private int width;
private int height;
private boolean focused;
private Button nestedButton;
TBMEntityButtonPress onPress;
private int entityID; private int entityID;
private boolean isSideA; private boolean isSideA;
public EntitySelectionButton(int x, int y, int widthIn, int heightIn, String buttonText, int entityID, boolean isSideA, TBMButtonPress onPress) { public EntitySelectionButton(int x, int y, int widthIn, int heightIn, String buttonText, int entityID, boolean isSideA, TBMEntityButtonPress onPress) {
super(x, y, widthIn, heightIn, Component.literal(buttonText)); this.x = x;
this.y = y;
this.width = widthIn;
this.height = heightIn;
this.onPress = onPress; this.onPress = onPress;
this.entityID = entityID; this.entityID = entityID;
this.isSideA = isSideA; this.isSideA = isSideA;
this.nestedButton = Button.builder(Component.literal(buttonText), (unused) -> {}).pos(x, y).size(widthIn, heightIn).build();
} }
public EntitySelectionButton(int x, int y, int widthIn, int heightIn, Component buttonTextComponent, int entityID, boolean isSideA, TBMButtonPress onPress) { public EntitySelectionButton(int x, int y, int widthIn, int heightIn, Component buttonTextComponent, int entityID, boolean isSideA, TBMEntityButtonPress onPress) {
super(x, y, widthIn, heightIn, buttonTextComponent); this.x = x;
this.y = y;
this.width = widthIn;
this.height = heightIn;
this.onPress = onPress; this.onPress = onPress;
this.entityID = entityID; this.entityID = entityID;
this.isSideA = isSideA; this.isSideA = isSideA;
this.nestedButton = Button.builder(buttonTextComponent, (unused) -> {}).pos(x, y).size(widthIn, heightIn).build();
} }
public int getID() { public int getID() {
@ -41,63 +56,86 @@ public class EntitySelectionButton extends AbstractButton {
@Override @Override
public void render(GuiGraphics guiGraphics, int mouseX, int mouseY, float partialTicks) { public void render(GuiGraphics guiGraphics, int mouseX, int mouseY, float partialTicks) {
super.render(guiGraphics, mouseX, mouseY, partialTicks); this.nestedButton.render(guiGraphics, mouseX, mouseY, partialTicks);
Entity e = Minecraft.getInstance().level.getEntity(entityID); Entity e = Minecraft.getInstance().level.getEntity(entityID);
if (e != null && e instanceof LivingEntity && ((LivingEntity) e).isAlive()) { if (e != null && e instanceof LivingEntity && ((LivingEntity) e).isAlive()) {
int health = (int) (((LivingEntity) e).getHealth() + 0.5f); int health = (int) (((LivingEntity) e).getHealth() + 0.5f);
int xpos = getX(); int xpos = this.x;
int xoffset; int xoffset;
if (isSideA) { if (isSideA) {
xpos += getWidth() + 4; xpos += this.width + 4;
xoffset = 4; xoffset = 4;
} else { } else {
xpos -= 6; xpos -= 6;
xoffset = -4; xoffset = -4;
} }
if (health > 200) { if (health > 200) {
guiGraphics.fill(xpos, getY() + getHeight() * 4 / 5, xpos + 2, getY() + getHeight(), 0xFFFF0000); guiGraphics.fill(xpos, this.y + this.height * 4 / 5, xpos + 2, this.y + this.height, 0xFFFF0000);
guiGraphics.fill(xpos, getY() + getHeight() * 3 / 5, xpos + 2, getY() + getHeight() * 4 / 5, 0xFFFFFF00); guiGraphics.fill(xpos, this.y + this.height * 3 / 5, xpos + 2, this.y + this.height * 4 / 5, 0xFFFFFF00);
guiGraphics.fill(xpos, getY() + getHeight() * 2 / 5, xpos + 2, getY() + getHeight() * 3 / 5, 0xFF00FF00); guiGraphics.fill(xpos, this.y + this.height * 2 / 5, xpos + 2, this.y + this.height * 3 / 5, 0xFF00FF00);
guiGraphics.fill(xpos, getY() + getHeight() / 5, xpos + 2, getY() + getHeight() * 2 / 5, 0xFF00FFFF); guiGraphics.fill(xpos, this.y + this.height / 5, xpos + 2, this.y + this.height * 2 / 5, 0xFF00FFFF);
guiGraphics.fill(xpos, getY(), xpos + 2, getY() + getHeight() / 5, 0xFF0000FF); guiGraphics.fill(xpos, this.y, xpos + 2, this.y + this.height / 5, 0xFF0000FF);
int healthHeight = ((health - 200) * getHeight() / 100); int healthHeight = ((health - 200) * this.height / 100);
guiGraphics.fill(xpos + xoffset, getY() + getHeight() - healthHeight, xpos + xoffset + 2, getY() + getHeight(), 0xFFFFFFFF); guiGraphics.fill(xpos + xoffset, this.y + this.height - healthHeight, xpos + xoffset + 2, this.y + this.height, 0xFFFFFFFF);
} else if (health > 100) { } else if (health > 100) {
guiGraphics.fill(xpos, getY() + getHeight() * 4 / 5, xpos + 2, getY() + getHeight(), 0xFFFF0000); guiGraphics.fill(xpos, this.y + this.height * 4 / 5, xpos + 2, this.y + this.height, 0xFFFF0000);
guiGraphics.fill(xpos, getY() + getHeight() * 3 / 5, xpos + 2, getY() + getHeight() * 4 / 5, 0xFFFFFF00); guiGraphics.fill(xpos, this.y + this.height * 3 / 5, xpos + 2, this.y + this.height * 4 / 5, 0xFFFFFF00);
guiGraphics.fill(xpos, getY() + getHeight() * 2 / 5, xpos + 2, getY() + getHeight() * 3 / 5, 0xFF00FF00); guiGraphics.fill(xpos, this.y + this.height * 2 / 5, xpos + 2, this.y + this.height * 3 / 5, 0xFF00FF00);
guiGraphics.fill(xpos, getY() + getHeight() / 5, xpos + 2, getY() + getHeight() * 2 / 5, 0xFF00FFFF); guiGraphics.fill(xpos, this.y + this.height / 5, xpos + 2, this.y + this.height * 2 / 5, 0xFF00FFFF);
int healthHeight = ((health - 100) * getHeight() / 100); int healthHeight = ((health - 100) * this.height / 100);
guiGraphics.fill(xpos + xoffset, getY() + getHeight() - healthHeight, xpos + xoffset + 2, getY() + getHeight(), 0xFF0000FF); guiGraphics.fill(xpos + xoffset, this.y + this.height - healthHeight, xpos + xoffset + 2, this.y + this.height, 0xFF0000FF);
} else if (health > 50) { } else if (health > 50) {
guiGraphics.fill(xpos, getY() + getHeight() * 4 / 5, xpos + 2, getY() + getHeight(), 0xFFFF0000); guiGraphics.fill(xpos, this.y + this.height * 4 / 5, xpos + 2, this.y + this.height, 0xFFFF0000);
guiGraphics.fill(xpos, getY() + getHeight() * 3 / 5, xpos + 2, getY() + getHeight() * 4 / 5, 0xFFFFFF00); guiGraphics.fill(xpos, this.y + this.height * 3 / 5, xpos + 2, this.y + this.height * 4 / 5, 0xFFFFFF00);
guiGraphics.fill(xpos, getY() + getHeight() * 2 / 5, xpos + 2, getY() + getHeight() * 3 / 5, 0xFF00FF00); guiGraphics.fill(xpos, this.y + this.height * 2 / 5, xpos + 2, this.y + this.height * 3 / 5, 0xFF00FF00);
int healthHeight = ((health - 50) * getHeight() / 50); int healthHeight = ((health - 50) * this.height / 50);
guiGraphics.fill(xpos + xoffset, getY() + getHeight() - healthHeight, xpos + xoffset + 2, getY() + getHeight(), 0xFF00FFFF); guiGraphics.fill(xpos + xoffset, this.y + this.height - healthHeight, xpos + xoffset + 2, this.y + this.height, 0xFF00FFFF);
} else if (health > 20) { } else if (health > 20) {
guiGraphics.fill(xpos, getY() + getHeight() * 4 / 5, xpos + 2, getY() + getHeight(), 0xFFFF0000); guiGraphics.fill(xpos, this.y + this.height * 4 / 5, xpos + 2, this.y + this.height, 0xFFFF0000);
guiGraphics.fill(xpos, getY() + getHeight() * 3 / 5, xpos + 2, getY() + getHeight() * 4 / 5, 0xFFFFFF00); guiGraphics.fill(xpos, this.y + this.height * 3 / 5, xpos + 2, this.y + this.height * 4 / 5, 0xFFFFFF00);
int healthHeight = ((health - 20) * getHeight() / 30); int healthHeight = ((health - 20) * this.height / 30);
guiGraphics.fill(xpos + xoffset, getY() + getHeight() - healthHeight, xpos + xoffset + 2, getY() + getHeight(), 0xFF00FF00); guiGraphics.fill(xpos + xoffset, this.y + this.height - healthHeight, xpos + xoffset + 2, this.y + this.height, 0xFF00FF00);
} else if (health > 10) { } else if (health > 10) {
guiGraphics.fill(xpos, getY() + getHeight() * 4 / 5, xpos + 2, getY() + getHeight(), 0xFFFF0000); guiGraphics.fill(xpos, this.y + this.height * 4 / 5, xpos + 2, this.y + this.height, 0xFFFF0000);
int healthHeight = ((health - 10) * getHeight() / 10); int healthHeight = ((health - 10) * this.height / 10);
guiGraphics.fill(xpos + xoffset, getY() + getHeight() - healthHeight, xpos + xoffset + 2, getY() + getHeight(), 0xFFFFFF00); guiGraphics.fill(xpos + xoffset, this.y + this.height - healthHeight, xpos + xoffset + 2, this.y + this.height, 0xFFFFFF00);
} else { } else {
int healthHeight = (health * getHeight() / 10); int healthHeight = (health * this.height / 10);
guiGraphics.fill(xpos + xoffset, getY() + getHeight() - healthHeight, xpos + xoffset + 2, getY() + getHeight(), 0xFFFF0000); guiGraphics.fill(xpos + xoffset, this.y + this.height - healthHeight, xpos + xoffset + 2, this.y + this.height, 0xFFFF0000);
} }
} }
} }
@Override
protected void updateWidgetNarration(NarrationElementOutput p_259858_) {
p_259858_.add(NarratedElementType.HINT, TurnBasedMinecraftMod.proxy.getEntity(entityID, Minecraft.getInstance().level.dimension()).getName());
}
@Override
public void onPress() { public void onPress() {
onPress.onPress(this); onPress.onPress(this);
} }
@Override
public void setFocused(boolean b) {
this.focused = b;
}
@Override
public boolean isFocused() {
return focused;
}
@Override
public NarrationPriority narrationPriority() {
return NarrationPriority.FOCUSED;
}
@Override
public void updateNarration(NarrationElementOutput narrationElementOutput) {
narrationElementOutput.add(NarratedElementType.HINT, TurnBasedMinecraftMod.proxy.getEntity(entityID, Minecraft.getInstance().level.dimension()).getName());
}
@Override
public boolean mouseClicked(double x, double y, int unknown) {
if (unknown == 0 && x >= this.x && y >= this.y && x <= (double)(this.x + this.width) && y <= (double)(this.y + this.height)) {
onPress();
return true;
}
return false;
}
} }

View file

@ -1,19 +1,26 @@
package com.burnedkirby.TurnBasedMinecraft.client; package com.burnedkirby.TurnBasedMinecraft.client;
import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.gui.components.AbstractButton; import net.minecraft.client.gui.components.Renderable;
import net.minecraft.client.gui.components.events.GuiEventListener;
import net.minecraft.client.gui.narration.NarratableEntry;
import net.minecraft.client.gui.narration.NarratedElementType; import net.minecraft.client.gui.narration.NarratedElementType;
import net.minecraft.client.gui.narration.NarrationElementOutput; import net.minecraft.client.gui.narration.NarrationElementOutput;
import net.minecraft.network.chat.Component;
public class ItemSelectionButton extends AbstractButton { public class ItemSelectionButton implements Renderable, GuiEventListener, NarratableEntry {
private int x;
TBMButtonPress onPress; private int y;
private int width;
private int height;
TBMItemButtonPress onPress;
private int itemStackID; private int itemStackID;
private boolean focused;
public ItemSelectionButton(int x, int y, int widthIn, int heightIn, String buttonText, int itemStackID, TBMButtonPress onPress) { public ItemSelectionButton(int x, int y, int widthIn, int heightIn, int itemStackID, TBMItemButtonPress onPress) {
super(x, y, widthIn, heightIn, Component.literal(buttonText)); this.x = x;
this.y = y;
this.width = widthIn;
this.height = heightIn;
this.onPress = onPress; this.onPress = onPress;
this.itemStackID = itemStackID; this.itemStackID = itemStackID;
} }
@ -24,23 +31,44 @@ public class ItemSelectionButton extends AbstractButton {
@Override @Override
public void render(GuiGraphics guiGraphics, int mouseX, int mouseY, float unk) { public void render(GuiGraphics guiGraphics, int mouseX, int mouseY, float unk) {
if (visible) { boolean hovered = mouseX >= this.x && mouseY >= this.y && mouseX < this.x + this.width && mouseY < this.y + this.height;
boolean hovered = mouseX >= getX() && mouseY >= getY() && mouseX < getX() + getWidth() && mouseY < getY() + getHeight();
if (hovered) { if (hovered) {
guiGraphics.fill(getX(), getY(), getX() + getWidth(), getY() + getHeight(), 0x80FFFFFF); guiGraphics.fill(this.x, this.y, this.x + this.width, this.y + this.height, 0x80FFFFFF);
} else { } else {
guiGraphics.fill(getX(), getY(), getX() + getWidth(), getY() + getHeight(), 0x20707070); guiGraphics.fill(this.x, this.y, this.x + this.width, this.y + this.height, 0x20707070);
}
} }
} }
@Override
protected void updateWidgetNarration(NarrationElementOutput p_259858_) {
p_259858_.add(NarratedElementType.HINT, "Item " + this.itemStackID);
}
@Override
public void onPress() { public void onPress() {
onPress.onPress(this); onPress.onPress(this);
} }
@Override
public void setFocused(boolean b) {
focused = b;
}
@Override
public boolean isFocused() {
return focused;
}
@Override
public NarrationPriority narrationPriority() {
return NarrationPriority.FOCUSED;
}
@Override
public void updateNarration(NarrationElementOutput narrationElementOutput) {
narrationElementOutput.add(NarratedElementType.HINT, "Item " + this.itemStackID);
}
@Override
public boolean mouseClicked(double x, double y, int unknown) {
if (unknown == 0 && x >= this.x && y >= this.y && x <= (double)(this.x + this.width) && y <= (double)(this.y + this.height)) {
onPress();
return true;
}
return false;
}
} }

View file

@ -0,0 +1,5 @@
package com.burnedkirby.TurnBasedMinecraft.client;
public interface TBMEntityButtonPress {
void onPress(EntitySelectionButton button);
}

View file

@ -0,0 +1,5 @@
package com.burnedkirby.TurnBasedMinecraft.client;
public interface TBMItemButtonPress {
void onPress(ItemSelectionButton button);
}

View file

@ -1,22 +1,21 @@
package com.burnedkirby.TurnBasedMinecraft.common; package com.burnedkirby.TurnBasedMinecraft.common;
import com.burnedkirby.TurnBasedMinecraft.common.networking.PacketBattleMessage;
import com.burnedkirby.TurnBasedMinecraft.common.networking.PacketEditingMessage;
import com.burnedkirby.TurnBasedMinecraft.common.networking.PacketGeneralMessage;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.damagesource.DamageTypes;
import net.minecraft.world.entity.monster.Creeper;
import net.neoforged.bus.api.SubscribeEvent;
import net.neoforged.neoforge.event.entity.living.LivingChangeTargetEvent;
import net.neoforged.neoforge.event.entity.living.LivingIncomingDamageEvent;
import net.neoforged.neoforge.network.PacketDistributor;
import java.util.Iterator; import java.util.Iterator;
import com.burnedkirby.TurnBasedMinecraft.common.networking.PacketBattleMessage;
import com.burnedkirby.TurnBasedMinecraft.common.networking.PacketEditingMessage;
import com.burnedkirby.TurnBasedMinecraft.common.networking.PacketGeneralMessage;
import net.minecraft.world.damagesource.DamageTypes;
import net.minecraft.world.entity.monster.Creeper;
import net.minecraft.server.level.ServerPlayer;
import net.minecraftforge.event.entity.living.LivingAttackEvent;
import net.minecraftforge.event.entity.living.LivingChangeTargetEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.network.PacketDistributor;
public class AttackEventHandler public class AttackEventHandler
{ {
private boolean isAttackerValid(LivingAttackEvent event) private boolean isAttackerValid(LivingIncomingDamageEvent event)
{ {
if(event.getSource().getEntity() == null) if(event.getSource().getEntity() == null)
{ {
@ -59,7 +58,7 @@ public class AttackEventHandler
} }
@SubscribeEvent @SubscribeEvent
public void entityAttacked(LivingAttackEvent event) public void entityAttacked(LivingIncomingDamageEvent event)
{ {
if(event.getEntity().level().isClientSide) if(event.getEntity().level().isClientSide)
{ {
@ -82,7 +81,7 @@ public class AttackEventHandler
if(!event.getEntity().hasCustomName()) if(!event.getEntity().hasCustomName())
{ {
TurnBasedMinecraftMod.logger.error("Cannot edit custom name from entity without custom name"); TurnBasedMinecraftMod.logger.error("Cannot edit custom name from entity without custom name");
TurnBasedMinecraftMod.getHandler().send(PacketDistributor.PLAYER.with(() -> (ServerPlayer)editingInfo.editor), new PacketGeneralMessage("Cannot edit custom name from entity without custom name")); PacketDistributor.sendToPlayer((ServerPlayer)editingInfo.editor, new PacketGeneralMessage("Cannot edit custom name from entity without custom name"));
return; return;
} }
editingInfo.entityInfo = config.getCustomEntityInfo(event.getEntity().getCustomName().getString()); editingInfo.entityInfo = config.getCustomEntityInfo(event.getEntity().getCustomName().getString());
@ -91,9 +90,9 @@ public class AttackEventHandler
editingInfo.entityInfo = new EntityInfo(); editingInfo.entityInfo = new EntityInfo();
editingInfo.entityInfo.customName = event.getEntity().getCustomName().getString(); editingInfo.entityInfo.customName = event.getEntity().getCustomName().getString();
} }
TurnBasedMinecraftMod.getHandler().send(PacketDistributor.PLAYER.with(() -> (ServerPlayer)editingInfo.editor), new PacketGeneralMessage("Editing custom name \"" + event.getEntity().getCustomName().getString() + "\"")); PacketDistributor.sendToPlayer((ServerPlayer)editingInfo.editor, new PacketGeneralMessage("Editing custom name \"" + event.getEntity().getCustomName().getString() + "\""));
TurnBasedMinecraftMod.logger.info("Begin editing custom \"" + event.getEntity().getCustomName().getString() + "\""); TurnBasedMinecraftMod.logger.info("Begin editing custom \"" + event.getEntity().getCustomName().getString() + "\"");
TurnBasedMinecraftMod.getHandler().send(PacketDistributor.PLAYER.with(() -> (ServerPlayer)editingInfo.editor), new PacketEditingMessage(PacketEditingMessage.Type.PICK_EDIT, editingInfo.entityInfo)); PacketDistributor.sendToPlayer((ServerPlayer)editingInfo.editor, new PacketEditingMessage(PacketEditingMessage.Type.PICK_EDIT, editingInfo.entityInfo));
} }
else else
{ {
@ -107,9 +106,9 @@ public class AttackEventHandler
{ {
editingInfo.entityInfo = editingInfo.entityInfo.clone(); editingInfo.entityInfo = editingInfo.entityInfo.clone();
} }
TurnBasedMinecraftMod.getHandler().send(PacketDistributor.PLAYER.with(() -> (ServerPlayer)editingInfo.editor), new PacketGeneralMessage("Editing entity \"" + editingInfo.entityInfo.classType.getName() + "\"")); PacketDistributor.sendToPlayer((ServerPlayer)editingInfo.editor, new PacketGeneralMessage("Editing entity \"" + editingInfo.entityInfo.classType.getName() + "\""));
TurnBasedMinecraftMod.logger.info("Begin editing \"" + editingInfo.entityInfo.classType.getName() + "\""); TurnBasedMinecraftMod.logger.info("Begin editing \"" + editingInfo.entityInfo.classType.getName() + "\"");
TurnBasedMinecraftMod.getHandler().send(PacketDistributor.PLAYER.with(() -> (ServerPlayer)editingInfo.editor), new PacketEditingMessage(PacketEditingMessage.Type.PICK_EDIT, editingInfo.entityInfo)); PacketDistributor.sendToPlayer((ServerPlayer)editingInfo.editor, new PacketEditingMessage(PacketEditingMessage.Type.PICK_EDIT, editingInfo.entityInfo));
} }
return; return;
} }
@ -154,16 +153,16 @@ public class AttackEventHandler
if(event.getEntity().level().isClientSide if(event.getEntity().level().isClientSide
|| config.isOldBattleBehaviorEnabled() || config.isOldBattleBehaviorEnabled()
|| (event.getEntity() != null && battleManager.isRecentlyLeftBattle(event.getEntity().getId())) || (event.getEntity() != null && battleManager.isRecentlyLeftBattle(event.getEntity().getId()))
|| (event.getNewTarget() != null && battleManager.isRecentlyLeftBattle(event.getNewTarget().getId())) || (event.getNewAboutToBeSetTarget() != null && battleManager.isRecentlyLeftBattle(event.getNewAboutToBeSetTarget().getId()))
|| (event.getEntity() != null && event.getNewTarget() != null && Utility.distanceBetweenEntities(event.getEntity(), event.getNewTarget()) > (double)config.getAggroStartBattleDistance())) || (event.getEntity() != null && event.getNewAboutToBeSetTarget() != null && Utility.distanceBetweenEntities(event.getEntity(), event.getNewAboutToBeSetTarget()) > (double)config.getAggroStartBattleDistance()))
{ {
return; return;
} }
else if(event.getEntity() != null else if(event.getEntity() != null
&& event.getNewTarget() != null && event.getNewAboutToBeSetTarget() != null
&& !config.getBattleIgnoringPlayers().contains(event.getEntity().getId()) && !config.getBattleIgnoringPlayers().contains(event.getEntity().getId())
&& !config.getBattleIgnoringPlayers().contains(event.getNewTarget().getId()) && !config.getBattleIgnoringPlayers().contains(event.getNewAboutToBeSetTarget().getId())
&& event.getEntity().level().dimension().equals(event.getNewTarget().level().dimension())) && event.getEntity().level().dimension().equals(event.getNewAboutToBeSetTarget().level().dimension()))
{ {
TurnBasedMinecraftMod.proxy.getBattleManager().checkTargeted(event); TurnBasedMinecraftMod.proxy.getBattleManager().checkTargeted(event);
} }

View file

@ -4,6 +4,7 @@ import com.burnedkirby.TurnBasedMinecraft.common.networking.PacketBattleInfo;
import com.burnedkirby.TurnBasedMinecraft.common.networking.PacketBattleMessage; import com.burnedkirby.TurnBasedMinecraft.common.networking.PacketBattleMessage;
import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceKey;
import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.damagesource.DamageSource; import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.effect.MobEffects; import net.minecraft.world.effect.MobEffects;
import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Entity;
@ -13,8 +14,8 @@ import net.minecraft.world.entity.monster.Creeper;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.*; import net.minecraft.world.item.*;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import net.minecraftforge.common.CreativeModeTabRegistry; import net.neoforged.neoforge.common.CreativeModeTabRegistry;
import net.minecraftforge.network.PacketDistributor; import net.neoforged.neoforge.network.PacketDistributor;
import java.util.*; import java.util.*;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
@ -448,7 +449,7 @@ public class Battle {
} }
PacketBattleInfo infoPacket = new PacketBattleInfo(getSideAIDs(), getSideBIDs(), timer, TurnBasedMinecraftMod.proxy.getConfig().getDecisionDurationNanos(), !TurnBasedMinecraftMod.proxy.getConfig().isBattleDecisionDurationForever()); PacketBattleInfo infoPacket = new PacketBattleInfo(getSideAIDs(), getSideBIDs(), timer, TurnBasedMinecraftMod.proxy.getConfig().getDecisionDurationNanos(), !TurnBasedMinecraftMod.proxy.getConfig().isBattleDecisionDurationForever());
for (Combatant p : players.values()) { for (Combatant p : players.values()) {
TurnBasedMinecraftMod.getHandler().send(PacketDistributor.PLAYER.with(() -> (ServerPlayer) p.entity), infoPacket); PacketDistributor.sendToPlayer((ServerPlayer)p.entity, infoPacket);
} }
} }
@ -463,7 +464,7 @@ public class Battle {
PacketBattleMessage packet = new PacketBattleMessage(type, from, to, dimension, amount, custom); PacketBattleMessage packet = new PacketBattleMessage(type, from, to, dimension, amount, custom);
for (Combatant p : players.values()) { for (Combatant p : players.values()) {
if (p.entity.isAlive()) { if (p.entity.isAlive()) {
TurnBasedMinecraftMod.getHandler().send(PacketDistributor.PLAYER.with(() -> (ServerPlayer) p.entity), packet); PacketDistributor.sendToPlayer((ServerPlayer)p.entity, packet);
} }
} }
} }
@ -573,7 +574,7 @@ public class Battle {
private void removeCombatantPostRemove(Combatant c) { private void removeCombatantPostRemove(Combatant c) {
if (c.entity instanceof Player) { if (c.entity instanceof Player) {
TurnBasedMinecraftMod.getHandler().send(PacketDistributor.PLAYER.with(() -> (ServerPlayer) c.entity), new PacketBattleMessage(PacketBattleMessage.MessageType.ENDED, 0, 0, dimension, 0)); PacketDistributor.sendToPlayer((ServerPlayer)c.entity, new PacketBattleMessage(PacketBattleMessage.MessageType.ENDED, 0, 0, dimension, 0));
} }
battleManager.addRecentlyLeftBattle(c); battleManager.addRecentlyLeftBattle(c);
} }
@ -778,7 +779,7 @@ public class Battle {
final Entity targetEntity = target.entity; final Entity targetEntity = target.entity;
final float yawDirection = Utility.yawDirection(next.entity.getX(), next.entity.getZ(), target.entity.getX(), target.entity.getZ()); final float yawDirection = Utility.yawDirection(next.entity.getX(), next.entity.getZ(), target.entity.getX(), target.entity.getZ());
final float pitchDirection = Utility.pitchDirection(next.entity.getX(), next.entity.getY(), next.entity.getZ(), target.entity.getX(), target.entity.getY(), target.entity.getZ()); final float pitchDirection = Utility.pitchDirection(next.entity.getX(), next.entity.getY(), next.entity.getZ(), target.entity.getX(), target.entity.getY(), target.entity.getZ());
final int randomTimeLeft = random.nextInt(heldItemStack.getItem().getUseDuration(heldItemStack) / 3); final int randomTimeLeft = random.nextInt(heldItemStack.getItem().getUseDuration(heldItemStack, (LivingEntity)next.entity) / 3);
if (TurnBasedMinecraftMod.proxy.getConfig().isFreezeCombatantsEnabled()) { if (TurnBasedMinecraftMod.proxy.getConfig().isFreezeCombatantsEnabled()) {
next.yaw = yawDirection; next.yaw = yawDirection;
next.pitch = pitchDirection; next.pitch = pitchDirection;
@ -793,6 +794,28 @@ public class Battle {
sendMessageToAllPlayers(PacketBattleMessage.MessageType.BOW_NO_AMMO, next.entity.getId(), 0, 0); sendMessageToAllPlayers(PacketBattleMessage.MessageType.BOW_NO_AMMO, next.entity.getId(), 0, 0);
} }
continue; continue;
} else if (heldItemStack.getItem() instanceof CrossbowItem) {
debugLog += " with crossbow";
if (Utility.doesPlayerHaveArrows((Player) next.entity)) {
final Entity nextEntity = next.entity;
final Entity targetEntity = target.entity;
final float yawDirection = Utility.yawDirection(next.entity.getX(), next.entity.getZ(), target.entity.getX(), target.entity.getZ());
final float pitchDirection = Utility.pitchDirection(next.entity.getX(), next.entity.getY(), next.entity.getZ(), target.entity.getX(), target.entity.getY(), target.entity.getZ());
if (TurnBasedMinecraftMod.proxy.getConfig().isFreezeCombatantsEnabled()) {
next.yaw = yawDirection;
next.pitch = pitchDirection;
}
// have player look at attack target
((ServerPlayer) nextEntity).connection.teleport(nextEntity.getX(), nextEntity.getY(), nextEntity.getZ(), yawDirection, pitchDirection);
CrossbowItem itemCrossbow = (CrossbowItem) heldItemStack.getItem();
TurnBasedMinecraftMod.proxy.getAttackerViaBowSet().add(new AttackerViaBow(nextEntity, getId()));
itemCrossbow.releaseUsing(heldItemStack, nextEntity.level(), (LivingEntity)nextEntity, -100);
itemCrossbow.use(nextEntity.level(), (Player)nextEntity, InteractionHand.MAIN_HAND);
sendMessageToAllPlayers(PacketBattleMessage.MessageType.FIRED_ARROW, nextEntity.getId(), targetEntity.getId(), 0);
} else {
sendMessageToAllPlayers(PacketBattleMessage.MessageType.CROSSBOW_NO_AMMO, next.entity.getId(), 0, 0);
}
continue;
} }
debugLog += " without bow"; debugLog += " without bow";
int hitChance = TurnBasedMinecraftMod.proxy.getConfig().getPlayerAttackProbability(); int hitChance = TurnBasedMinecraftMod.proxy.getConfig().getPlayerAttackProbability();
@ -1064,7 +1087,7 @@ public class Battle {
debugLog += " null"; debugLog += " null";
sendMessageToAllPlayers(PacketBattleMessage.MessageType.USED_ITEM, next.entity.getId(), 0, PacketBattleMessage.UsedItemAction.USED_NOTHING.getValue()); sendMessageToAllPlayers(PacketBattleMessage.MessageType.USED_ITEM, next.entity.getId(), 0, PacketBattleMessage.UsedItemAction.USED_NOTHING.getValue());
break; break;
} else if (targetItem.isEdible()) { } else if (Utility.isItemEdible(targetItemStack, (LivingEntity)next.entity)) {
debugLog += " food"; debugLog += " food";
sendMessageToAllPlayers(PacketBattleMessage.MessageType.USED_ITEM, next.entity.getId(), 0, PacketBattleMessage.UsedItemAction.USED_FOOD.getValue(), targetItemStack.getDisplayName().getString()); sendMessageToAllPlayers(PacketBattleMessage.MessageType.USED_ITEM, next.entity.getId(), 0, PacketBattleMessage.UsedItemAction.USED_FOOD.getValue(), targetItemStack.getDisplayName().getString());
final Entity nextEntity = next.entity; final Entity nextEntity = next.entity;
@ -1073,13 +1096,13 @@ public class Battle {
} else { } else {
// then check vanilla foods // then check vanilla foods
final CreativeModeTab foodAndDrinksTab = CreativeModeTabRegistry.getTab(CreativeModeTabs.FOOD_AND_DRINKS.location()); final CreativeModeTab foodAndDrinksTab = CreativeModeTabRegistry.getTab(CreativeModeTabs.FOOD_AND_DRINKS.location());
if (foodAndDrinksTab.contains(targetItemStack) && targetItem.isEdible()) { if (foodAndDrinksTab.contains(targetItemStack) && Utility.isItemEdible(targetItemStack, (LivingEntity)next.entity)) {
debugLog += " food"; debugLog += " food";
sendMessageToAllPlayers(PacketBattleMessage.MessageType.USED_ITEM, next.entity.getId(), 0, PacketBattleMessage.UsedItemAction.USED_FOOD.getValue(), targetItemStack.getDisplayName().getString()); sendMessageToAllPlayers(PacketBattleMessage.MessageType.USED_ITEM, next.entity.getId(), 0, PacketBattleMessage.UsedItemAction.USED_FOOD.getValue(), targetItemStack.getDisplayName().getString());
final Entity nextEntity = next.entity; final Entity nextEntity = next.entity;
final int nextItemToUse = next.itemToUse; final int nextItemToUse = next.itemToUse;
((Player) nextEntity).getInventory().setItem(nextItemToUse, targetItem.finishUsingItem(targetItemStack, nextEntity.level(), (LivingEntity) nextEntity)); ((Player) nextEntity).getInventory().setItem(nextItemToUse, targetItem.finishUsingItem(targetItemStack, nextEntity.level(), (LivingEntity) nextEntity));
} else if (targetItem instanceof PotionItem) { } else if (targetItem instanceof PotionItem && !(targetItem instanceof ThrowablePotionItem)) {
debugLog += " potion"; debugLog += " potion";
sendMessageToAllPlayers(PacketBattleMessage.MessageType.USED_ITEM, next.entity.getId(), 0, PacketBattleMessage.UsedItemAction.USED_POTION.getValue(), targetItemStack.getDisplayName().getString()); sendMessageToAllPlayers(PacketBattleMessage.MessageType.USED_ITEM, next.entity.getId(), 0, PacketBattleMessage.UsedItemAction.USED_POTION.getValue(), targetItemStack.getDisplayName().getString());
final Entity nextEntity = next.entity; final Entity nextEntity = next.entity;
@ -1090,7 +1113,10 @@ public class Battle {
sendMessageToAllPlayers(PacketBattleMessage.MessageType.USED_ITEM, next.entity.getId(), 0, PacketBattleMessage.UsedItemAction.USED_INVALID.getValue(), targetItemStack.getDisplayName().getString()); sendMessageToAllPlayers(PacketBattleMessage.MessageType.USED_ITEM, next.entity.getId(), 0, PacketBattleMessage.UsedItemAction.USED_INVALID.getValue(), targetItemStack.getDisplayName().getString());
final Entity nextEntity = next.entity; final Entity nextEntity = next.entity;
final int nextItemToUse = next.itemToUse; final int nextItemToUse = next.itemToUse;
((Player)nextEntity).getInventory().setItem(nextItemToUse, targetItem.finishUsingItem(targetItemStack, nextEntity.level(), (LivingEntity) nextEntity)); final int prevItem = ((Player)nextEntity).getInventory().selected;
((Player)nextEntity).getInventory().selected = nextItemToUse;
((Player)nextEntity).getInventory().setItem(nextItemToUse, targetItem.use(nextEntity.level(), (Player)nextEntity, InteractionHand.MAIN_HAND).getObject());
((Player)nextEntity).getInventory().selected = prevItem;
} }
} }
break; break;

View file

@ -7,10 +7,10 @@ import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.monster.Creeper; import net.minecraft.world.entity.monster.Creeper;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import net.minecraftforge.common.MinecraftForge; import net.neoforged.neoforge.common.NeoForge;
import net.minecraftforge.event.entity.living.LivingAttackEvent; import net.neoforged.neoforge.event.entity.living.LivingChangeTargetEvent;
import net.minecraftforge.event.entity.living.LivingChangeTargetEvent; import net.neoforged.neoforge.event.entity.living.LivingIncomingDamageEvent;
import net.minecraftforge.network.PacketDistributor; import net.neoforged.neoforge.network.PacketDistributor;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import java.util.*; import java.util.*;
@ -32,7 +32,7 @@ public class BattleManager
recentlyLeftBattle = new HashMap<Integer, Combatant>(); recentlyLeftBattle = new HashMap<Integer, Combatant>();
battleUpdater = new BattleUpdater(this); battleUpdater = new BattleUpdater(this);
entityToBattleMap = new HashMap<EntityIDDimPair, Integer>(); entityToBattleMap = new HashMap<EntityIDDimPair, Integer>();
MinecraftForge.EVENT_BUS.register(battleUpdater); NeoForge.EVENT_BUS.register(battleUpdater);
tempIDPair = new EntityIDDimPair(); tempIDPair = new EntityIDDimPair();
} }
@ -44,7 +44,7 @@ public class BattleManager
* @param event * @param event
* @return True if event should be canceled * @return True if event should be canceled
*/ */
public boolean checkAttack(final LivingAttackEvent event) public boolean checkAttack(final LivingIncomingDamageEvent event)
{ {
Config config = TurnBasedMinecraftMod.proxy.getConfig(); Config config = TurnBasedMinecraftMod.proxy.getConfig();
String receiverClassName = event.getEntity().getClass().getName(); String receiverClassName = event.getEntity().getClass().getName();
@ -183,13 +183,13 @@ public class BattleManager
{ {
// Check if "player_only_battles" is enabled and if both entities are players. // Check if "player_only_battles" is enabled and if both entities are players.
if (TurnBasedMinecraftMod.proxy.getConfig().isPlayerOnlyBattlesEnabled() && if (TurnBasedMinecraftMod.proxy.getConfig().isPlayerOnlyBattlesEnabled() &&
(!(event.getEntity() instanceof Player) || !(event.getNewTarget() instanceof Player))) { (!(event.getEntity() instanceof Player) || !(event.getNewAboutToBeSetTarget() instanceof Player))) {
return; return;
} }
String targetedCustomName; String targetedCustomName;
try { try {
targetedCustomName = event.getNewTarget().getCustomName().getString(); targetedCustomName = event.getNewAboutToBeSetTarget().getCustomName().getString();
} catch (NullPointerException e) { } catch (NullPointerException e) {
targetedCustomName = null; targetedCustomName = null;
} }
@ -207,7 +207,7 @@ public class BattleManager
} }
EntityInfo targetedInfo; EntityInfo targetedInfo;
if(event.getNewTarget() instanceof Player) if(event.getNewAboutToBeSetTarget() instanceof Player)
{ {
targetedInfo = null; targetedInfo = null;
} }
@ -216,10 +216,10 @@ public class BattleManager
targetedInfo = TurnBasedMinecraftMod.proxy.getConfig().getCustomEntityInfoReference(targetedCustomName); targetedInfo = TurnBasedMinecraftMod.proxy.getConfig().getCustomEntityInfoReference(targetedCustomName);
if(targetedInfo == null) if(targetedInfo == null)
{ {
targetedInfo = TurnBasedMinecraftMod.proxy.getConfig().getMatchingEntityInfo(event.getNewTarget()); targetedInfo = TurnBasedMinecraftMod.proxy.getConfig().getMatchingEntityInfo(event.getNewAboutToBeSetTarget());
} }
} }
if((event.getNewTarget() instanceof Player && ((Player)event.getNewTarget()).isCreative()) if((event.getNewAboutToBeSetTarget() instanceof Player && ((Player)event.getNewAboutToBeSetTarget()).isCreative())
|| attackerInfo == null || attackerInfo == null
|| attackerInfo.ignoreBattle || attackerInfo.ignoreBattle
|| TurnBasedMinecraftMod.proxy.getConfig().isIgnoreBattleType(attackerInfo.category) || TurnBasedMinecraftMod.proxy.getConfig().isIgnoreBattleType(attackerInfo.category)
@ -235,8 +235,8 @@ public class BattleManager
if(attackerBattle != null && !attackerBattle.hasCombatant(event.getEntity().getId())) { if(attackerBattle != null && !attackerBattle.hasCombatant(event.getEntity().getId())) {
attackerBattle = null; attackerBattle = null;
} }
Battle defenderBattle = battleMap.get(entityToBattleMap.get(new EntityIDDimPair(event.getNewTarget()))); Battle defenderBattle = battleMap.get(entityToBattleMap.get(new EntityIDDimPair(event.getNewAboutToBeSetTarget())));
if(defenderBattle != null && !defenderBattle.hasCombatant(event.getNewTarget().getId())) { if(defenderBattle != null && !defenderBattle.hasCombatant(event.getNewAboutToBeSetTarget().getId())) {
defenderBattle = null; defenderBattle = null;
} }
@ -244,13 +244,13 @@ public class BattleManager
return; return;
} else if(attackerBattle == null && defenderBattle == null) { } else if(attackerBattle == null && defenderBattle == null) {
// neither in battle // neither in battle
if(event.getEntity() instanceof Player || event.getNewTarget() instanceof Player) if(event.getEntity() instanceof Player || event.getNewAboutToBeSetTarget() instanceof Player)
{ {
// at least one is a player, create battle // at least one is a player, create battle
Collection<Entity> sideA = new ArrayList<Entity>(1); Collection<Entity> sideA = new ArrayList<Entity>(1);
Collection<Entity> sideB = new ArrayList<Entity>(1); Collection<Entity> sideB = new ArrayList<Entity>(1);
sideA.add(event.getEntity()); sideA.add(event.getEntity());
sideB.add(event.getNewTarget()); sideB.add(event.getNewAboutToBeSetTarget());
createBattle(sideA, sideB, event.getEntity().level().dimension()); createBattle(sideA, sideB, event.getEntity().level().dimension());
logger.debug("neither in battle, at least one is player, creating new battle"); logger.debug("neither in battle, at least one is player, creating new battle");
} }
@ -261,16 +261,16 @@ public class BattleManager
// battle max reached, cannot add to battle // battle max reached, cannot add to battle
return; return;
} else if (attackerBattle.hasCombatantInSideA(event.getEntity().getId())) { } else if (attackerBattle.hasCombatantInSideA(event.getEntity().getId())) {
attackerBattle.addCombatantToSideB(event.getNewTarget()); attackerBattle.addCombatantToSideB(event.getNewAboutToBeSetTarget());
} else { } else {
attackerBattle.addCombatantToSideA(event.getNewTarget()); attackerBattle.addCombatantToSideA(event.getNewAboutToBeSetTarget());
} }
entityToBattleMap.put(new EntityIDDimPair(event.getNewTarget()), attackerBattle.getId()); entityToBattleMap.put(new EntityIDDimPair(event.getNewAboutToBeSetTarget()), attackerBattle.getId());
} else { } else {
if (defenderBattle.getSize() >= TurnBasedMinecraftMod.proxy.getConfig().getMaxInBattle()) { if (defenderBattle.getSize() >= TurnBasedMinecraftMod.proxy.getConfig().getMaxInBattle()) {
// battle max reached, cannot add to battle // battle max reached, cannot add to battle
return; return;
} else if (defenderBattle.hasCombatantInSideA(event.getNewTarget().getId())) { } else if (defenderBattle.hasCombatantInSideA(event.getNewAboutToBeSetTarget().getId())) {
defenderBattle.addCombatantToSideB(event.getEntity()); defenderBattle.addCombatantToSideB(event.getEntity());
} else { } else {
defenderBattle.addCombatantToSideA(event.getEntity()); defenderBattle.addCombatantToSideA(event.getEntity());
@ -307,7 +307,7 @@ public class BattleManager
public void cleanup() public void cleanup()
{ {
battleUpdater.setRunning(false); battleUpdater.setRunning(false);
MinecraftForge.EVENT_BUS.unregister(battleUpdater); NeoForge.EVENT_BUS.unregister(battleUpdater);
battleMap.clear(); battleMap.clear();
battleUpdater = null; battleUpdater = null;
} }
@ -317,7 +317,7 @@ public class BattleManager
c.time = System.nanoTime(); c.time = System.nanoTime();
Config config = TurnBasedMinecraftMod.proxy.getConfig(); Config config = TurnBasedMinecraftMod.proxy.getConfig();
if(c.entity instanceof ServerPlayer) { if(c.entity instanceof ServerPlayer) {
TurnBasedMinecraftMod.getHandler().send(PacketDistributor.PLAYER.with(()->(ServerPlayer) c.entity), new PacketGeneralMessage("You just left battle! " + config.getLeaveBattleCooldownSeconds() + " seconds until you can attack/be-attacked again!")); PacketDistributor.sendToPlayer((ServerPlayer)c.entity, new PacketGeneralMessage("You just left battle! " + config.getLeaveBattleCooldownSeconds() + " seconds until you can attack/be-attacked again!"));
} }
recentlyLeftBattle.put(c.entity.getId(), c); recentlyLeftBattle.put(c.entity.getId(), c);
entityToBattleMap.remove(new EntityIDDimPair(c.entity)); entityToBattleMap.remove(new EntityIDDimPair(c.entity));
@ -337,7 +337,7 @@ public class BattleManager
iter.remove(); iter.remove();
if(entry.getValue().entity instanceof ServerPlayer) if(entry.getValue().entity instanceof ServerPlayer)
{ {
TurnBasedMinecraftMod.getHandler().send(PacketDistributor.PLAYER.with(()->(ServerPlayer)entry.getValue().entity), new PacketGeneralMessage("Timer ended, you can now attack/be-attacked again.")); PacketDistributor.sendToPlayer((ServerPlayer)entry.getValue().entity, new PacketGeneralMessage("Timer ended, you can now attack/be-attacked again."));
} }
} }
} }

View file

@ -1,8 +1,8 @@
package com.burnedkirby.TurnBasedMinecraft.common; package com.burnedkirby.TurnBasedMinecraft.common;
import net.minecraftforge.event.TickEvent; import net.neoforged.bus.api.SubscribeEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent; import net.neoforged.neoforge.event.tick.ServerTickEvent;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
@ -25,8 +25,9 @@ public class BattleUpdater
} }
@SubscribeEvent @SubscribeEvent
public void update(TickEvent.ServerTickEvent tickEvent) { public void update(ServerTickEvent.Post tickEvent) {
if(tickEvent.phase != TickEvent.Phase.START && isRunning.get() && ++tick > tickLimit) { //if(tickEvent.phase != TickEvent.Phase.START && isRunning.get() && ++tick > tickLimit) {
if(isRunning.get() && ++tick > tickLimit) {
tick = 0; tick = 0;
manager.battleMap.entrySet().removeIf(entry -> entry.getValue().update()); manager.battleMap.entrySet().removeIf(entry -> entry.getValue().update());
manager.updateRecentlyLeftBattle(); manager.updateRecentlyLeftBattle();

View file

@ -1,12 +1,12 @@
package com.burnedkirby.TurnBasedMinecraft.common; package com.burnedkirby.TurnBasedMinecraft.common;
import java.util.Comparator; import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.world.effect.MobEffects;
import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.world.effect.MobEffects; import java.util.Comparator;
public class Combatant public class Combatant
{ {

View file

@ -1,19 +1,18 @@
package com.burnedkirby.TurnBasedMinecraft.common; package com.burnedkirby.TurnBasedMinecraft.common;
import io.netty.buffer.ByteBuf;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.minecraft.network.codec.ByteBufCodecs;
import net.minecraft.network.codec.StreamCodec;
import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceKey;
import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import net.minecraftforge.network.NetworkEvent; import net.neoforged.neoforge.network.handling.IPayloadContext;
import net.minecraftforge.server.ServerLifecycleHooks; import net.neoforged.neoforge.server.ServerLifecycleHooks;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import java.util.HashSet; import java.util.*;
import java.util.Hashtable;
import java.util.Map;
import java.util.Set;
import java.util.function.Supplier;
public class CommonProxy public class CommonProxy
{ {
@ -173,5 +172,9 @@ public class CommonProxy
return ServerLifecycleHooks.getCurrentServer().getLevel(dim).getEntity(id); return ServerLifecycleHooks.getCurrentServer().getLevel(dim).getEntity(id);
} }
public <MSG> void handlePacket(MSG msg, Supplier<NetworkEvent.Context> ctx) {} public <MSG> void handlePacket(final MSG msg, final IPayloadContext ctx) {}
public static final StreamCodec<ByteBuf, Collection<Integer>> COLLECTION_INT_CODEC = ByteBufCodecs.INT.apply(ByteBufCodecs.collection(ArrayList::new));
public void showClientConfigGui() {}
} }

View file

@ -1,17 +1,16 @@
package com.burnedkirby.TurnBasedMinecraft.common; package com.burnedkirby.TurnBasedMinecraft.common;
import java.io.*;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import com.electronwill.nightconfig.core.file.CommentedFileConfig; import com.electronwill.nightconfig.core.file.CommentedFileConfig;
import com.electronwill.nightconfig.core.file.FileConfig;
import com.electronwill.nightconfig.toml.TomlFormat; import com.electronwill.nightconfig.toml.TomlFormat;
import net.minecraft.core.registries.Registries; import net.minecraft.core.registries.Registries;
import net.minecraft.data.registries.VanillaRegistries; import net.minecraft.data.registries.VanillaRegistries;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import com.electronwill.nightconfig.core.file.FileConfig; import java.io.*;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
public class Config public class Config
{ {
@ -37,10 +36,7 @@ public class Config
private int fleeBadProbability = 35; private int fleeBadProbability = 35;
private int minimumHitPercentage = 4; private int minimumHitPercentage = 4;
private int maxInBattle = 8; private int maxInBattle = 8;
private Set<String> musicBattleTypes;
private Set<String> musicSillyTypes;
private boolean freezeCombatantsInBattle = false; private boolean freezeCombatantsInBattle = false;
private int sillyMusicThreshold = 40;
private int configVersion = 0; private int configVersion = 0;
private Set<Integer> battleIgnoringPlayers = null; private Set<Integer> battleIgnoringPlayers = null;
private boolean onlyOPsSelfDisableTB = true; private boolean onlyOPsSelfDisableTB = true;
@ -63,8 +59,6 @@ public class Config
customEntityInfoMap = new HashMap<String, EntityInfo>(); customEntityInfoMap = new HashMap<String, EntityInfo>();
ignoreBattleTypes = new HashSet<String>(); ignoreBattleTypes = new HashSet<String>();
this.logger = logger; this.logger = logger;
musicBattleTypes = new HashSet<String>();
musicSillyTypes = new HashSet<String>();
battleIgnoringPlayers = new HashSet<Integer>(); battleIgnoringPlayers = new HashSet<Integer>();
possibleIgnoreHurtDamageSources = new HashSet<String>(); possibleIgnoreHurtDamageSources = new HashSet<String>();
ignoreHurtDamageSources = new HashSet<String>(); ignoreHurtDamageSources = new HashSet<String>();
@ -156,56 +150,6 @@ public class Config
{ {
CommentedFileConfig conf = getConfigObj(configFile); CommentedFileConfig conf = getConfigObj(configFile);
// client config
try {
Collection<String> battle_music_categories = conf.get("client_config.battle_music");
if (battle_music_categories != null) {
for (String category : battle_music_categories) {
musicBattleTypes.add(category);
}
} else {
musicBattleTypes.add("monster");
musicBattleTypes.add("animal");
musicBattleTypes.add("boss");
musicBattleTypes.add("player");
logNotFound("client_config.battle_music");
}
} catch (ClassCastException e) {
musicBattleTypes.add("monster");
musicBattleTypes.add("animal");
musicBattleTypes.add("boss");
musicBattleTypes.add("player");
logTOMLInvalidValue("client_config.battle_music");
}
try {
Collection<String> silly_music_categories = conf.get("client_config.silly_music");
if (silly_music_categories != null) {
for (String category : silly_music_categories) {
musicSillyTypes.add(category);
}
} else {
musicSillyTypes.add("passive");
logNotFound("client_config.silly_music");
}
} catch (ClassCastException e) {
musicSillyTypes.add("passive");
logTOMLInvalidValue("client_config.silly_music");
}
try {
OptionalInt silly_music_threshold = conf.getOptionalInt("client_config.silly_music_threshold");
if(silly_music_threshold.isPresent()) {
this.sillyMusicThreshold = silly_music_threshold.getAsInt();
} else {
this.sillyMusicThreshold = 40;
logNotFound("client_config.silly_music_threshold", "40");
}
} catch (ClassCastException e) {
this.sillyMusicThreshold = 40;
logTOMLInvalidValue("client_config.silly_music_threshold", "40");
}
// server_config // server_config
try { try {
OptionalInt leave_battle_cooldown = conf.getOptionalInt("server_config.leave_battle_cooldown"); OptionalInt leave_battle_cooldown = conf.getOptionalInt("server_config.leave_battle_cooldown");
@ -1328,16 +1272,6 @@ public class Config
this.maxInBattle = maxInBattle; this.maxInBattle = maxInBattle;
} }
public boolean isBattleMusicType(String type)
{
return musicBattleTypes.contains(type.toLowerCase());
}
public boolean isSillyMusicType(String type)
{
return musicSillyTypes.contains(type.toLowerCase());
}
public boolean isFreezeCombatantsEnabled() public boolean isFreezeCombatantsEnabled()
{ {
return freezeCombatantsInBattle; return freezeCombatantsInBattle;
@ -1347,11 +1281,6 @@ public class Config
freezeCombatantsInBattle = enabled; freezeCombatantsInBattle = enabled;
} }
public int getSillyMusicThreshold()
{
return sillyMusicThreshold;
}
public int getConfigVersion() public int getConfigVersion()
{ {
return configVersion; return configVersion;
@ -1521,7 +1450,7 @@ public class Config
possibleIgnoreHurtDamageSources.clear(); possibleIgnoreHurtDamageSources.clear();
try { try {
VanillaRegistries.createLookup().lookupOrThrow(Registries.DAMAGE_TYPE).listElements().forEach(dt -> possibleIgnoreHurtDamageSources.add(dt.get().msgId())); VanillaRegistries.createLookup().lookupOrThrow(Registries.DAMAGE_TYPE).listElements().forEach(dt -> possibleIgnoreHurtDamageSources.add(dt.value().msgId()));
} catch (Exception e) { } catch (Exception e) {
logger.warn("Config failed to load possible DamageSources! Undesired things may happen, like Zombies dying from Fire during battle!"); logger.warn("Config failed to load possible DamageSources! Undesired things may happen, like Zombies dying from Fire during battle!");
logger.warn(e); logger.warn(e);

View file

@ -2,9 +2,9 @@ package com.burnedkirby.TurnBasedMinecraft.common;
import com.burnedkirby.TurnBasedMinecraft.common.networking.PacketGeneralMessage; import com.burnedkirby.TurnBasedMinecraft.common.networking.PacketGeneralMessage;
import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.level.ServerPlayer;
import net.minecraftforge.event.entity.EntityTravelToDimensionEvent; import net.neoforged.bus.api.SubscribeEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent; import net.neoforged.neoforge.event.entity.EntityTravelToDimensionEvent;
import net.minecraftforge.network.PacketDistributor; import net.neoforged.neoforge.network.PacketDistributor;
public class DimensionChangedHandler { public class DimensionChangedHandler {
@SubscribeEvent @SubscribeEvent
@ -14,9 +14,7 @@ public class DimensionChangedHandler {
} }
if(TurnBasedMinecraftMod.proxy.getBattleManager().forceLeaveBattle(new EntityIDDimPair(event.getEntity())) if(TurnBasedMinecraftMod.proxy.getBattleManager().forceLeaveBattle(new EntityIDDimPair(event.getEntity()))
&& event.getEntity() instanceof ServerPlayer) { && event.getEntity() instanceof ServerPlayer) {
TurnBasedMinecraftMod.getHandler().send( PacketDistributor.sendToPlayer((ServerPlayer)event.getEntity(), new PacketGeneralMessage("Left battle due to moving to a different dimension"));
PacketDistributor.PLAYER.with(() -> (ServerPlayer)event.getEntity()),
new PacketGeneralMessage("Left battle due to moving to a different dimension"));
} }
} }
} }

View file

@ -1,9 +1,12 @@
package com.burnedkirby.TurnBasedMinecraft.common; package com.burnedkirby.TurnBasedMinecraft.common;
import io.netty.buffer.ByteBuf;
import net.minecraft.world.effect.MobEffectInstance; import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.world.effect.MobEffects; import net.minecraft.world.effect.MobEffects;
import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.LivingEntity;
import java.nio.charset.StandardCharsets;
public class EntityInfo public class EntityInfo
{ {
public Class classType; public Class classType;
@ -276,7 +279,7 @@ public class EntityInfo
{ {
if(this == FIRE) if(this == FIRE)
{ {
entity.setSecondsOnFire(duration / 20); entity.setRemainingFireTicks(duration / 2);
return; return;
} }
else if(this != UNKNOWN) else if(this != UNKNOWN)
@ -373,6 +376,28 @@ public class EntityInfo
customName = new String(); customName = new String();
} }
public EntityInfo(Class classType, boolean ignoreBattle, int attackPower, int attackProbability, int attackVariance,
Effect attackEffect, int attackEffectProbability, int defenseDamage, int defenseDamageProbability,
int evasion, int speed, String category, int decisionAttack, int decisionDefend, int decisionFlee,
String customName) {
this.classType = classType;
this.ignoreBattle = ignoreBattle;
this.attackPower = attackPower;
this.attackProbability = attackProbability;
this.attackVariance = attackVariance;
this.attackEffect = attackEffect;
this.attackEffectProbability = attackEffectProbability;
this.defenseDamage = defenseDamage;
this.defenseDamageProbability = defenseDamageProbability;
this.evasion = evasion;
this.speed = speed;
this.category = category;
this.decisionAttack = decisionAttack;
this.decisionDefend = decisionDefend;
this.decisionFlee = decisionFlee;
this.customName = customName;
}
public EntityInfo clone() public EntityInfo clone()
{ {
EntityInfo newEntityInfo = new EntityInfo(); EntityInfo newEntityInfo = new EntityInfo();
@ -394,4 +419,93 @@ public class EntityInfo
newEntityInfo.customName = new String(customName); newEntityInfo.customName = new String(customName);
return newEntityInfo; return newEntityInfo;
} }
public EntityInfo(ByteBuf buffer) {
int name_bytes_len = buffer.readInt();
if (name_bytes_len > 0) {
ByteBuf name_bytes = buffer.readBytes(name_bytes_len);
try {
classType = Class.forName(name_bytes.toString(StandardCharsets.UTF_8));
} catch (ClassNotFoundException e) {
TurnBasedMinecraftMod.logger.warn("Failed to decode EntityInfo.classType", e);
classType = null;
}
} else {
classType = null;
}
ignoreBattle = buffer.readBoolean();
attackPower = buffer.readInt();
attackProbability = buffer.readInt();
attackVariance = buffer.readInt();
int effect_len = buffer.readInt();
ByteBuf effect_bytes = buffer.readBytes(effect_len);
attackEffect = Effect.fromString(effect_bytes.toString(StandardCharsets.UTF_8));
attackEffectProbability = buffer.readInt();
defenseDamage = buffer.readInt();
defenseDamageProbability = buffer.readInt();
evasion = buffer.readInt();
speed = buffer.readInt();
int category_len = buffer.readInt();
ByteBuf category_bytes = buffer.readBytes(category_len);
category = category_bytes.toString(StandardCharsets.UTF_8);
decisionAttack = buffer.readInt();
decisionDefend = buffer.readInt();
decisionFlee = buffer.readInt();
int custom_len = buffer.readInt();
if (custom_len > 0) {
ByteBuf custom_bytes = buffer.readBytes(custom_len);
customName = custom_bytes.toString(StandardCharsets.UTF_8);
} else {
customName = "";
}
}
public void encode(ByteBuf buffer) {
if (classType == null) {
buffer.writeInt(0);
} else {
String name = classType.getName();
byte[] name_bytes = name.getBytes(StandardCharsets.UTF_8);
buffer.writeInt(name_bytes.length);
buffer.writeBytes(name_bytes);
}
buffer.writeBoolean(ignoreBattle);
buffer.writeInt(attackPower);
buffer.writeInt(attackProbability);
buffer.writeInt(attackVariance);
String effect_name = attackEffect.toString();
byte[] effect_bytes = effect_name.getBytes(StandardCharsets.UTF_8);
buffer.writeInt(effect_bytes.length);
buffer.writeBytes(effect_bytes);
buffer.writeInt(attackEffectProbability);
buffer.writeInt(defenseDamage);
buffer.writeInt(defenseDamageProbability);
buffer.writeInt(evasion);
buffer.writeInt(speed);
byte[] category_bytes = category.getBytes(StandardCharsets.UTF_8);
buffer.writeInt(category_bytes.length);
buffer.writeBytes(category_bytes);
buffer.writeInt(decisionAttack);
buffer.writeInt(decisionDefend);
buffer.writeInt(decisionFlee);
if (customName.isEmpty()) {
buffer.writeInt(0);
} else {
byte[] custom_bytes = customName.getBytes(StandardCharsets.UTF_8);
buffer.writeInt(custom_bytes.length);
buffer.writeBytes(custom_bytes);
}
}
} }

View file

@ -1,11 +1,11 @@
package com.burnedkirby.TurnBasedMinecraft.common; package com.burnedkirby.TurnBasedMinecraft.common;
import net.minecraftforge.event.entity.living.LivingHurtEvent; import net.neoforged.bus.api.SubscribeEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent; import net.neoforged.neoforge.event.entity.living.LivingIncomingDamageEvent;
public class HurtEventHandler { public class HurtEventHandler {
@SubscribeEvent @SubscribeEvent
public void handleHurtEvent(LivingHurtEvent event) { public void handleHurtEvent(LivingIncomingDamageEvent event) {
CommonProxy proxy = TurnBasedMinecraftMod.proxy; CommonProxy proxy = TurnBasedMinecraftMod.proxy;
if (event.getEntity().level().isClientSide || proxy.getBattleManager() == null) { if (event.getEntity().level().isClientSide || proxy.getBattleManager() == null) {
return; return;

View file

@ -1,8 +1,8 @@
package com.burnedkirby.TurnBasedMinecraft.common; package com.burnedkirby.TurnBasedMinecraft.common;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
import net.minecraftforge.event.entity.EntityJoinLevelEvent; import net.neoforged.bus.api.SubscribeEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent; import net.neoforged.neoforge.event.entity.EntityJoinLevelEvent;
public class PlayerJoinEventHandler public class PlayerJoinEventHandler
{ {

View file

@ -0,0 +1,15 @@
package com.burnedkirby.TurnBasedMinecraft.common;
import com.burnedkirby.TurnBasedMinecraft.client.ClientConfig;
import com.burnedkirby.TurnBasedMinecraft.client.ClientConfigGui;
import net.neoforged.api.distmarker.Dist;
import net.neoforged.fml.ModContainer;
import net.neoforged.fml.common.Mod;
import net.neoforged.neoforge.client.gui.IConfigScreenFactory;
@Mod(value = TurnBasedMinecraftMod.MODID, dist = Dist.CLIENT)
public class TBMM_Client {
public TBMM_Client(ModContainer container) {
container.registerExtensionPoint(IConfigScreenFactory.class, ClientConfigGui::new);
}
}

View file

@ -1,5 +1,6 @@
package com.burnedkirby.TurnBasedMinecraft.common; package com.burnedkirby.TurnBasedMinecraft.common;
import com.burnedkirby.TurnBasedMinecraft.client.ClientConfig;
import com.burnedkirby.TurnBasedMinecraft.client.ClientProxy; import com.burnedkirby.TurnBasedMinecraft.client.ClientProxy;
import com.burnedkirby.TurnBasedMinecraft.common.networking.*; import com.burnedkirby.TurnBasedMinecraft.common.networking.*;
import com.mojang.brigadier.LiteralMessage; import com.mojang.brigadier.LiteralMessage;
@ -18,20 +19,22 @@ import net.minecraft.network.chat.HoverEvent;
import net.minecraft.network.chat.MutableComponent; import net.minecraft.network.chat.MutableComponent;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.level.ServerPlayer;
import net.minecraftforge.common.MinecraftForge; import net.neoforged.bus.api.SubscribeEvent;
import net.minecraftforge.event.RegisterCommandsEvent; import net.neoforged.fml.ModContainer;
import net.minecraftforge.event.server.ServerStartingEvent; import net.neoforged.fml.common.Mod;
import net.minecraftforge.event.server.ServerStoppingEvent; import net.neoforged.fml.config.ModConfig;
import net.minecraftforge.eventbus.api.SubscribeEvent; import net.neoforged.fml.event.lifecycle.FMLClientSetupEvent;
import net.minecraftforge.fml.DistExecutor; import net.neoforged.fml.event.lifecycle.FMLCommonSetupEvent;
import net.minecraftforge.fml.common.Mod; import net.neoforged.fml.event.lifecycle.FMLDedicatedServerSetupEvent;
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent; import net.neoforged.fml.loading.FMLEnvironment;
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent; import net.neoforged.neoforge.client.gui.IConfigScreenFactory;
import net.minecraftforge.fml.event.lifecycle.FMLDedicatedServerSetupEvent; import net.neoforged.neoforge.common.NeoForge;
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; import net.neoforged.neoforge.event.RegisterCommandsEvent;
import net.minecraftforge.network.NetworkRegistry; import net.neoforged.neoforge.event.server.ServerStartingEvent;
import net.minecraftforge.network.PacketDistributor; import net.neoforged.neoforge.event.server.ServerStoppingEvent;
import net.minecraftforge.network.simple.SimpleChannel; import net.neoforged.neoforge.network.PacketDistributor;
import net.neoforged.neoforge.network.event.RegisterPayloadHandlersEvent;
import net.neoforged.neoforge.network.registration.PayloadRegistrar;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
@ -39,7 +42,7 @@ import org.apache.logging.log4j.Logger;
public class TurnBasedMinecraftMod { public class TurnBasedMinecraftMod {
public static final String MODID = "com_burnedkirby_turnbasedminecraft"; public static final String MODID = "com_burnedkirby_turnbasedminecraft";
public static final String NAME = "Turn Based Minecraft Mod"; public static final String NAME = "Turn Based Minecraft Mod";
public static final String VERSION = "1.23.1"; public static final String VERSION = "1.26.0";
public static final String CONFIG_FILENAME = "TBM_Config.toml"; public static final String CONFIG_FILENAME = "TBM_Config.toml";
public static final String DEFAULT_CONFIG_FILENAME = "TBM_Config_DEFAULT.toml"; public static final String DEFAULT_CONFIG_FILENAME = "TBM_Config_DEFAULT.toml";
public static final String CONFIG_DIRECTORY = "config/TurnBasedMinecraft/"; public static final String CONFIG_DIRECTORY = "config/TurnBasedMinecraft/";
@ -50,83 +53,59 @@ public class TurnBasedMinecraftMod {
public static final String MUSIC_SILLY = MUSIC_ROOT + "silly/"; public static final String MUSIC_SILLY = MUSIC_ROOT + "silly/";
public static final String MUSIC_BATTLE = MUSIC_ROOT + "battle/"; public static final String MUSIC_BATTLE = MUSIC_ROOT + "battle/";
private static final String PROTOCOL_VERSION = Integer.toString(2); private static final String PROTOCOL_VERSION = Integer.toString(3);
private static final ResourceLocation HANDLER_ID = new ResourceLocation(MODID, "main_channel"); private static final ResourceLocation HANDLER_ID = ResourceLocation.fromNamespaceAndPath(MODID, "main_channel");
private static final SimpleChannel HANDLER = NetworkRegistry.ChannelBuilder
.named(HANDLER_ID)
.clientAcceptedVersions(PROTOCOL_VERSION::equals)
.serverAcceptedVersions(PROTOCOL_VERSION::equals)
.networkProtocolVersion(() -> PROTOCOL_VERSION)
.simpleChannel();
protected static Logger logger = LogManager.getLogger(); protected static Logger logger = LogManager.getLogger();
public static ResourceLocation getNetResourceLocation() { public static ResourceLocation getNetResourceLocation() {
return HANDLER_ID; return HANDLER_ID;
} }
public static SimpleChannel getHandler() {
return HANDLER;
}
public static CommonProxy proxy; public static CommonProxy proxy;
public TurnBasedMinecraftMod() { public TurnBasedMinecraftMod(ModContainer container) {
FMLJavaModLoadingContext.get().getModEventBus().addListener(this::firstInit); container.getEventBus().addListener(this::firstInit);
FMLJavaModLoadingContext.get().getModEventBus().addListener(this::secondInitClient); container.getEventBus().addListener(this::secondInitClient);
FMLJavaModLoadingContext.get().getModEventBus().addListener(this::secondInitServer); container.getEventBus().addListener(this::secondInitServer);
container.getEventBus().addListener(this::registerNetwork);
NeoForge.EVENT_BUS.register(this);
container.registerConfig(ModConfig.Type.CLIENT, ClientConfig.CLIENT_SPEC);
}
MinecraftForge.EVENT_BUS.register(this); private void registerNetwork(final RegisterPayloadHandlersEvent event) {
final PayloadRegistrar registrar = event.registrar(PROTOCOL_VERSION);
registrar.playToServer(PacketBattleDecision.TYPE, PacketBattleDecision.STREAM_CODEC, new PacketBattleDecision.PayloadHandler());
registrar.playToClient(PacketBattleInfo.TYPE, PacketBattleInfo.STREAM_CODEC, new PacketBattleInfo.PayloadHandler());
registrar.playToClient(PacketBattleMessage.TYPE, PacketBattleMessage.STREAM_CODEC, new PacketBattleMessage.PayloadHandler());
registrar.playToServer(PacketBattleRequestInfo.TYPE, PacketBattleRequestInfo.STREAM_CODEC, new PacketBattleRequestInfo.PayloadHandler());
registrar.playToClient(PacketEditingMessage.TYPE, PacketEditingMessage.STREAM_CODEC, new PacketEditingMessage.PayloadHandler());
registrar.playToClient(PacketGeneralMessage.TYPE, PacketGeneralMessage.STREAM_CODEC, new PacketGeneralMessage.PayloadHandler());
registrar.playToClient(PacketClientGUI.TYPE, PacketClientGUI.STREAM_CODEC, new PacketClientGUI.PayloadHandler());
logger.debug("Register packets com_burnedkirby_turnbasedminecraft");
} }
private void firstInit(final FMLCommonSetupEvent event) { private void firstInit(final FMLCommonSetupEvent event) {
proxy = DistExecutor.safeRunForDist(() -> ClientProxy::new, () -> CommonProxy::new); if (FMLEnvironment.dist.isClient()) {
proxy = new ClientProxy();
} else {
proxy = new CommonProxy();
}
proxy.setLogger(logger); proxy.setLogger(logger);
proxy.initialize(); proxy.initialize();
// register packets
int packetHandlerID = 0;
HANDLER.registerMessage(
packetHandlerID++,
PacketBattleInfo.class,
PacketBattleInfo::encode,
PacketBattleInfo::decode,
PacketBattleInfo::handle);
HANDLER.registerMessage(
packetHandlerID++,
PacketBattleRequestInfo.class,
PacketBattleRequestInfo::encode,
PacketBattleRequestInfo::decode,
PacketBattleRequestInfo::handle);
HANDLER.registerMessage(
packetHandlerID++,
PacketBattleDecision.class,
PacketBattleDecision::encode,
PacketBattleDecision::decode,
PacketBattleDecision::handle);
HANDLER.registerMessage(
packetHandlerID++,
PacketBattleMessage.class,
PacketBattleMessage::encode,
PacketBattleMessage::decode,
PacketBattleMessage::handle);
HANDLER.registerMessage(
packetHandlerID++,
PacketGeneralMessage.class,
PacketGeneralMessage::encode,
PacketGeneralMessage::decode,
PacketGeneralMessage::handle);
HANDLER.registerMessage(
packetHandlerID++,
PacketEditingMessage.class,
PacketEditingMessage::encode,
PacketEditingMessage::decode,
PacketEditingMessage::handle);
// register event handler(s) // register event handler(s)
MinecraftForge.EVENT_BUS.register(new AttackEventHandler()); NeoForge.EVENT_BUS.register(new AttackEventHandler());
MinecraftForge.EVENT_BUS.register(new PlayerJoinEventHandler()); NeoForge.EVENT_BUS.register(new PlayerJoinEventHandler());
MinecraftForge.EVENT_BUS.register(new DimensionChangedHandler()); NeoForge.EVENT_BUS.register(new DimensionChangedHandler());
MinecraftForge.EVENT_BUS.register(new HurtEventHandler()); NeoForge.EVENT_BUS.register(new HurtEventHandler());
logger.debug("Init com_burnedkirby_turnbasedminecraft"); logger.debug("Init com_burnedkirby_turnbasedminecraft");
} }
@ -172,7 +151,8 @@ public class TurnBasedMinecraftMod {
proxy.getConfig().setBattleDisabledForAll(true); proxy.getConfig().setBattleDisabledForAll(true);
for (ServerPlayer player : c.getSource().getServer().getPlayerList().getPlayers()) { for (ServerPlayer player : c.getSource().getServer().getPlayerList().getPlayers()) {
proxy.getConfig().addBattleIgnoringPlayer(player.getId()); proxy.getConfig().addBattleIgnoringPlayer(player.getId());
getHandler().send(PacketDistributor.PLAYER.with(() -> player), new PacketGeneralMessage("OP disabled turn-based-combat for everyone")); PacketDistributor.sendToPlayer(player, new PacketGeneralMessage("OP disabled turn-based-combat for everyone"));
PacketDistributor.sendToPlayer(player, new PacketGeneralMessage("OP disabled turn-based-combat for everyone"));
} }
return 1; return 1;
})); }));
@ -193,7 +173,7 @@ public class TurnBasedMinecraftMod {
proxy.getConfig().setBattleDisabledForAll(false); proxy.getConfig().setBattleDisabledForAll(false);
proxy.getConfig().clearBattleIgnoringPlayers(); proxy.getConfig().clearBattleIgnoringPlayers();
for (ServerPlayer player : c.getSource().getServer().getPlayerList().getPlayers()) { for (ServerPlayer player : c.getSource().getServer().getPlayerList().getPlayers()) {
getHandler().send(PacketDistributor.PLAYER.with(() -> player), new PacketGeneralMessage("OP enabled turn-based-combat for everyone")); PacketDistributor.sendToPlayer(player, new PacketGeneralMessage("OP enabled turn-based-combat for everyone"));
} }
return 1; return 1;
})); }));
@ -204,7 +184,7 @@ public class TurnBasedMinecraftMod {
.then(Commands.argument("targets", EntityArgument.players()).executes(c -> { .then(Commands.argument("targets", EntityArgument.players()).executes(c -> {
for (ServerPlayer player : EntityArgument.getPlayers(c, "targets")) { for (ServerPlayer player : EntityArgument.getPlayers(c, "targets")) {
proxy.getConfig().addBattleIgnoringPlayer(player.getId()); proxy.getConfig().addBattleIgnoringPlayer(player.getId());
getHandler().send(PacketDistributor.PLAYER.with(() -> player), new PacketGeneralMessage("OP enabled turn-based-combat for you")); PacketDistributor.sendToPlayer(player, new PacketGeneralMessage("OP enabled turn-based-combat for you"));
c.getSource().sendSuccess(() -> Component.literal("Enabled turn-based-combat for " + player.getDisplayName().getString()), true); c.getSource().sendSuccess(() -> Component.literal("Enabled turn-based-combat for " + player.getDisplayName().getString()), true);
} }
return 1; return 1;
@ -216,7 +196,7 @@ public class TurnBasedMinecraftMod {
.then(Commands.argument("targets", EntityArgument.players()).executes(c -> { .then(Commands.argument("targets", EntityArgument.players()).executes(c -> {
for (ServerPlayer player : EntityArgument.getPlayers(c, "targets")) { for (ServerPlayer player : EntityArgument.getPlayers(c, "targets")) {
proxy.getConfig().removeBattleIgnoringPlayer(player.getId()); proxy.getConfig().removeBattleIgnoringPlayer(player.getId());
getHandler().send(PacketDistributor.PLAYER.with(() -> player), new PacketGeneralMessage("OP disabled turn-based-combat for you")); PacketDistributor.sendToPlayer(player, new PacketGeneralMessage("OP disabled turn-based-combat for you"));
c.getSource().sendSuccess(() -> Component.literal("Disabled turn-based-combat for " + player.getDisplayName().getString()), true); c.getSource().sendSuccess(() -> Component.literal("Disabled turn-based-combat for " + player.getDisplayName().getString()), true);
} }
return 1; return 1;
@ -229,12 +209,12 @@ public class TurnBasedMinecraftMod {
ServerPlayer player = c.getSource().getPlayerOrException(); ServerPlayer player = c.getSource().getPlayerOrException();
EditingInfo editingInfo = proxy.getEditingInfo(player.getId()); EditingInfo editingInfo = proxy.getEditingInfo(player.getId());
if (editingInfo != null && !editingInfo.isPendingEntitySelection) { if (editingInfo != null && !editingInfo.isPendingEntitySelection) {
getHandler().send(PacketDistributor.PLAYER.with(() -> player), new PacketEditingMessage(PacketEditingMessage.Type.PICK_EDIT, editingInfo.entityInfo)); PacketDistributor.sendToPlayer(player, new PacketEditingMessage(PacketEditingMessage.Type.PICK_EDIT, editingInfo.entityInfo));
} else if (editingInfo != null) { } else if (editingInfo != null) {
getHandler().send(PacketDistributor.PLAYER.with(() -> player), new PacketEditingMessage(PacketEditingMessage.Type.ATTACK_ENTITY)); PacketDistributor.sendToPlayer(player, new PacketEditingMessage(PacketEditingMessage.Type.ATTACK_ENTITY));
} else { } else {
proxy.setEditingPlayer(player); proxy.setEditingPlayer(player);
getHandler().send(PacketDistributor.PLAYER.with(() -> player), new PacketEditingMessage(PacketEditingMessage.Type.ATTACK_ENTITY)); PacketDistributor.sendToPlayer(player, new PacketEditingMessage(PacketEditingMessage.Type.ATTACK_ENTITY));
logger.info("Begin editing TBM Entity for player \"" + player.getDisplayName().getString() + "\" (\"" + c.getSource().getDisplayName() + "\")"); logger.info("Begin editing TBM Entity for player \"" + player.getDisplayName().getString() + "\" (\"" + c.getSource().getDisplayName() + "\")");
} }
return 1; return 1;
@ -245,14 +225,14 @@ public class TurnBasedMinecraftMod {
EditingInfo editingInfo = TurnBasedMinecraftMod.proxy.getEditingInfo(player.getId()); EditingInfo editingInfo = TurnBasedMinecraftMod.proxy.getEditingInfo(player.getId());
if (editingInfo != null && !editingInfo.isPendingEntitySelection) { if (editingInfo != null && !editingInfo.isPendingEntitySelection) {
if (!proxy.getConfig().editEntityEntry(editingInfo.entityInfo)) { if (!proxy.getConfig().editEntityEntry(editingInfo.entityInfo)) {
getHandler().send(PacketDistributor.PLAYER.with(() -> player), new PacketGeneralMessage("An error occurred while attempting to save an entry to the config")); PacketDistributor.sendToPlayer(player, new PacketGeneralMessage("An error occurred while attempting to save an entry to the config"));
proxy.removeEditingInfo(player.getId()); proxy.removeEditingInfo(player.getId());
} else { } else {
proxy.removeEditingInfo(player.getId()); proxy.removeEditingInfo(player.getId());
getHandler().send(PacketDistributor.PLAYER.with(() -> player), new PacketGeneralMessage("Entity info saved in config and loaded.")); PacketDistributor.sendToPlayer(player, new PacketGeneralMessage("Entity info saved in config and loaded."));
} }
} else if (editingInfo != null) { } else if (editingInfo != null) {
getHandler().send(PacketDistributor.PLAYER.with(() -> player), new PacketEditingMessage(PacketEditingMessage.Type.ATTACK_ENTITY)); PacketDistributor.sendToPlayer(player, new PacketEditingMessage(PacketEditingMessage.Type.ATTACK_ENTITY));
} else { } else {
Message exceptionMessage = new LiteralMessage("Cannot edit entity without starting editing (use \"/tbm-edit\")."); Message exceptionMessage = new LiteralMessage("Cannot edit entity without starting editing (use \"/tbm-edit\").");
throw new CommandSyntaxException(new SimpleCommandExceptionType(exceptionMessage), exceptionMessage); throw new CommandSyntaxException(new SimpleCommandExceptionType(exceptionMessage), exceptionMessage);
@ -265,7 +245,7 @@ public class TurnBasedMinecraftMod {
EditingInfo editingInfo = TurnBasedMinecraftMod.proxy.getEditingInfo(player.getId()); EditingInfo editingInfo = TurnBasedMinecraftMod.proxy.getEditingInfo(player.getId());
if (editingInfo != null) { if (editingInfo != null) {
proxy.removeEditingInfo(player.getId()); proxy.removeEditingInfo(player.getId());
getHandler().send(PacketDistributor.PLAYER.with(() -> player), new PacketGeneralMessage("Cancelled editing entry.")); PacketDistributor.sendToPlayer(player, new PacketGeneralMessage("Cancelled editing entry."));
} }
return 1; return 1;
})) }))
@ -277,11 +257,11 @@ public class TurnBasedMinecraftMod {
Message exceptionMessage = new LiteralMessage("Invalid action for tbm-edit"); Message exceptionMessage = new LiteralMessage("Invalid action for tbm-edit");
throw new CommandSyntaxException(new SimpleCommandExceptionType(exceptionMessage), exceptionMessage); throw new CommandSyntaxException(new SimpleCommandExceptionType(exceptionMessage), exceptionMessage);
} else if (editingInfo != null) { } else if (editingInfo != null) {
getHandler().send(PacketDistributor.PLAYER.with(() -> player), new PacketEditingMessage(PacketEditingMessage.Type.ATTACK_ENTITY)); PacketDistributor.sendToPlayer(player, new PacketEditingMessage(PacketEditingMessage.Type.ATTACK_ENTITY));
} else { } else {
proxy.setEditingPlayer(player); proxy.setEditingPlayer(player);
proxy.getEditingInfo(player.getId()).isEditingCustomName = true; proxy.getEditingInfo(player.getId()).isEditingCustomName = true;
getHandler().send(PacketDistributor.PLAYER.with(() -> player), new PacketEditingMessage(PacketEditingMessage.Type.ATTACK_ENTITY)); PacketDistributor.sendToPlayer(player, new PacketEditingMessage(PacketEditingMessage.Type.ATTACK_ENTITY));
logger.info("Begin editing custom TBM Entity for player \"" + player.getDisplayName().getString() + "\" (\"" + c.getSource().getDisplayName() + "\")"); logger.info("Begin editing custom TBM Entity for player \"" + player.getDisplayName().getString() + "\" (\"" + c.getSource().getDisplayName() + "\")");
} }
return 1; return 1;
@ -291,9 +271,9 @@ public class TurnBasedMinecraftMod {
ServerPlayer player = c.getSource().getPlayerOrException(); ServerPlayer player = c.getSource().getPlayerOrException();
EditingInfo editingInfo = TurnBasedMinecraftMod.proxy.getEditingInfo(player.getId()); EditingInfo editingInfo = TurnBasedMinecraftMod.proxy.getEditingInfo(player.getId());
if (editingInfo != null && !editingInfo.isPendingEntitySelection) { if (editingInfo != null && !editingInfo.isPendingEntitySelection) {
getHandler().send(PacketDistributor.PLAYER.with(() -> player), new PacketEditingMessage(PacketEditingMessage.Type.PICK_EDIT, editingInfo.entityInfo)); PacketDistributor.sendToPlayer(player, new PacketEditingMessage(PacketEditingMessage.Type.PICK_EDIT, editingInfo.entityInfo));
} else if (editingInfo != null) { } else if (editingInfo != null) {
getHandler().send(PacketDistributor.PLAYER.with(() -> player), new PacketEditingMessage(PacketEditingMessage.Type.ATTACK_ENTITY)); PacketDistributor.sendToPlayer(player, new PacketEditingMessage(PacketEditingMessage.Type.ATTACK_ENTITY));
} else { } else {
Message exceptionMessage = new LiteralMessage("Cannot edit entity without starting editing (use \"/tbm-edit\")."); Message exceptionMessage = new LiteralMessage("Cannot edit entity without starting editing (use \"/tbm-edit\").");
throw new CommandSyntaxException(new SimpleCommandExceptionType(exceptionMessage), exceptionMessage); throw new CommandSyntaxException(new SimpleCommandExceptionType(exceptionMessage), exceptionMessage);
@ -305,9 +285,9 @@ public class TurnBasedMinecraftMod {
ServerPlayer player = c.getSource().getPlayerOrException(); ServerPlayer player = c.getSource().getPlayerOrException();
EditingInfo editingInfo = TurnBasedMinecraftMod.proxy.getEditingInfo(player.getId()); EditingInfo editingInfo = TurnBasedMinecraftMod.proxy.getEditingInfo(player.getId());
if (editingInfo != null && !editingInfo.isPendingEntitySelection) { if (editingInfo != null && !editingInfo.isPendingEntitySelection) {
getHandler().send(PacketDistributor.PLAYER.with(() -> player), new PacketEditingMessage(PacketEditingMessage.Type.EDIT_IGNORE_BATTLE)); PacketDistributor.sendToPlayer(player, new PacketEditingMessage(PacketEditingMessage.Type.EDIT_IGNORE_BATTLE));
} else if (editingInfo != null) { } else if (editingInfo != null) {
getHandler().send(PacketDistributor.PLAYER.with(() -> player), new PacketEditingMessage(PacketEditingMessage.Type.ATTACK_ENTITY)); PacketDistributor.sendToPlayer(player, new PacketEditingMessage(PacketEditingMessage.Type.ATTACK_ENTITY));
} else { } else {
Message exceptionMessage = new LiteralMessage("Cannot edit entity without starting editing (use \"/tbm-edit\")."); Message exceptionMessage = new LiteralMessage("Cannot edit entity without starting editing (use \"/tbm-edit\").");
throw new CommandSyntaxException(new SimpleCommandExceptionType(exceptionMessage), exceptionMessage); throw new CommandSyntaxException(new SimpleCommandExceptionType(exceptionMessage), exceptionMessage);
@ -321,9 +301,9 @@ public class TurnBasedMinecraftMod {
boolean ignoreBattle = BoolArgumentType.getBool(c, "ignoreBattle"); boolean ignoreBattle = BoolArgumentType.getBool(c, "ignoreBattle");
if (editingInfo != null && !editingInfo.isPendingEntitySelection) { if (editingInfo != null && !editingInfo.isPendingEntitySelection) {
editingInfo.entityInfo.ignoreBattle = ignoreBattle; editingInfo.entityInfo.ignoreBattle = ignoreBattle;
getHandler().send(PacketDistributor.PLAYER.with(() -> player), new PacketEditingMessage(PacketEditingMessage.Type.PICK_EDIT, editingInfo.entityInfo)); PacketDistributor.sendToPlayer(player, new PacketEditingMessage(PacketEditingMessage.Type.PICK_EDIT, editingInfo.entityInfo));
} else if (editingInfo != null) { } else if (editingInfo != null) {
getHandler().send(PacketDistributor.PLAYER.with(() -> player), new PacketEditingMessage(PacketEditingMessage.Type.ATTACK_ENTITY)); PacketDistributor.sendToPlayer(player, new PacketEditingMessage(PacketEditingMessage.Type.ATTACK_ENTITY));
} else { } else {
Message exceptionMessage = new LiteralMessage("Cannot edit entity without starting editing (use \"/tbm-edit\")."); Message exceptionMessage = new LiteralMessage("Cannot edit entity without starting editing (use \"/tbm-edit\").");
throw new CommandSyntaxException(new SimpleCommandExceptionType(exceptionMessage), exceptionMessage); throw new CommandSyntaxException(new SimpleCommandExceptionType(exceptionMessage), exceptionMessage);
@ -336,9 +316,9 @@ public class TurnBasedMinecraftMod {
ServerPlayer player = c.getSource().getPlayerOrException(); ServerPlayer player = c.getSource().getPlayerOrException();
EditingInfo editingInfo = TurnBasedMinecraftMod.proxy.getEditingInfo(player.getId()); EditingInfo editingInfo = TurnBasedMinecraftMod.proxy.getEditingInfo(player.getId());
if (editingInfo != null && !editingInfo.isPendingEntitySelection) { if (editingInfo != null && !editingInfo.isPendingEntitySelection) {
getHandler().send(PacketDistributor.PLAYER.with(() -> player), new PacketEditingMessage(PacketEditingMessage.Type.EDIT_ATTACK_POWER)); PacketDistributor.sendToPlayer(player, new PacketEditingMessage(PacketEditingMessage.Type.EDIT_ATTACK_POWER));
} else if (editingInfo != null) { } else if (editingInfo != null) {
getHandler().send(PacketDistributor.PLAYER.with(() -> player), new PacketEditingMessage(PacketEditingMessage.Type.ATTACK_ENTITY)); PacketDistributor.sendToPlayer(player, new PacketEditingMessage(PacketEditingMessage.Type.ATTACK_ENTITY));
} else { } else {
Message exceptionMessage = new LiteralMessage("Cannot edit entity without starting editing (use \"/tbm-edit\")."); Message exceptionMessage = new LiteralMessage("Cannot edit entity without starting editing (use \"/tbm-edit\").");
throw new CommandSyntaxException(new SimpleCommandExceptionType(exceptionMessage), exceptionMessage); throw new CommandSyntaxException(new SimpleCommandExceptionType(exceptionMessage), exceptionMessage);
@ -355,9 +335,9 @@ public class TurnBasedMinecraftMod {
} }
if (editingInfo != null && !editingInfo.isPendingEntitySelection) { if (editingInfo != null && !editingInfo.isPendingEntitySelection) {
editingInfo.entityInfo.attackPower = attackPower; editingInfo.entityInfo.attackPower = attackPower;
getHandler().send(PacketDistributor.PLAYER.with(() -> player), new PacketEditingMessage(PacketEditingMessage.Type.PICK_EDIT, editingInfo.entityInfo)); PacketDistributor.sendToPlayer(player, new PacketEditingMessage(PacketEditingMessage.Type.PICK_EDIT, editingInfo.entityInfo));
} else if (editingInfo != null) { } else if (editingInfo != null) {
getHandler().send(PacketDistributor.PLAYER.with(() -> player), new PacketEditingMessage(PacketEditingMessage.Type.ATTACK_ENTITY)); PacketDistributor.sendToPlayer(player, new PacketEditingMessage(PacketEditingMessage.Type.ATTACK_ENTITY));
} else { } else {
Message exceptionMessage = new LiteralMessage("Cannot edit entity without starting editing (use \"/tbm-edit\")."); Message exceptionMessage = new LiteralMessage("Cannot edit entity without starting editing (use \"/tbm-edit\").");
throw new CommandSyntaxException(new SimpleCommandExceptionType(exceptionMessage), exceptionMessage); throw new CommandSyntaxException(new SimpleCommandExceptionType(exceptionMessage), exceptionMessage);
@ -370,9 +350,9 @@ public class TurnBasedMinecraftMod {
ServerPlayer player = c.getSource().getPlayerOrException(); ServerPlayer player = c.getSource().getPlayerOrException();
EditingInfo editingInfo = TurnBasedMinecraftMod.proxy.getEditingInfo(player.getId()); EditingInfo editingInfo = TurnBasedMinecraftMod.proxy.getEditingInfo(player.getId());
if (editingInfo != null && !editingInfo.isPendingEntitySelection) { if (editingInfo != null && !editingInfo.isPendingEntitySelection) {
getHandler().send(PacketDistributor.PLAYER.with(() -> player), new PacketEditingMessage(PacketEditingMessage.Type.EDIT_ATTACK_PROBABILITY)); PacketDistributor.sendToPlayer(player, new PacketEditingMessage(PacketEditingMessage.Type.EDIT_ATTACK_PROBABILITY));
} else if (editingInfo != null) { } else if (editingInfo != null) {
getHandler().send(PacketDistributor.PLAYER.with(() -> player), new PacketEditingMessage(PacketEditingMessage.Type.ATTACK_ENTITY)); PacketDistributor.sendToPlayer(player, new PacketEditingMessage(PacketEditingMessage.Type.ATTACK_ENTITY));
} else { } else {
Message exceptionMessage = new LiteralMessage("Cannot edit entity without starting editing (use \"/tbm-edit\")."); Message exceptionMessage = new LiteralMessage("Cannot edit entity without starting editing (use \"/tbm-edit\").");
throw new CommandSyntaxException(new SimpleCommandExceptionType(exceptionMessage), exceptionMessage); throw new CommandSyntaxException(new SimpleCommandExceptionType(exceptionMessage), exceptionMessage);
@ -391,9 +371,9 @@ public class TurnBasedMinecraftMod {
} }
if (editingInfo != null && !editingInfo.isPendingEntitySelection) { if (editingInfo != null && !editingInfo.isPendingEntitySelection) {
editingInfo.entityInfo.attackProbability = attackProbability; editingInfo.entityInfo.attackProbability = attackProbability;
getHandler().send(PacketDistributor.PLAYER.with(() -> player), new PacketEditingMessage(PacketEditingMessage.Type.PICK_EDIT, editingInfo.entityInfo)); PacketDistributor.sendToPlayer(player, new PacketEditingMessage(PacketEditingMessage.Type.PICK_EDIT, editingInfo.entityInfo));
} else if (editingInfo != null) { } else if (editingInfo != null) {
getHandler().send(PacketDistributor.PLAYER.with(() -> player), new PacketEditingMessage(PacketEditingMessage.Type.ATTACK_ENTITY)); PacketDistributor.sendToPlayer(player, new PacketEditingMessage(PacketEditingMessage.Type.ATTACK_ENTITY));
} else { } else {
Message exceptionMessage = new LiteralMessage("Cannot edit entity without starting editing (use \"/tbm-edit\")."); Message exceptionMessage = new LiteralMessage("Cannot edit entity without starting editing (use \"/tbm-edit\").");
throw new CommandSyntaxException(new SimpleCommandExceptionType(exceptionMessage), exceptionMessage); throw new CommandSyntaxException(new SimpleCommandExceptionType(exceptionMessage), exceptionMessage);
@ -406,9 +386,9 @@ public class TurnBasedMinecraftMod {
ServerPlayer player = c.getSource().getPlayerOrException(); ServerPlayer player = c.getSource().getPlayerOrException();
EditingInfo editingInfo = TurnBasedMinecraftMod.proxy.getEditingInfo(player.getId()); EditingInfo editingInfo = TurnBasedMinecraftMod.proxy.getEditingInfo(player.getId());
if (editingInfo != null && !editingInfo.isPendingEntitySelection) { if (editingInfo != null && !editingInfo.isPendingEntitySelection) {
getHandler().send(PacketDistributor.PLAYER.with(() -> player), new PacketEditingMessage(PacketEditingMessage.Type.EDIT_ATTACK_VARIANCE)); PacketDistributor.sendToPlayer(player, new PacketEditingMessage(PacketEditingMessage.Type.EDIT_ATTACK_VARIANCE));
} else if (editingInfo != null) { } else if (editingInfo != null) {
getHandler().send(PacketDistributor.PLAYER.with(() -> player), new PacketEditingMessage(PacketEditingMessage.Type.ATTACK_ENTITY)); PacketDistributor.sendToPlayer(player, new PacketEditingMessage(PacketEditingMessage.Type.ATTACK_ENTITY));
} else { } else {
Message exceptionMessage = new LiteralMessage("Cannot edit entity without starting editing (use \"/tbm-edit\")."); Message exceptionMessage = new LiteralMessage("Cannot edit entity without starting editing (use \"/tbm-edit\").");
throw new CommandSyntaxException(new SimpleCommandExceptionType(exceptionMessage), exceptionMessage); throw new CommandSyntaxException(new SimpleCommandExceptionType(exceptionMessage), exceptionMessage);
@ -425,9 +405,9 @@ public class TurnBasedMinecraftMod {
} }
if (editingInfo != null && !editingInfo.isPendingEntitySelection) { if (editingInfo != null && !editingInfo.isPendingEntitySelection) {
editingInfo.entityInfo.attackVariance = attackVariance; editingInfo.entityInfo.attackVariance = attackVariance;
getHandler().send(PacketDistributor.PLAYER.with(() -> player), new PacketEditingMessage(PacketEditingMessage.Type.PICK_EDIT, editingInfo.entityInfo)); PacketDistributor.sendToPlayer(player, new PacketEditingMessage(PacketEditingMessage.Type.PICK_EDIT, editingInfo.entityInfo));
} else if (editingInfo != null) { } else if (editingInfo != null) {
getHandler().send(PacketDistributor.PLAYER.with(() -> player), new PacketEditingMessage(PacketEditingMessage.Type.ATTACK_ENTITY)); PacketDistributor.sendToPlayer(player, new PacketEditingMessage(PacketEditingMessage.Type.ATTACK_ENTITY));
} else { } else {
Message exceptionMessage = new LiteralMessage("Cannot edit entity without starting editing (use \"/tbm-edit\")."); Message exceptionMessage = new LiteralMessage("Cannot edit entity without starting editing (use \"/tbm-edit\").");
throw new CommandSyntaxException(new SimpleCommandExceptionType(exceptionMessage), exceptionMessage); throw new CommandSyntaxException(new SimpleCommandExceptionType(exceptionMessage), exceptionMessage);
@ -440,9 +420,9 @@ public class TurnBasedMinecraftMod {
ServerPlayer player = c.getSource().getPlayerOrException(); ServerPlayer player = c.getSource().getPlayerOrException();
EditingInfo editingInfo = TurnBasedMinecraftMod.proxy.getEditingInfo(player.getId()); EditingInfo editingInfo = TurnBasedMinecraftMod.proxy.getEditingInfo(player.getId());
if (editingInfo != null && !editingInfo.isPendingEntitySelection) { if (editingInfo != null && !editingInfo.isPendingEntitySelection) {
getHandler().send(PacketDistributor.PLAYER.with(() -> player), new PacketEditingMessage(PacketEditingMessage.Type.EDIT_ATTACK_EFFECT)); PacketDistributor.sendToPlayer(player, new PacketEditingMessage(PacketEditingMessage.Type.EDIT_ATTACK_EFFECT));
} else if (editingInfo != null) { } else if (editingInfo != null) {
getHandler().send(PacketDistributor.PLAYER.with(() -> player), new PacketEditingMessage(PacketEditingMessage.Type.ATTACK_ENTITY)); PacketDistributor.sendToPlayer(player, new PacketEditingMessage(PacketEditingMessage.Type.ATTACK_ENTITY));
} else { } else {
Message exceptionMessage = new LiteralMessage("Cannot edit entity without starting editing (use \"/tbm-edit\")."); Message exceptionMessage = new LiteralMessage("Cannot edit entity without starting editing (use \"/tbm-edit\").");
throw new CommandSyntaxException(new SimpleCommandExceptionType(exceptionMessage), exceptionMessage); throw new CommandSyntaxException(new SimpleCommandExceptionType(exceptionMessage), exceptionMessage);
@ -456,9 +436,9 @@ public class TurnBasedMinecraftMod {
EntityInfo.Effect effect = EntityInfo.Effect.fromString(StringArgumentType.getString(c, "attackEffect")); EntityInfo.Effect effect = EntityInfo.Effect.fromString(StringArgumentType.getString(c, "attackEffect"));
if (editingInfo != null && !editingInfo.isPendingEntitySelection) { if (editingInfo != null && !editingInfo.isPendingEntitySelection) {
editingInfo.entityInfo.attackEffect = effect; editingInfo.entityInfo.attackEffect = effect;
getHandler().send(PacketDistributor.PLAYER.with(() -> player), new PacketEditingMessage(PacketEditingMessage.Type.PICK_EDIT, editingInfo.entityInfo)); PacketDistributor.sendToPlayer(player, new PacketEditingMessage(PacketEditingMessage.Type.PICK_EDIT, editingInfo.entityInfo));
} else if (editingInfo != null) { } else if (editingInfo != null) {
getHandler().send(PacketDistributor.PLAYER.with(() -> player), new PacketEditingMessage(PacketEditingMessage.Type.ATTACK_ENTITY)); PacketDistributor.sendToPlayer(player, new PacketEditingMessage(PacketEditingMessage.Type.ATTACK_ENTITY));
} else { } else {
Message exceptionMessage = new LiteralMessage("Cannot edit entity without starting editing (use \"/tbm-edit\")."); Message exceptionMessage = new LiteralMessage("Cannot edit entity without starting editing (use \"/tbm-edit\").");
throw new CommandSyntaxException(new SimpleCommandExceptionType(exceptionMessage), exceptionMessage); throw new CommandSyntaxException(new SimpleCommandExceptionType(exceptionMessage), exceptionMessage);
@ -471,9 +451,9 @@ public class TurnBasedMinecraftMod {
ServerPlayer player = c.getSource().getPlayerOrException(); ServerPlayer player = c.getSource().getPlayerOrException();
EditingInfo editingInfo = TurnBasedMinecraftMod.proxy.getEditingInfo(player.getId()); EditingInfo editingInfo = TurnBasedMinecraftMod.proxy.getEditingInfo(player.getId());
if (editingInfo != null && !editingInfo.isPendingEntitySelection) { if (editingInfo != null && !editingInfo.isPendingEntitySelection) {
getHandler().send(PacketDistributor.PLAYER.with(() -> player), new PacketEditingMessage(PacketEditingMessage.Type.EDIT_ATTACK_EFFECT_PROBABILITY)); PacketDistributor.sendToPlayer(player, new PacketEditingMessage(PacketEditingMessage.Type.EDIT_ATTACK_EFFECT_PROBABILITY));
} else if (editingInfo != null) { } else if (editingInfo != null) {
getHandler().send(PacketDistributor.PLAYER.with(() -> player), new PacketEditingMessage(PacketEditingMessage.Type.ATTACK_ENTITY)); PacketDistributor.sendToPlayer(player, new PacketEditingMessage(PacketEditingMessage.Type.ATTACK_ENTITY));
} else { } else {
Message exceptionMessage = new LiteralMessage("Cannot edit entity without starting editing (use \"/tbm-edit\")."); Message exceptionMessage = new LiteralMessage("Cannot edit entity without starting editing (use \"/tbm-edit\").");
throw new CommandSyntaxException(new SimpleCommandExceptionType(exceptionMessage), exceptionMessage); throw new CommandSyntaxException(new SimpleCommandExceptionType(exceptionMessage), exceptionMessage);
@ -492,9 +472,9 @@ public class TurnBasedMinecraftMod {
} }
if (editingInfo != null && !editingInfo.isPendingEntitySelection) { if (editingInfo != null && !editingInfo.isPendingEntitySelection) {
editingInfo.entityInfo.attackEffectProbability = attackEffectProbability; editingInfo.entityInfo.attackEffectProbability = attackEffectProbability;
getHandler().send(PacketDistributor.PLAYER.with(() -> player), new PacketEditingMessage(PacketEditingMessage.Type.PICK_EDIT, editingInfo.entityInfo)); PacketDistributor.sendToPlayer(player, new PacketEditingMessage(PacketEditingMessage.Type.PICK_EDIT, editingInfo.entityInfo));
} else if (editingInfo != null) { } else if (editingInfo != null) {
getHandler().send(PacketDistributor.PLAYER.with(() -> player), new PacketEditingMessage(PacketEditingMessage.Type.ATTACK_ENTITY)); PacketDistributor.sendToPlayer(player, new PacketEditingMessage(PacketEditingMessage.Type.ATTACK_ENTITY));
} else { } else {
Message exceptionMessage = new LiteralMessage("Cannot edit entity without starting editing (use \"/tbm-edit\")."); Message exceptionMessage = new LiteralMessage("Cannot edit entity without starting editing (use \"/tbm-edit\").");
throw new CommandSyntaxException(new SimpleCommandExceptionType(exceptionMessage), exceptionMessage); throw new CommandSyntaxException(new SimpleCommandExceptionType(exceptionMessage), exceptionMessage);
@ -507,9 +487,9 @@ public class TurnBasedMinecraftMod {
ServerPlayer player = c.getSource().getPlayerOrException(); ServerPlayer player = c.getSource().getPlayerOrException();
EditingInfo editingInfo = TurnBasedMinecraftMod.proxy.getEditingInfo(player.getId()); EditingInfo editingInfo = TurnBasedMinecraftMod.proxy.getEditingInfo(player.getId());
if (editingInfo != null && !editingInfo.isPendingEntitySelection) { if (editingInfo != null && !editingInfo.isPendingEntitySelection) {
getHandler().send(PacketDistributor.PLAYER.with(() -> player), new PacketEditingMessage(PacketEditingMessage.Type.EDIT_DEFENSE_DAMAGE)); PacketDistributor.sendToPlayer(player, new PacketEditingMessage(PacketEditingMessage.Type.EDIT_DEFENSE_DAMAGE));
} else if (editingInfo != null) { } else if (editingInfo != null) {
getHandler().send(PacketDistributor.PLAYER.with(() -> player), new PacketEditingMessage(PacketEditingMessage.Type.ATTACK_ENTITY)); PacketDistributor.sendToPlayer(player, new PacketEditingMessage(PacketEditingMessage.Type.ATTACK_ENTITY));
} else { } else {
Message exceptionMessage = new LiteralMessage("Cannot edit entity without starting editing (use \"/tbm-edit\")."); Message exceptionMessage = new LiteralMessage("Cannot edit entity without starting editing (use \"/tbm-edit\").");
throw new CommandSyntaxException(new SimpleCommandExceptionType(exceptionMessage), exceptionMessage); throw new CommandSyntaxException(new SimpleCommandExceptionType(exceptionMessage), exceptionMessage);
@ -526,9 +506,9 @@ public class TurnBasedMinecraftMod {
} }
if (editingInfo != null && !editingInfo.isPendingEntitySelection) { if (editingInfo != null && !editingInfo.isPendingEntitySelection) {
editingInfo.entityInfo.defenseDamage = defenseDamage; editingInfo.entityInfo.defenseDamage = defenseDamage;
getHandler().send(PacketDistributor.PLAYER.with(() -> player), new PacketEditingMessage(PacketEditingMessage.Type.PICK_EDIT, editingInfo.entityInfo)); PacketDistributor.sendToPlayer(player, new PacketEditingMessage(PacketEditingMessage.Type.PICK_EDIT, editingInfo.entityInfo));
} else if (editingInfo != null) { } else if (editingInfo != null) {
getHandler().send(PacketDistributor.PLAYER.with(() -> player), new PacketEditingMessage(PacketEditingMessage.Type.ATTACK_ENTITY)); PacketDistributor.sendToPlayer(player, new PacketEditingMessage(PacketEditingMessage.Type.ATTACK_ENTITY));
} else { } else {
Message exceptionMessage = new LiteralMessage("Cannot edit entity without starting editing (use \"/tbm-edit\")."); Message exceptionMessage = new LiteralMessage("Cannot edit entity without starting editing (use \"/tbm-edit\").");
throw new CommandSyntaxException(new SimpleCommandExceptionType(exceptionMessage), exceptionMessage); throw new CommandSyntaxException(new SimpleCommandExceptionType(exceptionMessage), exceptionMessage);
@ -541,9 +521,9 @@ public class TurnBasedMinecraftMod {
ServerPlayer player = c.getSource().getPlayerOrException(); ServerPlayer player = c.getSource().getPlayerOrException();
EditingInfo editingInfo = TurnBasedMinecraftMod.proxy.getEditingInfo(player.getId()); EditingInfo editingInfo = TurnBasedMinecraftMod.proxy.getEditingInfo(player.getId());
if (editingInfo != null && !editingInfo.isPendingEntitySelection) { if (editingInfo != null && !editingInfo.isPendingEntitySelection) {
getHandler().send(PacketDistributor.PLAYER.with(() -> player), new PacketEditingMessage(PacketEditingMessage.Type.EDIT_DEFENSE_DAMAGE_PROBABILITY)); PacketDistributor.sendToPlayer(player, new PacketEditingMessage(PacketEditingMessage.Type.EDIT_DEFENSE_DAMAGE_PROBABILITY));
} else if (editingInfo != null) { } else if (editingInfo != null) {
getHandler().send(PacketDistributor.PLAYER.with(() -> player), new PacketEditingMessage(PacketEditingMessage.Type.ATTACK_ENTITY)); PacketDistributor.sendToPlayer(player, new PacketEditingMessage(PacketEditingMessage.Type.ATTACK_ENTITY));
} else { } else {
Message exceptionMessage = new LiteralMessage("Cannot edit entity without starting editing (use \"/tbm-edit\")."); Message exceptionMessage = new LiteralMessage("Cannot edit entity without starting editing (use \"/tbm-edit\").");
throw new CommandSyntaxException(new SimpleCommandExceptionType(exceptionMessage), exceptionMessage); throw new CommandSyntaxException(new SimpleCommandExceptionType(exceptionMessage), exceptionMessage);
@ -562,9 +542,9 @@ public class TurnBasedMinecraftMod {
} }
if (editingInfo != null && !editingInfo.isPendingEntitySelection) { if (editingInfo != null && !editingInfo.isPendingEntitySelection) {
editingInfo.entityInfo.defenseDamageProbability = defenseDamageProbability; editingInfo.entityInfo.defenseDamageProbability = defenseDamageProbability;
getHandler().send(PacketDistributor.PLAYER.with(() -> player), new PacketEditingMessage(PacketEditingMessage.Type.PICK_EDIT, editingInfo.entityInfo)); PacketDistributor.sendToPlayer(player, new PacketEditingMessage(PacketEditingMessage.Type.PICK_EDIT, editingInfo.entityInfo));
} else if (editingInfo != null) { } else if (editingInfo != null) {
getHandler().send(PacketDistributor.PLAYER.with(() -> player), new PacketEditingMessage(PacketEditingMessage.Type.ATTACK_ENTITY)); PacketDistributor.sendToPlayer(player, new PacketEditingMessage(PacketEditingMessage.Type.ATTACK_ENTITY));
} else { } else {
Message exceptionMessage = new LiteralMessage("Cannot edit entity without starting editing (use \"/tbm-edit\")."); Message exceptionMessage = new LiteralMessage("Cannot edit entity without starting editing (use \"/tbm-edit\").");
throw new CommandSyntaxException(new SimpleCommandExceptionType(exceptionMessage), exceptionMessage); throw new CommandSyntaxException(new SimpleCommandExceptionType(exceptionMessage), exceptionMessage);
@ -577,9 +557,9 @@ public class TurnBasedMinecraftMod {
ServerPlayer player = c.getSource().getPlayerOrException(); ServerPlayer player = c.getSource().getPlayerOrException();
EditingInfo editingInfo = TurnBasedMinecraftMod.proxy.getEditingInfo(player.getId()); EditingInfo editingInfo = TurnBasedMinecraftMod.proxy.getEditingInfo(player.getId());
if (editingInfo != null && !editingInfo.isPendingEntitySelection) { if (editingInfo != null && !editingInfo.isPendingEntitySelection) {
getHandler().send(PacketDistributor.PLAYER.with(() -> player), new PacketEditingMessage(PacketEditingMessage.Type.EDIT_EVASION)); PacketDistributor.sendToPlayer(player, new PacketEditingMessage(PacketEditingMessage.Type.EDIT_EVASION));
} else if (editingInfo != null) { } else if (editingInfo != null) {
getHandler().send(PacketDistributor.PLAYER.with(() -> player), new PacketEditingMessage(PacketEditingMessage.Type.ATTACK_ENTITY)); PacketDistributor.sendToPlayer(player, new PacketEditingMessage(PacketEditingMessage.Type.ATTACK_ENTITY));
} else { } else {
Message exceptionMessage = new LiteralMessage("Cannot edit entity without starting editing (use \"/tbm-edit\")."); Message exceptionMessage = new LiteralMessage("Cannot edit entity without starting editing (use \"/tbm-edit\").");
throw new CommandSyntaxException(new SimpleCommandExceptionType(exceptionMessage), exceptionMessage); throw new CommandSyntaxException(new SimpleCommandExceptionType(exceptionMessage), exceptionMessage);
@ -598,9 +578,9 @@ public class TurnBasedMinecraftMod {
} }
if (editingInfo != null && !editingInfo.isPendingEntitySelection) { if (editingInfo != null && !editingInfo.isPendingEntitySelection) {
editingInfo.entityInfo.evasion = evasion; editingInfo.entityInfo.evasion = evasion;
getHandler().send(PacketDistributor.PLAYER.with(() -> player), new PacketEditingMessage(PacketEditingMessage.Type.PICK_EDIT, editingInfo.entityInfo)); PacketDistributor.sendToPlayer(player, new PacketEditingMessage(PacketEditingMessage.Type.PICK_EDIT, editingInfo.entityInfo));
} else if (editingInfo != null) { } else if (editingInfo != null) {
getHandler().send(PacketDistributor.PLAYER.with(() -> player), new PacketEditingMessage(PacketEditingMessage.Type.ATTACK_ENTITY)); PacketDistributor.sendToPlayer(player, new PacketEditingMessage(PacketEditingMessage.Type.ATTACK_ENTITY));
} else { } else {
Message exceptionMessage = new LiteralMessage("Cannot edit entity without starting editing (use \"/tbm-edit\")."); Message exceptionMessage = new LiteralMessage("Cannot edit entity without starting editing (use \"/tbm-edit\").");
throw new CommandSyntaxException(new SimpleCommandExceptionType(exceptionMessage), exceptionMessage); throw new CommandSyntaxException(new SimpleCommandExceptionType(exceptionMessage), exceptionMessage);
@ -613,9 +593,9 @@ public class TurnBasedMinecraftMod {
ServerPlayer player = c.getSource().getPlayerOrException(); ServerPlayer player = c.getSource().getPlayerOrException();
EditingInfo editingInfo = TurnBasedMinecraftMod.proxy.getEditingInfo(player.getId()); EditingInfo editingInfo = TurnBasedMinecraftMod.proxy.getEditingInfo(player.getId());
if (editingInfo != null && !editingInfo.isPendingEntitySelection) { if (editingInfo != null && !editingInfo.isPendingEntitySelection) {
getHandler().send(PacketDistributor.PLAYER.with(() -> player), new PacketEditingMessage(PacketEditingMessage.Type.EDIT_SPEED)); PacketDistributor.sendToPlayer(player, new PacketEditingMessage(PacketEditingMessage.Type.EDIT_SPEED));
} else if (editingInfo != null) { } else if (editingInfo != null) {
getHandler().send(PacketDistributor.PLAYER.with(() -> player), new PacketEditingMessage(PacketEditingMessage.Type.ATTACK_ENTITY)); PacketDistributor.sendToPlayer(player, new PacketEditingMessage(PacketEditingMessage.Type.ATTACK_ENTITY));
} else { } else {
Message exceptionMessage = new LiteralMessage("Cannot edit entity without starting editing (use \"/tbm-edit\")."); Message exceptionMessage = new LiteralMessage("Cannot edit entity without starting editing (use \"/tbm-edit\").");
throw new CommandSyntaxException(new SimpleCommandExceptionType(exceptionMessage), exceptionMessage); throw new CommandSyntaxException(new SimpleCommandExceptionType(exceptionMessage), exceptionMessage);
@ -632,9 +612,9 @@ public class TurnBasedMinecraftMod {
} }
if (editingInfo != null && !editingInfo.isPendingEntitySelection) { if (editingInfo != null && !editingInfo.isPendingEntitySelection) {
editingInfo.entityInfo.speed = speed; editingInfo.entityInfo.speed = speed;
getHandler().send(PacketDistributor.PLAYER.with(() -> player), new PacketEditingMessage(PacketEditingMessage.Type.PICK_EDIT, editingInfo.entityInfo)); PacketDistributor.sendToPlayer(player, new PacketEditingMessage(PacketEditingMessage.Type.PICK_EDIT, editingInfo.entityInfo));
} else if (editingInfo != null) { } else if (editingInfo != null) {
getHandler().send(PacketDistributor.PLAYER.with(() -> player), new PacketEditingMessage(PacketEditingMessage.Type.ATTACK_ENTITY)); PacketDistributor.sendToPlayer(player, new PacketEditingMessage(PacketEditingMessage.Type.ATTACK_ENTITY));
} else { } else {
Message exceptionMessage = new LiteralMessage("Cannot edit entity without starting editing (use \"/tbm-edit\")."); Message exceptionMessage = new LiteralMessage("Cannot edit entity without starting editing (use \"/tbm-edit\").");
throw new CommandSyntaxException(new SimpleCommandExceptionType(exceptionMessage), exceptionMessage); throw new CommandSyntaxException(new SimpleCommandExceptionType(exceptionMessage), exceptionMessage);
@ -647,9 +627,9 @@ public class TurnBasedMinecraftMod {
ServerPlayer player = c.getSource().getPlayerOrException(); ServerPlayer player = c.getSource().getPlayerOrException();
EditingInfo editingInfo = TurnBasedMinecraftMod.proxy.getEditingInfo(player.getId()); EditingInfo editingInfo = TurnBasedMinecraftMod.proxy.getEditingInfo(player.getId());
if (editingInfo != null && !editingInfo.isPendingEntitySelection) { if (editingInfo != null && !editingInfo.isPendingEntitySelection) {
getHandler().send(PacketDistributor.PLAYER.with(() -> player), new PacketEditingMessage(PacketEditingMessage.Type.EDIT_CATEGORY)); PacketDistributor.sendToPlayer(player, new PacketEditingMessage(PacketEditingMessage.Type.EDIT_CATEGORY));
} else if (editingInfo != null) { } else if (editingInfo != null) {
getHandler().send(PacketDistributor.PLAYER.with(() -> player), new PacketEditingMessage(PacketEditingMessage.Type.ATTACK_ENTITY)); PacketDistributor.sendToPlayer(player, new PacketEditingMessage(PacketEditingMessage.Type.ATTACK_ENTITY));
} else { } else {
Message exceptionMessage = new LiteralMessage("Cannot edit entity without starting editing (use \"/tbm-edit\")."); Message exceptionMessage = new LiteralMessage("Cannot edit entity without starting editing (use \"/tbm-edit\").");
throw new CommandSyntaxException(new SimpleCommandExceptionType(exceptionMessage), exceptionMessage); throw new CommandSyntaxException(new SimpleCommandExceptionType(exceptionMessage), exceptionMessage);
@ -663,9 +643,9 @@ public class TurnBasedMinecraftMod {
String category = StringArgumentType.getString(c, "category"); String category = StringArgumentType.getString(c, "category");
if (editingInfo != null && !editingInfo.isPendingEntitySelection) { if (editingInfo != null && !editingInfo.isPendingEntitySelection) {
editingInfo.entityInfo.category = category; editingInfo.entityInfo.category = category;
getHandler().send(PacketDistributor.PLAYER.with(() -> player), new PacketEditingMessage(PacketEditingMessage.Type.PICK_EDIT, editingInfo.entityInfo)); PacketDistributor.sendToPlayer(player, new PacketEditingMessage(PacketEditingMessage.Type.PICK_EDIT, editingInfo.entityInfo));
} else if (editingInfo != null) { } else if (editingInfo != null) {
getHandler().send(PacketDistributor.PLAYER.with(() -> player), new PacketEditingMessage(PacketEditingMessage.Type.ATTACK_ENTITY)); PacketDistributor.sendToPlayer(player, new PacketEditingMessage(PacketEditingMessage.Type.ATTACK_ENTITY));
} else { } else {
Message exceptionMessage = new LiteralMessage("Cannot edit entity without starting editing (use \"/tbm-edit\")."); Message exceptionMessage = new LiteralMessage("Cannot edit entity without starting editing (use \"/tbm-edit\").");
throw new CommandSyntaxException(new SimpleCommandExceptionType(exceptionMessage), exceptionMessage); throw new CommandSyntaxException(new SimpleCommandExceptionType(exceptionMessage), exceptionMessage);
@ -678,9 +658,9 @@ public class TurnBasedMinecraftMod {
ServerPlayer player = c.getSource().getPlayerOrException(); ServerPlayer player = c.getSource().getPlayerOrException();
EditingInfo editingInfo = TurnBasedMinecraftMod.proxy.getEditingInfo(player.getId()); EditingInfo editingInfo = TurnBasedMinecraftMod.proxy.getEditingInfo(player.getId());
if (editingInfo != null && !editingInfo.isPendingEntitySelection) { if (editingInfo != null && !editingInfo.isPendingEntitySelection) {
getHandler().send(PacketDistributor.PLAYER.with(() -> player), new PacketEditingMessage(PacketEditingMessage.Type.EDIT_DECISION_ATTACK)); PacketDistributor.sendToPlayer(player, new PacketEditingMessage(PacketEditingMessage.Type.EDIT_DECISION_ATTACK));
} else if (editingInfo != null) { } else if (editingInfo != null) {
getHandler().send(PacketDistributor.PLAYER.with(() -> player), new PacketEditingMessage(PacketEditingMessage.Type.ATTACK_ENTITY)); PacketDistributor.sendToPlayer(player, new PacketEditingMessage(PacketEditingMessage.Type.ATTACK_ENTITY));
} else { } else {
Message exceptionMessage = new LiteralMessage("Cannot edit entity without starting editing (use \"/tbm-edit\")."); Message exceptionMessage = new LiteralMessage("Cannot edit entity without starting editing (use \"/tbm-edit\").");
throw new CommandSyntaxException(new SimpleCommandExceptionType(exceptionMessage), exceptionMessage); throw new CommandSyntaxException(new SimpleCommandExceptionType(exceptionMessage), exceptionMessage);
@ -699,9 +679,9 @@ public class TurnBasedMinecraftMod {
} }
if (editingInfo != null && !editingInfo.isPendingEntitySelection) { if (editingInfo != null && !editingInfo.isPendingEntitySelection) {
editingInfo.entityInfo.decisionAttack = decisionAttack; editingInfo.entityInfo.decisionAttack = decisionAttack;
getHandler().send(PacketDistributor.PLAYER.with(() -> player), new PacketEditingMessage(PacketEditingMessage.Type.PICK_EDIT, editingInfo.entityInfo)); PacketDistributor.sendToPlayer(player, new PacketEditingMessage(PacketEditingMessage.Type.PICK_EDIT, editingInfo.entityInfo));
} else if (editingInfo != null) { } else if (editingInfo != null) {
getHandler().send(PacketDistributor.PLAYER.with(() -> player), new PacketEditingMessage(PacketEditingMessage.Type.ATTACK_ENTITY)); PacketDistributor.sendToPlayer(player, new PacketEditingMessage(PacketEditingMessage.Type.ATTACK_ENTITY));
} else { } else {
Message exceptionMessage = new LiteralMessage("Cannot edit entity without starting editing (use \"/tbm-edit\")."); Message exceptionMessage = new LiteralMessage("Cannot edit entity without starting editing (use \"/tbm-edit\").");
throw new CommandSyntaxException(new SimpleCommandExceptionType(exceptionMessage), exceptionMessage); throw new CommandSyntaxException(new SimpleCommandExceptionType(exceptionMessage), exceptionMessage);
@ -714,9 +694,9 @@ public class TurnBasedMinecraftMod {
ServerPlayer player = c.getSource().getPlayerOrException(); ServerPlayer player = c.getSource().getPlayerOrException();
EditingInfo editingInfo = TurnBasedMinecraftMod.proxy.getEditingInfo(player.getId()); EditingInfo editingInfo = TurnBasedMinecraftMod.proxy.getEditingInfo(player.getId());
if (editingInfo != null && !editingInfo.isPendingEntitySelection) { if (editingInfo != null && !editingInfo.isPendingEntitySelection) {
getHandler().send(PacketDistributor.PLAYER.with(() -> player), new PacketEditingMessage(PacketEditingMessage.Type.EDIT_DECISION_DEFEND)); PacketDistributor.sendToPlayer(player, new PacketEditingMessage(PacketEditingMessage.Type.EDIT_DECISION_DEFEND));
} else if (editingInfo != null) { } else if (editingInfo != null) {
getHandler().send(PacketDistributor.PLAYER.with(() -> player), new PacketEditingMessage(PacketEditingMessage.Type.ATTACK_ENTITY)); PacketDistributor.sendToPlayer(player, new PacketEditingMessage(PacketEditingMessage.Type.ATTACK_ENTITY));
} else { } else {
Message exceptionMessage = new LiteralMessage("Cannot edit entity without starting editing (use \"/tbm-edit\")."); Message exceptionMessage = new LiteralMessage("Cannot edit entity without starting editing (use \"/tbm-edit\").");
throw new CommandSyntaxException(new SimpleCommandExceptionType(exceptionMessage), exceptionMessage); throw new CommandSyntaxException(new SimpleCommandExceptionType(exceptionMessage), exceptionMessage);
@ -735,9 +715,9 @@ public class TurnBasedMinecraftMod {
} }
if (editingInfo != null && !editingInfo.isPendingEntitySelection) { if (editingInfo != null && !editingInfo.isPendingEntitySelection) {
editingInfo.entityInfo.decisionDefend = decisionDefend; editingInfo.entityInfo.decisionDefend = decisionDefend;
getHandler().send(PacketDistributor.PLAYER.with(() -> player), new PacketEditingMessage(PacketEditingMessage.Type.PICK_EDIT, editingInfo.entityInfo)); PacketDistributor.sendToPlayer(player, new PacketEditingMessage(PacketEditingMessage.Type.PICK_EDIT, editingInfo.entityInfo));
} else if (editingInfo != null) { } else if (editingInfo != null) {
getHandler().send(PacketDistributor.PLAYER.with(() -> player), new PacketEditingMessage(PacketEditingMessage.Type.ATTACK_ENTITY)); PacketDistributor.sendToPlayer(player, new PacketEditingMessage(PacketEditingMessage.Type.ATTACK_ENTITY));
} else { } else {
Message exceptionMessage = new LiteralMessage("Cannot edit entity without starting editing (use \"/tbm-edit\")."); Message exceptionMessage = new LiteralMessage("Cannot edit entity without starting editing (use \"/tbm-edit\").");
throw new CommandSyntaxException(new SimpleCommandExceptionType(exceptionMessage), exceptionMessage); throw new CommandSyntaxException(new SimpleCommandExceptionType(exceptionMessage), exceptionMessage);
@ -750,9 +730,9 @@ public class TurnBasedMinecraftMod {
ServerPlayer player = c.getSource().getPlayerOrException(); ServerPlayer player = c.getSource().getPlayerOrException();
EditingInfo editingInfo = TurnBasedMinecraftMod.proxy.getEditingInfo(player.getId()); EditingInfo editingInfo = TurnBasedMinecraftMod.proxy.getEditingInfo(player.getId());
if (editingInfo != null && !editingInfo.isPendingEntitySelection) { if (editingInfo != null && !editingInfo.isPendingEntitySelection) {
getHandler().send(PacketDistributor.PLAYER.with(() -> player), new PacketEditingMessage(PacketEditingMessage.Type.EDIT_DECISION_FLEE)); PacketDistributor.sendToPlayer(player, new PacketEditingMessage(PacketEditingMessage.Type.EDIT_DECISION_FLEE));
} else if (editingInfo != null) { } else if (editingInfo != null) {
getHandler().send(PacketDistributor.PLAYER.with(() -> player), new PacketEditingMessage(PacketEditingMessage.Type.ATTACK_ENTITY)); PacketDistributor.sendToPlayer(player, new PacketEditingMessage(PacketEditingMessage.Type.ATTACK_ENTITY));
} else { } else {
Message exceptionMessage = new LiteralMessage("Cannot edit entity without starting editing (use \"/tbm-edit\")."); Message exceptionMessage = new LiteralMessage("Cannot edit entity without starting editing (use \"/tbm-edit\").");
throw new CommandSyntaxException(new SimpleCommandExceptionType(exceptionMessage), exceptionMessage); throw new CommandSyntaxException(new SimpleCommandExceptionType(exceptionMessage), exceptionMessage);
@ -766,9 +746,9 @@ public class TurnBasedMinecraftMod {
int decisionFlee = IntegerArgumentType.getInteger(c, "decisionFlee"); int decisionFlee = IntegerArgumentType.getInteger(c, "decisionFlee");
if (editingInfo != null && !editingInfo.isPendingEntitySelection) { if (editingInfo != null && !editingInfo.isPendingEntitySelection) {
editingInfo.entityInfo.decisionFlee = decisionFlee; editingInfo.entityInfo.decisionFlee = decisionFlee;
getHandler().send(PacketDistributor.PLAYER.with(() -> player), new PacketEditingMessage(PacketEditingMessage.Type.PICK_EDIT, editingInfo.entityInfo)); PacketDistributor.sendToPlayer(player, new PacketEditingMessage(PacketEditingMessage.Type.PICK_EDIT, editingInfo.entityInfo));
} else if (editingInfo != null) { } else if (editingInfo != null) {
getHandler().send(PacketDistributor.PLAYER.with(() -> player), new PacketEditingMessage(PacketEditingMessage.Type.ATTACK_ENTITY)); PacketDistributor.sendToPlayer(player, new PacketEditingMessage(PacketEditingMessage.Type.ATTACK_ENTITY));
} else { } else {
Message exceptionMessage = new LiteralMessage("Cannot edit entity without starting editing (use \"/tbm-edit\")."); Message exceptionMessage = new LiteralMessage("Cannot edit entity without starting editing (use \"/tbm-edit\").");
throw new CommandSyntaxException(new SimpleCommandExceptionType(exceptionMessage), exceptionMessage); throw new CommandSyntaxException(new SimpleCommandExceptionType(exceptionMessage), exceptionMessage);
@ -784,7 +764,7 @@ public class TurnBasedMinecraftMod {
.requires(c -> c.hasPermission(2)) .requires(c -> c.hasPermission(2))
.executes(c -> { .executes(c -> {
ServerPlayer player = c.getSource().getPlayerOrException(); ServerPlayer player = c.getSource().getPlayerOrException();
getHandler().send(PacketDistributor.PLAYER.with(() -> player), new PacketEditingMessage(PacketEditingMessage.Type.SERVER_EDIT)); PacketDistributor.sendToPlayer(player, new PacketEditingMessage(PacketEditingMessage.Type.SERVER_EDIT));
return 1; return 1;
}) })
.then(Commands.literal("leave_battle_cooldown").executes(c -> { .then(Commands.literal("leave_battle_cooldown").executes(c -> {
@ -1691,6 +1671,15 @@ public class TurnBasedMinecraftMod {
return 1; return 1;
}))) })))
); );
// tbm-client-edit
event.getDispatcher().register(
Commands.literal("tbm-client-edit").executes(c -> {
ServerPlayer player = c.getSource().getPlayerOrException();
PacketDistributor.sendToPlayer(player, new PacketClientGUI(0));
return 1;
})
);
} }
@SubscribeEvent @SubscribeEvent

View file

@ -4,10 +4,14 @@ import net.minecraft.core.registries.Registries;
import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ArrowItem; import net.minecraft.world.item.ArrowItem;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import javax.annotation.Nullable;
public class Utility public class Utility
{ {
public static float yawDirection(double posX, double posZ, double targetX, double targetZ) public static float yawDirection(double posX, double posZ, double targetX, double targetZ)
@ -59,7 +63,11 @@ public class Utility
} }
public static ResourceKey<Level> deserializeDimension(String dimString) { public static ResourceKey<Level> deserializeDimension(String dimString) {
ResourceLocation dimRes = new ResourceLocation(dimString); ResourceLocation dimRes = ResourceLocation.parse(dimString);
return ResourceKey.create(Registries.DIMENSION, dimRes); return ResourceKey.create(Registries.DIMENSION, dimRes);
} }
public static boolean isItemEdible(ItemStack itemStack, @Nullable LivingEntity entity) {
return itemStack.getFoodProperties(entity) != null;
}
} }

View file

@ -1,49 +1,50 @@
package com.burnedkirby.TurnBasedMinecraft.common.networking; package com.burnedkirby.TurnBasedMinecraft.common.networking;
import java.util.function.Supplier;
import com.burnedkirby.TurnBasedMinecraft.common.Battle; import com.burnedkirby.TurnBasedMinecraft.common.Battle;
import com.burnedkirby.TurnBasedMinecraft.common.TurnBasedMinecraftMod; import com.burnedkirby.TurnBasedMinecraft.common.TurnBasedMinecraftMod;
import com.burnedkirby.TurnBasedMinecraft.common.Battle.Decision; import io.netty.buffer.ByteBuf;
import net.minecraft.network.chat.Component;
import net.minecraft.network.codec.ByteBufCodecs;
import net.minecraft.network.codec.StreamCodec;
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.entity.player.Player;
import net.neoforged.neoforge.network.handling.IPayloadContext;
import net.neoforged.neoforge.network.handling.IPayloadHandler;
import org.jetbrains.annotations.NotNull;
import net.minecraft.server.level.ServerPlayer; public record PacketBattleDecision(int battleID, int decision, int targetIDorItemID) implements CustomPacketPayload
import net.minecraft.network.FriendlyByteBuf;
import net.minecraftforge.network.NetworkEvent;
public class PacketBattleDecision
{ {
private int battleID; public static final CustomPacketPayload.Type<PacketBattleDecision> TYPE = new CustomPacketPayload.Type<>(ResourceLocation.fromNamespaceAndPath(TurnBasedMinecraftMod.MODID, "network_packetbattledecision"));
private Battle.Decision decision;
private int targetIDOrItemID;
public PacketBattleDecision() {} public static final StreamCodec<ByteBuf, PacketBattleDecision> STREAM_CODEC = StreamCodec.composite(
ByteBufCodecs.INT,
PacketBattleDecision::battleID,
ByteBufCodecs.VAR_INT,
PacketBattleDecision::decision,
ByteBufCodecs.INT,
PacketBattleDecision::targetIDorItemID,
PacketBattleDecision::new
);
public PacketBattleDecision(int battleID, Battle.Decision decision, int targetIDOrItemID) @Override
{ public Type<? extends CustomPacketPayload> type() {
this.battleID = battleID; return TYPE;
this.decision = decision;
this.targetIDOrItemID = targetIDOrItemID;
} }
public static void encode(PacketBattleDecision pkt, FriendlyByteBuf buf) { public static class PayloadHandler implements IPayloadHandler<PacketBattleDecision> {
buf.writeInt(pkt.battleID); @Override
buf.writeInt(pkt.decision.getValue()); public void handle(final @NotNull PacketBattleDecision pkt, final IPayloadContext ctx) {
buf.writeInt(pkt.targetIDOrItemID); ctx.enqueueWork(() -> {
}
public static PacketBattleDecision decode(FriendlyByteBuf buf) {
return new PacketBattleDecision(buf.readInt(), Decision.valueOf(buf.readInt()), buf.readInt());
}
public static void handle(final PacketBattleDecision pkt, Supplier<NetworkEvent.Context> ctx) {
ctx.get().enqueueWork(() -> {
Battle b = TurnBasedMinecraftMod.proxy.getBattleManager().getBattleByID(pkt.battleID); Battle b = TurnBasedMinecraftMod.proxy.getBattleManager().getBattleByID(pkt.battleID);
if(b != null) if(b != null) {
{ Player player = ctx.player();
ServerPlayer player = ctx.get().getSender(); b.setDecision(player.getId(), Battle.Decision.valueOf(pkt.decision), pkt.targetIDorItemID);
b.setDecision(player.getId(), pkt.decision, pkt.targetIDOrItemID);
} }
}).exceptionally(e -> {
ctx.disconnect(Component.literal("Exception handling PacketBattleDecision! " + e.getMessage()));
return null;
}); });
ctx.get().setPacketHandled(true); }
} }
} }

View file

@ -1,76 +1,48 @@
package com.burnedkirby.TurnBasedMinecraft.common.networking; package com.burnedkirby.TurnBasedMinecraft.common.networking;
import java.util.ArrayList; import com.burnedkirby.TurnBasedMinecraft.common.CommonProxy;
import java.util.Collection;
import java.util.function.Supplier;
import com.burnedkirby.TurnBasedMinecraft.common.TurnBasedMinecraftMod; import com.burnedkirby.TurnBasedMinecraft.common.TurnBasedMinecraftMod;
import io.netty.buffer.ByteBuf;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.network.chat.Component;
import net.minecraft.network.codec.ByteBufCodecs;
import net.minecraft.network.codec.StreamCodec;
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Entity;
import net.minecraft.network.FriendlyByteBuf; import net.neoforged.neoforge.network.handling.IPayloadContext;
import net.minecraftforge.network.NetworkEvent; import net.neoforged.neoforge.network.handling.IPayloadHandler;
import org.jetbrains.annotations.NotNull;
public class PacketBattleInfo import java.util.Collection;
public record PacketBattleInfo(Collection<Integer> sideA, Collection<Integer> sideB, long decisionNanos, long maxDecisionNanos, boolean turnTimerEnabled) implements CustomPacketPayload
{ {
private Collection<Integer> sideA; public static final CustomPacketPayload.Type<PacketBattleInfo> TYPE = new CustomPacketPayload.Type<>(ResourceLocation.fromNamespaceAndPath(TurnBasedMinecraftMod.MODID, "network_packetbattleinfo"));
private Collection<Integer> sideB;
private long decisionNanos;
private long maxDecisionNanos; public static final StreamCodec<ByteBuf, PacketBattleInfo> STREAM_CODEC = StreamCodec.composite(
private boolean turnTimerEnabled; CommonProxy.COLLECTION_INT_CODEC,
PacketBattleInfo::sideA,
CommonProxy.COLLECTION_INT_CODEC,
PacketBattleInfo::sideB,
ByteBufCodecs.VAR_LONG,
PacketBattleInfo::decisionNanos,
ByteBufCodecs.VAR_LONG,
PacketBattleInfo::maxDecisionNanos,
ByteBufCodecs.BOOL,
PacketBattleInfo::turnTimerEnabled,
PacketBattleInfo::new
);
public PacketBattleInfo() @Override
{ public Type<? extends CustomPacketPayload> type() {
sideA = new ArrayList<Integer>(); return TYPE;
sideB = new ArrayList<Integer>();
decisionNanos = TurnBasedMinecraftMod.proxy.getConfig().getDecisionDurationNanos();
maxDecisionNanos = decisionNanos;
turnTimerEnabled = false;
} }
public PacketBattleInfo(Collection<Integer> sideA, Collection<Integer> sideB, long decisionNanos, long maxDecisionNanos, boolean turnTimerEnabled) public static class PayloadHandler implements IPayloadHandler<PacketBattleInfo> {
{ @Override
this.sideA = sideA; public void handle(final @NotNull PacketBattleInfo pkt, final IPayloadContext ctx) {
this.sideB = sideB; ctx.enqueueWork(() -> {
this.decisionNanos = decisionNanos;
this.maxDecisionNanos = maxDecisionNanos;
this.turnTimerEnabled = turnTimerEnabled;
}
public static void encode(PacketBattleInfo msg, FriendlyByteBuf buf) {
buf.writeInt(msg.sideA.size());
buf.writeInt(msg.sideB.size());
for(Integer id : msg.sideA) {
buf.writeInt(id);
}
for(Integer id : msg.sideB) {
buf.writeInt(id);
}
buf.writeLong(msg.decisionNanos);
buf.writeLong(msg.maxDecisionNanos);
buf.writeBoolean(msg.turnTimerEnabled);
}
public static PacketBattleInfo decode(FriendlyByteBuf buf) {
int sideACount = buf.readInt();
int sideBCount = buf.readInt();
Collection<Integer> sideA = new ArrayList<Integer>(sideACount);
Collection<Integer> sideB = new ArrayList<Integer>(sideBCount);
for(int i = 0; i < sideACount; ++i) {
sideA.add(buf.readInt());
}
for(int i = 0; i < sideBCount; ++i) {
sideB.add(buf.readInt());
}
long decisionNanos = buf.readLong();
long maxDecisionNanos = buf.readLong();
boolean turnTimerEnabled = buf.readBoolean();
return new PacketBattleInfo(sideA, sideB, decisionNanos, maxDecisionNanos, turnTimerEnabled);
}
public static void handle(final PacketBattleInfo pkt, Supplier<NetworkEvent.Context> ctx) {
ctx.get().enqueueWork(() -> {
if(TurnBasedMinecraftMod.proxy.getLocalBattle() == null) if(TurnBasedMinecraftMod.proxy.getLocalBattle() == null)
{ {
return; return;
@ -96,7 +68,10 @@ public class PacketBattleInfo
TurnBasedMinecraftMod.proxy.setBattleGuiBattleChanged(); TurnBasedMinecraftMod.proxy.setBattleGuiBattleChanged();
TurnBasedMinecraftMod.proxy.setBattleGuiTurnTimerEnabled(pkt.turnTimerEnabled); TurnBasedMinecraftMod.proxy.setBattleGuiTurnTimerEnabled(pkt.turnTimerEnabled);
TurnBasedMinecraftMod.proxy.setBattleGuiTurnTimerMax((int)(pkt.maxDecisionNanos / 1000000000L)); TurnBasedMinecraftMod.proxy.setBattleGuiTurnTimerMax((int)(pkt.maxDecisionNanos / 1000000000L));
}).exceptionally(e -> {
ctx.disconnect(Component.literal("Exception handling PacketBattleInfo! " + e.getMessage()));
return null;
}); });
ctx.get().setPacketHandled(true); }
} }
} }

View file

@ -1,21 +1,48 @@
package com.burnedkirby.TurnBasedMinecraft.common.networking; package com.burnedkirby.TurnBasedMinecraft.common.networking;
import com.burnedkirby.TurnBasedMinecraft.common.TurnBasedMinecraftMod;
import com.burnedkirby.TurnBasedMinecraft.common.Utility;
import io.netty.buffer.ByteBuf;
import net.minecraft.network.chat.Component;
import net.minecraft.network.codec.ByteBufCodecs;
import net.minecraft.network.codec.StreamCodec;
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.Level;
import net.neoforged.fml.loading.FMLEnvironment;
import net.neoforged.neoforge.network.handling.IPayloadContext;
import net.neoforged.neoforge.network.handling.IPayloadHandler;
import org.jetbrains.annotations.NotNull;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.function.Supplier;
import com.burnedkirby.TurnBasedMinecraft.common.TurnBasedMinecraftMod; public class PacketBattleMessage implements CustomPacketPayload
import com.burnedkirby.TurnBasedMinecraft.common.Utility;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.resources.ResourceKey;
import net.minecraft.world.level.Level;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.fml.DistExecutor;
import net.minecraftforge.network.NetworkEvent;
public class PacketBattleMessage
{ {
public static final CustomPacketPayload.Type<PacketBattleMessage> TYPE = new CustomPacketPayload.Type<>(ResourceLocation.fromNamespaceAndPath(TurnBasedMinecraftMod.MODID, "network_packetbattlemessage"));
public static final StreamCodec<ByteBuf, PacketBattleMessage> STREAM_CODEC = StreamCodec.composite(
ByteBufCodecs.VAR_INT.map(MessageType::valueOf, MessageType::getValue),
PacketBattleMessage::getMessageType,
ByteBufCodecs.INT,
PacketBattleMessage::getEntityIDFrom,
ByteBufCodecs.INT,
PacketBattleMessage::getEntityIDTo,
ByteBufCodecs.STRING_UTF8.map(Utility::deserializeDimension, Utility::serializeDimension),
PacketBattleMessage::getDimension,
ByteBufCodecs.INT,
PacketBattleMessage::getAmount,
ByteBufCodecs.STRING_UTF8,
PacketBattleMessage::getCustom,
PacketBattleMessage::new
);
@Override
public Type<? extends CustomPacketPayload> type() {
return TYPE;
}
public enum MessageType public enum MessageType
{ {
ENTERED(0), ENTERED(0),
@ -39,7 +66,8 @@ public class PacketBattleMessage
BOW_NO_AMMO(18), BOW_NO_AMMO(18),
CREEPER_WAIT(19), CREEPER_WAIT(19),
CREEPER_WAIT_FINAL(20), CREEPER_WAIT_FINAL(20),
CREEPER_EXPLODE(21); CREEPER_EXPLODE(21),
CROSSBOW_NO_AMMO(22);
private int value; private int value;
private static Map<Integer, MessageType> map = new HashMap<Integer, MessageType>(); private static Map<Integer, MessageType> map = new HashMap<Integer, MessageType>();
@ -132,6 +160,11 @@ public class PacketBattleMessage
public ResourceKey<Level> getDimension() { public ResourceKey<Level> getDimension() {
return dimension; return dimension;
} }
public String getDimensionSerialized() {
return Utility.serializeDimension(dimension);
}
public PacketBattleMessage() { custom = new String(); } public PacketBattleMessage() { custom = new String(); }
public PacketBattleMessage(MessageType messageType, int entityIDFrom, int entityIDTo, ResourceKey<Level> dimension, int amount) public PacketBattleMessage(MessageType messageType, int entityIDFrom, int entityIDTo, ResourceKey<Level> dimension, int amount)
@ -154,30 +187,17 @@ public class PacketBattleMessage
this.custom = custom; this.custom = custom;
} }
public static void encode(PacketBattleMessage pkt, FriendlyByteBuf buf) { public static class PayloadHandler implements IPayloadHandler<PacketBattleMessage> {
buf.writeInt(pkt.messageType.getValue()); @Override
buf.writeInt(pkt.entityIDFrom); public void handle(final @NotNull PacketBattleMessage pkt, final IPayloadContext ctx) {
buf.writeInt(pkt.entityIDTo); ctx.enqueueWork(() -> {
buf.writeUtf(Utility.serializeDimension(pkt.dimension)); if (FMLEnvironment.dist.isClient()) {
buf.writeInt(pkt.amount); TurnBasedMinecraftMod.proxy.handlePacket(pkt, ctx);
buf.writeUtf(pkt.custom);
} }
}).exceptionally(e -> {
public static PacketBattleMessage decode(FriendlyByteBuf buf) { ctx.disconnect(Component.literal("Exception handling PacketBattleMessage! " + e.getMessage()));
return new PacketBattleMessage( return null;
MessageType.valueOf(
buf.readInt()),
buf.readInt(),
buf.readInt(),
Utility.deserializeDimension(buf.readUtf()),
buf.readInt(),
buf.readUtf());
}
public static void handle(final PacketBattleMessage pkt, Supplier<NetworkEvent.Context> ctx) {
ctx.get().enqueueWork(() -> {
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> TurnBasedMinecraftMod.proxy.handlePacket(pkt, ctx));
}); });
ctx.get().setPacketHandled(true); }
} }
} }

View file

@ -1,40 +1,55 @@
package com.burnedkirby.TurnBasedMinecraft.common.networking; package com.burnedkirby.TurnBasedMinecraft.common.networking;
import java.util.function.Supplier;
import com.burnedkirby.TurnBasedMinecraft.common.Battle; import com.burnedkirby.TurnBasedMinecraft.common.Battle;
import com.burnedkirby.TurnBasedMinecraft.common.TurnBasedMinecraftMod; import com.burnedkirby.TurnBasedMinecraft.common.TurnBasedMinecraftMod;
import io.netty.buffer.ByteBuf;
import net.minecraft.network.chat.Component;
import net.minecraft.network.codec.ByteBufCodecs;
import net.minecraft.network.codec.StreamCodec;
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
import net.minecraft.resources.ResourceLocation;
import net.neoforged.neoforge.network.handling.IPayloadContext;
import net.neoforged.neoforge.network.handling.IPayloadHandler;
import org.jetbrains.annotations.NotNull;
import net.minecraft.network.FriendlyByteBuf; public record PacketBattleRequestInfo(int battleID) implements CustomPacketPayload
import net.minecraftforge.network.NetworkEvent;
public class PacketBattleRequestInfo
{ {
private int battleID; public static final CustomPacketPayload.Type<PacketBattleRequestInfo> TYPE = new CustomPacketPayload.Type<>(ResourceLocation.fromNamespaceAndPath(TurnBasedMinecraftMod.MODID, "network_packetbattlerequestinfo"));
public PacketBattleRequestInfo() {} public static final StreamCodec<ByteBuf, PacketBattleRequestInfo> STREAM_CODEC = StreamCodec.composite(
ByteBufCodecs.INT,
PacketBattleRequestInfo::battleID,
PacketBattleRequestInfo::new
);
public PacketBattleRequestInfo(int battleID) public PacketBattleRequestInfo(int battleID)
{ {
this.battleID = battleID; this.battleID = battleID;
} }
public static void encode(PacketBattleRequestInfo pkt, FriendlyByteBuf buf) { @Override
buf.writeInt(pkt.battleID); public Type<? extends CustomPacketPayload> type() {
return TYPE;
} }
public static PacketBattleRequestInfo decode(FriendlyByteBuf buf) { public static class PayloadHandler implements IPayloadHandler<PacketBattleRequestInfo> {
return new PacketBattleRequestInfo(buf.readInt()); @Override
} public void handle(final @NotNull PacketBattleRequestInfo pkt, final IPayloadContext ctx) {
ctx.enqueueWork(() -> {
public static void handle(final PacketBattleRequestInfo pkt, Supplier<NetworkEvent.Context> ctx) {
ctx.get().enqueueWork(() -> {
Battle b = TurnBasedMinecraftMod.proxy.getBattleManager().getBattleByID(pkt.battleID); Battle b = TurnBasedMinecraftMod.proxy.getBattleManager().getBattleByID(pkt.battleID);
if(b == null) { if(b == null) {
return; return;
} }
TurnBasedMinecraftMod.getHandler().reply(new PacketBattleInfo(b.getSideAIDs(), b.getSideBIDs(), b.getTimerNanos(), TurnBasedMinecraftMod.proxy.getConfig().getDecisionDurationNanos(), !TurnBasedMinecraftMod.proxy.getConfig().isBattleDecisionDurationForever()), ctx.get()); ctx.reply(new PacketBattleInfo(
b.getSideAIDs(),
b.getSideBIDs(),
b.getTimerNanos(),
TurnBasedMinecraftMod.proxy.getConfig().getDecisionDurationNanos(),
!TurnBasedMinecraftMod.proxy.getConfig().isBattleDecisionDurationForever()));
}).exceptionally(e -> {
ctx.disconnect(Component.literal("Exception handling PacketBattleRequestInfo! " + e.getMessage()));
return null;
}); });
ctx.get().setPacketHandled(true); }
} }
} }

View file

@ -0,0 +1,42 @@
package com.burnedkirby.TurnBasedMinecraft.common.networking;
import com.burnedkirby.TurnBasedMinecraft.common.TurnBasedMinecraftMod;
import io.netty.buffer.ByteBuf;
import net.minecraft.network.chat.Component;
import net.minecraft.network.codec.ByteBufCodecs;
import net.minecraft.network.codec.StreamCodec;
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
import net.minecraft.resources.ResourceLocation;
import net.neoforged.fml.loading.FMLEnvironment;
import net.neoforged.neoforge.network.handling.IPayloadContext;
import net.neoforged.neoforge.network.handling.IPayloadHandler;
import org.jetbrains.annotations.NotNull;
public record PacketClientGUI(int reserved) implements CustomPacketPayload {
public static final CustomPacketPayload.Type<PacketClientGUI> TYPE = new CustomPacketPayload.Type<>(ResourceLocation.fromNamespaceAndPath(TurnBasedMinecraftMod.MODID, "network_packetclientgui"));
public static final StreamCodec<ByteBuf, PacketClientGUI> STREAM_CODEC = StreamCodec.composite(
ByteBufCodecs.VAR_INT,
PacketClientGUI::reserved,
PacketClientGUI::new
);
@Override
public Type<? extends CustomPacketPayload> type() {
return TYPE;
}
public static class PayloadHandler implements IPayloadHandler<PacketClientGUI> {
@Override
public void handle(final @NotNull PacketClientGUI pkt, final IPayloadContext ctx) {
ctx.enqueueWork(() -> {
if (FMLEnvironment.dist.isClient()) {
TurnBasedMinecraftMod.proxy.showClientConfigGui();
}
}).exceptionally(e -> {
ctx.disconnect(Component.literal("Exception handling PacketClientGUI! " + e.getMessage()));
return null;
});
}
}
}

View file

@ -2,17 +2,38 @@ package com.burnedkirby.TurnBasedMinecraft.common.networking;
import com.burnedkirby.TurnBasedMinecraft.common.EntityInfo; import com.burnedkirby.TurnBasedMinecraft.common.EntityInfo;
import com.burnedkirby.TurnBasedMinecraft.common.TurnBasedMinecraftMod; import com.burnedkirby.TurnBasedMinecraft.common.TurnBasedMinecraftMod;
import io.netty.buffer.ByteBuf;
import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.FriendlyByteBuf;
import net.minecraftforge.api.distmarker.Dist; import net.minecraft.network.chat.Component;
import net.minecraftforge.fml.DistExecutor; import net.minecraft.network.codec.ByteBufCodecs;
import net.minecraftforge.network.NetworkEvent; import net.minecraft.network.codec.StreamCodec;
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
import net.minecraft.resources.ResourceLocation;
import net.neoforged.fml.loading.FMLEnvironment;
import net.neoforged.neoforge.network.handling.IPayloadContext;
import net.neoforged.neoforge.network.handling.IPayloadHandler;
import org.jetbrains.annotations.NotNull;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.function.Supplier;
public class PacketEditingMessage public class PacketEditingMessage implements CustomPacketPayload
{ {
public static final CustomPacketPayload.Type<PacketEditingMessage> TYPE = new CustomPacketPayload.Type<>(ResourceLocation.fromNamespaceAndPath(TurnBasedMinecraftMod.MODID, "network_packeteditingmessage"));
public static final StreamCodec<ByteBuf, PacketEditingMessage> STREAM_CODEC = StreamCodec.composite(
ByteBufCodecs.INT.map(Type::valueOf, Type::getValue),
PacketEditingMessage::getType,
StreamCodec.ofMember(EntityInfo::encode, EntityInfo::new),
PacketEditingMessage::getEntityInfo,
PacketEditingMessage::new
);
@Override
public CustomPacketPayload.Type<? extends CustomPacketPayload> type() {
return TYPE;
}
public enum Type public enum Type
{ {
ATTACK_ENTITY(0), ATTACK_ENTITY(0),
@ -88,58 +109,40 @@ public class PacketEditingMessage
} }
} }
public static void encode(PacketEditingMessage pkt, FriendlyByteBuf buf) { public PacketEditingMessage(final FriendlyByteBuf buf) {
buf.writeInt(pkt.type.getValue()); this.type = Type.valueOf(buf.readInt());
if(pkt.entityInfo.classType != null) { this.entityInfo = new EntityInfo();
buf.writeUtf(pkt.entityInfo.classType.getName());
} else {
buf.writeUtf("unknown");
}
buf.writeBoolean(pkt.entityInfo.ignoreBattle);
buf.writeInt(pkt.entityInfo.attackPower);
buf.writeInt(pkt.entityInfo.attackProbability);
buf.writeInt(pkt.entityInfo.attackVariance);
buf.writeUtf(pkt.entityInfo.attackEffect.toString());
buf.writeInt(pkt.entityInfo.attackEffectProbability);
buf.writeInt(pkt.entityInfo.defenseDamage);
buf.writeInt(pkt.entityInfo.defenseDamageProbability);
buf.writeInt(pkt.entityInfo.evasion);
buf.writeInt(pkt.entityInfo.speed);
buf.writeUtf(pkt.entityInfo.category);
buf.writeInt(pkt.entityInfo.decisionAttack);
buf.writeInt(pkt.entityInfo.decisionDefend);
buf.writeInt(pkt.entityInfo.decisionFlee);
buf.writeUtf(pkt.entityInfo.customName);
}
public static PacketEditingMessage decode(FriendlyByteBuf buf) {
Type type = Type.valueOf(buf.readInt());
EntityInfo einfo = new EntityInfo();
try { try {
einfo.classType = einfo.getClass().getClassLoader().loadClass(buf.readUtf()); this.entityInfo.classType = this.entityInfo.getClass().getClassLoader().loadClass(buf.readUtf());
} catch (ClassNotFoundException e) { /* ignored */ } } catch (ClassNotFoundException e) { /* ignored */ }
einfo.ignoreBattle = buf.readBoolean(); this.entityInfo.ignoreBattle = buf.readBoolean();
einfo.attackPower = buf.readInt(); this.entityInfo.attackPower = buf.readInt();
einfo.attackProbability = buf.readInt(); this.entityInfo.attackProbability = buf.readInt();
einfo.attackVariance = buf.readInt(); this.entityInfo.attackVariance = buf.readInt();
einfo.attackEffect = EntityInfo.Effect.fromString(buf.readUtf()); this.entityInfo.attackEffect = EntityInfo.Effect.fromString(buf.readUtf());
einfo.attackEffectProbability = buf.readInt(); this.entityInfo.attackEffectProbability = buf.readInt();
einfo.defenseDamage = buf.readInt(); this.entityInfo.defenseDamage = buf.readInt();
einfo.defenseDamageProbability = buf.readInt(); this.entityInfo.defenseDamageProbability = buf.readInt();
einfo.evasion = buf.readInt(); this.entityInfo.evasion = buf.readInt();
einfo.speed = buf.readInt(); this.entityInfo.speed = buf.readInt();
einfo.category = buf.readUtf(); this.entityInfo.category = buf.readUtf();
einfo.decisionAttack = buf.readInt(); this.entityInfo.decisionAttack = buf.readInt();
einfo.decisionDefend = buf.readInt(); this.entityInfo.decisionDefend = buf.readInt();
einfo.decisionFlee = buf.readInt(); this.entityInfo.decisionFlee = buf.readInt();
einfo.customName = buf.readUtf(); this.entityInfo.customName = buf.readUtf();
return new PacketEditingMessage(type, einfo);
} }
public static void handle(final PacketEditingMessage pkt, Supplier<NetworkEvent.Context> ctx) { public static class PayloadHandler implements IPayloadHandler<PacketEditingMessage> {
ctx.get().enqueueWork(() -> { @Override
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> TurnBasedMinecraftMod.proxy.handlePacket(pkt, ctx)); public void handle(final @NotNull PacketEditingMessage pkt, final IPayloadContext ctx) {
ctx.enqueueWork(() -> {
if (FMLEnvironment.dist.isClient()) {
TurnBasedMinecraftMod.proxy.handlePacket(pkt, ctx);
}
}).exceptionally(e -> {
ctx.disconnect(Component.literal("Exception handling PacketEditingMessage! " + e.getMessage()));
return null;
}); });
ctx.get().setPacketHandled(true); }
} }
} }

View file

@ -1,44 +1,52 @@
package com.burnedkirby.TurnBasedMinecraft.common.networking; package com.burnedkirby.TurnBasedMinecraft.common.networking;
import java.util.function.Supplier;
import com.burnedkirby.TurnBasedMinecraft.common.TurnBasedMinecraftMod; import com.burnedkirby.TurnBasedMinecraft.common.TurnBasedMinecraftMod;
import io.netty.buffer.ByteBuf;
import net.minecraft.network.chat.Component;
import net.minecraft.network.codec.ByteBufCodecs;
import net.minecraft.network.codec.StreamCodec;
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
import net.minecraft.resources.ResourceLocation;
import net.neoforged.fml.loading.FMLEnvironment;
import net.neoforged.neoforge.network.handling.IPayloadContext;
import net.neoforged.neoforge.network.handling.IPayloadHandler;
import org.jetbrains.annotations.NotNull;
import net.minecraft.network.FriendlyByteBuf; public record PacketGeneralMessage(String message) implements CustomPacketPayload
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.fml.DistExecutor;
import net.minecraftforge.network.NetworkEvent;
public class PacketGeneralMessage
{ {
String message; public static final CustomPacketPayload.Type<PacketGeneralMessage> TYPE = new CustomPacketPayload.Type<>(ResourceLocation.fromNamespaceAndPath(TurnBasedMinecraftMod.MODID, "network_packetgeneralmessage"));
public static final StreamCodec<ByteBuf, PacketGeneralMessage> STREAM_CODEC = StreamCodec.composite(
ByteBufCodecs.STRING_UTF8,
PacketGeneralMessage::message,
PacketGeneralMessage::new
);
public String getMessage() { public String getMessage() {
return message; return message;
} }
public PacketGeneralMessage()
{
message = new String();
}
public PacketGeneralMessage(String message) public PacketGeneralMessage(String message)
{ {
this.message = message; this.message = message;
} }
public static void encode(PacketGeneralMessage pkt, FriendlyByteBuf buf) { @Override
buf.writeUtf(pkt.message); public Type<? extends CustomPacketPayload> type() {
return TYPE;
} }
public static PacketGeneralMessage decode(FriendlyByteBuf buf) { public static class PayloadHandler implements IPayloadHandler<PacketGeneralMessage> {
return new PacketGeneralMessage(buf.readUtf()); @Override
public void handle(final @NotNull PacketGeneralMessage pkt, final IPayloadContext ctx) {
ctx.enqueueWork(() -> {
if (FMLEnvironment.dist.isClient()) {
TurnBasedMinecraftMod.proxy.handlePacket(pkt, ctx);
} }
}).exceptionally(e -> {
public static void handle(final PacketGeneralMessage pkt, Supplier<NetworkEvent.Context> ctx) { ctx.disconnect(Component.literal("Exception handling PacketGeneralMessage! " + e.getMessage()));
ctx.get().enqueueWork(() -> { return null;
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> TurnBasedMinecraftMod.proxy.handlePacket(pkt, ctx));
}); });
ctx.get().setPacketHandled(true); }
} }
} }

View file

@ -1,53 +0,0 @@
# This is an example mods.toml file. It contains the data relating to the loading mods.
# There are several mandatory fields (#mandatory), and many more that are optional (#optional).
# The overall format is standard TOML format, v0.5.0.
# Note that there are a couple of TOML lists in this file.
# Find more information on toml format here: https://github.com/toml-lang/toml
# The name of the mod loader type to load - for regular FML @Mod mods it should be javafml
modLoader="javafml" #mandatory
# A version range to match for said mod loader - for regular FML @Mod it will be the forge version
loaderVersion="${loader_version_range}" #mandatory (34 is current forge version)
# A URL to refer people to when problems occur with this mod
issueTrackerURL="https://github.com/Stephen-Seo/TurnBasedMinecraftMod/issues" #optional
license="MIT"
# A list of mods - how many allowed here is determined by the individual mod loader
[[mods]] #mandatory
# The modid of the mod
modId="${mod_id}" #mandatory
# The version number of the mod - there's a few well known ${} variables useable here or just hardcode it
version="${mod_version}" #mandatory
# A display name for the mod
displayName="${mod_name}" #mandatory
# A URL to query for updates for this mod. See the JSON update specification <here>
#updateJSONURL="" #optional
# A URL for the "homepage" for this mod, displayed in the mod UI
displayURL="https://github.com/Stephen-Seo/TurnBasedMinecraftMod" #optional
# A file name (in the root of the mod JAR) containing a logo for display
#logoFile="" #optional
# A text field displayed in the mod UI
credits="Thanks for this mod goes to Java" #optional
# A text field displayed in the mod UI
authors="${mod_authors}" #optional
# The description text for the mod (multi line!) (#mandatory)
description='''
Implements turn-based-battle in Minecraft.
'''
# A dependency - use the . to indicate dependency for a specific modid. Dependencies are optional.
[[dependencies.com_burnedkirby_turnbasedminecraft]] #optional
# the modid of the dependency
modId="forge" #mandatory
# Does this dependency have to exist - if not, ordering below must be specified
mandatory=true #mandatory
# The version range of the dependency
versionRange="${forge_version_range}" #mandatory
# An ordering relationship for the dependency - BEFORE or AFTER required if the relationship is not mandatory
ordering="NONE"
# Side this dependency is applied on - BOTH, CLIENT or SERVER
side="BOTH"
# Here's another dependency
[[dependencies.com_burnedkirby_turnbasedminecraft]]
modId="minecraft"
mandatory=true
versionRange="${minecraft_version_range}"
ordering="NONE"
side="BOTH"

View file

@ -1,21 +1,13 @@
# Please do not change this option, the mod uses this to keep track of what new # Please do not change this option, the mod uses this to keep track of what new
# changes to add to the config. # changes to add to the config.
version = 10 version = 11
# Change this to "true" if you want the config to never be replaced. This means # Change this to "true" if you want the config to never be replaced. This means
# that you will not get new mob listings from future updates unless this remains # that you will not get new mob listings from future updates unless this remains
# "false"! # "false"!
do_not_overwrite = false do_not_overwrite = false
[client_config]
# What categories play this type of music (battle_music). Unknown categories will default to this type.
battle_music = ["monster", "animal", "boss", "player"]
# What categories play this type of music (silly_music).
silly_music = ["passive"]
# Minimum percentage of silly entities in battle to use silly music.
silly_music_threshold = 40
# Note that client config is no longer stored here but rather in the settings.
[server_config] [server_config]
@ -138,6 +130,37 @@ decision_defend_probability = 0
decision_flee_probability = 0 decision_flee_probability = 0
ignore_battle = false ignore_battle = false
[[server_config.entity]]
name = "net.minecraft.world.entity.monster.Bogged"
attack_power = 3
attack_probability = 75
attack_variance = 1
attack_effect = "poison"
attack_effect_probability = 50
defense_damage = 0
evasion = 10
category = "monster"
speed = 20
decision_attack_probability = 100
decision_defend_probability = 0
decision_flee_probability = 0
ignore_battle = false
[[server_config.entity]]
name = "net.minecraft.world.entity.monster.breeze.Breeze"
attack_power = 1
attack_probability = 50
attack_effect = "unknown"
attack_variance = 0
defense_damage = 0
evasion = 45
category = "monster"
speed = 45
decision_attack_probability = 100
decision_defend_probability = 0
decision_flee_probability = 0
ignore_battle = false
[[server_config.entity]] [[server_config.entity]]
name = "net.minecraft.world.entity.monster.CaveSpider" name = "net.minecraft.world.entity.monster.CaveSpider"
attack_power = 2 attack_power = 2
@ -684,6 +707,21 @@ decision_defend_probability = 0
decision_flee_probability = 100 decision_flee_probability = 100
ignore_battle = false ignore_battle = false
[[server_config.entity]]
name = "net.minecraft.world.entity.animal.armadillo.Armadillo"
attack_power = 0
attack_probability = 0
attack_variance = 0
attack_effect = "unknown"
defense_damage = 0
evasion = 10
category = "passive"
speed = 20
decision_attack_probability = 0
decision_defend_probability = 50
decision_flee_probability = 50
ignore_battle = false
[[server_config.entity]] [[server_config.entity]]
name = "net.minecraft.world.entity.animal.axolotl.Axolotl" name = "net.minecraft.world.entity.animal.axolotl.Axolotl"
attack_power = 2 attack_power = 2

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

View file

@ -1,18 +0,0 @@
[
{
"modid": "com_burnedkirby_turnbasedminecraft",
"name": "Turn Based Minecraft",
"description": "Changes battles to be turn-based.",
"version": "1.23.1",
"mcversion": "1.20.1",
"url": "",
"updateUrl": "",
"authorList": ["Stephen Seo"],
"credits": "The Forge and FML guys, for making this possible.
Dependencies:
JavaMP3 by delthas, josephx86, GlaDOSik, and kevinstadler (MIT License)",
"logoFile": "",
"screenshots": [],
"dependencies": []
}
]

View file

@ -0,0 +1,93 @@
# This is an example neoforge.mods.toml file. It contains the data relating to the loading mods.
# There are several mandatory fields (#mandatory), and many more that are optional (#optional).
# The overall format is standard TOML format, v0.5.0.
# Note that there are a couple of TOML lists in this file.
# Find more information on toml format here: https://github.com/toml-lang/toml
# The name of the mod loader type to load - for regular FML @Mod mods it should be javafml
modLoader="javafml" #mandatory
# A version range to match for said mod loader - for regular FML @Mod it will be the FML version. This is currently 2.
loaderVersion="${loader_version_range}" #mandatory
# The license for you mod. This is mandatory metadata and allows for easier comprehension of your redistributive properties.
# Review your options at https://choosealicense.com/. All rights reserved is the default copyright stance, and is thus the default here.
license="${mod_license}"
# A URL to refer people to when problems occur with this mod
#issueTrackerURL="https://change.me.to.your.issue.tracker.example.invalid/" #optional
# A list of mods - how many allowed here is determined by the individual mod loader
[[mods]] #mandatory
# The modid of the mod
modId="${mod_id}" #mandatory
# The version number of the mod
version="${mod_version}" #mandatory
# A display name for the mod
displayName="${mod_name}" #mandatory
# A URL to query for updates for this mod. See the JSON update specification https://docs.neoforged.net/docs/misc/updatechecker/
#updateJSONURL="https://change.me.example.invalid/updates.json" #optional
# A URL for the "homepage" for this mod, displayed in the mod UI
#displayURL="https://change.me.to.your.mods.homepage.example.invalid/" #optional
# A file name (in the root of the mod JAR) containing a logo for display
#logoFile="examplemod.png" #optional
logoFile="assets/com_burnedkirby_turnbasedminecraft/tbmm_icon.png"
# A text field displayed in the mod UI
#credits="" #optional
# A text field displayed in the mod UI
authors="${mod_authors}" #optional
# The description text for the mod (multi line!) (#mandatory)
description='''${mod_description}'''
# The [[mixins]] block allows you to declare your mixin config to FML so that it gets loaded.
#[[mixins]]
#config="${mod_id}.mixins.json"
# The [[accessTransformers]] block allows you to declare where your AT file is.
# If this block is omitted, a fallback attempt will be made to load an AT from META-INF/accesstransformer.cfg
#[[accessTransformers]]
#file="META-INF/accesstransformer.cfg"
# The coremods config file path is not configurable and is always loaded from META-INF/coremods.json
# A dependency - use the . to indicate dependency for a specific modid. Dependencies are optional.
[[dependencies.${mod_id}]] #optional
# the modid of the dependency
modId="neoforge" #mandatory
# The type of the dependency. Can be one of "required", "optional", "incompatible" or "discouraged" (case insensitive).
# 'required' requires the mod to exist, 'optional' does not
# 'incompatible' will prevent the game from loading when the mod exists, and 'discouraged' will show a warning
type="required" #mandatory
# Optional field describing why the dependency is required or why it is incompatible
# reason="..."
# The version range of the dependency
versionRange="${neo_version_range}" #mandatory
# An ordering relationship for the dependency.
# BEFORE - This mod is loaded BEFORE the dependency
# AFTER - This mod is loaded AFTER the dependency
ordering="NONE"
# Side this dependency is applied on - BOTH, CLIENT, or SERVER
side="BOTH"
# Here's another dependency
[[dependencies.${mod_id}]]
modId="minecraft"
type="required"
# This version range declares a minimum of the current minecraft version up to but not including the next major version
versionRange="${minecraft_version_range}"
ordering="NONE"
side="BOTH"
# Features are specific properties of the game environment, that you may want to declare you require. This example declares
# that your mod requires GL version 3.2 or higher. Other features will be added. They are side aware so declaring this won't
# stop your mod loading on the server for example.
#[features.${mod_id}]
#openGLVersion="[3.2,)"