Compare commits

...

78 Commits

Author SHA1 Message Date
3cfd4c59bb Actualizar README.md 2025-12-31 14:37:06 +00:00
6781cbfa05 Actualizar README.md 2025-12-31 08:58:50 +00:00
5af7143532 Actualizar README.md 2025-12-31 08:57:12 +00:00
c71320aa08 Eliminar .github/workflows/build.yml 2025-12-31 08:52:29 +00:00
457f754221 Eliminar .github/workflows/build-release.yml
Some checks failed
build / build (17, ubuntu-20.04) (push) Has been cancelled
2025-12-31 08:52:10 +00:00
3bf1df5448 Port to Minecraft 1.21.11
Some checks failed
build / build (17, ubuntu-20.04) (push) Has been cancelled
build-release / build (release) Has been cancelled
2025-12-31 08:26:44 +01:00
ec9a0ff865 Port to Minecraft 1.21.9
Some checks failed
build / build (17, ubuntu-20.04) (push) Has been cancelled
2025-12-31 07:39:39 +01:00
959f435e8f Port to Minecraft 1.21.10
Some checks failed
build / build (17, ubuntu-20.04) (push) Has been cancelled
2025-12-31 07:32:59 +01:00
Rain Graham
e0eba682ed update to 1.21.8 2025-09-05 11:51:07 +01:00
Rain Graham
459e6de64a update to 1.20.5 2025-04-27 11:44:36 +01:00
Liz Graham
db9040acc5 update to 1.21.4 2025-01-20 06:48:43 +00:00
Rain Graham
be27cf0f30 Merge pull request #27 from mpustovoi/1.18.2
Create ru_ru.json
2024-11-17 09:21:20 +00:00
Rain Graham
734ea7a1a2 Merge pull request #35 from SnowCutieOwO/patch-1
Create zh_cn.json
2024-11-17 09:20:54 +00:00
Liz Graham
71832342af update to 1.21.3, fix bugs, close issue #31, #34, #37 and #39. 2024-11-17 09:18:01 +00:00
Rain Graham
4b4b2ad206 break config, but now works in 1.21.3 2024-11-05 15:31:44 +00:00
SnowCutieOwO
e795778ba8 Create zh_cn.json
Added Simplified Chinese translation <3
2024-08-04 13:04:38 +08:00
Liz Graham
99ffeb1f99 update to 1.21, update to Gradle 8.8, update to Loom 1.7 2024-06-27 15:09:42 +01:00
Liz Graham
4e1a122289 add cave dust particle
calculate position inside blocks
changed menu
changed modid to cavedust
change some default values
fix bug where user got softlocked in the particle cycle in multiplayer
2024-05-17 02:30:53 +01:00
Korben
2161bbd1ba Create ru_ru.json 2024-03-13 12:29:23 +03:00
Liz Graham
e35fdaa8ce Merge pull request #19 from Myuui/1.18.2
French Translation by @Myuui
2024-01-21 01:59:17 +00:00
Liz Graham
a0aef4a5ef Merge pull request #20 from arunsathiya/1.18.2
ci: Use GITHUB_OUTPUT envvar instead of set-output command
2024-01-21 01:57:17 +00:00
Liz Graham
39cf0a0703 update to 1.20.4
loader to 1.15.5
loom to 1.5
gradle to 8.5
2024-01-17 14:48:06 +00:00
Arun
22928e4885 ci: Use GITHUB_OUTPUT envvar instead of set-output command 2024-01-11 21:22:27 -08:00
Myuui
8cb6407f8b French Translation by Myuui 2023-12-17 23:58:18 +01:00
Liz Graham
4f3e80bac4 update to 1.20.2 2023-12-04 18:41:42 +00:00
Liz Graham
12016db5f2 Update README.md 2023-06-21 02:48:46 +01:00
Liz Graham
e6b4636119 update to 1.20 2023-06-21 02:47:36 +01:00
Liz Graham
10a4c88d9b Update gradle.properties 2023-05-23 19:06:12 +01:00
Liz Graham
2bc02401b0 Update fabric.mod.json 2023-05-23 19:00:31 +01:00
Liz Graham
a071eba485 Update build-release.yml 2023-05-22 03:58:09 +01:00
Liz Graham
0dde5fa1eb Bump to 1.4.0
Also lock version to 1.19.4
2023-05-22 03:29:26 +01:00
Liz Graham
f00d0171ae Improve error handling for incompatible particles 2023-05-22 03:28:49 +01:00
Liz Graham
93a18d622b Fix bugs and fix #4
Particles can no longer spawn under the world.
Particles no longer spawn in blocks, instead spawning in air.
Fixed bug present since 1.2.0, which meant particle amount was dependant on blocks around player.
New particle multiplier allowing greater control of particle amount.
New F3 screen text, allows user to debug particle amount.
Removed upper and lower limit buttons.
2023-05-22 03:26:34 +01:00
Liz Graham
cfe0ec666f UI update 2023-05-22 03:26:34 +01:00
Liz Graham
1b20ee94c4 Update build-release.yml 2023-05-21 23:26:55 +01:00
Liz Graham
f0fdd69260 Bump to 1.3.0 2023-05-21 07:47:21 +01:00
Liz Graham
6197a489b3 Update README.md 2023-05-21 07:44:36 +01:00
Liz Graham
1a097e6daf Update README.md 2023-05-21 07:43:40 +01:00
Liz Graham
2fb8ba966a set default id to white ash's id 2023-05-21 07:30:15 +01:00
Liz Graham
6a5d68cc84 update to 1.19.4 2023-05-21 07:27:43 +01:00
Liz Graham
b5687628df Fix issues with out of array IDs 2023-05-21 06:58:47 +01:00
Liz Graham
5486f49555 Fix different bug with bounds causing a crash 2023-05-21 06:26:21 +01:00
Liz Graham
3469807388 Fix bug with bounds causing a crash
Implement in-game particle cycling
2023-05-21 06:09:07 +01:00
Liz Graham
a05356f475 update loom to 1.2-snapshot 2023-05-21 02:46:17 +01:00
Liz Graham
149ddbe6fe update gradle to 8.1.1 2023-05-21 02:46:01 +01:00
Liz Graham
eabe134475 remove redundant functions for negative bounds 2023-05-21 02:42:57 +01:00
Liz Graham
fa76355a87 Update modmenu to 5.1.0-beta.3 2023-05-21 02:41:20 +01:00
Liz Graham
fb540f04ff Update to 1.19.3
Took 37 seconds
2023-01-19 01:00:17 +00:00
Liz Graham
c0c99c61bb Update to loom 1.0
Took 40 minutes
2023-01-19 00:59:47 +00:00
Liz Graham
a8c1ce20b0 Merge branch '1.18.2' into 1.19.2 2022-08-26 13:38:43 +01:00
Liz Graham
35dd3e057c reduce size of icon image by 51% 2022-08-14 02:19:14 +01:00
Liz Graham
ab9ed3df3e reduce size of icon image by 51% 2022-08-14 02:19:08 +01:00
Liz Graham
008d3dda86 update to 1.19.2 2022-08-14 02:03:48 +01:00
Liz Graham
ec3767bc98 Merge branch '1.18.2' into 1.19 2022-06-01 20:09:29 +01:00
Liz Graham
059af3ea45 update license 2022-06-01 20:09:12 +01:00
Liz Graham
785d04f922 update license 2022-06-01 19:56:52 +01:00
Liz Graham
f375d1f6e1 Merge branch '1.18' into 1.19 2022-06-01 19:54:19 +01:00
Liz Graham
39da57ee43 none of this is needed lol 2022-06-01 19:49:48 +01:00
Liz Graham
8bc4805db0 update fabric-loom to 0.12 2022-06-01 19:44:40 +01:00
Liz Graham
b1b578cdbc update to 1.19-pre5 2022-06-01 19:44:18 +01:00
Liz Graham
90a10ce8a6 add backupsrc to .gitignore 2022-06-01 19:30:52 +01:00
Liz Graham
056a251a70 update to 1.19-pre1
-update mappings
-bump fabric.mod.json versions
-change `new TranslatableText` to `Text.translatable`
-change isBedWorking to bedWorking
2022-05-19 20:47:37 +01:00
Liz Graham
809846cfcf update license 2022-03-26 01:27:29 +00:00
Liz Graham
374833fba5 reupdate to 1.18.2 because I fucked up 2022-03-26 01:22:05 +00:00
Liz Graham
62bce166d5 Bump version to 1.2.0 2022-03-26 01:10:21 +00:00
Liz Graham
c6f74a103e A whole load of shit 2022-03-26 01:08:37 +00:00
Liz Graham
7d970a461a Update MathHelper class 2022-03-25 19:46:19 +00:00
Liz Graham
fc94b55e83 Merge remote-tracking branch 'origin/1.18' into 1.18 2022-03-25 19:31:07 +00:00
Liz Graham
88ee5d1cc2 update license 2022-03-25 19:19:40 +00:00
Liz Graham
45a2106054 move shouldParticlesSpawn to own class 2022-03-25 17:33:15 +00:00
Liz Graham
4dda0e8049 Update build-release.yml
include modrinth mod ids
2022-03-25 15:37:08 +00:00
Liz Graham
5affe34a83 remove dumb entry from .gitignore 2022-03-25 15:34:16 +00:00
Liz Graham
fa5213a4a8 update build.yml
add a few extra steps to make sha shorter for artifact
2022-03-25 15:33:38 +00:00
Liz Graham
9584d5ad94 work pls 2022-03-25 15:07:00 +00:00
Liz Graham
705402c139 ??? 2022-03-25 15:02:58 +00:00
Liz Graham
0bf6db4415 hopefully fix workflow ?? 2022-03-25 15:00:47 +00:00
Liz Graham
f26764f5c9 add build-release.yml 2022-03-25 14:57:57 +00:00
Liz Graham
d5f549c417 update fabric json and change config code 2022-03-20 16:56:58 +00:00
34 changed files with 1313 additions and 605 deletions

View File

