Compare commits

..

8 Commits

Author SHA1 Message Date
Liz Graham
9f48759061 do underwater check 2022-03-17 22:06:01 +00:00
Liz Graham
b32f492afc fix for 1.18.2 2022-03-17 22:04:00 +00:00
Liz Graham
6e632fd070 remove debug mixin 2022-03-17 21:49:18 +00:00
Liz Graham
8172ab95cf add basic config 2022-03-17 21:49:10 +00:00
Liz Graham
5a132871d8 Update README.md 2022-03-03 03:36:30 +00:00
Liz Graham
616bb03a71 Update README.md 2022-03-03 03:35:03 +00:00
Liz Graham
a014beab37 change modid to dust 2022-03-03 03:26:13 +00:00
Liz Graham
cc25e591de update to 1.18.2 2022-03-03 03:23:08 +00:00
19 changed files with 204 additions and 735 deletions

View File

@@ -1,61 +0,0 @@
name: build-release
on:
release:
types:
- published
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout sources
uses: actions/checkout@v2
- name: Set up JDK 16
uses: actions/setup-java@v2
with:
distribution: 'temurin'
java-version: 17
- name: Cache Gradle packages
uses: actions/cache@v2
with:
path: |
~/.gradle/caches
~/.gradle/loom-cache
~/.gradle/wrapper
~/.m2/repository
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
restore-keys: ${{ runner.os }}-gradle
- run: chmod +x gradlew
- name: Build Release
run: ./gradlew build --stacktrace
- name: Upload artifacts to Modrinth, Curseforge and GitHub
uses: Kir-Antipov/mc-publish@v2.0
with:
modrinth-id: jawg7zT1
modrinth-token: ${{ secrets.MODRINTH_TOKEN }}
curseforge-id: 594750
curseforge-token: ${{ secrets.CURSEFORGE_TOKEN }}
github-token: ${{ secrets.GITHUB_TOKEN }}
files: build/libs/!(*-@(dev|sources|all)).jar
version-type: release
loaders: fabric
java: 17
dependencies: |
fabric | depends | 0.46.0
P7dR8mSH | depends | 0.46.0
kirin | includes | 1.10.0-beta.2
modmenu | recommends | *
mOgUt4GM | recommends | *
version-resolver: latest # Defaults to selecting the latest compatible version of Minecraft, using the tag from the fabric.mod.json

View File

