mirror of
https://github.com/FabricMC/fabric.git
synced 2025-03-31 09:10:00 -04:00
Bring branch up-to-date with main repo (#11)
This commit is contained in:
parent
a464bac675
commit
dc47106241
41 changed files with 690 additions and 97 deletions
README.mdbuild.gradle
fabric-api-base
fabric-game-rule-api-v1/src/main/java/net/fabricmc/fabric/mixin/gamerule/client
fabric-item-groups-v0/src/main/resources/assets/fabric/lang
fabric-object-builder-api-v1
fabric-object-builders-v0/src/main/java/net/fabricmc/fabric/api/block
fabric-registry-sync-v0
build.gradle
src
main
java/net/fabricmc/fabric
api/event/registry
mixin/registry/sync
resources
testmod/java/net/fabricmc/fabric/test/registry/sync
fabric-renderer-api-v1
build.gradle
src/main/java/net/fabricmc/fabric
fabric-renderer-indigo
build.gradle
src/main/java/net/fabricmc/fabric/impl/client/indigo/renderer
fabric-textures-v0/src/main/java/net/fabricmc/fabric/api/event/client
fabric-tool-attribute-api-v1
build.gradle
src
main/java/net/fabricmc/fabric
api/tool/attribute/v1
impl/tool/attribute
testmod
java/net/fabricmc/fabric/test/tool/attribute
resources/data/fabric-tool-attribute-api-v1-testmod/tags/items
94
README.md
94
README.md
|
@ -1,7 +1,93 @@
|
|||
# Fabric
|
||||
# Fabric API
|
||||
|
||||
Essential hooks and patches for modding with Fabric.
|
||||
Essential hooks for modding with Fabric.
|
||||
|
||||
## Getting Started
|
||||
Fabric API is the library for essential hooks and interoperability mechanisms for Fabric mods. Examples include:
|
||||
|
||||
To setup a Fabric development environment, check out the [example fabric mod](https://github.com/FabricMC/fabric-example-mod) and follow the instructions there.
|
||||
- Exposing functionality that is useful but difficult to access for many mods such as particles, biomes and dimensions
|
||||
- Adding events, hooks and APIs to improve interopability between mods.
|
||||
- Essential features such as registry synchronization and adding information to crash reports.
|
||||
- An advanced rendering API designed for compatibility with optimization mods and graphics overhaul mods.
|
||||
|
||||
Also check out [Fabric Loader](https://github.com/FabricMC/fabric-loader), the (mostly) version-independent mod loader that powers Fabric. Fabric API is a mod like any other Fabric mod which requires Fabric Loader to be installed.
|
||||
|
||||
For support and discussion for both developers and users, visit [the Fabric Discord server](https://discord.gg/v6v4pMv).
|
||||
|
||||
## Using Fabric API to play with mods
|
||||
|
||||
Make sure you have install fabric loader first. More information about installing Fabric Loader can be found [here](https://fabricmc.net/use/).
|
||||
|
||||
To use Fabric API, download it from [CurseForge](https://www.curseforge.com/minecraft/mc-mods/fabric-api) or [GitHub Releases](https://github.com/FabricMC/fabric/releases).
|
||||
|
||||
The downloaded jar file should be placed in your `mods` folder.
|
||||
|
||||
## Using Fabric API to develop mods
|
||||
|
||||
To setup a Fabric development environment, check out the [Fabric example mod](https://github.com/FabricMC/fabric-example-mod) and follow the instructions there. The example mod already depends on Fabric API.
|
||||
|
||||
To include the full Fabric API with all modules in the development environment, add the following to your `dependencies` block in the gradle buildscript:
|
||||
|
||||
### Groovy DSL
|
||||
|
||||
```groovy
|
||||
modImplementation "net.fabricmc.fabric-api:fabric-api:FABRIC_API_VERSION"
|
||||
```
|
||||
|
||||
### Kotlin DSL
|
||||
|
||||
```kotlin
|
||||
modImplementation("net.fabricmc.fabric-api:fabric-api:FABRIC_API_VERSION")
|
||||
```
|
||||
|
||||
Alternatively, modules from Fabric API can be specified individually as shown below:
|
||||
|
||||
### Groovy DSL
|
||||
|
||||
```groovy
|
||||
// Make a collection of all api modules we wish to use
|
||||
Set<String> apiModules = [
|
||||
"fabric-api-base",
|
||||
"fabric-command-api-v1",
|
||||
"fabric-lifecycle-events-v1",
|
||||
"fabric-networking-v0"
|
||||
]
|
||||
|
||||
// Add each module as a dependency
|
||||
apiModules.forEach {
|
||||
modImplementation(fabricApi.module(it, FABRIC_API_VERSION))
|
||||
}
|
||||
```
|
||||
|
||||
### Kotlin DSL
|
||||
|
||||
```kotlin
|
||||
// Make a set of all api modules we wish to use
|
||||
setOf(
|
||||
"fabric-api-base",
|
||||
"fabric-command-api-v1",
|
||||
"fabric-lifecycle-events-v1",
|
||||
"fabric-networking-v0"
|
||||
).forEach {
|
||||
// Add each module as a dependency
|
||||
modImplementation(fabricApi.module(it, FABRIC_API_VERSION))
|
||||
}
|
||||
```
|
||||
|
||||
<!--Linked to gradle documentation on properties-->
|
||||
Instead of hardcoding version constants all over the build script, Gradle properties may be used to replace these constants. Properties are defined in the `gradle.properties` file at the root of a project. More information is available [here](https://docs.gradle.org/current/userguide/organizing_gradle_projects.html#declare_properties_in_gradle_properties_file).
|
||||
|
||||
## Contributing
|
||||
|
||||
See something Fabric API doesn't support, a bug or something that may be useful? We welcome contributions to improve Fabric API.
|
||||
|
||||
Check out [the Contributing guidelines](../CONTRIBUTING.md)*.
|
||||
|
||||
\* The contributing guidelines are work in progress
|
||||
|
||||
## Modules
|
||||
|
||||
Fabric API is designed to be modular for ease of updating. This also has the advantage of splitting up the codebase into smaller chunks.
|
||||
|
||||
Each module contains its own `README.md`* explaining the module's purpose and additional info on using the module.
|
||||
|
||||
\* The README for each module is being worked on; not every module has a README at the moment
|
||||
|
|
104
build.gradle
104
build.gradle
|
@ -5,22 +5,23 @@ buildscript {
|
|||
}
|
||||
|
||||
plugins {
|
||||
id 'java'
|
||||
id 'eclipse'
|
||||
id 'idea'
|
||||
id 'maven-publish'
|
||||
id 'fabric-loom' version '0.5.25' apply false
|
||||
id 'net.minecrell.licenser' version '0.4.1'
|
||||
id "java"
|
||||
id "eclipse"
|
||||
id "idea"
|
||||
id "maven-publish"
|
||||
id "fabric-loom" version "0.5.33" apply false
|
||||
id "net.minecrell.licenser" version "0.4.1"
|
||||
id "org.ajoberstar.grgit" version "3.1.1"
|
||||
id 'com.matthewprenger.cursegradle' version "1.4.0"
|
||||
id "com.matthewprenger.cursegradle" version "1.4.0"
|
||||
}
|
||||
|
||||
def ENV = System.getenv()
|
||||
|
||||
class Globals {
|
||||
static def baseVersion = "0.22.1"
|
||||
static def baseVersion = "0.24.1"
|
||||
static def mcVersion = "1.16.3"
|
||||
static def yarnVersion = "+build.1"
|
||||
static def yarnVersion = "+build.47"
|
||||
static def loaderVersion = "0.10.3+build.211"
|
||||
}
|
||||
|
||||
version = Globals.baseVersion + "+" + (ENV.BUILD_NUMBER ? ("build." + ENV.BUILD_NUMBER) : "local") + "-" + getBranch()
|
||||
|
@ -32,12 +33,14 @@ def getSubprojectVersion(project, version) {
|
|||
if (grgit == null) {
|
||||
return version + "+nogit"
|
||||
}
|
||||
|
||||
def latestCommits = grgit.log(paths: [project.name], maxCommits: 1)
|
||||
|
||||
if (latestCommits.isEmpty()) {
|
||||
return version + "+uncommited"
|
||||
} else {
|
||||
return version + "+" + latestCommits.get(0).id.substring(0, 8) + DigestUtils.sha256Hex(Globals.mcVersion).substring(0, 2)
|
||||
}
|
||||
|
||||
return version + "+" + latestCommits.get(0).id.substring(0, 8) + DigestUtils.sha256Hex(Globals.mcVersion).substring(0, 2)
|
||||
}
|
||||
|
||||
def getBranch() {
|
||||
|
@ -45,18 +48,20 @@ def getBranch() {
|
|||
def branch = System.getenv().GIT_BRANCH
|
||||
return branch.substring(branch.lastIndexOf("/") + 1)
|
||||
}
|
||||
|
||||
if (grgit == null) {
|
||||
return "unknown"
|
||||
}
|
||||
|
||||
def branch = grgit.branch.current().name
|
||||
return branch.substring(branch.lastIndexOf("/") + 1)
|
||||
}
|
||||
|
||||
allprojects {
|
||||
apply plugin: 'checkstyle'
|
||||
apply plugin: 'maven-publish'
|
||||
apply plugin: 'fabric-loom'
|
||||
apply plugin: 'net.minecrell.licenser'
|
||||
apply plugin: "checkstyle"
|
||||
apply plugin: "maven-publish"
|
||||
apply plugin: "fabric-loom"
|
||||
apply plugin: "net.minecrell.licenser"
|
||||
|
||||
sourceCompatibility = 1.8
|
||||
targetCompatibility = 1.8
|
||||
|
@ -73,7 +78,7 @@ allprojects {
|
|||
dependencies {
|
||||
minecraft "com.mojang:minecraft:$Globals.mcVersion"
|
||||
mappings "net.fabricmc:yarn:${Globals.mcVersion}${Globals.yarnVersion}:v2"
|
||||
modCompile "net.fabricmc:fabric-loader:0.9.2+build.206"
|
||||
modCompile "net.fabricmc:fabric-loader:${Globals.loaderVersion}"
|
||||
}
|
||||
|
||||
configurations {
|
||||
|
@ -116,42 +121,44 @@ allprojects {
|
|||
}
|
||||
|
||||
license {
|
||||
header rootProject.file('HEADER')
|
||||
include '**/*.java'
|
||||
header rootProject.file("HEADER")
|
||||
include "**/*.java"
|
||||
}
|
||||
}
|
||||
|
||||
task sourcesJar(type: Jar, dependsOn: classes) {
|
||||
classifier = 'sources'
|
||||
archiveClassifier = "sources"
|
||||
from sourceSets.main.allSource
|
||||
}
|
||||
|
||||
checkstyle {
|
||||
configFile = rootProject.file("checkstyle.xml")
|
||||
toolVersion = '8.31'
|
||||
toolVersion = "8.31"
|
||||
}
|
||||
}
|
||||
|
||||
javadoc {
|
||||
options {
|
||||
source = "8"
|
||||
encoding = 'UTF-8'
|
||||
charSet = 'UTF-8'
|
||||
encoding = "UTF-8"
|
||||
charSet = "UTF-8"
|
||||
memberLevel = JavadocMemberLevel.PACKAGE
|
||||
links(
|
||||
'https://guava.dev/releases/21.0/api/docs/',
|
||||
'https://asm.ow2.io/javadoc/',
|
||||
'https://docs.oracle.com/javase/8/docs/api/',
|
||||
'http://jenkins.liteloader.com/job/Mixin/javadoc/',
|
||||
'https://logging.apache.org/log4j/2.x/log4j-api/apidocs/'
|
||||
"https://guava.dev/releases/21.0/api/docs/",
|
||||
"https://asm.ow2.io/javadoc/",
|
||||
"https://docs.oracle.com/javase/8/docs/api/",
|
||||
"http://jenkins.liteloader.com/job/Mixin/javadoc/",
|
||||
"https://logging.apache.org/log4j/2.x/log4j-api/apidocs/"
|
||||
// Need to add minecraft jd publication etc once there is one available
|
||||
)
|
||||
// Disable the crazy super-strict doclint tool in Java 8
|
||||
addStringOption('Xdoclint:none', '-quiet')
|
||||
addStringOption("Xdoclint:none", "-quiet")
|
||||
}
|
||||
|
||||
allprojects.each {
|
||||
source(it.sourceSets.main.allJava.srcDirs)
|
||||
}
|
||||
|
||||
classpath = sourceSets.main.compileClasspath
|
||||
include("**/api/**")
|
||||
failOnError false
|
||||
|
@ -161,12 +168,12 @@ task javadocJar(type: Jar) {
|
|||
dependsOn javadoc
|
||||
from javadoc.destinationDir
|
||||
//Set as `fatjavadoc` to prevent an ide form trying to use this javadoc, over using the modules javadoc
|
||||
classifier = 'fatjavadoc'
|
||||
archiveClassifier = "fatjavadoc"
|
||||
}
|
||||
|
||||
build.dependsOn javadocJar
|
||||
|
||||
subprojects {
|
||||
|
||||
dependencies {
|
||||
testmodCompile sourceSets.main.output
|
||||
}
|
||||
|
@ -186,6 +193,7 @@ subprojects {
|
|||
artifact(file("${project.buildDir}/libs/$archivesBaseName-${version}-maven.jar")) {
|
||||
builtBy remapMavenJar
|
||||
}
|
||||
|
||||
artifact(sourcesJar) {
|
||||
builtBy remapSourcesJar
|
||||
}
|
||||
|
@ -213,10 +221,13 @@ publishing {
|
|||
artifact(file("${project.buildDir}/libs/$archivesBaseName-${version}-maven.jar")) {
|
||||
builtBy remapMavenJar
|
||||
}
|
||||
|
||||
artifact(sourcesJar) {
|
||||
builtBy remapSourcesJar
|
||||
}
|
||||
|
||||
artifact javadocJar
|
||||
|
||||
pom.withXml {
|
||||
def depsNode = asNode().appendNode("dependencies")
|
||||
subprojects.each {
|
||||
|
@ -235,12 +246,12 @@ publishing {
|
|||
|
||||
void setupRepositories(RepositoryHandler repositories) {
|
||||
//repositories.mavenLocal() // uncomment for testing
|
||||
if (project.hasProperty('mavenPass')) {
|
||||
if (project.hasProperty("mavenPass")) {
|
||||
repositories.maven {
|
||||
url "http://mavenupload.modmuss50.me/"
|
||||
credentials {
|
||||
username 'buildslave'
|
||||
password project.getProperty('mavenPass')
|
||||
username "buildslave"
|
||||
password project.getProperty("mavenPass")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -266,43 +277,48 @@ dependencies {
|
|||
}
|
||||
|
||||
curseforge {
|
||||
if (project.hasProperty('curse_api_key')) {
|
||||
apiKey = project.getProperty('curse_api_key')
|
||||
if (project.hasProperty("curse_api_key")) {
|
||||
apiKey = project.getProperty("curse_api_key")
|
||||
}
|
||||
|
||||
project {
|
||||
id = '306612'
|
||||
changelog = 'A changelog can be found at https://github.com/FabricMC/fabric/commits'
|
||||
releaseType = 'release'
|
||||
addGameVersion '1.16.3'
|
||||
addGameVersion 'Fabric'
|
||||
id = "306612"
|
||||
changelog = "A changelog can be found at https://github.com/FabricMC/fabric/commits"
|
||||
releaseType = "release"
|
||||
addGameVersion "1.16.3"
|
||||
addGameVersion "Fabric"
|
||||
|
||||
mainArtifact(file("${project.buildDir}/libs/${archivesBaseName}-${version}.jar")) {
|
||||
displayName = "[$Globals.mcVersion] Fabric API $Globals.baseVersion build $ENV.BUILD_NUMBER"
|
||||
}
|
||||
|
||||
afterEvaluate {
|
||||
uploadTask.dependsOn("remapJar")
|
||||
}
|
||||
}
|
||||
|
||||
options {
|
||||
forgeGradleIntegration = false
|
||||
}
|
||||
}
|
||||
|
||||
apply from: 'https://github.com/FabricMC/fabric-docs/raw/master/gradle/ideconfig.gradle'
|
||||
apply from: "https://github.com/FabricMC/fabric-docs/raw/master/gradle/ideconfig.gradle"
|
||||
|
||||
import org.kohsuke.github.GHReleaseBuilder
|
||||
import org.kohsuke.github.GitHub
|
||||
|
||||
task github(dependsOn: remapMavenJar) {
|
||||
onlyIf {
|
||||
project.hasProperty('github_api_key')
|
||||
project.hasProperty("github_api_key")
|
||||
}
|
||||
|
||||
doLast {
|
||||
def github = GitHub.connectUsingOAuth(project.getProperty('github_api_key') as String)
|
||||
def github = GitHub.connectUsingOAuth(project.getProperty("github_api_key") as String)
|
||||
def repository = github.getRepository("FabricMC/fabric")
|
||||
|
||||
def releaseBuilder = new GHReleaseBuilder(repository, version as String)
|
||||
releaseBuilder.name("[$Globals.mcVersion] Fabric API $Globals.baseVersion build $ENV.BUILD_NUMBER")
|
||||
releaseBuilder.body('A changelog can be found at https://github.com/FabricMC/fabric/commits')
|
||||
releaseBuilder.body("A changelog can be found at https://github.com/FabricMC/fabric/commits")
|
||||
releaseBuilder.commitish(getBranch())
|
||||
|
||||
def ghRelease = releaseBuilder.create()
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
archivesBaseName = "fabric-api-base"
|
||||
version = getSubprojectVersion(project, "0.1.3")
|
||||
version = getSubprojectVersion(project, "0.2.0")
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.api.util;
|
||||
|
||||
/**
|
||||
* Represents a function that accepts an boolean-valued argument and produces a result.
|
||||
*
|
||||
* <p>This is the {@code boolean}-consuming primitive specialization for {@link java.util.function.Function}.
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface BooleanFunction<R> {
|
||||
/**
|
||||
* Applies this function to the given argument.
|
||||
*
|
||||
* @param value the function argument
|
||||
* @return the function result
|
||||
*/
|
||||
R apply(boolean value);
|
||||
}
|
|
@ -16,16 +16,124 @@
|
|||
|
||||
package net.fabricmc.fabric.api.util;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.function.BooleanSupplier;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Represents a boolean value which can be true, false or refer to a default value.
|
||||
*/
|
||||
public enum TriState {
|
||||
/**
|
||||
* Represents the boolean value of {@code false}.
|
||||
*/
|
||||
FALSE,
|
||||
/**
|
||||
* Represents a value that refers to a "default" value, often as a fallback.
|
||||
*/
|
||||
DEFAULT,
|
||||
/**
|
||||
* Represents the boolean value of {@code true}.
|
||||
*/
|
||||
TRUE;
|
||||
|
||||
public static TriState of(boolean b) {
|
||||
return b ? TRUE : FALSE;
|
||||
/**
|
||||
* Gets the corresponding tri-state from a boolean value.
|
||||
*
|
||||
* @param bool the boolean value
|
||||
* @return {@link TriState#TRUE} or {@link TriState#FALSE} depending on the value of the boolean.
|
||||
*/
|
||||
public static TriState of(boolean bool) {
|
||||
return bool ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a tri-state from a nullable boxed boolean.
|
||||
*
|
||||
* @param bool the boolean value
|
||||
* @return {@link TriState#DEFAULT} if {@code null}.
|
||||
* Otherwise {@link TriState#TRUE} or {@link TriState#FALSE} depending on the value of the boolean.
|
||||
*/
|
||||
public static TriState of(@Nullable Boolean bool) {
|
||||
return bool == null ? DEFAULT : of(bool.booleanValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the tri-state.
|
||||
*
|
||||
* @return true if the tri-state is {@link TriState#TRUE}.
|
||||
* Otherwise false.
|
||||
*/
|
||||
public boolean get() {
|
||||
return this == TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the tri-state as a boxed, nullable boolean.
|
||||
*
|
||||
* @return {@code null} if {@link TriState#DEFAULT}.
|
||||
* Otherwise {@code true} if {@link TriState#TRUE} or {@code false} if {@link TriState#FALSE}.
|
||||
*/
|
||||
@Nullable
|
||||
public Boolean getBoxed() {
|
||||
return this == DEFAULT ? null : this.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of this tri-state.
|
||||
* If the value is {@link TriState#DEFAULT} then use the supplied value.
|
||||
*
|
||||
* @param value the value to fallback to
|
||||
* @return the value of the tri-state or the supplied value if {@link TriState#DEFAULT}.
|
||||
*/
|
||||
public boolean orElse(boolean value) {
|
||||
return this == DEFAULT ? value : this.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of this tri-state.
|
||||
* If the value is {@link TriState#DEFAULT} then use the supplied value.
|
||||
*
|
||||
* @param supplier the supplier used to get the value to fallback to
|
||||
* @return the value of the tri-state or the value of the supplier if the tri-state is {@link TriState#DEFAULT}.
|
||||
*/
|
||||
public boolean orElseGet(BooleanSupplier supplier) {
|
||||
return this == DEFAULT ? supplier.getAsBoolean() : this.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps the boolean value of this tri-state if it is {@link TriState#TRUE} or {@link TriState#FALSE}.
|
||||
*
|
||||
* @param mapper the mapper to use
|
||||
* @param <T> the type of object being supplier by the mapper
|
||||
* @return an optional containing the mapped value; {@link Optional#empty()} if the tri-state is {@link TriState#DEFAULT} or the value provided by the mapper is {@code null}.
|
||||
*/
|
||||
public <T> Optional<T> map(BooleanFunction<@Nullable ? extends T> mapper) {
|
||||
Objects.requireNonNull(mapper, "Mapper function cannot be null");
|
||||
|
||||
if (this == DEFAULT) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
return Optional.ofNullable(mapper.apply(this.get()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of this tri-state, or throws an exception if this tri-state's value is {@link TriState#DEFAULT}.
|
||||
*
|
||||
* @param exceptionSupplier the supplying function that produces an exception to be thrown
|
||||
* @param <X> Type of the exception to be thrown
|
||||
* @return the value
|
||||
* @throws X if the value is {@link TriState#DEFAULT}
|
||||
*/
|
||||
public <X extends Throwable> boolean orElseThrow(Supplier<X> exceptionSupplier) throws X {
|
||||
if (this != DEFAULT) {
|
||||
return this.get();
|
||||
}
|
||||
|
||||
throw exceptionSupplier.get();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,6 +33,7 @@ import net.minecraft.world.GameRules;
|
|||
|
||||
import net.fabricmc.fabric.api.gamerule.v1.CustomGameRuleCategory;
|
||||
|
||||
// For any future maintainers who wonder why this class does not compile because of jsr305, please reload gradle using `--refresh-dependencies`.
|
||||
@Mixin(EditGameRulesScreen.RuleListWidget.class)
|
||||
public abstract class RuleListWidgetMixin extends net.minecraft.client.gui.widget.EntryListWidget<EditGameRulesScreen.AbstractRuleWidget> {
|
||||
@Unique
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"fabric.gui.creativeTabPage": "Sayfa: %d/%d"
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
archivesBaseName = "fabric-object-builder-api-v1"
|
||||
version = getSubprojectVersion(project, "1.8.1")
|
||||
version = getSubprojectVersion(project, "1.9.0")
|
||||
|
||||
dependencies {
|
||||
compile project(path: ':fabric-api-base', configuration: 'dev')
|
||||
|
|
|
@ -50,6 +50,7 @@ public class FabricBlockSettings extends AbstractBlock.Settings {
|
|||
protected FabricBlockSettings(AbstractBlock.Settings settings) {
|
||||
super(((AbstractBlockSettingsAccessor) settings).getMaterial(), ((AbstractBlockSettingsAccessor) settings).getMaterialColorFactory());
|
||||
// Mostly Copied from vanilla's copy method
|
||||
// Note: If new methods are added to Block settings, an accessor must be added here
|
||||
AbstractBlockSettingsAccessor thisAccessor = (AbstractBlockSettingsAccessor) this;
|
||||
AbstractBlockSettingsAccessor otherAccessor = (AbstractBlockSettingsAccessor) settings;
|
||||
|
||||
|
@ -58,7 +59,7 @@ public class FabricBlockSettings extends AbstractBlock.Settings {
|
|||
this.resistance(otherAccessor.getResistance());
|
||||
this.collidable(otherAccessor.getCollidable());
|
||||
thisAccessor.setRandomTicks(otherAccessor.getRandomTicks());
|
||||
this.lightLevel(otherAccessor.getLuminance());
|
||||
this.luminance(otherAccessor.getLuminance());
|
||||
thisAccessor.setMaterialColorFactory(otherAccessor.getMaterialColorFactory());
|
||||
this.sounds(otherAccessor.getSoundGroup());
|
||||
this.slipperiness(otherAccessor.getSlipperiness());
|
||||
|
@ -134,8 +135,8 @@ public class FabricBlockSettings extends AbstractBlock.Settings {
|
|||
}
|
||||
|
||||
@Override
|
||||
public FabricBlockSettings lightLevel(ToIntFunction<BlockState> levelFunction) {
|
||||
super.lightLevel(levelFunction);
|
||||
public FabricBlockSettings luminance(ToIntFunction<BlockState> luminanceFunction) {
|
||||
super.luminance(luminanceFunction);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -224,8 +225,17 @@ public class FabricBlockSettings extends AbstractBlock.Settings {
|
|||
|
||||
/* FABRIC ADDITIONS*/
|
||||
|
||||
/**
|
||||
* @deprecated Please use {@link FabricBlockSettings#luminance(int)}.
|
||||
*/
|
||||
@Deprecated
|
||||
public FabricBlockSettings lightLevel(int lightLevel) {
|
||||
this.lightLevel(ignored -> lightLevel);
|
||||
this.luminance(lightLevel);
|
||||
return this;
|
||||
}
|
||||
|
||||
public FabricBlockSettings luminance(int luminance) {
|
||||
this.luminance(ignored -> luminance);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.api.object.builder.v1.villager;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.registry.RegistryKey;
|
||||
import net.minecraft.village.VillagerProfession;
|
||||
import net.minecraft.village.VillagerType;
|
||||
import net.minecraft.world.biome.Biome;
|
||||
|
||||
import net.fabricmc.fabric.mixin.object.builder.VillagerTypeAccessor;
|
||||
|
||||
/**
|
||||
* Utilities related to the creation of {@link VillagerType}s.
|
||||
* Not to be confused with a {@link VillagerProfession}, a villager type defines the appearance of a villager.
|
||||
*
|
||||
* <p>Creation and registration of custom villager types may be done by using {@link VillagerTypeHelper#register(Identifier)}.
|
||||
*
|
||||
* <p>Creation and registration of a villager type does not guarantee villagers of a specific type will be created in a world.
|
||||
* Typically the villager type is bound to a specific group of biomes.
|
||||
* To allow a villager type to be spawned in a specific biome, use {@link VillagerTypeHelper#addVillagerTypeToBiome(RegistryKey, VillagerType)}.
|
||||
*
|
||||
* <p>The texture used for the appearance of the villager is located at {@code assets/IDENTIFIER_NAMESPACE/textures/entity/villager/type/IDENTIFIER_PATH.png}.
|
||||
*/
|
||||
public final class VillagerTypeHelper {
|
||||
private static final Logger LOGGER = LogManager.getLogger();
|
||||
|
||||
/**
|
||||
* Creates and registers a new villager type.
|
||||
*
|
||||
* @param id the id of the villager type
|
||||
* @return a new villager type
|
||||
*/
|
||||
public static VillagerType register(Identifier id) {
|
||||
Objects.requireNonNull(id, "Id of villager type cannot be null");
|
||||
return VillagerTypeAccessor.callRegister(id.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the biome a villager type can spawn in.
|
||||
*
|
||||
* @param biomeKey the registry key of the biome
|
||||
* @param villagerType the villager type
|
||||
*/
|
||||
public static void addVillagerTypeToBiome(RegistryKey<Biome> biomeKey, VillagerType villagerType) {
|
||||
Objects.requireNonNull(biomeKey, "Biome registry key cannot be null");
|
||||
Objects.requireNonNull(villagerType, "Villager type cannot be null");
|
||||
|
||||
if (VillagerTypeAccessor.getBiomeTypeToIdMap().put(biomeKey, villagerType) != null) {
|
||||
LOGGER.debug("Overriding existing Biome -> VillagerType registration for Biome {}", biomeKey.getValue().toString());
|
||||
}
|
||||
}
|
||||
|
||||
private VillagerTypeHelper() {
|
||||
}
|
||||
}
|
|
@ -49,7 +49,7 @@ public interface AbstractBlockSettingsAccessor {
|
|||
@Accessor
|
||||
boolean getRandomTicks();
|
||||
|
||||
@Accessor
|
||||
@Accessor("luminance")
|
||||
ToIntFunction<BlockState> getLuminance();
|
||||
|
||||
@Accessor
|
||||
|
@ -110,13 +110,14 @@ public interface AbstractBlockSettingsAccessor {
|
|||
@Accessor
|
||||
void setToolRequired(boolean toolRequired);
|
||||
|
||||
// Cannot be an invoker due to conflicts in mixin: method_9631(Ljava/util/function/ToIntFunction;)Lnet/minecraft/class_4970$class_2251; for target net.minecraft.block.AbstractBlock$Settings conflicts with existing mapping field_10663:Ljava/util/function/ToIntFunction;
|
||||
@Accessor("luminance")
|
||||
void setLuminanceFunction(ToIntFunction<BlockState> luminanceFunction);
|
||||
|
||||
/* INVOKERS */
|
||||
@Invoker
|
||||
Block.Settings invokeSounds(BlockSoundGroup group);
|
||||
|
||||
@Invoker
|
||||
Block.Settings invokeLightLevel(ToIntFunction<BlockState> lightLevelFunction);
|
||||
|
||||
@Invoker
|
||||
Block.Settings invokeBreakInstantly();
|
||||
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.mixin.object.builder;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
import org.spongepowered.asm.mixin.gen.Invoker;
|
||||
|
||||
import net.minecraft.util.registry.RegistryKey;
|
||||
import net.minecraft.village.VillagerType;
|
||||
import net.minecraft.world.biome.Biome;
|
||||
|
||||
@Mixin(VillagerType.class)
|
||||
public interface VillagerTypeAccessor {
|
||||
@Accessor("BIOME_TO_TYPE")
|
||||
static Map<RegistryKey<Biome>, VillagerType> getBiomeTypeToIdMap() {
|
||||
throw new AssertionError("Untransformed Accessor!");
|
||||
}
|
||||
|
||||
// FIXME: This should be called `register` in yarn
|
||||
@Invoker("create")
|
||||
static VillagerType callRegister(String id) {
|
||||
throw new AssertionError("Untransformed Accessor!");
|
||||
}
|
||||
}
|
|
@ -16,7 +16,8 @@
|
|||
"TradeOffersAccessor",
|
||||
"TradeOffersMixin",
|
||||
"TypeAwareTradeMixin",
|
||||
"VillagerProfessionAccessor"
|
||||
"VillagerProfessionAccessor",
|
||||
"VillagerTypeAccessor"
|
||||
],
|
||||
"client": [
|
||||
"ModelPredicateProviderRegistryAccessor",
|
||||
|
|
|
@ -67,7 +67,7 @@ public final class BlockSettingsExtensions {
|
|||
}
|
||||
|
||||
public static void lightLevel(Settings settings, int lightLevel) {
|
||||
((AbstractBlockSettingsAccessor) settings).invokeLightLevel(ignored -> lightLevel);
|
||||
((AbstractBlockSettingsAccessor) settings).setLuminanceFunction(ignored -> lightLevel);
|
||||
}
|
||||
|
||||
public static void breakInstantly(Settings settings) {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
archivesBaseName = "fabric-registry-sync-v0"
|
||||
version = getSubprojectVersion(project, "0.5.2")
|
||||
version = getSubprojectVersion(project, "0.6.0")
|
||||
|
||||
dependencies {
|
||||
compile project(path: ':fabric-api-base', configuration: 'dev')
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.api.event.registry;
|
||||
|
||||
import net.minecraft.util.registry.DynamicRegistryManager;
|
||||
|
||||
import net.fabricmc.fabric.api.event.Event;
|
||||
import net.fabricmc.fabric.api.event.EventFactory;
|
||||
|
||||
/**
|
||||
* This event gets triggered when a new {@link DynamicRegistryManager} gets created, but before it gets filled.
|
||||
* Therefore, this is the ideal place to register callbacks to dynamic registries.
|
||||
* For example, the following code is used to register a callback that gets triggered for any registered Biome, both JSON and code defined.
|
||||
*
|
||||
* <pre>
|
||||
* {@code
|
||||
* DynamicRegistrySetupCallback.EVENT.register(registryManager -> {
|
||||
* Registry<Biome> biomes = registryManager.get(Registry.BIOME_KEY);
|
||||
* RegistryEntryAddedCallback.event(biomes).register((rawId, id, object) -> {
|
||||
* // Do something
|
||||
* });
|
||||
* });
|
||||
* }
|
||||
* </pre>
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface DynamicRegistrySetupCallback {
|
||||
void onRegistrySetup(DynamicRegistryManager registryManager);
|
||||
|
||||
Event<DynamicRegistrySetupCallback> EVENT = EventFactory.createArrayBacked(
|
||||
DynamicRegistrySetupCallback.class,
|
||||
callbacks -> registryManager -> {
|
||||
for (DynamicRegistrySetupCallback callback : callbacks) {
|
||||
callback.onRegistrySetup(registryManager);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.mixin.registry.sync;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
|
||||
|
||||
import net.minecraft.util.registry.DynamicRegistryManager;
|
||||
|
||||
import net.fabricmc.fabric.api.event.registry.DynamicRegistrySetupCallback;
|
||||
|
||||
@Mixin(DynamicRegistryManager.class)
|
||||
public class DynamicRegistryManagerMixin {
|
||||
@Inject(method = "create", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/dynamic/RegistryOps$EntryLoader$Impl;<init>()V"), locals = LocalCapture.CAPTURE_FAILHARD)
|
||||
private static void onCreateImpl(CallbackInfoReturnable<DynamicRegistryManager.Impl> cir, DynamicRegistryManager.Impl registryManager) {
|
||||
DynamicRegistrySetupCallback.EVENT.invoker().onRegistrySetup(registryManager);
|
||||
}
|
||||
}
|
|
@ -45,8 +45,8 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
|||
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
import net.minecraft.util.registry.SimpleRegistry;
|
||||
import net.minecraft.util.registry.RegistryKey;
|
||||
import net.minecraft.util.registry.SimpleRegistry;
|
||||
|
||||
import net.fabricmc.fabric.api.event.Event;
|
||||
import net.fabricmc.fabric.api.event.EventFactory;
|
||||
|
@ -132,8 +132,8 @@ public abstract class MixinIdRegistry<T> extends Registry<T> implements Remappab
|
|||
@Unique
|
||||
private boolean fabric_isObjectNew = false;
|
||||
|
||||
@Inject(method = "set", at = @At("HEAD"))
|
||||
public void setPre(int id, RegistryKey<T> registryId, T object, Lifecycle lifecycle, CallbackInfoReturnable<T> info) {
|
||||
@Inject(method = "set(ILnet/minecraft/util/registry/RegistryKey;Ljava/lang/Object;Lcom/mojang/serialization/Lifecycle;Z)Ljava/lang/Object;", at = @At("HEAD"))
|
||||
public void setPre(int id, RegistryKey<T> registryId, T object, Lifecycle lifecycle, boolean checkDuplicateKeys, CallbackInfoReturnable<T> info) {
|
||||
int indexedEntriesId = entryToRawId.getInt(object);
|
||||
|
||||
if (indexedEntriesId >= 0) {
|
||||
|
@ -148,7 +148,7 @@ public abstract class MixinIdRegistry<T> extends Registry<T> implements Remappab
|
|||
if (oldObject != null && oldObject != object) {
|
||||
int oldId = entryToRawId.getInt(oldObject);
|
||||
|
||||
if (oldId != id) {
|
||||
if (oldId != id && checkDuplicateKeys) {
|
||||
throw new RuntimeException("Attempted to register ID " + registryId + " at different raw IDs (" + oldId + ", " + id + ")! If you're trying to override an item, use .set(), not .register()!");
|
||||
}
|
||||
|
||||
|
@ -160,8 +160,8 @@ public abstract class MixinIdRegistry<T> extends Registry<T> implements Remappab
|
|||
}
|
||||
}
|
||||
|
||||
@Inject(method = "set", at = @At("RETURN"))
|
||||
public void setPost(int id, RegistryKey<T> registryId, T object, Lifecycle lifecycle, CallbackInfoReturnable<T> info) {
|
||||
@Inject(method = "set(ILnet/minecraft/util/registry/RegistryKey;Ljava/lang/Object;Lcom/mojang/serialization/Lifecycle;Z)Ljava/lang/Object;", at = @At("RETURN"))
|
||||
public void setPost(int id, RegistryKey<T> registryId, T object, Lifecycle lifecycle, boolean checkDuplicateKeys, CallbackInfoReturnable<T> info) {
|
||||
if (fabric_isObjectNew) {
|
||||
fabric_addObjectEvent.invoker().onEntryAdded(id, registryId.getValue(), object);
|
||||
}
|
||||
|
|
|
@ -129,7 +129,7 @@ public class MixinLevelStorageSession {
|
|||
}
|
||||
}
|
||||
|
||||
@Inject(method = "method_27426", at = @At("HEAD"))
|
||||
@Inject(method = "backupLevelDataFile(Lnet/minecraft/util/registry/DynamicRegistryManager;Lnet/minecraft/world/SaveProperties;Lnet/minecraft/nbt/CompoundTag;)V", at = @At("HEAD"))
|
||||
public void saveWorld(DynamicRegistryManager registryTracker, SaveProperties saveProperties, CompoundTag compoundTag, CallbackInfo info) {
|
||||
if (!Files.exists(directory)) {
|
||||
return;
|
||||
|
|
|
@ -11,7 +11,8 @@
|
|||
"MixinPlayerManager",
|
||||
"MixinLevelStorageSession",
|
||||
"MixinRegistry",
|
||||
"MixinSimpleRegistry"
|
||||
"MixinSimpleRegistry",
|
||||
"DynamicRegistryManagerMixin"
|
||||
],
|
||||
"client": [
|
||||
"client.MixinBlockColorMap",
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
"FabricMC"
|
||||
],
|
||||
"depends": {
|
||||
"fabricloader": ">=0.4.0",
|
||||
"fabricloader": ">=0.9.2",
|
||||
"fabric-api-base": "*",
|
||||
"fabric-networking-v0": "*"
|
||||
},
|
||||
|
|
|
@ -34,9 +34,11 @@ import net.minecraft.world.gen.feature.DefaultFeatureConfig;
|
|||
import net.minecraft.world.gen.feature.Feature;
|
||||
|
||||
import net.fabricmc.api.ModInitializer;
|
||||
import net.fabricmc.fabric.api.event.registry.DynamicRegistrySetupCallback;
|
||||
import net.fabricmc.fabric.api.event.registry.FabricRegistryBuilder;
|
||||
import net.fabricmc.fabric.api.event.registry.RegistryAttribute;
|
||||
import net.fabricmc.fabric.api.event.registry.RegistryAttributeHolder;
|
||||
import net.fabricmc.fabric.api.event.registry.RegistryEntryAddedCallback;
|
||||
|
||||
public class RegistrySyncTest implements ModInitializer {
|
||||
/**
|
||||
|
@ -73,9 +75,17 @@ public class RegistrySyncTest implements ModInitializer {
|
|||
|
||||
Registry.register(fabricRegistry, new Identifier("registry_sync", "test"), "test");
|
||||
|
||||
Validate.isTrue(Registry.REGISTRIES.getIds().contains(new Identifier("registry_sync", "fabric_registry")));
|
||||
|
||||
Validate.isTrue(RegistryAttributeHolder.get(fabricRegistry).hasAttribute(RegistryAttribute.MODDED));
|
||||
Validate.isTrue(RegistryAttributeHolder.get(fabricRegistry).hasAttribute(RegistryAttribute.SYNCED));
|
||||
Validate.isTrue(!RegistryAttributeHolder.get(fabricRegistry).hasAttribute(RegistryAttribute.PERSISTED));
|
||||
|
||||
DynamicRegistrySetupCallback.EVENT.register(registryManager -> {
|
||||
RegistryEntryAddedCallback.event(registryManager.get(Registry.BIOME_KEY)).register((rawId, id, object) -> {
|
||||
System.out.println(id);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
archivesBaseName = "fabric-renderer-api-v1"
|
||||
version = getSubprojectVersion(project, "0.3.1")
|
||||
version = getSubprojectVersion(project, "0.3.2")
|
||||
|
||||
dependencies {
|
||||
compile project(path: ':fabric-api-base', configuration: 'dev')
|
||||
|
|
|
@ -157,10 +157,10 @@ public interface QuadEmitter extends MutableQuadView {
|
|||
right = 1 - right;
|
||||
|
||||
case NORTH:
|
||||
pos(0, right, top, depth);
|
||||
pos(1, right, bottom, depth);
|
||||
pos(2, left, bottom, depth);
|
||||
pos(3, left, top, depth);
|
||||
pos(0, 1 - left, top, depth);
|
||||
pos(1, 1 - left, bottom, depth);
|
||||
pos(2, 1 - right, bottom, depth);
|
||||
pos(3, 1 - right, top, depth);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -74,7 +74,7 @@ public abstract class ModelHelper {
|
|||
* <p>Retrieves sprites from the block texture atlas via {@link SpriteFinder}.
|
||||
*/
|
||||
public static List<BakedQuad>[] toQuadLists(Mesh mesh) {
|
||||
SpriteFinder finder = SpriteFinder.get(MinecraftClient.getInstance().getBakedModelManager().method_24153(SpriteAtlasTexture.BLOCK_ATLAS_TEX));
|
||||
SpriteFinder finder = SpriteFinder.get(MinecraftClient.getInstance().getBakedModelManager().method_24153(SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE));
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
final ImmutableList.Builder<BakedQuad>[] builders = new ImmutableList.Builder[7];
|
||||
|
|
|
@ -134,7 +134,7 @@ public class SpriteFinderImpl implements SpriteFinder {
|
|||
} else if (quadrant instanceof Node) {
|
||||
return ((Node) quadrant).find(u, v);
|
||||
} else {
|
||||
return MinecraftClient.getInstance().getSpriteAtlas(SpriteAtlasTexture.BLOCK_ATLAS_TEX).apply(MissingSprite.getMissingSpriteId());
|
||||
return MinecraftClient.getInstance().getSpriteAtlas(SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE).apply(MissingSprite.getMissingSpriteId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
archivesBaseName = "fabric-renderer-indigo"
|
||||
version = getSubprojectVersion(project, "0.4.1")
|
||||
version = getSubprojectVersion(project, "0.4.2")
|
||||
|
||||
dependencies {
|
||||
compile project(path: ':fabric-api-base', configuration: 'dev')
|
||||
|
|
|
@ -104,6 +104,6 @@ public class TextureHelper {
|
|||
UVLOCKERS[Direction.NORTH.getId()] = (q, i, t) -> q.sprite(i, t, 1 - q.x(i), 1 - q.y(i));
|
||||
UVLOCKERS[Direction.SOUTH.getId()] = (q, i, t) -> q.sprite(i, t, q.x(i), 1 - q.y(i));
|
||||
UVLOCKERS[Direction.DOWN.getId()] = (q, i, t) -> q.sprite(i, t, q.x(i), 1 - q.z(i));
|
||||
UVLOCKERS[Direction.UP.getId()] = (q, i, t) -> q.sprite(i, t, q.x(i), 1 - q.z(i));
|
||||
UVLOCKERS[Direction.UP.getId()] = (q, i, t) -> q.sprite(i, t, q.x(i), q.z(i));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -132,7 +132,7 @@ public class ItemRenderContext extends AbstractRenderContext implements RenderCo
|
|||
*/
|
||||
private VertexConsumer selectVertexConsumer(RenderLayer layerIn) {
|
||||
final RenderLayer layer = transformMode == ModelTransformation.Mode.GUI ? TexturedRenderLayers.getEntityTranslucentCull() : layerIn;
|
||||
return ItemRenderer.getArmorVertexConsumer(vertexConsumerProvider, layer, true, itemStack.hasGlint());
|
||||
return ItemRenderer.getArmorGlintConsumer(vertexConsumerProvider, layer, true, itemStack.hasGlint());
|
||||
}
|
||||
|
||||
private class Maker extends MutableQuadViewImpl implements QuadEmitter {
|
||||
|
|
|
@ -53,7 +53,7 @@ public interface ClientSpriteRegistryCallback {
|
|||
*/
|
||||
@Deprecated
|
||||
static void registerBlockAtlas(ClientSpriteRegistryCallback callback) {
|
||||
event(SpriteAtlasTexture.BLOCK_ATLAS_TEX).register(callback);
|
||||
event(SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE).register(callback);
|
||||
}
|
||||
|
||||
class Registry {
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
archivesBaseName = "fabric-tool-attribute-api-v1"
|
||||
version = getSubprojectVersion(project, "1.2.3")
|
||||
version = getSubprojectVersion(project, "1.2.4")
|
||||
|
||||
dependencies {
|
||||
compile project(path: ':fabric-api-base', configuration: 'dev')
|
||||
compile project(path: ':fabric-tag-extensions-v0', configuration: 'dev')
|
||||
testmodCompile project(path: ':fabric-object-builder-api-v1', configuration: 'dev')
|
||||
testmodCompile project(path: ':fabric-events-lifecycle-v0', configuration: 'dev')
|
||||
compile project(path: ':fabric-api-base', configuration: 'dev')
|
||||
compile project(path: ':fabric-tag-extensions-v0', configuration: 'dev')
|
||||
testmodCompile project(path: ':fabric-object-builder-api-v1', configuration: 'dev')
|
||||
testmodCompile project(path: ':fabric-lifecycle-events-v1', configuration: 'dev')
|
||||
}
|
||||
|
|
|
@ -107,7 +107,7 @@ public interface DynamicAttributeTool {
|
|||
/**
|
||||
* Add modifiers for any {@link net.minecraft.entity.attribute.EntityAttributes} your item should give when equipped, based on the stack.
|
||||
*
|
||||
* <p>Appends to either attribute modifier NBT or the result from {@link net.minecraft.item.Item#getModifiers(EquipmentSlot)}.</p>
|
||||
* <p>Appends to either attribute modifier NBT or the result from {@link net.minecraft.item.Item#getAttributeModifiers(EquipmentSlot)}.</p>
|
||||
*
|
||||
* @param slot The equipment slot this item is equipped in.
|
||||
* @param stack The stack that's equipped.
|
||||
|
|
|
@ -22,6 +22,7 @@ import java.util.IdentityHashMap;
|
|||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
|
@ -120,6 +121,7 @@ public final class ToolManagerImpl {
|
|||
|
||||
private static ToolHandler toolHandlerInvoker(ToolHandler[] toolHandlers) {
|
||||
return new ToolHandler() {
|
||||
@NotNull
|
||||
@Override
|
||||
public ActionResult isEffectiveOn(Tag<Item> tag, BlockState state, ItemStack stack, LivingEntity user) {
|
||||
for (ToolHandler toolHandler : toolHandlers) {
|
||||
|
@ -133,6 +135,7 @@ public final class ToolManagerImpl {
|
|||
return ActionResult.PASS;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public TypedActionResult<Float> getMiningSpeedMultiplier(Tag<Item> tag, BlockState state, ItemStack stack, LivingEntity user) {
|
||||
for (ToolHandler toolHandler : toolHandlers) {
|
||||
|
@ -152,6 +155,7 @@ public final class ToolManagerImpl {
|
|||
return ENTRIES.computeIfAbsent(block, (bb) -> new EntryImpl());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static Entry entryNullable(Block block) {
|
||||
return ENTRIES.get(block);
|
||||
}
|
||||
|
@ -240,6 +244,7 @@ public final class ToolManagerImpl {
|
|||
* @param user the user involved in breaking the block, null if not applicable.
|
||||
* @return the result of effectiveness
|
||||
*/
|
||||
@NotNull
|
||||
default ActionResult isEffectiveOn(Tag<Item> tag, BlockState state, ItemStack stack, @Nullable LivingEntity user) {
|
||||
return ActionResult.PASS;
|
||||
}
|
||||
|
@ -253,8 +258,9 @@ public final class ToolManagerImpl {
|
|||
* @param user the user involved in breaking the block, null if not applicable.
|
||||
* @return the result of mining speed.
|
||||
*/
|
||||
@NotNull
|
||||
default TypedActionResult<Float> getMiningSpeedMultiplier(Tag<Item> tag, BlockState state, ItemStack stack, @Nullable LivingEntity user) {
|
||||
return null;
|
||||
return TypedActionResult.pass(1.0F);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,8 @@
|
|||
|
||||
package net.fabricmc.fabric.impl.tool.attribute.handlers;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.item.Item;
|
||||
|
@ -34,6 +36,7 @@ import net.fabricmc.fabric.impl.tool.attribute.ToolManagerImpl;
|
|||
* <p>Only applicable to modded blocks that are registered, as only they have the registered required mining level.</p>
|
||||
*/
|
||||
public class ModdedToolsModdedBlocksToolHandler implements ToolManagerImpl.ToolHandler {
|
||||
@NotNull
|
||||
@Override
|
||||
public ActionResult isEffectiveOn(Tag<Item> tag, BlockState state, ItemStack stack, LivingEntity user) {
|
||||
if (stack.getItem() instanceof DynamicAttributeTool) {
|
||||
|
@ -50,6 +53,7 @@ public class ModdedToolsModdedBlocksToolHandler implements ToolManagerImpl.ToolH
|
|||
return ActionResult.PASS;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public TypedActionResult<Float> getMiningSpeedMultiplier(Tag<Item> tag, BlockState state, ItemStack stack, LivingEntity user) {
|
||||
if (stack.getItem() instanceof DynamicAttributeTool) {
|
||||
|
|
|
@ -18,6 +18,8 @@ package net.fabricmc.fabric.impl.tool.attribute.handlers;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.item.Item;
|
||||
|
@ -50,6 +52,7 @@ public class ModdedToolsVanillaBlocksToolHandler implements ToolManagerImpl.Tool
|
|||
return (ToolItem) vanillaItems.get(miningLevel);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ActionResult isEffectiveOn(Tag<Item> tag, BlockState state, ItemStack stack, LivingEntity user) {
|
||||
if (stack.getItem() instanceof DynamicAttributeTool) {
|
||||
|
@ -69,6 +72,7 @@ public class ModdedToolsVanillaBlocksToolHandler implements ToolManagerImpl.Tool
|
|||
return ActionResult.PASS;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public TypedActionResult<Float> getMiningSpeedMultiplier(Tag<Item> tag, BlockState state, ItemStack stack, LivingEntity user) {
|
||||
if (stack.getItem() instanceof DynamicAttributeTool) {
|
||||
|
|
|
@ -16,6 +16,8 @@
|
|||
|
||||
package net.fabricmc.fabric.impl.tool.attribute.handlers;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.item.Item;
|
||||
|
@ -41,6 +43,7 @@ import net.fabricmc.fabric.impl.tool.attribute.ToolManagerImpl;
|
|||
public class ShearsVanillaBlocksToolHandler implements ToolManagerImpl.ToolHandler {
|
||||
private final Item vanillaItem = Items.SHEARS;
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ActionResult isEffectiveOn(Tag<Item> tag, BlockState state, ItemStack stack, LivingEntity user) {
|
||||
if (ToolManagerImpl.entryNullable(state.getBlock()) != null) {
|
||||
|
@ -59,6 +62,7 @@ public class ShearsVanillaBlocksToolHandler implements ToolManagerImpl.ToolHandl
|
|||
return ActionResult.PASS;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public TypedActionResult<Float> getMiningSpeedMultiplier(Tag<Item> tag, BlockState state, ItemStack stack, LivingEntity user) {
|
||||
float speed = 1.0F;
|
||||
|
|
|
@ -16,6 +16,8 @@
|
|||
|
||||
package net.fabricmc.fabric.impl.tool.attribute.handlers;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.item.Item;
|
||||
|
@ -36,6 +38,7 @@ import net.fabricmc.fabric.impl.tool.attribute.ToolManagerImpl;
|
|||
* <p>Only applicable to modded blocks that are registered, as only they have the registered required mining level.</p>
|
||||
*/
|
||||
public class VanillaToolsModdedBlocksToolHandler implements ToolManagerImpl.ToolHandler {
|
||||
@NotNull
|
||||
@Override
|
||||
public ActionResult isEffectiveOn(Tag<Item> tag, BlockState state, ItemStack stack, LivingEntity user) {
|
||||
if (!(stack.getItem() instanceof DynamicAttributeTool)) {
|
||||
|
@ -51,12 +54,13 @@ public class VanillaToolsModdedBlocksToolHandler implements ToolManagerImpl.Tool
|
|||
return ActionResult.PASS;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public TypedActionResult<Float> getMiningSpeedMultiplier(Tag<Item> tag, BlockState state, ItemStack stack, LivingEntity user) {
|
||||
if (!(stack.getItem() instanceof DynamicAttributeTool)) {
|
||||
ToolManagerImpl.Entry entry = ToolManagerImpl.entryNullable(state.getBlock());
|
||||
|
||||
if (entry != null && entry.getMiningLevel(tag) >= 0 && tag.contains(stack.getItem())) {
|
||||
if (entry != null && entry.getMiningLevel(tag) >= 0) {
|
||||
float multiplier = stack.getItem() instanceof ToolItem ? ((ToolItem) stack.getItem()).getMaterial().getMiningSpeedMultiplier() : stack.getItem().getMiningSpeedMultiplier(stack, state);
|
||||
if (multiplier != 1.0F) return TypedActionResult.success(multiplier);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implementation handlers of the fabric tool attribute module.
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
package net.fabricmc.fabric.impl.tool.attribute.handlers;
|
||||
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implementation of the fabric tool attribute module.
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
package net.fabricmc.fabric.impl.tool.attribute;
|
||||
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
|
@ -27,6 +27,7 @@ import net.minecraft.item.Item;
|
|||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.item.ToolItem;
|
||||
import net.minecraft.item.ToolMaterials;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.sound.BlockSoundGroup;
|
||||
import net.minecraft.tag.Tag;
|
||||
|
@ -34,15 +35,18 @@ import net.minecraft.util.Identifier;
|
|||
import net.minecraft.util.registry.Registry;
|
||||
|
||||
import net.fabricmc.api.ModInitializer;
|
||||
import net.fabricmc.fabric.api.event.server.ServerTickCallback;
|
||||
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents;
|
||||
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
||||
import net.fabricmc.fabric.api.object.builder.v1.block.FabricMaterialBuilder;
|
||||
import net.fabricmc.fabric.api.tag.TagRegistry;
|
||||
import net.fabricmc.fabric.api.tool.attribute.v1.DynamicAttributeTool;
|
||||
import net.fabricmc.fabric.api.tool.attribute.v1.FabricToolTags;
|
||||
|
||||
public class ToolAttributeTest implements ModInitializer {
|
||||
private static final float DEFAULT_BREAK_SPEED = 1.0F;
|
||||
private static final float TOOL_BREAK_SPEED = 10.0F;
|
||||
// A custom tool type, taters
|
||||
private static final Tag<Item> TATER = TagRegistry.item(new Identifier("fabric-tool-attribute-api-v1-testmod", "taters"));
|
||||
|
||||
private boolean hasValidated = false;
|
||||
|
||||
|
@ -51,12 +55,18 @@ public class ToolAttributeTest implements ModInitializer {
|
|||
Item testShovel;
|
||||
Item testPickaxe;
|
||||
|
||||
Item testStoneLevelTater;
|
||||
Item testStoneDynamicLevelTater;
|
||||
Item testDiamondLevelTater;
|
||||
Item testDiamondDynamicLevelTater;
|
||||
Block taterEffectiveBlock;
|
||||
|
||||
@Override
|
||||
public void onInitialize() {
|
||||
// Register a custom shovel that has a mining level of 2 (iron) dynamically.
|
||||
testShovel = Registry.register(Registry.ITEM, new Identifier("fabric-tool-attribute-api-v1-testmod", "test_shovel"), new TestTool(new Item.Settings(), FabricToolTags.SHOVELS));
|
||||
testShovel = Registry.register(Registry.ITEM, new Identifier("fabric-tool-attribute-api-v1-testmod", "test_shovel"), new TestTool(new Item.Settings(), FabricToolTags.SHOVELS, 2));
|
||||
//Register a custom pickaxe that has a mining level of 2 (iron) dynamically.
|
||||
testPickaxe = Registry.register(Registry.ITEM, new Identifier("fabric-tool-attribute-api-v1-testmod", "test_pickaxe"), new TestTool(new Item.Settings(), FabricToolTags.PICKAXES));
|
||||
testPickaxe = Registry.register(Registry.ITEM, new Identifier("fabric-tool-attribute-api-v1-testmod", "test_pickaxe"), new TestTool(new Item.Settings(), FabricToolTags.PICKAXES, 2));
|
||||
// Register a block that requires a shovel that is as strong or stronger than an iron one.
|
||||
gravelBlock = Registry.register(Registry.BLOCK, new Identifier("fabric-tool-attribute-api-v1-testmod", "hardened_gravel_block"),
|
||||
new Block(FabricBlockSettings.of(new FabricMaterialBuilder(MaterialColor.SAND).build(), MaterialColor.STONE)
|
||||
|
@ -74,7 +84,24 @@ public class ToolAttributeTest implements ModInitializer {
|
|||
.sounds(BlockSoundGroup.STONE)));
|
||||
Registry.register(Registry.ITEM, new Identifier("fabric-tool-attribute-api-v1-testmod", "hardened_stone_block"), new BlockItem(stoneBlock, new Item.Settings()));
|
||||
|
||||
ServerTickCallback.EVENT.register(this::validate);
|
||||
// Register a tater that has a mining level of 1 (stone).
|
||||
testStoneLevelTater = Registry.register(Registry.ITEM, new Identifier("fabric-tool-attribute-api-v1-testmod", "test_stone_level_tater"), new ToolItem(ToolMaterials.STONE, new Item.Settings()));
|
||||
// Register a tater that has a mining level of 1 (stone) dynamically.
|
||||
testStoneDynamicLevelTater = Registry.register(Registry.ITEM, new Identifier("fabric-tool-attribute-api-v1-testmod", "test_stone_dynamic_level_tater"), new TestTool(new Item.Settings(), TATER, 1));
|
||||
//Register a tater that has a mining level of 3 (diamond).
|
||||
testDiamondLevelTater = Registry.register(Registry.ITEM, new Identifier("fabric-tool-attribute-api-v1-testmod", "test_diamond_level_tater"), new ToolItem(ToolMaterials.DIAMOND, new Item.Settings()));
|
||||
//Register a tater that has a mining level of 3 (diamond) dynamically.
|
||||
testDiamondDynamicLevelTater = Registry.register(Registry.ITEM, new Identifier("fabric-tool-attribute-api-v1-testmod", "test_diamond_dynamic_level_tater"), new TestTool(new Item.Settings(), TATER, 3));
|
||||
|
||||
taterEffectiveBlock = Registry.register(Registry.BLOCK, new Identifier("fabric-tool-attribute-api-v1-testmod", "tater_effective_block"),
|
||||
new Block(FabricBlockSettings.of(Material.ORGANIC_PRODUCT, MaterialColor.ORANGE)
|
||||
.breakByTool(TATER, 2) // requires iron tater
|
||||
.requiresTool()
|
||||
.strength(0.6F)
|
||||
.sounds(BlockSoundGroup.CROP)));
|
||||
Registry.register(Registry.ITEM, new Identifier("fabric-tool-attribute-api-v1-testmod", "tater_effective_block"), new BlockItem(taterEffectiveBlock, new Item.Settings()));
|
||||
|
||||
ServerTickEvents.START_SERVER_TICK.register(this::validate);
|
||||
}
|
||||
|
||||
private void validate(MinecraftServer server) {
|
||||
|
@ -117,6 +144,18 @@ public class ToolAttributeTest implements ModInitializer {
|
|||
testToolOnBlock(new ItemStack(testShovel), Blocks.GRAVEL, false, TOOL_BREAK_SPEED);
|
||||
testToolOnBlock(new ItemStack(testPickaxe), Blocks.GRAVEL, false, DEFAULT_BREAK_SPEED);
|
||||
testToolOnBlock(new ItemStack(testPickaxe), Blocks.STONE, true, TOOL_BREAK_SPEED);
|
||||
|
||||
//Test taters respect our tater block
|
||||
testToolOnBlock(new ItemStack(testDiamondDynamicLevelTater), taterEffectiveBlock, true, TOOL_BREAK_SPEED);
|
||||
testToolOnBlock(new ItemStack(testDiamondLevelTater), taterEffectiveBlock, true, ToolMaterials.DIAMOND.getMiningSpeedMultiplier());
|
||||
testToolOnBlock(new ItemStack(testStoneDynamicLevelTater), taterEffectiveBlock, false, TOOL_BREAK_SPEED);
|
||||
testToolOnBlock(new ItemStack(testStoneLevelTater), taterEffectiveBlock, false, ToolMaterials.STONE.getMiningSpeedMultiplier());
|
||||
|
||||
//Test other tools on our tater block
|
||||
testToolOnBlock(new ItemStack(testPickaxe), taterEffectiveBlock, false, DEFAULT_BREAK_SPEED);
|
||||
testToolOnBlock(new ItemStack(testShovel), taterEffectiveBlock, false, DEFAULT_BREAK_SPEED);
|
||||
testToolOnBlock(new ItemStack(Items.IRON_PICKAXE), taterEffectiveBlock, false, DEFAULT_BREAK_SPEED);
|
||||
testToolOnBlock(new ItemStack(Items.IRON_SHOVEL), taterEffectiveBlock, false, DEFAULT_BREAK_SPEED);
|
||||
}
|
||||
|
||||
private void testToolOnBlock(ItemStack item, Block block, boolean inEffective, float inSpeed) {
|
||||
|
@ -132,16 +171,18 @@ public class ToolAttributeTest implements ModInitializer {
|
|||
|
||||
private static class TestTool extends Item implements DynamicAttributeTool {
|
||||
final Tag<Item> toolType;
|
||||
final int miningLevel;
|
||||
|
||||
private TestTool(Settings settings, Tag<Item> toolType) {
|
||||
private TestTool(Settings settings, Tag<Item> toolType, int miningLevel) {
|
||||
super(settings);
|
||||
this.toolType = toolType;
|
||||
this.miningLevel = miningLevel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMiningLevel(Tag<Item> tag, BlockState state, ItemStack stack, LivingEntity user) {
|
||||
if (tag.equals(toolType)) {
|
||||
return 2;
|
||||
return this.miningLevel;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"replace": false,
|
||||
"values": [
|
||||
"fabric-tool-attribute-api-v1-testmod:test_stone_level_tater",
|
||||
"fabric-tool-attribute-api-v1-testmod:test_stone_dynamic_level_tater",
|
||||
"fabric-tool-attribute-api-v1-testmod:test_diamond_level_tater",
|
||||
"fabric-tool-attribute-api-v1-testmod:test_diamond_dynamic_level_tater"
|
||||
]
|
||||
}
|
Loading…
Add table
Reference in a new issue