@@ -1,50 +0,0 @@
# Automatically build the project and run any configured tests for every push
# and submitted pull request. This can help catch issues that only occur on
# certain platforms or Java versions, and provides a first line of defence
# against bad commits.
name: build
on: [pull_request, push]
jobs:
build:
strategy:
matrix:
# Use these Java versions
java: [
17 # Minimum supported by Minecraft 1.18
]
os: [ubuntu-20.04] # and run on Linux
runs-on: ${{ matrix.os }}
steps:
- name: Checkout repository
uses: actions/checkout@v2
- name: Extract current branch name
shell: bash
# bash pattern expansion to grab branch name without slashes
run: ref="${GITHUB_REF#refs/heads/}" && echo "::set-output name=branch::${ref////-}"
id: ref
- name: Validate gradle wrapper
uses: gradle/wrapper-validation-action@v1
- name: Setup JDK${{ matrix.java }}
uses: actions/setup-java@v1
with:
java-version: ${{ matrix.java }}
- name: Make gradle wrapper executable
if: ${{ runner.os != 'Windows' }}
run: chmod +x gradlew
- name: Build
run: ./gradlew build
- name: Capture build artifacts
if: ${{ runner.os == 'Linux' && matrix.java == '17' }} # Only upload artifacts built from latest java on one OS
uses: actions/upload-artifact@v2
with:
name: dust-fabric-${{ github.sha }}
path: build/libs/*[0-9].jar

1
.gitignore vendored
View File

@@ -31,3 +31,4 @@ bin/
# fabric
run/
BackupSrc/

470
LICENSE
View File

@@ -1,121 +1,373 @@
Creative Commons Legal Code
Mozilla Public License Version 2.0
==================================
CC0 1.0 Universal
1. Definitions
--------------
CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN
ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS
INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES
REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS
PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM
THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED
HEREUNDER.
1.1. "Contributor"
means each individual or legal entity that creates, contributes to
the creation of, or owns Covered Software.
Statement of Purpose
1.2. "Contributor Version"
means the combination of the Contributions of others (if any) used
by a Contributor and that particular Contributor's Contribution.
The laws of most jurisdictions throughout the world automatically confer
exclusive Copyright and Related Rights (defined below) upon the creator
and subsequent owner(s) (each and all, an "owner") of an original work of
authorship and/or a database (each, a "Work").
1.3. "Contribution"
means Covered Software of a particular Contributor.
Certain owners wish to permanently relinquish those rights to a Work for
the purpose of contributing to a commons of creative, cultural and
scientific works ("Commons") that the public can reliably and without fear
of later claims of infringement build upon, modify, incorporate in other
works, reuse and redistribute as freely as possible in any form whatsoever
and for any purposes, including without limitation commercial purposes.
These owners may contribute to the Commons to promote the ideal of a free
culture and the further production of creative, cultural and scientific
works, or to gain reputation or greater distribution for their Work in
part through the use and efforts of others.
1.4. "Covered Software"
means Source Code Form to which the initial Contributor has attached
the notice in Exhibit A, the Executable Form of such Source Code
Form, and Modifications of such Source Code Form, in each case
including portions thereof.
For these and/or other purposes and motivations, and without any
expectation of additional consideration or compensation, the person
associating CC0 with a Work (the "Affirmer"), to the extent that he or she
is an owner of Copyright and Related Rights in the Work, voluntarily
elects to apply CC0 to the Work and publicly distribute the Work under its
terms, with knowledge of his or her Copyright and Related Rights in the
Work and the meaning and intended legal effect of CC0 on those rights.
1.5. "Incompatible With Secondary Licenses"
means
1. Copyright and Related Rights. A Work made available under CC0 may be
protected by copyright and related or neighboring rights ("Copyright and
Related Rights"). Copyright and Related Rights include, but are not
limited to, the following:
(a) that the initial Contributor has attached the notice described
in Exhibit B to the Covered Software; or
i. the right to reproduce, adapt, distribute, perform, display,
communicate, and translate a Work;
ii. moral rights retained by the original author(s) and/or performer(s);
iii. publicity and privacy rights pertaining to a person's image or
likeness depicted in a Work;
iv. rights protecting against unfair competition in regards to a Work,
subject to the limitations in paragraph 4(a), below;
v. rights protecting the extraction, dissemination, use and reuse of data
in a Work;
vi. database rights (such as those arising under Directive 96/9/EC of the
European Parliament and of the Council of 11 March 1996 on the legal
protection of databases, and under any national implementation
thereof, including any amended or successor version of such
directive); and
vii. other similar, equivalent or corresponding rights throughout the
world based on applicable law or treaty, and any national
implementations thereof.
(b) that the Covered Software was made available under the terms of
version 1.1 or earlier of the License, but not also under the
terms of a Secondary License.
2. Waiver. To the greatest extent permitted by, but not in contravention
of, applicable law, Affirmer hereby overtly, fully, permanently,
irrevocably and unconditionally waives, abandons, and surrenders all of
Affirmer's Copyright and Related Rights and associated claims and causes
of action, whether now known or unknown (including existing as well as
future claims and causes of action), in the Work (i) in all territories
worldwide, (ii) for the maximum duration provided by applicable law or
treaty (including future time extensions), (iii) in any current or future
medium and for any number of copies, and (iv) for any purpose whatsoever,
including without limitation commercial, advertising or promotional
purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each
member of the public at large and to the detriment of Affirmer's heirs and
successors, fully intending that such Waiver shall not be subject to
revocation, rescission, cancellation, termination, or any other legal or
equitable action to disrupt the quiet enjoyment of the Work by the public
as contemplated by Affirmer's express Statement of Purpose.
1.6. "Executable Form"
means any form of the work other than Source Code Form.
3. Public License Fallback. Should any part of the Waiver for any reason
be judged legally invalid or ineffective under applicable law, then the
Waiver shall be preserved to the maximum extent permitted taking into
account Affirmer's express Statement of Purpose. In addition, to the
extent the Waiver is so judged Affirmer hereby grants to each affected
person a royalty-free, non transferable, non sublicensable, non exclusive,
irrevocable and unconditional license to exercise Affirmer's Copyright and
Related Rights in the Work (i) in all territories worldwide, (ii) for the
maximum duration provided by applicable law or treaty (including future
time extensions), (iii) in any current or future medium and for any number
of copies, and (iv) for any purpose whatsoever, including without
limitation commercial, advertising or promotional purposes (the
"License"). The License shall be deemed effective as of the date CC0 was
applied by Affirmer to the Work. Should any part of the License for any
reason be judged legally invalid or ineffective under applicable law, such
partial invalidity or ineffectiveness shall not invalidate the remainder
of the License, and in such case Affirmer hereby affirms that he or she
will not (i) exercise any of his or her remaining Copyright and Related
Rights in the Work or (ii) assert any associated claims and causes of
action with respect to the Work, in either case contrary to Affirmer's
express Statement of Purpose.
1.7. "Larger Work"
means a work that combines Covered Software with other material, in
a separate file or files, that is not Covered Software.
4. Limitations and Disclaimers.
1.8. "License"
means this document.
a. No trademark or patent rights held by Affirmer are waived, abandoned,
surrendered, licensed or otherwise affected by this document.
b. Affirmer offers the Work as-is and makes no representations or
warranties of any kind concerning the Work, express, implied,
statutory or otherwise, including without limitation warranties of
title, merchantability, fitness for a particular purpose, non
infringement, or the absence of latent or other defects, accuracy, or
the present or absence of errors, whether or not discoverable, all to
the greatest extent permissible under applicable law.
c. Affirmer disclaims responsibility for clearing rights of other persons
that may apply to the Work or any use thereof, including without
limitation any person's Copyright and Related Rights in the Work.
Further, Affirmer disclaims responsibility for obtaining any necessary
consents, permissions or other rights required for any use of the
Work.
d. Affirmer understands and acknowledges that Creative Commons is not a
party to this document and has no duty or obligation with respect to
this CC0 or use of the Work.
1.9. "Licensable"
means having the right to grant, to the maximum extent possible,
whether at the time of the initial grant or subsequently, any and
all of the rights conveyed by this License.
1.10. "Modifications"
means any of the following:
(a) any file in Source Code Form that results from an addition to,
deletion from, or modification of the contents of Covered
Software; or
(b) any new file in Source Code Form that contains any Covered
Software.
1.11. "Patent Claims" of a Contributor
means any patent claim(s), including without limitation, method,
process, and apparatus claims, in any patent Licensable by such
Contributor that would be infringed, but for the grant of the
License, by the making, using, selling, offering for sale, having
made, import, or transfer of either its Contributions or its
Contributor Version.
1.12. "Secondary License"
means either the GNU General Public License, Version 2.0, the GNU
Lesser General Public License, Version 2.1, the GNU Affero General
Public License, Version 3.0, or any later versions of those
licenses.
1.13. "Source Code Form"
means the form of the work preferred for making modifications.
1.14. "You" (or "Your")
means an individual or a legal entity exercising rights under this
License. For legal entities, "You" includes any entity that
controls, is controlled by, or is under common control with You. For
purposes of this definition, "control" means (a) the power, direct
or indirect, to cause the direction or management of such entity,
whether by contract or otherwise, or (b) ownership of more than
fifty percent (50%) of the outstanding shares or beneficial
ownership of such entity.
2. License Grants and Conditions
--------------------------------
2.1. Grants
Each Contributor hereby grants You a world-wide, royalty-free,
non-exclusive license:
(a) under intellectual property rights (other than patent or trademark)
Licensable by such Contributor to use, reproduce, make available,
modify, display, perform, distribute, and otherwise exploit its
Contributions, either on an unmodified basis, with Modifications, or
as part of a Larger Work; and
(b) under Patent Claims of such Contributor to make, use, sell, offer
for sale, have made, import, and otherwise transfer either its
Contributions or its Contributor Version.
2.2. Effective Date
The licenses granted in Section 2.1 with respect to any Contribution
become effective for each Contribution on the date the Contributor first
distributes such Contribution.
2.3. Limitations on Grant Scope
The licenses granted in this Section 2 are the only rights granted under
this License. No additional rights or licenses will be implied from the
distribution or licensing of Covered Software under this License.
Notwithstanding Section 2.1(b) above, no patent license is granted by a
Contributor:
(a) for any code that a Contributor has removed from Covered Software;
or
(b) for infringements caused by: (i) Your and any other third party's
modifications of Covered Software, or (ii) the combination of its
Contributions with other software (except as part of its Contributor
Version); or
(c) under Patent Claims infringed by Covered Software in the absence of
its Contributions.
This License does not grant any rights in the trademarks, service marks,
or logos of any Contributor (except as may be necessary to comply with
the notice requirements in Section 3.4).
2.4. Subsequent Licenses
No Contributor makes additional grants as a result of Your choice to
distribute the Covered Software under a subsequent version of this
License (see Section 10.2) or under the terms of a Secondary License (if
permitted under the terms of Section 3.3).
2.5. Representation
Each Contributor represents that the Contributor believes its
Contributions are its original creation(s) or it has sufficient rights
to grant the rights to its Contributions conveyed by this License.
2.6. Fair Use
This License is not intended to limit any rights You have under
applicable copyright doctrines of fair use, fair dealing, or other
equivalents.
2.7. Conditions
Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
in Section 2.1.
3. Responsibilities
-------------------
3.1. Distribution of Source Form
All distribution of Covered Software in Source Code Form, including any
Modifications that You create or to which You contribute, must be under
the terms of this License. You must inform recipients that the Source
Code Form of the Covered Software is governed by the terms of this
License, and how they can obtain a copy of this License. You may not
attempt to alter or restrict the recipients' rights in the Source Code
Form.
3.2. Distribution of Executable Form
If You distribute Covered Software in Executable Form then:
(a) such Covered Software must also be made available in Source Code
Form, as described in Section 3.1, and You must inform recipients of
the Executable Form how they can obtain a copy of such Source Code
Form by reasonable means in a timely manner, at a charge no more
than the cost of distribution to the recipient; and
(b) You may distribute such Executable Form under the terms of this
License, or sublicense it under different terms, provided that the
license for the Executable Form does not attempt to limit or alter
the recipients' rights in the Source Code Form under this License.
3.3. Distribution of a Larger Work
You may create and distribute a Larger Work under terms of Your choice,
provided that You also comply with the requirements of this License for
the Covered Software. If the Larger Work is a combination of Covered
Software with a work governed by one or more Secondary Licenses, and the
Covered Software is not Incompatible With Secondary Licenses, this
License permits You to additionally distribute such Covered Software
under the terms of such Secondary License(s), so that the recipient of
the Larger Work may, at their option, further distribute the Covered
Software under the terms of either this License or such Secondary
License(s).
3.4. Notices
You may not remove or alter the substance of any license notices
(including copyright notices, patent notices, disclaimers of warranty,
or limitations of liability) contained within the Source Code Form of
the Covered Software, except that You may alter any license notices to
the extent required to remedy known factual inaccuracies.
3.5. Application of Additional Terms
You may choose to offer, and to charge a fee for, warranty, support,
indemnity or liability obligations to one or more recipients of Covered
Software. However, You may do so only on Your own behalf, and not on
behalf of any Contributor. You must make it absolutely clear that any
such warranty, support, indemnity, or liability obligation is offered by
You alone, and You hereby agree to indemnify every Contributor for any
liability incurred by such Contributor as a result of warranty, support,
indemnity or liability terms You offer. You may include additional
disclaimers of warranty and limitations of liability specific to any
jurisdiction.
4. Inability to Comply Due to Statute or Regulation
---------------------------------------------------
If it is impossible for You to comply with any of the terms of this
License with respect to some or all of the Covered Software due to
statute, judicial order, or regulation then You must: (a) comply with
the terms of this License to the maximum extent possible; and (b)
describe the limitations and the code they affect. Such description must
be placed in a text file included with all distributions of the Covered
Software under this License. Except to the extent prohibited by statute
or regulation, such description must be sufficiently detailed for a
recipient of ordinary skill to be able to understand it.
5. Termination
--------------
5.1. The rights granted under this License will terminate automatically
if You fail to comply with any of its terms. However, if You become
compliant, then the rights granted under this License from a particular
Contributor are reinstated (a) provisionally, unless and until such
Contributor explicitly and finally terminates Your grants, and (b) on an
ongoing basis, if such Contributor fails to notify You of the
non-compliance by some reasonable means prior to 60 days after You have
come back into compliance. Moreover, Your grants from a particular
Contributor are reinstated on an ongoing basis if such Contributor
notifies You of the non-compliance by some reasonable means, this is the
first time You have received notice of non-compliance with this License
from such Contributor, and You become compliant prior to 30 days after
Your receipt of the notice.
5.2. If You initiate litigation against any entity by asserting a patent
infringement claim (excluding declaratory judgment actions,
counter-claims, and cross-claims) alleging that a Contributor Version
directly or indirectly infringes any patent, then the rights granted to
You by any and all Contributors for the Covered Software under Section
2.1 of this License shall terminate.
5.3. In the event of termination under Sections 5.1 or 5.2 above, all
end user license agreements (excluding distributors and resellers) which
have been validly granted by You or Your distributors under this License
prior to termination shall survive termination.
************************************************************************
* *
* 6. Disclaimer of Warranty *
* ------------------------- *
* *
* Covered Software is provided under this License on an "as is" *
* basis, without warranty of any kind, either expressed, implied, or *
* statutory, including, without limitation, warranties that the *
* Covered Software is free of defects, merchantable, fit for a *
* particular purpose or non-infringing. The entire risk as to the *
* quality and performance of the Covered Software is with You. *
* Should any Covered Software prove defective in any respect, You *
* (not any Contributor) assume the cost of any necessary servicing, *
* repair, or correction. This disclaimer of warranty constitutes an *
* essential part of this License. No use of any Covered Software is *
* authorized under this License except under this disclaimer. *
* *
************************************************************************
************************************************************************
* *
* 7. Limitation of Liability *
* -------------------------- *
* *
* Under no circumstances and under no legal theory, whether tort *
* (including negligence), contract, or otherwise, shall any *
* Contributor, or anyone who distributes Covered Software as *
* permitted above, be liable to You for any direct, indirect, *
* special, incidental, or consequential damages of any character *
* including, without limitation, damages for lost profits, loss of *
* goodwill, work stoppage, computer failure or malfunction, or any *
* and all other commercial damages or losses, even if such party *
* shall have been informed of the possibility of such damages. This *
* limitation of liability shall not apply to liability for death or *
* personal injury resulting from such party's negligence to the *
* extent applicable law prohibits such limitation. Some *
* jurisdictions do not allow the exclusion or limitation of *
* incidental or consequential damages, so this exclusion and *
* limitation may not apply to You. *
* *
************************************************************************
8. Litigation
-------------
Any litigation relating to this License may be brought only in the
courts of a jurisdiction where the defendant maintains its principal
place of business and such litigation shall be governed by laws of that
jurisdiction, without reference to its conflict-of-law provisions.
Nothing in this Section shall prevent a party's ability to bring
cross-claims or counter-claims.
9. Miscellaneous
----------------
This License represents the complete agreement concerning the subject
matter hereof. If any provision of this License is held to be
unenforceable, such provision shall be reformed only to the extent
necessary to make it enforceable. Any law or regulation which provides
that the language of a contract shall be construed against the drafter
shall not be used to construe this License against a Contributor.
10. Versions of the License
---------------------------
10.1. New Versions
Mozilla Foundation is the license steward. Except as provided in Section
10.3, no one other than the license steward has the right to modify or
publish new versions of this License. Each version will be given a
distinguishing version number.
10.2. Effect of New Versions
You may distribute the Covered Software under the terms of the version
of the License under which You originally received the Covered Software,
or under the terms of any subsequent version published by the license
steward.
10.3. Modified Versions
If you create software not governed by this License, and you want to
create a new license for such software, you may create and use a
modified version of this License if you rename the license and remove
any references to the name of the license steward (except to note that
such modified license differs from this License).
10.4. Distributing Source Code Form that is Incompatible With Secondary
Licenses
If You choose to distribute Source Code Form that is Incompatible With
Secondary Licenses under the terms of this version of the License, the
notice described in Exhibit B of this License must be attached.
Exhibit A - Source Code Form License Notice
-------------------------------------------
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
If it is not possible or desirable to put the notice in a particular
file, then You may include the notice in a location (such as a LICENSE
file in a relevant directory) where a recipient would be likely to look
for such a notice.
You may add additional accurate notices of copyright ownership.
Exhibit B - "Incompatible With Secondary Licenses" Notice
---------------------------------------------------------
This Source Code Form is "Incompatible With Secondary Licenses", as
defined by the Mozilla Public License, v. 2.0.

View File

@@ -1,4 +1,4 @@
# Cave Dust
![Texto alternativo](https://cdn.modrinth.com/data/cached_images/4015b426707768dbddeb346d89b02fedbdd1984f.png)
## What...what is "Cave Dust"?
@@ -6,8 +6,10 @@ I'm glad you asked! It's just a mod that adds the white ash particle from the Ba
Now to the nitty gritty:
It works by checking if the player has the sky above them while being below sea level and then scales the amount of particles based on depth.
<br><br>It has a config system that you can access using Mod Menu, most things you can change in-game, but to change the particle you'll need to open the config file manually :)
<br><br>It has a config system that you can access using Mod Menu.
<br>
## Dependencies
Cave Dust requires the [Fabric API](https://www.curseforge.com/minecraft/mc-mods/fabric-api) but everything else Cave Dust *needs* is included.
***HOWEVER***, I recommend [Mod Menu](https://www.curseforge.com/minecraft/mc-mods/modmenu) to be able to use the config screen :p
### Thanks to LizIsTired for the original Cave Dust mod! https://github.com/LizIsTired/cave_dust

View File

@@ -1,12 +1,12 @@
plugins {
id 'fabric-loom' version '0.11-SNAPSHOT'
id 'fabric-loom' version '1.14.7'
id 'maven-publish'
}
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
base {
archivesName = project.archives_base_name
}
archivesBaseName = project.archives_base_name
version = project.mod_version
group = project.maven_group
@@ -19,7 +19,7 @@ repositories {
}
}
maven {
url = "https://maven.terraformersmc.com"
url = "https://maven.terraformersmc.com/releases"
}
maven {
name = 'minelp'
@@ -61,7 +61,7 @@ processResources {
tasks.withType(JavaCompile).configureEach {
// Minecraft 1.18 (1.18-pre2) upwards uses Java 17.
it.options.release = 17
it.options.release = 21
}
java {
@@ -69,11 +69,13 @@ java {
// if it is present.
// If you remove this line, sources will not be generated.
withSourcesJar()
sourceCompatibility = JavaVersion.VERSION_21
targetCompatibility = JavaVersion.VERSION_21
}
jar {
from("LICENSE") {
rename { "${it}_${project.archivesBaseName}"}
rename { "${it}_${project.archives_base_name}" }
}
}

View File

@@ -2,19 +2,17 @@
org.gradle.jvmargs=-Xmx1G
# Fabric Properties
# check these on https://fabricmc.net/develop
minecraft_version=1.18.1
yarn_mappings=1.18.1+build.22
loader_version=0.13.3
minecraft_version=1.21.11
yarn_mappings=1.21.11+build.3
loader_version=0.18.4
loom_version=1.14-SNAPSHOT
# Mod Properties
mod_version = 1.1.0
maven_group = com.lizistired
archives_base_name = cave_dust
mod_version=1.0.0
maven_group=com.straice
archives_base_name=cave_dust_reforged
# Dependencies
fabric_version=0.46.4+1.18
clothconfig_version = 6.1.48
modmenu_version = 3.0.1
minelp_version=4.4.0-beta.2
kirin_version=1.10.0-beta.2
fabric_version=0.140.2+1.21.11
modmenu_version=17.0.0-beta.1
kirin_version=1.21.4+1.21.11

Binary file not shown.

View File

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

54
gradlew vendored
View File

@@ -1,7 +1,7 @@
#!/bin/sh
#
# Copyright © 2015-2021 the original authors.
# Copyright © 2015-2021 the original authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -15,6 +15,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
# SPDX-License-Identifier: Apache-2.0
#
##############################################################################
#
@@ -32,10 +34,10 @@
# Busybox and similar reduced shells will NOT work, because this script
# requires all of these POSIX shell features:
# * functions;
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
# * compound commands having a testable exit status, especially «case»;
# * various built-in commands including «command», «set», and «ulimit».
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
# * compound commands having a testable exit status, especially «case»;
# * various built-in commands including «command», «set», and «ulimit».
#
# Important for patching:
#
@@ -55,7 +57,7 @@
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/master/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.
#
# You can find Gradle at https://github.com/gradle/gradle/.
@@ -80,13 +82,12 @@ do
esac
done
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
APP_NAME="Gradle"
# This is normally unused
# shellcheck disable=SC2034
APP_BASE_NAME=${0##*/}
# 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"'
# 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.
MAX_FD=maximum
@@ -133,22 +134,29 @@ location of your Java installation."
fi
else
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
location of your Java installation."
fi
fi
# Increase the maximum file descriptors if we can.
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #(
max*)
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC2039,SC3045
MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit"
esac
case $MAX_FD in #(
'' | soft) :;; #(
*)
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC2039,SC3045
ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD"
esac
@@ -193,11 +201,15 @@ if "$cygwin" || "$msys" ; then
done
fi
# Collect all arguments for the java command;
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
# shell script including quotes and variable substitutions, so put them in
# double quotes to make sure that they get re-expanded; and
# * put everything else in single quotes, so that it's not re-expanded.
# 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"'
# Collect all arguments for the java command:
# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
# and any embedded shellness will be escaped.
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
# treated as '${Hostname}' itself on the command line.
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
@@ -205,6 +217,12 @@ set -- \
org.gradle.wrapper.GradleWrapperMain \
"$@"
# Stop when "xargs" is not available.
if ! command -v xargs >/dev/null 2>&1
then
die "xargs is not available"
fi
# Use "xargs" to parse quoted args.
#
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.