@@ -27,12 +27,6 @@ jobs:
run: ref="${GITHUB_REF#refs/heads/}" && echo "::set-output name=branch::${ref////-}" run: ref="${GITHUB_REF#refs/heads/}" && echo "::set-output name=branch::${ref////-}"
id: ref id: ref
- name: Set outputs
id: vars
run: echo "::set-output name=sha_short::$(git rev-parse --short HEAD)"
- name: Check outputs
run: echo ${{ steps.vars.outputs.sha_short }}
- name: Validate gradle wrapper - name: Validate gradle wrapper
uses: gradle/wrapper-validation-action@v1 uses: gradle/wrapper-validation-action@v1
@@ -52,5 +46,5 @@ jobs:
if: ${{ runner.os == 'Linux' && matrix.java == '17' }} # Only upload artifacts built from latest java on one OS if: ${{ runner.os == 'Linux' && matrix.java == '17' }} # Only upload artifacts built from latest java on one OS
uses: actions/upload-artifact@v2 uses: actions/upload-artifact@v2
with: with:
name: dust-fabric-${{ steps.vars.outputs.sha_short }} name: dust-fabric-${{ github.sha }}
path: build/libs/*[0-9].jar path: build/libs/*[0-9].jar

494
LICENSE
View File

@@ -1,373 +1,121 @@
Mozilla Public License Version 2.0 Creative Commons Legal Code
==================================
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
1.1. "Contributor" ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS
means each individual or legal entity that creates, contributes to INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES
the creation of, or owns Covered Software. REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS
PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM
1.2. "Contributor Version" THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED
means the combination of the Contributions of others (if any) used HEREUNDER.
by a Contributor and that particular Contributor's Contribution.
Statement of Purpose
1.3. "Contribution"
means Covered Software of a particular Contributor. The laws of most jurisdictions throughout the world automatically confer
exclusive Copyright and Related Rights (defined below) upon the creator
1.4. "Covered Software" and subsequent owner(s) (each and all, an "owner") of an original work of
means Source Code Form to which the initial Contributor has attached authorship and/or a database (each, a "Work").
the notice in Exhibit A, the Executable Form of such Source Code
Form, and Modifications of such Source Code Form, in each case Certain owners wish to permanently relinquish those rights to a Work for
including portions thereof. the purpose of contributing to a commons of creative, cultural and
scientific works ("Commons") that the public can reliably and without fear
1.5. "Incompatible With Secondary Licenses" of later claims of infringement build upon, modify, incorporate in other
means works, reuse and redistribute as freely as possible in any form whatsoever
and for any purposes, including without limitation commercial purposes.
(a) that the initial Contributor has attached the notice described These owners may contribute to the Commons to promote the ideal of a free
in Exhibit B to the Covered Software; or culture and the further production of creative, cultural and scientific
works, or to gain reputation or greater distribution for their Work in
(b) that the Covered Software was made available under the terms of part through the use and efforts of others.
version 1.1 or earlier of the License, but not also under the
terms of a Secondary License. For these and/or other purposes and motivations, and without any
expectation of additional consideration or compensation, the person
1.6. "Executable Form" associating CC0 with a Work (the "Affirmer"), to the extent that he or she
means any form of the work other than Source Code Form. 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
1.7. "Larger Work" terms, with knowledge of his or her Copyright and Related Rights in the
means a work that combines Covered Software with other material, in Work and the meaning and intended legal effect of CC0 on those rights.
a separate file or files, that is not Covered Software.
1. Copyright and Related Rights. A Work made available under CC0 may be
1.8. "License" protected by copyright and related or neighboring rights ("Copyright and
means this document. Related Rights"). Copyright and Related Rights include, but are not
limited to, the following:
1.9. "Licensable"
means having the right to grant, to the maximum extent possible, i. the right to reproduce, adapt, distribute, perform, display,
whether at the time of the initial grant or subsequently, any and communicate, and translate a Work;
all of the rights conveyed by this License. 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
1.10. "Modifications" likeness depicted in a Work;
means any of the following: iv. rights protecting against unfair competition in regards to a Work,
subject to the limitations in paragraph 4(a), below;
(a) any file in Source Code Form that results from an addition to, v. rights protecting the extraction, dissemination, use and reuse of data
deletion from, or modification of the contents of Covered in a Work;
Software; or 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
(b) any new file in Source Code Form that contains any Covered protection of databases, and under any national implementation
Software. thereof, including any amended or successor version of such
directive); and
1.11. "Patent Claims" of a Contributor vii. other similar, equivalent or corresponding rights throughout the
means any patent claim(s), including without limitation, method, world based on applicable law or treaty, and any national
process, and apparatus claims, in any patent Licensable by such implementations thereof.
Contributor that would be infringed, but for the grant of the
License, by the making, using, selling, offering for sale, having 2. Waiver. To the greatest extent permitted by, but not in contravention
made, import, or transfer of either its Contributions or its of, applicable law, Affirmer hereby overtly, fully, permanently,
Contributor Version. irrevocably and unconditionally waives, abandons, and surrenders all of
Affirmer's Copyright and Related Rights and associated claims and causes
1.12. "Secondary License" of action, whether now known or unknown (including existing as well as
means either the GNU General Public License, Version 2.0, the GNU future claims and causes of action), in the Work (i) in all territories
Lesser General Public License, Version 2.1, the GNU Affero General worldwide, (ii) for the maximum duration provided by applicable law or
Public License, Version 3.0, or any later versions of those treaty (including future time extensions), (iii) in any current or future
licenses. medium and for any number of copies, and (iv) for any purpose whatsoever,
including without limitation commercial, advertising or promotional
1.13. "Source Code Form" purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each
means the form of the work preferred for making modifications. 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
1.14. "You" (or "Your") revocation, rescission, cancellation, termination, or any other legal or
means an individual or a legal entity exercising rights under this equitable action to disrupt the quiet enjoyment of the Work by the public
License. For legal entities, "You" includes any entity that as contemplated by Affirmer's express Statement of Purpose.
controls, is controlled by, or is under common control with You. For
purposes of this definition, "control" means (a) the power, direct 3. Public License Fallback. Should any part of the Waiver for any reason
or indirect, to cause the direction or management of such entity, be judged legally invalid or ineffective under applicable law, then the
whether by contract or otherwise, or (b) ownership of more than Waiver shall be preserved to the maximum extent permitted taking into
fifty percent (50%) of the outstanding shares or beneficial account Affirmer's express Statement of Purpose. In addition, to the
ownership of such entity. extent the Waiver is so judged Affirmer hereby grants to each affected
person a royalty-free, non transferable, non sublicensable, non exclusive,
2. License Grants and Conditions 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
2.1. Grants time extensions), (iii) in any current or future medium and for any number
of copies, and (iv) for any purpose whatsoever, including without
Each Contributor hereby grants You a world-wide, royalty-free, limitation commercial, advertising or promotional purposes (the
non-exclusive license: "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
(a) under intellectual property rights (other than patent or trademark) reason be judged legally invalid or ineffective under applicable law, such
Licensable by such Contributor to use, reproduce, make available, partial invalidity or ineffectiveness shall not invalidate the remainder
modify, display, perform, distribute, and otherwise exploit its of the License, and in such case Affirmer hereby affirms that he or she
Contributions, either on an unmodified basis, with Modifications, or will not (i) exercise any of his or her remaining Copyright and Related
as part of a Larger Work; and 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
(b) under Patent Claims of such Contributor to make, use, sell, offer express Statement of Purpose.
for sale, have made, import, and otherwise transfer either its
Contributions or its Contributor Version. 4. Limitations and Disclaimers.
2.2. Effective Date a. No trademark or patent rights held by Affirmer are waived, abandoned,
surrendered, licensed or otherwise affected by this document.
The licenses granted in Section 2.1 with respect to any Contribution b. Affirmer offers the Work as-is and makes no representations or
become effective for each Contribution on the date the Contributor first warranties of any kind concerning the Work, express, implied,
distributes such Contribution. statutory or otherwise, including without limitation warranties of
title, merchantability, fitness for a particular purpose, non
2.3. Limitations on Grant Scope infringement, or the absence of latent or other defects, accuracy, or
the present or absence of errors, whether or not discoverable, all to
The licenses granted in this Section 2 are the only rights granted under the greatest extent permissible under applicable law.
this License. No additional rights or licenses will be implied from the c. Affirmer disclaims responsibility for clearing rights of other persons
distribution or licensing of Covered Software under this License. that may apply to the Work or any use thereof, including without
Notwithstanding Section 2.1(b) above, no patent license is granted by a limitation any person's Copyright and Related Rights in the Work.
Contributor: Further, Affirmer disclaims responsibility for obtaining any necessary
consents, permissions or other rights required for any use of the
(a) for any code that a Contributor has removed from Covered Software; Work.
or d. Affirmer understands and acknowledges that Creative Commons is not a
party to this document and has no duty or obligation with respect to
(b) for infringements caused by: (i) Your and any other third party's this CC0 or use of the Work.
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

@@ -5,10 +5,10 @@ org.gradle.jvmargs=-Xmx1G
# check these on https://fabricmc.net/develop # check these on https://fabricmc.net/develop
minecraft_version=1.18.2 minecraft_version=1.18.2
yarn_mappings=1.18.2+build.1 yarn_mappings=1.18.2+build.1
loader_version=0.12.11 loader_version=0.13.3
# Mod Properties # Mod Properties
mod_version = 1.2.0 mod_version = 1.1.0
maven_group = com.lizistired maven_group = com.lizistired
archives_base_name = cave_dust archives_base_name = cave_dust

View File

@@ -1,12 +1,7 @@
package net.lizistired.cavedust; package net.lizistired.cavedust;
//minecraft imports //minecraft imports
import net.lizistired.cavedust.mixin.ClientWorldAccessor;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
import net.minecraft.text.Text;
import net.minecraft.text.TranslatableText;
import net.minecraft.util.Util;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World; import net.minecraft.world.World;
//other imports //other imports
import com.minelittlepony.common.util.GamePaths; import com.minelittlepony.common.util.GamePaths;
@@ -18,9 +13,6 @@ import org.slf4j.LoggerFactory;
import java.nio.file.Path; import java.nio.file.Path;
//static imports //static imports
import static net.lizistired.cavedust.utils.MathHelper.*; import static net.lizistired.cavedust.utils.MathHelper.*;
import static net.lizistired.cavedust.utils.MathHelper.generateRandomDouble;
import static net.lizistired.cavedust.utils.ParticleSpawnUtil.shouldParticlesSpawn;
import static net.lizistired.cavedust.utils.KeybindingHelper.*;
public class CaveDust implements ClientModInitializer { public class CaveDust implements ClientModInitializer {
@@ -40,53 +32,36 @@ public class CaveDust implements ClientModInitializer {
return config; return config;
} }
@Override @Override
public void onInitializeClient() { public void onInitializeClient() {
//config path and loading //config path and loading
Path CaveDustFolder = GamePaths.getConfigDirectory().resolve("cavedust"); Path CaveDustFolder = GamePaths.getConfigDirectory().resolve("cavedust");
config = new CaveDustConfig(CaveDustFolder.getParent().resolve("cavedust.json"), this); config = new CaveDustConfig(CaveDustFolder.getParent().resolve("cavedust.json"), this);
config.load(); config.load();
registerKeyBindings();
//register end client tick to create cave dust function, using end client tick for async //register end client tick to create cave dust function, using end client tick for async
ClientTickEvents.END_CLIENT_TICK.register(this::createCaveDust); ClientTickEvents.END_CLIENT_TICK.register(this::createCaveDust);
} }
private void createCaveDust(MinecraftClient client) { private void createCaveDust(MinecraftClient client) {
if (keyBinding1.wasPressed()){
getConfig().toggleCaveDust();
LOGGER.info("Toggled dust");
client.player.sendSystemMessage(new TranslatableText("debug.cavedust.toggle." + config.getCaveDustEnabled()), Util.NIL_UUID);
}
if (keyBinding2.wasPressed()){
getConfig().load();
LOGGER.info("Reloaded config");
client.player.sendSystemMessage(new TranslatableText("debug.cavedust.reload"), Util.NIL_UUID);
}
//ensure world is not null
if (client.world == null) return; if (client.world == null) return;
World world = client.world; World world = client.world;
//LOGGER.info(String.valueOf(((ClientWorldAccessor) client.world.getLevelProperties()).getFlatWorld()));
// )
double probabilityNormalized = normalize(config.getLowerLimit(), config.getUpperLimit(), client.player.getBlockY());
for (int i = 0; i < probabilityNormalized * config.getParticleMultiplier() * 10; i++) { if (shouldParticlesSpawn(client, config)) {
try { double probabilityNormalized = normalize(config.getLowerLimit(), config.getUpperLimit(), client.player.getBlockY());
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());
BlockPos particlePos = new BlockPos(x, y, z);
if (!shouldParticlesSpawn(client, config, particlePos)){return;} 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());
world.addParticle(config.getParticle(), x, y, z, 0, 0, 0);}
world.addParticle(config.getParticle(), x, y, z, config.getVelocityRandomnessRandom(), config.getVelocityRandomnessRandom(), config.getVelocityRandomnessRandom()); catch (NullPointerException e) {
} LOGGER.error(String.valueOf(e));
catch (NullPointerException e) { getConfig().setParticle("minecraft:white_ash");
LOGGER.error(String.valueOf(e)); }
getConfig().setParticle("minecraft:white_ash");
} }
} }
} }

View File

@@ -6,7 +6,6 @@ import net.minecraft.particle.ParticleTypes;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
import net.minecraft.util.registry.Registry; import net.minecraft.util.registry.Registry;
import static net.lizistired.cavedust.CaveDust.*; import static net.lizistired.cavedust.CaveDust.*;
import static net.lizistired.cavedust.utils.MathHelper.*;
import java.nio.file.Path; import java.nio.file.Path;
@@ -20,16 +19,13 @@ public class CaveDustConfig extends JsonFile {
private int dimensionMinX = -5; private int dimensionMinX = -5;
private int dimensionMinY = -5; private int dimensionMinY = -5;
private int dimensionMinZ = -5; private int dimensionMinZ = -5;
private int velocityRandomness = 1;
private boolean caveDustEnabled = true; private boolean caveDustEnabled = true;
private String particleName = "white_ash"; private String particleName = "white_ash";
private boolean seaLevelCheck = true; private boolean seaLevelCheck = true;
private boolean superFlatStatus = false;
//private boolean enhancedDetection = true;
private float upperLimit = 64; private float upperLimit = 64;
private float lowerLimit = -64; private float lowerLimit = -64;
private int particleMultiplier = 1; private float particleMultiplier = 1;
public CaveDustConfig(Path file, CaveDust caveDust) { public CaveDustConfig(Path file, CaveDust caveDust) {
super(file); super(file);
@@ -140,12 +136,12 @@ public class CaveDustConfig extends JsonFile {
return lowerLimit; return lowerLimit;
} }
public int getParticleMultiplier(){ public float getParticleMultiplier(){
return particleMultiplier; return particleMultiplier;
} }
public float setParticleMultiplier(float particleMultiplier){ public float setParticleMultiplier(float particleMultiplier){
this.particleMultiplier = (int) particleMultiplier; this.particleMultiplier = particleMultiplier;
save(); save();
return getParticleMultiplier(); return getParticleMultiplier();
} }
@@ -168,7 +164,7 @@ public class CaveDustConfig extends JsonFile {
public ParticleEffect getParticle(){ public ParticleEffect getParticle(){
try { try {
return (ParticleEffect) Registry.PARTICLE_TYPE.get(new Identifier(particleName.toLowerCase())); return (ParticleEffect) Registry.PARTICLE_TYPE.get(Identifier.tryParse(particleName.toLowerCase()));
} catch (ClassCastException e) { } 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\"."); 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"; particleName = "minecraft:white_ash";
@@ -187,41 +183,6 @@ public class CaveDustConfig extends JsonFile {
return getSeaLevelCheck(); return getSeaLevelCheck();
} }
public float getVelocityRandomnessRandom(){
if (velocityRandomness == 0) {return 0;}
return (float) generateRandomDouble(-velocityRandomness, velocityRandomness);
}
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 boolean getEnhancedDetection(){
return enhancedDetection;
}
public boolean setEnhancedDetection(){
enhancedDetection = !enhancedDetection;
save();
return getEnhancedDetection();
}*/
public void resetConfig(){ public void resetConfig(){
dimensionMinX = -5; dimensionMinX = -5;
dimensionMinY = -5; dimensionMinY = -5;

View File

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

View File

@@ -9,8 +9,8 @@ import net.minecraft.text.TranslatableText;
import javax.annotation.Nullable; import javax.annotation.Nullable;
public class ModMenuConfigScreen extends GameGui { public class ModMenuScreen extends GameGui {
public ModMenuConfigScreen(@Nullable Screen parent) { public ModMenuScreen(@Nullable Screen parent) {
super(new TranslatableText("menu.cavedust.title"), parent); super(new TranslatableText("menu.cavedust.title"), parent);
} }
@@ -32,18 +32,6 @@ public class ModMenuConfigScreen extends GameGui {
.setText("menu.cavedust.global." + config.getCaveDustEnabled()) .setText("menu.cavedust.global." + config.getCaveDustEnabled())
.setTooltip(new TranslatableText("menu.cavedust.global.tooltip." + config.getCaveDustEnabled())); .setTooltip(new TranslatableText("menu.cavedust.global.tooltip." + config.getCaveDustEnabled()));
/*addButton(new Button(left, row += 24).onClick(sender -> {
sender.getStyle().setText("menu.cavedust.enhanceddetection." + config.setEnhancedDetection()).setTooltip(new TranslatableText("menu.cavedust.enhanceddetection.tooltip"));
})).getStyle()
.setText("menu.cavedust.enhanceddetection." + config.getEnhancedDetection())
.setTooltip(new TranslatableText("menu.cavedust.enhanceddetection.tooltip"));*/
addButton(new Button(left, row += 24).onClick(sender -> {
sender.getStyle().setText("menu.cavedust.superflatstatus." + config.setSuperFlatStatus()).setTooltip(new TranslatableText("menu.cavedust.superflatstatus.tooltip"));
})).getStyle()
.setText("menu.cavedust.superflatstatus." + config.getSuperFlatStatus())
.setTooltip(new TranslatableText("menu.cavedust.superflatstatus.tooltip"));
addButton(new Slider(left += -110, row += 24, -50, 0, config.getDimensionsMinX())) addButton(new Slider(left += -110, row += 24, -50, 0, config.getDimensionsMinX()))
.onChange(config::setDimensionsMinX) .onChange(config::setDimensionsMinX)
.setTextFormat(transText::formatMinX) .setTextFormat(transText::formatMinX)
@@ -84,23 +72,18 @@ public class ModMenuConfigScreen extends GameGui {
.setTextFormat(transText::formatLowerLimit) .setTextFormat(transText::formatLowerLimit)
.getStyle().setTooltip(new TranslatableText("menu.cavedust.lowerlimit.tooltip")); .getStyle().setTooltip(new TranslatableText("menu.cavedust.lowerlimit.tooltip"));
addButton(new Slider(left, row += 24, 1, 100, config.getParticleMultiplier())) addButton(new Slider(left, row += 24, 0, 10, config.getParticleMultiplier()))
.onChange(config::setParticleMultiplier) .onChange(config::setParticleMultiplier)
.setTextFormat(transText::formatParticleMultiplier) .setTextFormat(transText::formatParticleMultiplier)
.getStyle().setTooltip(new TranslatableText("menu.cavedust.particlemultiplier.tooltip")); .getStyle().setTooltip(new TranslatableText("menu.cavedust.particlemultiplier.tooltip"));
addButton(new Slider(left, row += 24, 0, 10, config.getVelocityRandomness()))
.onChange(config::setVelocityRandomness)
.setTextFormat(transText::formatVelocityRandomness)
.getStyle().setTooltip(new TranslatableText("menu.cavedust.velocityrandomness.tooltip"));
addButton(new Button(left, row += 24).onClick(sender -> { addButton(new Button(left, row += 24).onClick(sender -> {
config.resetConfig(); config.resetConfig();
finish(); finish();
})).getStyle().setText(new TranslatableText("menu.cavedust.reset")).setTooltip(new TranslatableText("menu.cavedust.reset.tooltip")); })).getStyle().setText(new TranslatableText("menu.cavedust.reset")).setTooltip(new TranslatableText("menu.cavedust.reset.tooltip"));
addButton(new Button(left, row += 60) addButton(new Button(left, row += 180)
.onClick(sender -> finish())).getStyle() .onClick(sender -> finish())).getStyle()
.setText("gui.done"); .setText("gui.done");
} }

View File

@@ -1,12 +0,0 @@
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,10 +1,8 @@
package net.lizistired.cavedust.mixin; package net.lizistired.cavedust.mixin;
import net.lizistired.cavedust.CaveDustConfig;
import net.minecraft.client.gui.hud.DebugHud; import net.minecraft.client.gui.hud.DebugHud;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Inject;
@@ -15,7 +13,6 @@ import java.lang.management.ManagementFactory;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import static net.lizistired.cavedust.utils.MathHelper.*; import static net.lizistired.cavedust.utils.MathHelper.*;
import static net.lizistired.cavedust.utils.ParticleSpawnUtil.shouldParticlesSpawn;
@Mixin(DebugHud.class) @Mixin(DebugHud.class)
public abstract class MixinDebugScreenOverlay { public abstract class MixinDebugScreenOverlay {

View File

@@ -1,29 +0,0 @@
package net.lizistired.cavedust.utils;
import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper;
import net.minecraft.client.option.KeyBinding;
import net.minecraft.client.option.StickyKeyBinding;
import net.minecraft.client.util.InputUtil;
import org.lwjgl.glfw.GLFW;
public class KeybindingHelper {
public static KeyBinding keyBinding1;
public static KeyBinding keyBinding2;
public static void registerKeyBindings(){
keyBinding1 = KeyBindingHelper.registerKeyBinding(new KeyBinding(
"key.cavedust.toggle",
InputUtil.Type.KEYSYM,// The translation key of the keybinding's name // The type of the keybinding, KEYSYM for keyboard, MOUSE for mouse.
GLFW.GLFW_KEY_KP_ADD, // The keycode of the key
"category.cavedust.spook" // The translation key of the keybinding's category.
));
keyBinding2 = KeyBindingHelper.registerKeyBinding(new KeyBinding(
"key.cavedust.reload", // The translation key of the keybinding's name
InputUtil.Type.KEYSYM, // The type of the keybinding, KEYSYM for keyboard, MOUSE for mouse.
GLFW.GLFW_KEY_KP_ENTER, // The keycode of the key
"category.cavedust.spook" // The translation key of the keybinding's category.
));
}
}

View File

@@ -1,40 +1,74 @@
package net.lizistired.cavedust.utils; 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.Random;
import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.ThreadLocalRandom;
import static net.minecraft.world.biome.BiomeKeys.LUSH_CAVES;
public class MathHelper { public class MathHelper {
/** private static float timer;
* Normalizes a value to between a range, eg. you want to map a value of 100 to 0 - 1, with 50 being 0.5. public static boolean shouldParticlesSpawn;
* @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) { public static double normalize(double min, double max, double val) {
return 1 - ((val - min) / (max - min)); 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(); Random random = new Random();
return random.ints(min, max) return random.ints(min, max)
.findFirst() .findFirst()
.getAsInt(); .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) { public static double generateRandomDouble(double min, double max) {
return ThreadLocalRandom.current().nextDouble(min, 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.requireNonNull(client.player).isSubmergedInWater()
|| client.world.getBiome(Objects.requireNonNull(client.player).getBlockPos()).matchesKey(LUSH_CAVES))
{
timer = 0;
shouldParticlesSpawn = false;
return false;
}
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

@@ -1,100 +0,0 @@
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 java.util.Optional;
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) {
//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.requireNonNull(client.player).isSubmergedInWater()
|| client.world.getBiome(Objects.requireNonNull(client.player.getBlockPos())).matchesKey(LUSH_CAVES))
{
timer = 0;
shouldParticlesSpawn = false;
return false;
}
World world = client.world;
int seaLevel = world.getSeaLevel();
if (!client.player.clientWorld.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, 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.requireNonNull(client.player).isSubmergedInWater()
|| client.world.getBiome(Objects.requireNonNull(pos)).matchesKey(LUSH_CAVES))
{
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 (!client.player.clientWorld.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

@@ -32,7 +32,4 @@ public class TranslatableTextHelper {
public Text formatParticleMultiplier(AbstractSlider<Float> slider) { public Text formatParticleMultiplier(AbstractSlider<Float> slider) {
return new TranslatableText("menu.cavedust.particlemultiplier", (int)Math.floor(slider.getValue())); return new TranslatableText("menu.cavedust.particlemultiplier", (int)Math.floor(slider.getValue()));
} }
public Text formatVelocityRandomness(AbstractSlider<Float> slider) {
return new TranslatableText("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; import net.minecraft.client.MinecraftClient;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 227 KiB

After

Width:  |  Height:  |  Size: 126 KiB

View File

@@ -23,22 +23,5 @@
"menu.cavedust.reset": "Reset settings", "menu.cavedust.reset": "Reset settings",
"menu.cavedust.reset.tooltip": "Are you sure you want to reset all settings?", "menu.cavedust.reset.tooltip": "Are you sure you want to reset all settings?",
"menu.cavedust.particlemultiplier": "Particle multiplier: %s", "menu.cavedust.particlemultiplier": "Particle multiplier: %s",
"menu.cavedust.particlemultiplier.tooltip": "Multiplies the amount of particles at any given depth.", "menu.cavedust.particlemultiplier.tooltip": "Multiplies the amount of particles at any given depth."
"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?",
"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"
} }

View File

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

View File

@@ -11,7 +11,7 @@
"issues": "https://github.com/LizIsTired/dust/issues", "issues": "https://github.com/LizIsTired/dust/issues",
"sources": "https://github.com/LizIsTired/dust" "sources": "https://github.com/LizIsTired/dust"
}, },
"license": "MPL-2.0", "license": "CC0-1.0",
"icon": "assets/modid/icon.png", "icon": "assets/modid/icon.png",
"environment": "*", "environment": "*",
"entrypoints": { "entrypoints": {
@@ -28,7 +28,7 @@
"depends": { "depends": {
"fabricloader": ">=0.12.11", "fabricloader": ">=0.12.11",
"fabric": "*", "fabric": "*",
"minecraft": "1.18.2", "minecraft": "1.18.x",
"java": ">=17" "java": ">=17"
}, },
"suggests": { "suggests": {
@@ -37,7 +37,7 @@
"custom": { "custom": {
"modmenu": { "modmenu": {
"links": { "links": {
"modmenu.discord": "https://discord.gg/4m6kQSX6bx" "modmenu.discord": "https://discord.gg/AgBfPFMJgX"
} }
} }
} }