37
gradlew.bat vendored
View File

@@ -13,8 +13,10 @@
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@rem SPDX-License-Identifier: Apache-2.0
@rem
@if "%DEBUG%" == "" @echo off
@if "%DEBUG%"=="" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@@ -25,7 +27,8 @@
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
if "%DIRNAME%"=="" set DIRNAME=.
@rem This is normally unused
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@@ -40,13 +43,13 @@ if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto execute
if %ERRORLEVEL% equ 0 goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
echo. 1>&2
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2
goto fail
@@ -56,11 +59,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
echo. 1>&2
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2
goto fail
@@ -75,13 +78,15 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
if %ERRORLEVEL% equ 0 goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
set EXIT_CODE=%ERRORLEVEL%
if %EXIT_CODE% equ 0 set EXIT_CODE=1
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
exit /b %EXIT_CODE%
:mainEnd
if "%OS%"=="Windows_NT" endlocal

View File

@@ -1,68 +1,129 @@
package net.lizistired.cavedust;
//minecraft imports
import net.minecraft.client.MinecraftClient;
import net.minecraft.world.World;
//other imports
import com.minelittlepony.common.util.GamePaths;
// minecraft imports
import net.fabricmc.api.ClientModInitializer;
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
import net.fabricmc.fabric.api.client.particle.v1.ParticleFactoryRegistry;
import net.minecraft.client.MinecraftClient;
import net.minecraft.particle.ParticleEffect;
import net.minecraft.registry.Registries;
import net.minecraft.text.Text;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
// other imports
import com.minelittlepony.common.util.GamePaths;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
//java imports
import java.nio.file.Path;
//static imports
import static net.lizistired.cavedust.utils.MathHelper.*;
// java imports
import java.nio.file.Path;
// static imports
import static net.lizistired.cavedust.utils.KeybindingHelper.*;
import static net.lizistired.cavedust.utils.MathHelper.generateRandomDouble;
import static net.lizistired.cavedust.utils.MathHelper.normalize;
import static net.lizistired.cavedust.utils.ParticleSpawnUtil.shouldParticlesSpawn;
public class CaveDust implements ClientModInitializer {
//logger
public static final Logger LOGGER = LoggerFactory.getLogger("caveDust");
//make class static
private static CaveDust instance;
public static CaveDust getInstance() {
return instance;
}
public CaveDust() {
instance = this;
}
//config assignment
private static CaveDustConfig config;
public CaveDustConfig getConfig() {
return config;
}
// logger
public static final Logger LOGGER = LoggerFactory.getLogger("cavedust");
@Override
public void onInitializeClient() {
//config path and loading
Path CaveDustFolder = GamePaths.getConfigDirectory().resolve("cavedust");
config = new CaveDustConfig(CaveDustFolder.getParent().resolve("cavedust.json"), this);
config.load();
//register end client tick to create cave dust function, using end client tick for async
ClientTickEvents.END_CLIENT_TICK.register(this::createCaveDust);
}
// make class static
private static CaveDust instance;
private void createCaveDust(MinecraftClient client) {
public static CaveDust getInstance() {
return instance;
}
if (client.world == null) return;
World world = client.world;
public CaveDust() {
instance = this;
}
if (shouldParticlesSpawn(client, config)) {
double probabilityNormalized = normalize(config.getLowerLimit(), config.getUpperLimit(), client.player.getBlockY());
// config assignment
private static CaveDustConfig config;
for (int i = 0; i < probabilityNormalized * config.getParticleMultiplier(); i++) {
try {
double x = client.player.getPos().getX() + generateRandomDouble(config.getDimensionsMinX(), config.getDimensionsMaxX());
double y = client.player.getPos().getY() + generateRandomDouble(config.getDimensionsMinX(), config.getDimensionsMaxY());
double z = client.player.getPos().getZ() + generateRandomDouble(config.getDimensionsMinX(), config.getDimensionsMaxZ());
public CaveDustConfig getConfig() {
return config;
}
world.addParticle(config.getParticle(), x, y, z, 0, 0, 0);}
public static ParticleEffect WHITE_ASH_ID =
(ParticleEffect) Registries.PARTICLE_TYPE.get(Identifier.of("cavedust", "cave_dust"));
catch (NullPointerException e) {
LOGGER.error(String.valueOf(e));
getConfig().setParticle("minecraft:white_ash");
}
}
}
}
public static int PARTICLE_AMOUNT = 0;
@Override
public void onInitializeClient() {
// config path and loading
Path caveDustFolder = GamePaths.getConfigDirectory().resolve("cavedust");
config = new CaveDustConfig(caveDustFolder.getParent().resolve("cavedust.json"), this);
config.load();
registerKeyBindings();
ParticleFactoryRegistry.getInstance().register(CaveDustServer.CAVE_DUST, CaveDustParticleFactory.Factory::new);
// register end client tick to create cave dust function, using end client tick for async
ClientTickEvents.END_CLIENT_TICK.register(this::createCaveDust);
}
private void createCaveDust(MinecraftClient client) {
if (client.player == null) return;
if (keyBinding1.wasPressed()) {
getConfig().toggleCaveDust();
LOGGER.info("Toggled dust");
client.player.sendMessage(
Text.translatable("debug.cavedust.toggle." + config.getCaveDustEnabled()),
false
);
}
if (keyBinding2.wasPressed()) {
getConfig().load();
LOGGER.info("Reloaded config");
client.player.sendMessage(Text.translatable("debug.cavedust.reload"), false);
}
// ensure world is not null
if (client.world == null) return;
World world = client.world;
double probabilityNormalized =
normalize(config.getLowerLimit(), config.getUpperLimit(), client.player.getBlockY());
PARTICLE_AMOUNT = (int) (probabilityNormalized
* config.getParticleMultiplier()
* config.getParticleMultiplierMultiplier());
for (int i = 0; i < PARTICLE_AMOUNT; i++) {
int x = (int) (client.player.getX()
+ generateRandomDouble(-config.getDimensionWidth(), config.getDimensionWidth()));
int y = (int) (client.player.getEyeY()
+ generateRandomDouble(-config.getDimensionHeight(), config.getDimensionHeight()));
int z = (int) (client.player.getZ()
+ generateRandomDouble(-config.getDimensionWidth(), config.getDimensionWidth()));
double miniX = x + Math.random();
double miniY = y + Math.random();
double miniZ = z + Math.random();
BlockPos particlePos = new BlockPos(x, y, z);
if (shouldParticlesSpawn(client, config, particlePos)) {
if (client.world.getBlockState(particlePos).isAir()) {
world.addParticleClient(
getConfig().getParticle(),
miniX, miniY, miniZ,
config.getVelocityRandomnessRandom() * 0.01,
config.getVelocityRandomnessRandom() * 0.01,
config.getVelocityRandomnessRandom() * 0.01
);
}
}
}
}
}

View File

@@ -1,107 +1,74 @@
package net.lizistired.cavedust;
import com.google.common.collect.ImmutableList;
import net.lizistired.cavedust.utils.JsonFile;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.render.RenderLayer;
import net.minecraft.particle.ParticleEffect;
import net.minecraft.particle.ParticleType;
import net.minecraft.particle.ParticleTypes;
import net.minecraft.registry.Registries;
import net.minecraft.registry.Registry;
import net.minecraft.registry.RegistryKey;
import net.minecraft.registry.RegistryKeys;
import net.minecraft.text.Text;
import net.minecraft.util.Identifier;
import net.minecraft.util.registry.Registry;
import static net.lizistired.cavedust.CaveDust.*;
import static net.lizistired.cavedust.utils.MathHelper.*;
import java.nio.file.Path;
import java.util.*;
public class CaveDustConfig extends JsonFile {
private transient final CaveDust CaveDust;
private transient final net.lizistired.cavedust.CaveDust CaveDust;
private int dimensionMaxX = 5;
private int dimensionMaxY = 5;
private int dimensionMaxZ = 5;
private int dimensionMinX = -5;
private int dimensionMinY = -5;
private int dimensionMinZ = -5;
private int width = 10;
private int height = 10;
private int velocityRandomness = 0;
private boolean caveDustEnabled = true;
private String particleName = "white_ash";
private boolean seaLevelCheck = true;
private boolean superFlatStatus = false;
private float upperLimit = 64;
private float lowerLimit = -64;
private float particleMultiplier = 1;
private int particleMultiplier = 1;
public CaveDustConfig(Path file, CaveDust caveDust) {
int listNumber = 0;
private int particleMultiplierMultiplier = 10;
List<Identifier> list = List.of(Registries.PARTICLE_TYPE.getIds().toArray(new Identifier[0]));
Identifier newId = Identifier.of("cavedust", "cave_dust");
public CaveDustConfig(Path file, net.lizistired.cavedust.CaveDust caveDust) {
super(file);
this.CaveDust = caveDust;
}
public float setDimensionsMinX(float size){
if (this.dimensionMinX != size) {
this.dimensionMinX = (int)size;
public float setDimensionWidth(float size){
if (this.width != size) {
this.width = (int)size;
save();
}
return getDimensionsMinX();
return getDimensionWidth();
}
public float setDimensionsMinY(float size){
if (this.dimensionMinY != size) {
this.dimensionMinY = (int)size;
public float setDimensionHeight(float size){
if (this.height != size) {
this.height = (int)size;
save();
}
return getDimensionsMinY();
return getDimensionHeight();
}
public float setDimensionsMinZ(float size){
if (this.dimensionMinZ != size) {
this.dimensionMinZ = (int)size;
save();
}
return getDimensionsMinZ();
public float getDimensionWidth(){
return width;
}
public float getDimensionsMinX(){
return dimensionMinX;
}
public float getDimensionsMinY(){
return dimensionMinY;
}
public float getDimensionsMinZ(){
return dimensionMinZ;
}
public float setDimensionsMaxX(float size){
if (this.dimensionMaxX != size) {
this.dimensionMaxX = (int)size;
save();
}
return getDimensionsMaxX();
}
public float setDimensionsMaxY(float size){
if (this.dimensionMaxY != size) {
this.dimensionMaxY = (int)size;
save();
}
return getDimensionsMaxY();
}
public float setDimensionsMaxZ(float size){
if (this.dimensionMaxZ != size) {
this.dimensionMaxZ = (int)size;
save();
}
return getDimensionsMaxZ();
}
public float getDimensionsMaxX(){
return dimensionMaxX;
}
public float getDimensionsMaxY(){
return dimensionMaxY;
}
public float getDimensionsMaxZ(){
return dimensionMaxZ;
public float getDimensionHeight(){
return height;
}
public float setUpperLimit(float upperLimit){
@@ -136,16 +103,26 @@ public class CaveDustConfig extends JsonFile {
return lowerLimit;
}
public float getParticleMultiplier(){
public int getParticleMultiplier(){
return particleMultiplier;
}
public float setParticleMultiplier(float particleMultiplier){
this.particleMultiplier = particleMultiplier;
this.particleMultiplier = (int) particleMultiplier;
save();
return getParticleMultiplier();
}
public int getParticleMultiplierMultiplier(){
return particleMultiplierMultiplier;
}
public float setParticleMultiplierMultiplier(float particleMultiplierMultiplier){
this.particleMultiplierMultiplier = (int) particleMultiplierMultiplier;
save();
return getParticleMultiplierMultiplier();
}
public boolean toggleCaveDust(){
caveDustEnabled = !caveDustEnabled;
save();
@@ -156,20 +133,32 @@ public class CaveDustConfig extends JsonFile {
return caveDustEnabled;
}
public ParticleEffect setParticle(String particleType){
particleName = particleType;
save();
return getParticle();
}
//todo
//public Identifier setParticle(String particleType){
//particleName = particleType;
//save();
//return getParticle().get().getKey().get().getValue();
//}
//public ParticleEffect getParticle(){
// try {
// return Registries.PARTICLE_TYPE.getOptional(Identifier.of(Registries.PARTICLE_TYPE.getOptional(getParticleID()).get().getKey().get().getValue().toString().toLowerCase()));
// } catch (ClassCastException e) {
// MinecraftClient.getInstance().player.sendMessage(Text.translatable("debug.cavedust.particleerror"), true);
// LOGGER.error("Cannot spawn particle, check config.");
// iterateParticle();
// save();
// return getParticle();
// }
//}
public ParticleEffect getParticle(){
try {
return (ParticleEffect) Registry.PARTICLE_TYPE.get(Identifier.tryParse(particleName.toLowerCase()));
} catch (ClassCastException e) {
LOGGER.error(e + "\nThere was an error loading the specified particle from the config, make sure a valid particle name is specified. Falling back to \"minecraft:white_ash\".");
particleName = "minecraft:white_ash";
save();
return ParticleTypes.WHITE_ASH;
try{
return (ParticleEffect) Registries.PARTICLE_TYPE.get(newId);
}
catch (ClassCastException e){
iterateParticle();
return getParticle();
}
}
@@ -183,23 +172,61 @@ public class CaveDustConfig extends JsonFile {
return getSeaLevelCheck();
}
public void resetConfig(){
dimensionMinX = -5;
dimensionMinY = -5;
dimensionMinZ = -5;
public float getVelocityRandomnessRandom(){
if (velocityRandomness == 0) {return 0;}
return (float) generateRandomDouble(-velocityRandomness, velocityRandomness);
}
dimensionMaxX = 5;
dimensionMaxY = 5;
dimensionMaxZ = 5;
public float getVelocityRandomness(){
return velocityRandomness;
}
public float setVelocityRandomness(float velocityRandomness){
this.velocityRandomness = (int) velocityRandomness;
save();
return getVelocityRandomness();
}
public boolean getSuperFlatStatus(){
return superFlatStatus;
}
public boolean setSuperFlatStatus(){
superFlatStatus = !superFlatStatus;
save();
return getSuperFlatStatus();
}
public void iterateParticle() {
try {
listNumber = listNumber + 1;
newId = list.get(listNumber);
} catch (IndexOutOfBoundsException e){
newId = list.get(0);
listNumber = 0;
}
save();
}
public ParticleEffect getParticleID(){
return getParticle();
}
public void resetConfig(){
width = 10;
height = 10;
upperLimit = 64;
lowerLimit = -64;
particleMultiplier = 1;
particleMultiplierMultiplier = 10;
velocityRandomness = 0;
newId = Identifier.of("cavedust", "cave_dust");
seaLevelCheck = true;
caveDustEnabled = true;
particleName = "minecraft:white_ash";
save();
}
}

View File

@@ -6,6 +6,6 @@ import com.terraformersmc.modmenu.api.ModMenuApi;
public class CaveDustModMenuFactory implements ModMenuApi {
@Override
public ConfigScreenFactory<?> getModConfigScreenFactory() {
return net.lizistired.cavedust.ModMenuScreen::new;
return ModMenuConfigScreen::new;
}
}

View File

@@ -0,0 +1,83 @@
package net.lizistired.cavedust;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.particle.BillboardParticle;
import net.minecraft.client.particle.Particle;
import net.minecraft.client.particle.ParticleFactory;
import net.minecraft.client.particle.SpriteProvider;
import net.minecraft.client.world.ClientWorld;
import net.minecraft.particle.SimpleParticleType;
import net.minecraft.util.math.random.Random;
@Environment(EnvType.CLIENT)
public class CaveDustParticleFactory extends BillboardParticle {
private final SpriteProvider spriteProvider;
CaveDustParticleFactory(
ClientWorld world,
double x, double y, double z,
double velocityX, double velocityY, double velocityZ,
SpriteProvider spriteProvider
) {
// En 1.21.9+ BillboardParticle puede recibir sprite inicial
super(world, x, y, z, velocityX, velocityY, velocityZ, spriteProvider.getFirst());
this.spriteProvider = spriteProvider;
this.maxAge = 200; // 20 ticks = 1s
this.scale = 0.1f;
this.velocityX = velocityX;
this.velocityY = -0.007f;
this.velocityZ = velocityZ;
this.collidesWithWorld = true;
this.alpha = 1.0f;
// Selecciona el sprite correcto según edad/maxAge (equivalente a setSpriteForAge)
this.updateSprite(spriteProvider);
}
@Override
protected BillboardParticle.RenderType getRenderType() {
return BillboardParticle.RenderType.PARTICLE_ATLAS_TRANSLUCENT;
}
@Override
public void tick() {
super.tick();
if (!this.isAlive()) {
return;
}
this.alpha -= 0.005f;
if (this.alpha <= 0.0f) {
this.markDead();
return;
}
this.updateSprite(this.spriteProvider);
}
@Environment(EnvType.CLIENT)
public static class Factory implements ParticleFactory<SimpleParticleType> {
private final SpriteProvider spriteProvider;
public Factory(SpriteProvider spriteProvider) {
this.spriteProvider = spriteProvider;
}
@Override
public Particle createParticle(
SimpleParticleType type,
ClientWorld world,
double x, double y, double z,
double velocityX, double velocityY, double velocityZ,
Random random
) {
return new CaveDustParticleFactory(world, x, y, z, velocityX, velocityY, velocityZ, this.spriteProvider);
}
}
}

View File

@@ -0,0 +1,19 @@
package net.lizistired.cavedust;
import net.fabricmc.api.ModInitializer;
import net.fabricmc.fabric.api.particle.v1.FabricParticleTypes;
import net.minecraft.particle.SimpleParticleType;
import net.minecraft.registry.Registries;
import net.minecraft.registry.Registry;
import net.minecraft.util.Identifier;
public class CaveDustServer implements ModInitializer {
public static final SimpleParticleType CAVE_DUST = FabricParticleTypes.simple();
/**
* Runs the mod initializer.
*/
@Override
public void onInitialize() {
Registry.register(Registries.PARTICLE_TYPE, Identifier.of("cavedust", "cave_dust"), CAVE_DUST);
}
}

View File

@@ -0,0 +1,121 @@
package net.lizistired.cavedust;
import com.minelittlepony.common.client.gui.GameGui;
import com.minelittlepony.common.client.gui.element.*;
import net.lizistired.cavedust.utils.TranslatableTextHelper;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.particle.ParticleType;
import net.minecraft.registry.Registries;
import net.minecraft.text.Text;
import org.jetbrains.annotations.Nullable;
import java.util.NoSuchElementException;
public class ModMenuConfigScreen extends GameGui {
public ModMenuConfigScreen(@Nullable Screen parent) {
super(Text.translatable("menu.cavedust.title"), parent);
}
@Override
public void init() {
int left = width / 2 - 100;
int row = height / 4 + 14;
CaveDustConfig config = CaveDust.getInstance().getConfig();
TranslatableTextHelper transText = new TranslatableTextHelper();;
config.load();
addButton(new Label(width / 2, 30)).setCentered().getStyle()
.setText(getTitle());
addButton(new Button(left += -110, row += -60).onClick(sender -> {
sender.getStyle().setText("menu.cavedust.global." + config.toggleCaveDust()).setTooltip(Text.translatable("menu.cavedust.global.tooltip." + config.getCaveDustEnabled()));
})).getStyle()
.setText("menu.cavedust.global." + config.getCaveDustEnabled())
.setTooltip(Text.translatable("menu.cavedust.global.tooltip." + config.getCaveDustEnabled()));
/*addButton(new Button(left, row += 24).onClick(sender -> {
sender.getStyle().setText("menu.cavedust.enhanceddetection." + config.setEnhancedDetection()).setTooltip(Text.translatable("menu.cavedust.enhanceddetection.tooltip"));
})).getStyle()
.setText("menu.cavedust.enhanceddetection." + config.getEnhancedDetection())
.setTooltip(Text.translatable("menu.cavedust.enhanceddetection.tooltip"));*/
addButton(new Button(left, row += 24).onClick(sender -> {
sender.getStyle().setText("menu.cavedust.superflatstatus." + config.setSuperFlatStatus()).setTooltip(Text.translatable("menu.cavedust.superflatstatus.tooltip"));
})).getStyle()
.setText("menu.cavedust.superflatstatus." + config.getSuperFlatStatus())
.setTooltip(Text.translatable("menu.cavedust.superflatstatus.tooltip"));
/*addButton(new Slider(left, row += 48, -64, 319, config.getUpperLimit()))
.onChange(config::setUpperLimit)
.setTextFormat(transText::formatUpperLimit)
.getStyle().setTooltip(Text.translatable("menu.cavedust.upperlimit.tooltip"));
addButton(new Slider(left, row += 24, -64, 319, config.getLowerLimit()))
.onChange(config::setLowerLimit)
.setTextFormat(transText::formatLowerLimit)
.getStyle().setTooltip(Text.translatable("menu.cavedust.lowerlimit.tooltip"));*/
addButton(new Slider(left, row += 24, 1, 100, config.getParticleMultiplier()))
.onChange(config::setParticleMultiplier)
.setTextFormat(transText::formatParticleMultiplier)
.getStyle().setTooltip(Text.translatable("menu.cavedust.particlemultiplier.tooltip"));
addButton(new Slider(left, row += 24, 1, 100, config.getParticleMultiplierMultiplier()))
.onChange(config::setParticleMultiplierMultiplier)
.setTextFormat(transText::formatParticleMultiplierMultiplier)
.getStyle().setTooltip(Text.translatable("menu.cavedust.particlemultipliermultiplier.tooltip"));
addButton(new Button(left, row += 24).onClick(sender ->{
config.iterateParticle();
sender.getStyle().setText("Particle: " + (getNameOfParticle()));
})).getStyle().setText("Particle: " + (getNameOfParticle()))
.setTooltip(Text.translatable("menu.cavedust.particle.tooltip"));
addButton(new Slider(left += 220, row -= 96, 1, 50, config.getDimensionWidth()))
.onChange(config::setDimensionWidth)
.setTextFormat(transText::formatMaxWidth)
.getStyle().setTooltip(Text.translatable("menu.cavedust.width.tooltip"));
addButton(new Slider(left, row += 24, 1, 50, config.getDimensionHeight()))
.onChange(config::setDimensionHeight)
.setTextFormat(transText::formatMaxHeight)
.getStyle().setTooltip(Text.translatable("menu.cavedust.height.tooltip"));
addButton(new Slider(left, row += 24, 0, 10, config.getVelocityRandomness()))
.onChange(config::setVelocityRandomness)
.setTextFormat(transText::formatVelocityRandomness)
.getStyle().setTooltip(Text.translatable("menu.cavedust.velocityrandomness.tooltip"));
addButton(new Button(left -= 110, row += 120).onClick(sender -> {
config.resetConfig();
finish();
client.setScreen(new ModMenuConfigScreen(parent));
})).getStyle().setText(Text.translatable("menu.cavedust.reset")).setTooltip(Text.translatable("menu.cavedust.reset.tooltip"));
addButton(new Button(left, row += 24)
.onClick(sender -> finish())).getStyle()
.setText("gui.done");
}
@Override
public void render(DrawContext context, int mouseX, int mouseY, float partialTicks) {
super.render(context, mouseX, mouseY, partialTicks);
}
private String getNameOfParticle(){
CaveDustConfig config = CaveDust.getInstance().getConfig();
config.load();
try {
return Registries.PARTICLE_TYPE.getEntry((ParticleType<?>) config.getParticleID()).getIdAsString();
} catch (NoSuchElementException e){
CaveDust.LOGGER.error(String.valueOf(e));
return "null";
}
}
}

View File

@@ -1,97 +0,0 @@
package net.lizistired.cavedust;
import com.minelittlepony.common.client.gui.GameGui;
import com.minelittlepony.common.client.gui.element.*;
import net.lizistired.cavedust.utils.TranslatableTextHelper;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.text.TranslatableText;
import javax.annotation.Nullable;
public class ModMenuScreen extends GameGui {
public ModMenuScreen(@Nullable Screen parent) {
super(new TranslatableText("menu.cavedust.title"), parent);
}
@Override
public void init() {
int left = width / 2 - 100;
int row = height / 4 + 14;
CaveDustConfig config = CaveDust.getInstance().getConfig();
TranslatableTextHelper transText = new TranslatableTextHelper();
config.load();
addButton(new Label(width / 2, 30)).setCentered().getStyle()
.setText(getTitle());
addButton(new Button(left, row += -60).onClick(sender -> {
sender.getStyle().setText("menu.cavedust.global." + config.toggleCaveDust()).setTooltip(new TranslatableText("menu.cavedust.global.tooltip." + config.getCaveDustEnabled()));
})).getStyle()
.setText("menu.cavedust.global." + config.getCaveDustEnabled())
.setTooltip(new TranslatableText("menu.cavedust.global.tooltip." + config.getCaveDustEnabled()));
addButton(new Slider(left += -110, row += 24, -50, 0, config.getDimensionsMinX()))
.onChange(config::setDimensionsMinX)
.setTextFormat(transText::formatMinX)
.getStyle().setTooltip(new TranslatableText("menu.cavedust.minX.tooltip"));
addButton(new Slider(left, row += 24, -50, 0, config.getDimensionsMinY()))
.onChange(config::setDimensionsMinY)
.setTextFormat(transText::formatMinY)
.getStyle().setTooltip(new TranslatableText("menu.cavedust.minY.tooltip"));
addButton(new Slider(left, row += 24, -50, 0, config.getDimensionsMinZ()))
.onChange(config::setDimensionsMinZ)
.setTextFormat(transText::formatMinZ)
.getStyle().setTooltip(new TranslatableText("menu.cavedust.minZ.tooltip"));
addButton(new Slider(left += 220, row += -48, 0, 50, config.getDimensionsMaxX()))
.onChange(config::setDimensionsMaxX)
.setTextFormat(transText::formatMaxX)
.getStyle().setTooltip(new TranslatableText("menu.cavedust.maxX.tooltip"));
addButton(new Slider(left, row += 24, 0, 50, config.getDimensionsMaxY()))
.onChange(config::setDimensionsMaxY)
.setTextFormat(transText::formatMaxY)
.getStyle().setTooltip(new TranslatableText("menu.cavedust.maxY.tooltip"));
addButton(new Slider(left, row += 24, 0, 50, config.getDimensionsMaxZ()))
.onChange(config::setDimensionsMaxZ)
.setTextFormat(transText::formatMaxZ)
.getStyle().setTooltip(new TranslatableText("menu.cavedust.maxZ.tooltip"));
addButton(new Slider(left += -110, row += 24, -64, 319, config.getUpperLimit()))
.onChange(config::setUpperLimit)
.setTextFormat(transText::formatUpperLimit)
.getStyle().setTooltip(new TranslatableText("menu.cavedust.upperlimit.tooltip"));
addButton(new Slider(left, row += 24, -64, 319, config.getLowerLimit()))
.onChange(config::setLowerLimit)
.setTextFormat(transText::formatLowerLimit)
.getStyle().setTooltip(new TranslatableText("menu.cavedust.lowerlimit.tooltip"));
addButton(new Slider(left, row += 24, 0, 10, config.getParticleMultiplier()))
.onChange(config::setParticleMultiplier)
.setTextFormat(transText::formatParticleMultiplier)
.getStyle().setTooltip(new TranslatableText("menu.cavedust.particlemultiplier.tooltip"));
addButton(new Button(left, row += 24).onClick(sender -> {
config.resetConfig();
finish();
})).getStyle().setText(new TranslatableText("menu.cavedust.reset")).setTooltip(new TranslatableText("menu.cavedust.reset.tooltip"));
addButton(new Button(left, row += 180)
.onClick(sender -> finish())).getStyle()
.setText("gui.done");
}
@Override
public void render(MatrixStack matrices, int mouseX, int mouseY, float partialTicks) {
renderBackground(matrices);
super.render(matrices, mouseX, mouseY, partialTicks);
}
}

View File

@@ -0,0 +1,12 @@
package net.lizistired.cavedust.mixin;
import net.minecraft.client.world.ClientWorld;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
@Mixin(ClientWorld.Properties.class)
public interface ClientWorldAccessor {
@Accessor
boolean getFlatWorld();
}

View File

@@ -1,45 +1,36 @@
package net.lizistired.cavedust.mixin;
import net.minecraft.client.gui.hud.DebugHud;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import java.lang.management.BufferPoolMXBean;
import java.lang.management.ManagementFactory;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import static net.lizistired.cavedust.utils.MathHelper.*;
import static net.lizistired.cavedust.CaveDust.PARTICLE_AMOUNT;
@Mixin(DebugHud.class)
public abstract class MixinDebugScreenOverlay {
@Unique
private static final List<BufferPoolMXBean> pools = ManagementFactory.getPlatformMXBeans(BufferPoolMXBean.class);
@Unique
private static final BufferPoolMXBean directPool;
static {
BufferPoolMXBean found = null;
for (BufferPoolMXBean pool : pools) {
if (pool.getName().equals("direct")) {
found = pool;
break;
}
}
directPool = Objects.requireNonNull(found);
}
@Inject(method = "getRightText", at = @At("RETURN"))
private void appendShaderPackText(CallbackInfoReturnable<List<String>> cir) {
@Inject(
method = "getRightText()Ljava/util/List;",
at = @At("RETURN"),
cancellable = true,
require = 0
)
private void appendDebugText(CallbackInfoReturnable<List<String>> cir) {
List<String> messages = cir.getReturnValue();
if (messages == null) return;
messages.add("");
messages.add("Should particles spawn: " + shouldParticlesSpawn);
messages.add("");
// Evita modificar una lista inmutable/compartida
List<String> out = new ArrayList<>(messages);
out.add("");
out.add("Particle amount evaluated: " + PARTICLE_AMOUNT);
out.add("");
cir.setReturnValue(out);
}
}
}

View File

@@ -0,0 +1,33 @@
package net.lizistired.cavedust.utils;
import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper;
import net.minecraft.client.option.KeyBinding;
import net.minecraft.client.util.InputUtil;
import net.minecraft.util.Identifier;
import org.lwjgl.glfw.GLFW;
public class KeybindingHelper {
public static KeyBinding keyBinding1;
public static KeyBinding keyBinding2;
// 1.21.9+ requiere Category (no String)
private static final KeyBinding.Category CATEGORY =
KeyBinding.Category.create(Identifier.of("cavedust", "spook"));
public static void registerKeyBindings() {
keyBinding1 = KeyBindingHelper.registerKeyBinding(new KeyBinding(
"key.cavedust.toggle",
InputUtil.Type.KEYSYM,
GLFW.GLFW_KEY_KP_ADD,
CATEGORY
));
keyBinding2 = KeyBindingHelper.registerKeyBinding(new KeyBinding(
"key.cavedust.reload",
InputUtil.Type.KEYSYM,
GLFW.GLFW_KEY_KP_ENTER,
CATEGORY
));
}
}

View File

@@ -1,74 +1,44 @@
package net.lizistired.cavedust.utils;
import net.lizistired.cavedust.CaveDustConfig;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.render.DimensionEffects;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.util.Identifier;
import net.minecraft.util.registry.Registry;
import net.minecraft.world.World;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.biome.OverworldBiomeCreator;
import net.minecraft.world.dimension.DimensionType;
import net.minecraft.world.gen.feature.OceanRuinFeature;
import java.util.Objects;
import java.util.Optional;
import java.util.Random;
import java.util.concurrent.ThreadLocalRandom;
import static net.minecraft.world.biome.BiomeKeys.LUSH_CAVES;
public class MathHelper {
private static float timer;
public static boolean shouldParticlesSpawn;
/**
* Normalizes a value to between a range, eg. you want to map a value of 100 to 0 - 1, with 50 being 0.5.
* @param min Minimum value
* @param max Maximum value
* @param val Value to be normalized
* @return Normalized value (double)
*/
public static double normalize(double min, double max, double val) {
return 1 - ((val - min) / (max - min));
}
public static int getRandomNumberUsingInts(int min, int max) {
/**
* Generates a random int between min and max
* @param min Minimum value
* @param max Maximum value
* @return Random number (int)
*/
public static int generateRandomInt(int min, int max) {
Random random = new Random();
return random.ints(min, max)
.findFirst()
.getAsInt();
}
/**
* Generates a random double between min and max
* @param min Minimum value
* @param max Maximum value
* @return Random number (double)
*/
public static double generateRandomDouble(double min, double max) {
return ThreadLocalRandom.current().nextDouble(min, max);
}
public static boolean shouldParticlesSpawn(MinecraftClient client, CaveDustConfig config) {
//checks if the config is enabled, if the game isn't paused, if the world is valid, if the particle is valid and if the player isn't in a lush caves biome
if (!config.getCaveDustEnabled()
|| client.isPaused()
|| client.world == null
|| !client.world.getDimension().isBedWorking()
|| Objects.equals(client.world.getBiomeKey(Objects.requireNonNull(client.player).getBlockPos()), Optional.of(LUSH_CAVES))
|| Objects.requireNonNull(client.player).isSubmergedInWater())
{
timer = 0;
shouldParticlesSpawn = false;
return false;
try {
return ThreadLocalRandom.current().nextDouble(min, max);
} catch (IllegalArgumentException e) {
return 0;
}
World world = client.world;
int seaLevel = world.getSeaLevel();
if (!client.player.clientWorld.isSkyVisible(client.player.getBlockPos())) {
if (client.player.getBlockPos().getY() < seaLevel){
timer = timer + 1;
if (timer > 10){
timer = 10;
shouldParticlesSpawn = true;
return true;
}
}
}
shouldParticlesSpawn = false;
return false;
}
}

View File

@@ -0,0 +1,115 @@
package net.lizistired.cavedust.utils;
import net.lizistired.cavedust.CaveDustConfig;
import net.lizistired.cavedust.mixin.ClientWorldAccessor;
import net.minecraft.client.MinecraftClient;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import java.util.Objects;
import static net.minecraft.world.biome.BiomeKeys.LUSH_CAVES;
public class ParticleSpawnUtil {
private static float timer;
public static boolean shouldParticlesSpawn;
/**
* Returns true if particles should spawn.
* @param client MinecraftClient
* @param config CaveDustConfig
* @return boolean
*/
public static boolean shouldParticlesSpawn(MinecraftClient client, CaveDustConfig config) {
if (client.player == null) {
timer = 0;
shouldParticlesSpawn = false;
return false;
}
// checks if the config is enabled, if the game isn't paused, if the world is valid,
// only in overworld, and if the player isn't in a lush caves biome
if (!config.getCaveDustEnabled()
|| client.isPaused()
|| client.world == null
|| !client.world.getRegistryKey().equals(World.OVERWORLD)
|| client.player.isSubmergedInWater()
|| client.world.getBiome(client.player.getBlockPos()).matchesKey(LUSH_CAVES)) {
timer = 0;
shouldParticlesSpawn = false;
return false;
}
World world = client.world;
int seaLevel = world.getSeaLevel();
if (!world.isSkyVisible(client.player.getBlockPos())) {
if (client.player.getBlockPos().getY() + 2 < seaLevel) {
timer = timer + 1;
if (timer > 10) {
timer = 10;
shouldParticlesSpawn = true;
return true;
}
}
}
shouldParticlesSpawn = false;
return false;
}
/**
* Returns true if particles should spawn (uses particle position instead of player).
* @param client MinecraftClient
* @param config CaveDustConfig
* @param pos BlockPos
* @return boolean
*/
public static boolean shouldParticlesSpawn(MinecraftClient client, CaveDustConfig config, BlockPos pos) {
// checks if the config is enabled, if the game isn't paused, if the world is valid,
// only in overworld, and if the particle position isn't in lush caves
if (!config.getCaveDustEnabled()
|| client.isPaused()
|| client.world == null
|| !client.world.getRegistryKey().equals(World.OVERWORLD)
|| (client.world.getBottomY() > pos.getY())
|| client.world.getBiome(Objects.requireNonNull(pos)).matchesKey(LUSH_CAVES)) {
timer = 0;
shouldParticlesSpawn = false;
return false;
}
if (client.player == null) {
timer = 0;
shouldParticlesSpawn = false;
return false;
}
if (!config.getSuperFlatStatus()) {
if (((ClientWorldAccessor) client.world.getLevelProperties()).getFlatWorld()) {
return false;
}
}
World world = client.world;
int seaLevel = world.getSeaLevel();
if (!world.isSkyVisible(pos)) {
if (pos.getY() + 2 < seaLevel) {
timer = timer + 1;
if (timer > 10) {
timer = 10;
shouldParticlesSpawn = true;
return true;
}
}
}
shouldParticlesSpawn = false;
return false;
}
}

View File

@@ -2,34 +2,28 @@ package net.lizistired.cavedust.utils;
import com.minelittlepony.common.client.gui.element.AbstractSlider;
import net.minecraft.text.Text;
import net.minecraft.text.TranslatableText;
public class TranslatableTextHelper {
public Text formatMinX(AbstractSlider<Float> slider) {
return new TranslatableText("menu.cavedust.minX", (int)Math.floor(slider.getValue()));
public Text formatMaxWidth(AbstractSlider<Float> slider) {
return Text.translatable("menu.cavedust.width", (int)Math.floor(slider.getValue()));
}
public Text formatMinY(AbstractSlider<Float> slider) {
return new TranslatableText("menu.cavedust.minY", (int)Math.floor(slider.getValue()));
}
public Text formatMinZ(AbstractSlider<Float> slider) {
return new TranslatableText("menu.cavedust.minZ", (int)Math.floor(slider.getValue()));
}
public Text formatMaxX(AbstractSlider<Float> slider) {
return new TranslatableText("menu.cavedust.maxX", (int)Math.floor(slider.getValue()));
}
public Text formatMaxY(AbstractSlider<Float> slider) {
return new TranslatableText("menu.cavedust.maxY", (int)Math.floor(slider.getValue()));
}
public Text formatMaxZ(AbstractSlider<Float> slider) {
return new TranslatableText("menu.cavedust.maxZ", (int)Math.floor(slider.getValue()));
public Text formatMaxHeight(AbstractSlider<Float> slider) {
return Text.translatable("menu.cavedust.height", (int)Math.floor(slider.getValue()));
}
public Text formatUpperLimit(AbstractSlider<Float> slider) {
return new TranslatableText("menu.cavedust.upperlimit", (int)Math.floor(slider.getValue()));
return Text.translatable("menu.cavedust.upperlimit", (int)Math.floor(slider.getValue()));
}
public Text formatLowerLimit(AbstractSlider<Float> slider) {
return new TranslatableText("menu.cavedust.lowerlimit", (int)Math.floor(slider.getValue()));
return Text.translatable("menu.cavedust.lowerlimit", (int)Math.floor(slider.getValue()));
}
public Text formatParticleMultiplier(AbstractSlider<Float> slider) {
return new TranslatableText("menu.cavedust.particlemultiplier", (int)Math.floor(slider.getValue()));
return Text.translatable("menu.cavedust.particlemultiplier", (int)Math.floor(slider.getValue()));
}
public Text formatParticleMultiplierMultiplier(AbstractSlider<Float> slider) {
return Text.translatable("menu.cavedust.particlemultipliermultiplier", (int)Math.floor(slider.getValue()));
}
public Text formatVelocityRandomness(AbstractSlider<Float> slider) {
return Text.translatable("menu.cavedust.velocityrandomness", (int) Math.floor(slider.getValue()));
}
}

View File

@@ -1,4 +1,4 @@
package net.lizistired.caveDust.utils;
package net.lizistired.cavedust.utils;
import net.minecraft.client.MinecraftClient;

Binary file not shown.

After

Width:  |  Height:  |  Size: 250 KiB

View File

@@ -0,0 +1,41 @@
{
"menu.cavedust.title": "Cave Dust",
"menu.cavedust.global.false": "Cave Dust: Disabled",
"menu.cavedust.global.true": "Cave Dust: Enabled",
"menu.cavedust.global.tooltip.false": "Enable cave dust particles?",
"menu.cavedust.global.tooltip.true": "Disable cave dust particles?",
"menu.cavedust.width": "Width bounds: %s",
"menu.cavedust.height": "Height bounds: %s",
"menu.cavedust.width.tooltip": "Maximum width to spawn particle.",
"menu.cavedust.height.tooltip": "Maximum height to spawn particle.",
"menu.cavedust.upperlimit": "Upper limit height: %s",
"menu.cavedust.lowerlimit": "Lower limit height: %s",
"menu.cavedust.upperlimit.tooltip": "The height where particles will fade out and stop spawning (uses player y).",
"menu.cavedust.lowerlimit.tooltip": "The height where particles spawn the most (uses player y).",
"menu.cavedust.reset": "Reset settings",
"menu.cavedust.reset.tooltip": "Are you sure you want to reset all settings?",
"menu.cavedust.particlemultiplier": "Particle amount: %s",
"menu.cavedust.particlemultiplier.tooltip": "Amount of particles to spawn at any given depth.",
"menu.cavedust.particlemultipliermultiplier": "Particle multiplier: %s",
"menu.cavedust.particlemultipliermultiplier.tooltip": "Multiplies particle amount.",
"menu.cavedust.velocityrandomness": "Velocity randomness: %s",
"menu.cavedust.velocityrandomness.tooltip": "The randomness of the velocity of the particles.",
"menu.cavedust.enhanceddetection.true": "Enhanced detection: Enabled",
"menu.cavedust.enhanceddetection.false": "Enhanced detection: Disabled",
"menu.cavedust.enhanceddetection.tooltip": "Enhanced detection enables more accurate checks, using the particles position\n instead of the player, has some performance impact.",
"menu.cavedust.superflatstatus.true": "Superflat particles: Enabled",
"menu.cavedust.superflatstatus.false": "Superflat particles: Disabled",
"menu.cavedust.superflatstatus.tooltip": "Should particles spawn on superflat worlds?",
"menu.cavedust.particle": "Particle: ",
"menu.cavedust.particle.tooltip": "Particle to spawn. Click to cycle.",
"key.cavedust.reload": "Reload Config",
"key.cavedust.toggle": "Toggle Particles",
"category.cavedust.spook": "Cave Dust",
"debug.cavedust.toggle.true": "(Cave Dust) Enabled particles",
"debug.cavedust.toggle.false": "(Cave Dust) Disabled particles",
"debug.cavedust.reload": "(Cave Dust) Reloaded config",
"debug.cavedust.particleerror": "(Cave Dust) Error setting particle, skipping to next particle!"
}

View File

@@ -0,0 +1,44 @@
{
"menu.cavedust.title": "Cave Dust",
"menu.cavedust.global.false": "Cave Dust: Désactivée",
"menu.cavedust.global.true": "Cave Dust: Activée",
"menu.cavedust.global.tooltip.false": "Activer les particules de poussière de grotte ?",
"menu.cavedust.global.tooltip.true": "Désactiver les particules de poussière de grotte ?",
"menu.cavedust.minX": "Minimum X: %s",
"menu.cavedust.minY": "Minimum Y: %s",
"menu.cavedust.minZ": "Minimum Z: %s",
"menu.cavedust.maxX": "Maximum X: %s",
"menu.cavedust.maxY": "Maximum Y: %s",
"menu.cavedust.maxZ": "Maximum Z: %s",
"menu.cavedust.minX.tooltip": "Minimum X: %s",
"menu.cavedust.minY.tooltip": "Minimum Y: %s",
"menu.cavedust.minZ.tooltip": "Minimum Z: %s",
"menu.cavedust.maxX.tooltip": "Maximum X: %s",
"menu.cavedust.maxY.tooltip": "Maximum Y: %s",
"menu.cavedust.maxZ.tooltip": "Maximum Z: %s",
"menu.cavedust.upperlimit": "Limite supérieure : %s",
"menu.cavedust.lowerlimit": "Limite inférieure : %s",
"menu.cavedust.upperlimit.tooltip": "La hauteur à laquelle les particules s'estompent et cessent de spawner (utilise l'axe Y du joueur).",
"menu.cavedust.lowerlimit.tooltip": "La hauteur où les particules apparaissent le plus (utilise l'axe Y du joueur).",
"menu.cavedust.reset": "Réinitialiser les paramètres",
"menu.cavedust.reset.tooltip": "Êtes-vous sûr de vouloir réinitialiser tous les paramètres ?",
"menu.cavedust.particlemultiplier": "Multiplicateur de particules : %s",
"menu.cavedust.particlemultiplier.tooltip": "Multiplie la quantité de particules à une profondeur donnée.",
"menu.cavedust.velocityrandomness": "Aléatoire de la vélocité : %s",
"menu.cavedust.velocityrandomness.tooltip": "Le niveau d'aléatoire de la vélocité des particules.",
"menu.cavedust.enhanceddetection.true": "Détection améliorée : Activée",
"menu.cavedust.enhanceddetection.false": "Détection améliorée : Désactivée",
"menu.cavedust.enhanceddetection.tooltip": "La détection améliorée permet des vérifications plus précises en utilisant la position des particules\n plutôt que celle du joueur, mais impacte les performances.",
"menu.cavedust.superflatstatus.true": "Particules sur monde Superflat : Activées",
"menu.cavedust.superflatstatus.false": "Particules sur monde Superflat : Désactivées",
"menu.cavedust.superflatstatus.tooltip": "Les particules doivent-elles apparaître sur les mondes Superflat ?",
"key.cavedust.reload": "Recharger la configuration",
"key.cavedust.toggle": "Activer/Désactiver les particules",
"category.cavedust.spook": "Cave Dust",
"debug.cavedust.toggle.true": "(Cave Dust) Particules activées",
"debug.cavedust.toggle.false": "(Cave Dust) Particules désactivées",
"debug.cavedust.reload": "(Cave Dust) Configuration rechargée"
}

View File

@@ -0,0 +1,44 @@
{
"menu.cavedust.title": "Пещерная пыль",
"menu.cavedust.global.false": "Пещерная пыль: отключена",
"menu.cavedust.global.true": "Пещерная пыль: включена",
"menu.cavedust.global.tooltip.false": "Включить частицы пещерной пыли?",
"menu.cavedust.global.tooltip.true": "Отключить частицы пещерной пыли?",
"menu.cavedust.minX": "Минимум по X: %s",
"menu.cavedust.minY": "Минимум по Y: %s",
"menu.cavedust.minZ": "Минимум по Z: %s",
"menu.cavedust.maxX": "Максимум по X: %s",
"menu.cavedust.maxY": "Максимум по Y: %s",
"menu.cavedust.maxZ": "Максимум по Z: %s",
"menu.cavedust.minX.tooltip": "Минимум по X: %s",
"menu.cavedust.minY.tooltip": "Минимум по Y: %s",
"menu.cavedust.minZ.tooltip": "Минимум по Z: %s",
"menu.cavedust.maxX.tooltip": "Максимум по X: %s",
"menu.cavedust.maxY.tooltip": "Максимум по Y: %s",
"menu.cavedust.maxZ.tooltip": "Максимум по Z: %s",
"menu.cavedust.upperlimit": "Верхний предел: %s",
"menu.cavedust.lowerlimit": "Нижний предел: %s",
"menu.cavedust.upperlimit.tooltip": "Высота, на которой частицы будут исчезать и перестанут появляться (испольует координату Y игрока).",
"menu.cavedust.lowerlimit.tooltip": "The height where particles spawn the most (испольует координату Y игрока).",
"menu.cavedust.reset": "Сброс настроек",
"menu.cavedust.reset.tooltip": "Вы уверены, что хотите сбросить все настройки?",
"menu.cavedust.particlemultiplier": "Множитель частиц: %s",
"menu.cavedust.particlemultiplier.tooltip": "Увеличивает количество частиц на любой заданной глубине.",
"menu.cavedust.velocityrandomness": "Случайность скорости: %s",
"menu.cavedust.velocityrandomness.tooltip": "Случайность скорости движения частиц.",
"menu.cavedust.enhanceddetection.true": "Улучшенное обнаружение: включено",
"menu.cavedust.enhanceddetection.false": "Улучшенное обнаружение: отключено",
"menu.cavedust.enhanceddetection.tooltip": "Улучшенное обнаружение позволяет проводить более точные проверки, используя положение частиц\nвместо положения игрока, что оказывает некоторое влияние на производительность.",
"menu.cavedust.superflatstatus.true": "Частицы в суперплоскости: включены",
"menu.cavedust.superflatstatus.false": "Частицы в суперплоскости: отключены",
"menu.cavedust.superflatstatus.tooltip": "Должны ли частицы появляться в суперплоских мирах?",
"key.cavedust.reload": "Перезагрузить конфигурацию",
"key.cavedust.toggle": "Переключить частицы",
"category.cavedust.spook": "Пещерная пыль",
"debug.cavedust.toggle.true": "[Пещерная пыль] Включенные частицы",
"debug.cavedust.toggle.false": "[Пещерная пыль] Отключенные частицы",
"debug.cavedust.reload": "[Пещерная пыль] Конфигурация перезагружена"
}

View File

@@ -0,0 +1,41 @@
{
"menu.cavedust.title": "洞穴尘埃",
"menu.cavedust.global.false": "洞穴尘埃: 功能启用",
"menu.cavedust.global.true": "洞穴尘埃: 功能禁用",
"menu.cavedust.global.tooltip.false": "启用洞穴尘埃粒子效果?",
"menu.cavedust.global.tooltip.true": "禁用洞穴尘埃粒子效果?",
"menu.cavedust.width": "边界宽度: %s",
"menu.cavedust.height": "边界高度: %s",
"menu.cavedust.width.tooltip": "生成粒子效果的最大宽度.",
"menu.cavedust.height.tooltip": "生成粒子效果的最大高度.",
"menu.cavedust.upperlimit": "最大高度限制: %s",
"menu.cavedust.lowerlimit": "最低高度限制: %s",
"menu.cavedust.upperlimit.tooltip": "粒子效果消失的高度 (读取玩家所在的 y 轴).",
"menu.cavedust.lowerlimit.tooltip": "粒子效果出现最多的高度 (读取玩家所在的 y 轴).",
"menu.cavedust.reset": "重置所有设置",
"menu.cavedust.reset.tooltip": "你确定要这么做吗?",
"menu.cavedust.particlemultiplier": "粒子数量: %s",
"menu.cavedust.particlemultiplier.tooltip": "指定深度生成的粒子效果数量.",
"menu.cavedust.particlemultipliermultiplier": "粒子效果倍率: %s",
"menu.cavedust.particlemultipliermultiplier.tooltip": "粒子效果的生成倍率.",
"menu.cavedust.velocityrandomness": "速度随机性: %s",
"menu.cavedust.velocityrandomness.tooltip": "粒子效果的速度随机程度.",
"menu.cavedust.enhanceddetection.true": "强化检测: 功能启用",
"menu.cavedust.enhanceddetection.false": "强化检测: 功能禁用",
"menu.cavedust.enhanceddetection.tooltip": "强化检测会使用粒子效果而非玩家的位置进行更精确的检测\n 对性能略有影响.",
"menu.cavedust.superflatstatus.true": "超平坦粒子: 功能启用",
"menu.cavedust.superflatstatus.false": "超平坦粒子: 功能禁用",
"menu.cavedust.superflatstatus.tooltip": "是否允许超平坦世界生成洞穴尘埃?",
"menu.cavedust.particle": "粒子效果: ",
"menu.cavedust.particle.tooltip": "生成的粒子效果名称, 点击切换.",
"key.cavedust.reload": "重载配置",
"key.cavedust.toggle": "切换粒子",
"category.cavedust.spook": "洞穴尘埃",
"debug.cavedust.toggle.true": "(洞穴尘埃) 粒子效果已启用",
"debug.cavedust.toggle.false": "(洞穴尘埃) 粒子效果已禁用",
"debug.cavedust.reload": "(洞穴尘埃) 配置已重载",
"debug.cavedust.particleerror": "(洞穴尘埃) 设置当前粒子效果时出现问题, 已自动切换至下一个粒子效果!"
}

View File

@@ -0,0 +1,5 @@
{
"textures": [
"minecraft:generic_0"
]
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 126 KiB

View File

@@ -1,27 +0,0 @@
{
"menu.cavedust.title": "Cave Dust",
"menu.cavedust.global.false": "Cave Dust: Disabled",
"menu.cavedust.global.true": "Cave Dust: Enabled",
"menu.cavedust.global.tooltip.false": "Enable cave dust particles?",
"menu.cavedust.global.tooltip.true": "Disable cave dust particles?",
"menu.cavedust.minX": "Minimum X: %s",
"menu.cavedust.minY": "Minimum Y: %s",
"menu.cavedust.minZ": "Minimum Z: %s",
"menu.cavedust.maxX": "Maximum X: %s",
"menu.cavedust.maxY": "Maximum Y: %s",
"menu.cavedust.maxZ": "Maximum Z: %s",
"menu.cavedust.minX.tooltip": "Minimum X: %s",
"menu.cavedust.minY.tooltip": "Minimum Y: %s",
"menu.cavedust.minZ.tooltip": "Minimum Z: %s",
"menu.cavedust.maxX.tooltip": "Maximum X: %s",
"menu.cavedust.maxY.tooltip": "Maximum Y: %s",
"menu.cavedust.maxZ.tooltip": "Maximum Z: %s",
"menu.cavedust.upperlimit": "Upper limit: %s",
"menu.cavedust.lowerlimit": "Lower limit: %s",
"menu.cavedust.upperlimit.tooltip": "The height where particles will fade out and stop spawning (uses player y).",
"menu.cavedust.lowerlimit.tooltip": "The height where particles spawn the most (uses player y).",
"menu.cavedust.reset": "Reset settings",
"menu.cavedust.reset.tooltip": "Are you sure you want to reset all settings?",
"menu.cavedust.particlemultiplier": "Particle multiplier: %s",
"menu.cavedust.particlemultiplier.tooltip": "Multiplies the amount of particles at any given depth."
}

View File

@@ -4,6 +4,8 @@
"package": "net.lizistired.cavedust.mixin",
"compatibilityLevel": "JAVA_16",
"mixins": [
"ClientWorldAccessor",
"MixinDebugScreenOverlay"
],
"client": [
],

View File

@@ -1,44 +1,43 @@
{
"schemaVersion": 1,
"id": "cavedust",
"id": "cavedustreforged",
"version": "${version}",
"name": "Cave Dust",
"name": "Cave Dust Reforged",
"description": "Makes dust underground that scales with depth!",
"authors": [
"LizIsTired"
"DekinDev"
],
"contributors": [
"LizIsTired (Original mod)"
],
"contact": {
"issues": "https://github.com/LizIsTired/dust/issues",
"sources": "https://github.com/LizIsTired/dust"
"issues": "https://git.straice.com/DekinDev/cave_dust_reforged/issues",
"sources": "https://git.straice.com/DekinDev/cave_dust_reforged",
"homepage": "https://modrinth.com/project/cave-dust-reforged"
},
"license": "CC0-1.0",
"icon": "assets/modid/icon.png",
"license": "MPL-2.0",
"icon": "assets/cavedust/icon.png",
"environment": "*",
"entrypoints": {
"client": [
"net.lizistired.cavedust.CaveDust"
],
"main": [
"net.lizistired.cavedust.CaveDustServer"],
"modmenu": [
"net.lizistired.cavedust.CaveDustModMenuFactory"
]
},
"mixins": [
"dust.mixins.json"
"cavedust.mixins.json"
],
"depends": {
"fabricloader": ">=0.12.11",
"fabricloader": ">=0.17.2",
"fabric": "*",
"minecraft": "1.18.x",
"minecraft": "1.21.11",
"java": ">=17"
},
"suggests": {
"modmenu": ">=3.0.1"
},
"custom": {
"modmenu": {
"links": {
"modmenu.discord": "https://discord.gg/AgBfPFMJgX"
}
}
}
}