feat: working custom arch. cutter machine
This commit is contained in:
parent
4c3f441f41
commit
69b8c79e57
32 changed files with 1334 additions and 93 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -20,3 +20,4 @@ hs_err_pid*
|
||||||
# Common working directory
|
# Common working directory
|
||||||
run
|
run
|
||||||
/repo/
|
/repo/
|
||||||
|
/.kotlin/
|
||||||
|
|
|
||||||
56
build.gradle
56
build.gradle
|
|
@ -42,7 +42,6 @@ java.toolchain.languageVersion = JavaLanguageVersion.of(21)
|
||||||
kotlin.jvmToolchain(21)
|
kotlin.jvmToolchain(21)
|
||||||
|
|
||||||
neoForge {
|
neoForge {
|
||||||
// Specify the version of NeoForge to use.
|
|
||||||
version = project.neo_version
|
version = project.neo_version
|
||||||
|
|
||||||
parchment {
|
parchment {
|
||||||
|
|
@ -50,16 +49,10 @@ neoForge {
|
||||||
minecraftVersion = project.parchment_minecraft_version
|
minecraftVersion = project.parchment_minecraft_version
|
||||||
}
|
}
|
||||||
|
|
||||||
// This line is optional. Access Transformers are automatically detected
|
|
||||||
// accessTransformers.add('src/main/resources/META-INF/accesstransformer.cfg')
|
|
||||||
|
|
||||||
// Default run configurations.
|
|
||||||
// These can be tweaked, removed, or duplicated as needed.
|
|
||||||
runs {
|
runs {
|
||||||
client {
|
client {
|
||||||
client()
|
client()
|
||||||
|
|
||||||
// Comma-separated list of namespaces to load gametests from. Empty = all namespaces.
|
|
||||||
systemProperty 'neoforge.enabledGameTestNamespaces', project.mod_id
|
systemProperty 'neoforge.enabledGameTestNamespaces', project.mod_id
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -69,9 +62,6 @@ neoForge {
|
||||||
systemProperty 'neoforge.enabledGameTestNamespaces', project.mod_id
|
systemProperty 'neoforge.enabledGameTestNamespaces', project.mod_id
|
||||||
}
|
}
|
||||||
|
|
||||||
// This run config launches GameTestServer and runs all registered gametests, then exits.
|
|
||||||
// By default, the server will crash when no gametests are provided.
|
|
||||||
// The gametest system is also enabled by default for other run configs under the /test command.
|
|
||||||
gameTestServer {
|
gameTestServer {
|
||||||
type = "gameTestServer"
|
type = "gameTestServer"
|
||||||
systemProperty 'neoforge.enabledGameTestNamespaces', project.mod_id
|
systemProperty 'neoforge.enabledGameTestNamespaces', project.mod_id
|
||||||
|
|
@ -80,41 +70,23 @@ neoForge {
|
||||||
data {
|
data {
|
||||||
data()
|
data()
|
||||||
|
|
||||||
// example of overriding the workingDirectory set in configureEach above, uncomment if you want to use it
|
|
||||||
// gameDirectory = project.file('run-data')
|
|
||||||
|
|
||||||
// Specify the modid for data generation, where to output the resulting resource, and where to look for existing resources.
|
|
||||||
programArguments.addAll '--mod', project.mod_id, '--all', '--output', file('src/generated/resources/').getAbsolutePath(), '--existing', file('src/main/resources/').getAbsolutePath()
|
programArguments.addAll '--mod', project.mod_id, '--all', '--output', file('src/generated/resources/').getAbsolutePath(), '--existing', file('src/main/resources/').getAbsolutePath()
|
||||||
}
|
}
|
||||||
|
|
||||||
// applies to all the run configs above
|
|
||||||
configureEach {
|
configureEach {
|
||||||
// Recommended logging data for a userdev environment
|
|
||||||
// The markers can be added/remove as needed separated by commas.
|
|
||||||
// "SCAN": For mods scan.
|
|
||||||
// "REGISTRIES": For firing of registry events.
|
|
||||||
// "REGISTRYDUMP": For getting the contents of all registries.
|
|
||||||
systemProperty 'forge.logging.markers', 'REGISTRIES'
|
systemProperty 'forge.logging.markers', 'REGISTRIES'
|
||||||
|
|
||||||
// Recommended logging level for the console
|
|
||||||
// You can set various levels here.
|
|
||||||
// Please read: https://stackoverflow.com/questions/2031163/when-to-use-the-different-log-levels
|
|
||||||
logLevel = org.slf4j.event.Level.DEBUG
|
logLevel = org.slf4j.event.Level.DEBUG
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mods {
|
mods {
|
||||||
// define mod <-> source bindings
|
|
||||||
// these are used to tell the game which sources are for which mod
|
|
||||||
// mostly optional in a single mod project
|
|
||||||
// but multi mod projects should define one per mod
|
|
||||||
"${mod_id}" {
|
"${mod_id}" {
|
||||||
sourceSet(sourceSets.main)
|
sourceSet(sourceSets.main)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Include resources generated by data generators.
|
|
||||||
sourceSets.main.resources { srcDir 'src/generated/resources' }
|
sourceSets.main.resources { srcDir 'src/generated/resources' }
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -135,31 +107,8 @@ dependencies {
|
||||||
runtimeOnly "curse.maven:sophisticated-core-618298:8046952"
|
runtimeOnly "curse.maven:sophisticated-core-618298:8046952"
|
||||||
runtimeOnly "curse.maven:sophisticated-storage-619320:8034906"
|
runtimeOnly "curse.maven:sophisticated-storage-619320:8034906"
|
||||||
runtimeOnly "curse.maven:pocket-storage-367734:6834323"
|
runtimeOnly "curse.maven:pocket-storage-367734:6834323"
|
||||||
|
|
||||||
// Example mod dependency with JEI
|
|
||||||
// The JEI API is declared for compile time use, while the full JEI artifact is used at runtime
|
|
||||||
// compileOnly "mezz.jei:jei-${mc_version}-common-api:${jei_version}"
|
|
||||||
// compileOnly "mezz.jei:jei-${mc_version}-forge-api:${jei_version}"
|
|
||||||
// runtimeOnly "mezz.jei:jei-${mc_version}-forge:${jei_version}"
|
|
||||||
|
|
||||||
// Example mod dependency using a mod jar from ./libs with a flat dir repository
|
|
||||||
// This maps to ./libs/coolmod-${mc_version}-${coolmod_version}.jar
|
|
||||||
// The group id is ignored when searching -- in this case, it is "blank"
|
|
||||||
// implementation "blank:coolmod-${mc_version}:${coolmod_version}"
|
|
||||||
|
|
||||||
// Example mod dependency using a file as dependency
|
|
||||||
// implementation files("libs/coolmod-${mc_version}-${coolmod_version}.jar")
|
|
||||||
|
|
||||||
// Example project dependency using a sister or child project:
|
|
||||||
// implementation project(":myproject")
|
|
||||||
|
|
||||||
// For more info:
|
|
||||||
// http://www.gradle.org/docs/current/userguide/artifact_dependencies_tutorial.html
|
|
||||||
// http://www.gradle.org/docs/current/userguide/dependency_management.html
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// This block of code expands all declared replace properties in the specified resource targets.
|
|
||||||
// A missing property will result in an error. Properties are expanded using ${} Groovy notation.
|
|
||||||
var generateModMetadata = tasks.register("generateModMetadata", ProcessResources) {
|
var generateModMetadata = tasks.register("generateModMetadata", ProcessResources) {
|
||||||
var replaceProperties = [minecraft_version : minecraft_version,
|
var replaceProperties = [minecraft_version : minecraft_version,
|
||||||
minecraft_version_range: minecraft_version_range,
|
minecraft_version_range: minecraft_version_range,
|
||||||
|
|
@ -178,13 +127,9 @@ var generateModMetadata = tasks.register("generateModMetadata", ProcessResources
|
||||||
into "build/generated/sources/modMetadata"
|
into "build/generated/sources/modMetadata"
|
||||||
}
|
}
|
||||||
|
|
||||||
// Include the output of "generateModMetadata" as an input directory for the build
|
|
||||||
// this works with both building through Gradle and the IDE.
|
|
||||||
sourceSets.main.resources.srcDir generateModMetadata
|
sourceSets.main.resources.srcDir generateModMetadata
|
||||||
// To avoid having to run "generateModMetadata" manually, make it run on every project reload
|
|
||||||
neoForge.ideSyncTask generateModMetadata
|
neoForge.ideSyncTask generateModMetadata
|
||||||
|
|
||||||
// Example configuration to allow publishing using the maven-publish plugin
|
|
||||||
publishing {
|
publishing {
|
||||||
publications {
|
publications {
|
||||||
register('mavenJava', MavenPublication) {
|
register('mavenJava', MavenPublication) {
|
||||||
|
|
@ -198,7 +143,6 @@ publishing {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// IDEA no longer automatically downloads sources/javadoc jars for dependencies, so we need to explicitly enable the behavior.
|
|
||||||
idea {
|
idea {
|
||||||
module {
|
module {
|
||||||
downloadSources = true
|
downloadSources = true
|
||||||
|
|
|
||||||
104
mclschcannoncompat.ipr
Normal file
104
mclschcannoncompat.ipr
Normal file
|
|
@ -0,0 +1,104 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="CompilerConfiguration">
|
||||||
|
<option name="DEFAULT_COMPILER" value="Javac"/>
|
||||||
|
<resourceExtensions>
|
||||||
|
<entry name=".+\.(properties|xml|html|dtd|tld)"/>
|
||||||
|
<entry name=".+\.(gif|png|jpeg|jpg)"/>
|
||||||
|
</resourceExtensions>
|
||||||
|
<wildcardResourcePatterns>
|
||||||
|
<entry name="!?*.class"/>
|
||||||
|
<entry name="!?*.scala"/>
|
||||||
|
<entry name="!?*.groovy"/>
|
||||||
|
<entry name="!?*.java"/>
|
||||||
|
</wildcardResourcePatterns>
|
||||||
|
<annotationProcessing enabled="false" useClasspath="true"/>
|
||||||
|
<bytecodeTargetLevel target="21"/>
|
||||||
|
</component>
|
||||||
|
<component name="CopyrightManager" default="">
|
||||||
|
<module2copyright/>
|
||||||
|
</component>
|
||||||
|
<component name="DependencyValidationManager">
|
||||||
|
<option name="SKIP_IMPORT_STATEMENTS" value="false"/>
|
||||||
|
</component>
|
||||||
|
<component name="Encoding" useUTFGuessing="true" native2AsciiForPropertiesFiles="false"/>
|
||||||
|
<component name="GradleUISettings">
|
||||||
|
<setting name="root"/>
|
||||||
|
</component>
|
||||||
|
<component name="GradleUISettings2">
|
||||||
|
<setting name="root"/>
|
||||||
|
</component>
|
||||||
|
<component name="IdProvider" IDEtalkID="11DA1DB66DD62DDA1ED602B7079FE97C"/>
|
||||||
|
<component name="JavadocGenerationManager">
|
||||||
|
<option name="OUTPUT_DIRECTORY"/>
|
||||||
|
<option name="OPTION_SCOPE" value="protected"/>
|
||||||
|
<option name="OPTION_HIERARCHY" value="true"/>
|
||||||
|
<option name="OPTION_NAVIGATOR" value="true"/>
|
||||||
|
<option name="OPTION_INDEX" value="true"/>
|
||||||
|
<option name="OPTION_SEPARATE_INDEX" value="true"/>
|
||||||
|
<option name="OPTION_DOCUMENT_TAG_USE" value="false"/>
|
||||||
|
<option name="OPTION_DOCUMENT_TAG_AUTHOR" value="false"/>
|
||||||
|
<option name="OPTION_DOCUMENT_TAG_VERSION" value="false"/>
|
||||||
|
<option name="OPTION_DOCUMENT_TAG_DEPRECATED" value="true"/>
|
||||||
|
<option name="OPTION_DEPRECATED_LIST" value="true"/>
|
||||||
|
<option name="OTHER_OPTIONS" value=""/>
|
||||||
|
<option name="HEAP_SIZE"/>
|
||||||
|
<option name="LOCALE"/>
|
||||||
|
<option name="OPEN_IN_BROWSER" value="true"/>
|
||||||
|
</component>
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/mclschcannoncompat.iml" filepath="$PROJECT_DIR$/mclschcannoncompat.iml"/>
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" assert-keyword="true" jdk-15="true" project-jdk-type="JavaSDK" assert-jdk-15="true" project-jdk-name="21">
|
||||||
|
<output url="file://$PROJECT_DIR$/out"/>
|
||||||
|
</component>
|
||||||
|
<component name="SvnBranchConfigurationManager">
|
||||||
|
<option name="mySupportsUserInfoFilter" value="true"/>
|
||||||
|
</component>
|
||||||
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="" vcs=""/>
|
||||||
|
</component>
|
||||||
|
<component name="masterDetails">
|
||||||
|
<states>
|
||||||
|
<state key="ArtifactsStructureConfigurable.UI">
|
||||||
|
<UIState>
|
||||||
|
<splitter-proportions>
|
||||||
|
<SplitterProportionsDataImpl/>
|
||||||
|
</splitter-proportions>
|
||||||
|
<settings/>
|
||||||
|
</UIState>
|
||||||
|
</state>
|
||||||
|
<state key="Copyright.UI">
|
||||||
|
<UIState>
|
||||||
|
<splitter-proportions>
|
||||||
|
<SplitterProportionsDataImpl/>
|
||||||
|
</splitter-proportions>
|
||||||
|
</UIState>
|
||||||
|
</state>
|
||||||
|
<state key="ProjectJDKs.UI">
|
||||||
|
<UIState>
|
||||||
|
<splitter-proportions>
|
||||||
|
<SplitterProportionsDataImpl>
|
||||||
|
<option name="proportions">
|
||||||
|
<list>
|
||||||
|
<option value="0.2"/>
|
||||||
|
</list>
|
||||||
|
</option>
|
||||||
|
</SplitterProportionsDataImpl>
|
||||||
|
</splitter-proportions>
|
||||||
|
<last-edited>1.6</last-edited>
|
||||||
|
</UIState>
|
||||||
|
</state>
|
||||||
|
<state key="ScopeChooserConfigurable.UI">
|
||||||
|
<UIState>
|
||||||
|
<splitter-proportions>
|
||||||
|
<SplitterProportionsDataImpl/>
|
||||||
|
</splitter-proportions>
|
||||||
|
<settings/>
|
||||||
|
</UIState>
|
||||||
|
</state>
|
||||||
|
</states>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
207
mclschcannoncompat.iws
Normal file
207
mclschcannoncompat.iws
Normal file
|
|
@ -0,0 +1,207 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ChangeListManager">
|
||||||
|
<option name="TRACKING_ENABLED" value="true"/>
|
||||||
|
<option name="SHOW_DIALOG" value="false"/>
|
||||||
|
<option name="HIGHLIGHT_CONFLICTS" value="true"/>
|
||||||
|
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false"/>
|
||||||
|
<option name="LAST_RESOLUTION" value="IGNORE"/>
|
||||||
|
</component>
|
||||||
|
<component name="ChangesViewManager" flattened_view="true" show_ignored="false"/>
|
||||||
|
<component name="CreatePatchCommitExecutor">
|
||||||
|
<option name="PATCH_PATH" value=""/>
|
||||||
|
<option name="REVERSE_PATCH" value="false"/>
|
||||||
|
</component>
|
||||||
|
<component name="DaemonCodeAnalyzer">
|
||||||
|
<disable_hints/>
|
||||||
|
</component>
|
||||||
|
<component name="DebuggerManager">
|
||||||
|
<breakpoint_any>
|
||||||
|
<breakpoint>
|
||||||
|
<option name="NOTIFY_CAUGHT" value="true"/>
|
||||||
|
<option name="NOTIFY_UNCAUGHT" value="true"/>
|
||||||
|
<option name="ENABLED" value="false"/>
|
||||||
|
<option name="LOG_ENABLED" value="false"/>
|
||||||
|
<option name="LOG_EXPRESSION_ENABLED" value="false"/>
|
||||||
|
<option name="SUSPEND_POLICY" value="SuspendAll"/>
|
||||||
|
<option name="COUNT_FILTER_ENABLED" value="false"/>
|
||||||
|
<option name="COUNT_FILTER" value="0"/>
|
||||||
|
<option name="CONDITION_ENABLED" value="false"/>
|
||||||
|
<option name="CLASS_FILTERS_ENABLED" value="false"/>
|
||||||
|
<option name="INSTANCE_FILTERS_ENABLED" value="false"/>
|
||||||
|
<option name="CONDITION" value=""/>
|
||||||
|
<option name="LOG_MESSAGE" value=""/>
|
||||||
|
</breakpoint>
|
||||||
|
<breakpoint>
|
||||||
|
<option name="NOTIFY_CAUGHT" value="true"/>
|
||||||
|
<option name="NOTIFY_UNCAUGHT" value="true"/>
|
||||||
|
<option name="ENABLED" value="false"/>
|
||||||
|
<option name="LOG_ENABLED" value="false"/>
|
||||||
|
<option name="LOG_EXPRESSION_ENABLED" value="false"/>
|
||||||
|
<option name="SUSPEND_POLICY" value="SuspendAll"/>
|
||||||
|
<option name="COUNT_FILTER_ENABLED" value="false"/>
|
||||||
|
<option name="COUNT_FILTER" value="0"/>
|
||||||
|
<option name="CONDITION_ENABLED" value="false"/>
|
||||||
|
<option name="CLASS_FILTERS_ENABLED" value="false"/>
|
||||||
|
<option name="INSTANCE_FILTERS_ENABLED" value="false"/>
|
||||||
|
<option name="CONDITION" value=""/>
|
||||||
|
<option name="LOG_MESSAGE" value=""/>
|
||||||
|
</breakpoint>
|
||||||
|
</breakpoint_any>
|
||||||
|
<breakpoint_rules/>
|
||||||
|
<ui_properties/>
|
||||||
|
</component>
|
||||||
|
<component name="ModuleEditorState">
|
||||||
|
<option name="LAST_EDITED_MODULE_NAME"/>
|
||||||
|
<option name="LAST_EDITED_TAB_NAME"/>
|
||||||
|
</component>
|
||||||
|
<component name="ProjectInspectionProfilesVisibleTreeState">
|
||||||
|
<entry key="Project Default">
|
||||||
|
<profile-state/>
|
||||||
|
</entry>
|
||||||
|
</component>
|
||||||
|
<component name="ProjectLevelVcsManager">
|
||||||
|
<OptionsSetting value="true" id="Add"/>
|
||||||
|
<OptionsSetting value="true" id="Remove"/>
|
||||||
|
<OptionsSetting value="true" id="Checkout"/>
|
||||||
|
<OptionsSetting value="true" id="Update"/>
|
||||||
|
<OptionsSetting value="true" id="Status"/>
|
||||||
|
<OptionsSetting value="true" id="Edit"/>
|
||||||
|
<ConfirmationsSetting value="0" id="Add"/>
|
||||||
|
<ConfirmationsSetting value="0" id="Remove"/>
|
||||||
|
</component>
|
||||||
|
<component name="ProjectReloadState">
|
||||||
|
<option name="STATE" value="0"/>
|
||||||
|
</component>
|
||||||
|
<component name="PropertiesComponent">
|
||||||
|
<property name="GoToFile.includeJavaFiles" value="false"/>
|
||||||
|
<property name="GoToClass.toSaveIncludeLibraries" value="false"/>
|
||||||
|
<property name="MemberChooser.sorted" value="false"/>
|
||||||
|
<property name="MemberChooser.showClasses" value="true"/>
|
||||||
|
<property name="GoToClass.includeLibraries" value="false"/>
|
||||||
|
<property name="MemberChooser.copyJavadoc" value="false"/>
|
||||||
|
</component>
|
||||||
|
<component name="RunManager">
|
||||||
|
<configuration default="true" type="Remote" factoryName="Remote">
|
||||||
|
<option name="USE_SOCKET_TRANSPORT" value="true"/>
|
||||||
|
<option name="SERVER_MODE" value="false"/>
|
||||||
|
<option name="SHMEM_ADDRESS" value="javadebug"/>
|
||||||
|
<option name="HOST" value="localhost"/>
|
||||||
|
<option name="PORT" value="5005"/>
|
||||||
|
<method>
|
||||||
|
<option name="BuildArtifacts" enabled="false"/>
|
||||||
|
</method>
|
||||||
|
</configuration>
|
||||||
|
<configuration default="true" type="Applet" factoryName="Applet">
|
||||||
|
<module name=""/>
|
||||||
|
<option name="MAIN_CLASS_NAME"/>
|
||||||
|
<option name="HTML_FILE_NAME"/>
|
||||||
|
<option name="HTML_USED" value="false"/>
|
||||||
|
<option name="WIDTH" value="400"/>
|
||||||
|
<option name="HEIGHT" value="300"/>
|
||||||
|
<option name="POLICY_FILE" value="$APPLICATION_HOME_DIR$/bin/appletviewer.policy"/>
|
||||||
|
<option name="VM_PARAMETERS"/>
|
||||||
|
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false"/>
|
||||||
|
<option name="ALTERNATIVE_JRE_PATH"/>
|
||||||
|
<method>
|
||||||
|
<option name="BuildArtifacts" enabled="false"/>
|
||||||
|
<option name="Make" enabled="true"/>
|
||||||
|
</method>
|
||||||
|
</configuration>
|
||||||
|
<configuration default="true" type="Application" factoryName="Application">
|
||||||
|
<extension name="coverage" enabled="false" merge="false"/>
|
||||||
|
<option name="MAIN_CLASS_NAME"/>
|
||||||
|
<option name="VM_PARAMETERS"/>
|
||||||
|
<option name="PROGRAM_PARAMETERS"/>
|
||||||
|
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$"/>
|
||||||
|
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false"/>
|
||||||
|
<option name="ALTERNATIVE_JRE_PATH"/>
|
||||||
|
<option name="ENABLE_SWING_INSPECTOR" value="false"/>
|
||||||
|
<option name="ENV_VARIABLES"/>
|
||||||
|
<option name="PASS_PARENT_ENVS" value="true"/>
|
||||||
|
<module name=""/>
|
||||||
|
<envs/>
|
||||||
|
<method>
|
||||||
|
<option name="BuildArtifacts" enabled="false"/>
|
||||||
|
<option name="Make" enabled="true"/>
|
||||||
|
</method>
|
||||||
|
</configuration>
|
||||||
|
<configuration default="true" type="JUnit" factoryName="JUnit">
|
||||||
|
<extension name="coverage" enabled="false" merge="false"/>
|
||||||
|
<module name=""/>
|
||||||
|
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false"/>
|
||||||
|
<option name="ALTERNATIVE_JRE_PATH"/>
|
||||||
|
<option name="PACKAGE_NAME"/>
|
||||||
|
<option name="MAIN_CLASS_NAME"/>
|
||||||
|
<option name="METHOD_NAME"/>
|
||||||
|
<option name="TEST_OBJECT" value="class"/>
|
||||||
|
<option name="VM_PARAMETERS"/>
|
||||||
|
<option name="PARAMETERS"/>
|
||||||
|
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$"/>
|
||||||
|
<option name="ENV_VARIABLES"/>
|
||||||
|
<option name="PASS_PARENT_ENVS" value="true"/>
|
||||||
|
<option name="TEST_SEARCH_SCOPE">
|
||||||
|
<value defaultName="moduleWithDependencies"/>
|
||||||
|
</option>
|
||||||
|
<envs/>
|
||||||
|
<method>
|
||||||
|
<option name="BuildArtifacts" enabled="false"/>
|
||||||
|
<option name="Make" enabled="true"/>
|
||||||
|
</method>
|
||||||
|
</configuration>
|
||||||
|
<list size="0"/>
|
||||||
|
<configuration name="<template>" type="WebApp" default="true" selected="false">
|
||||||
|
<Host>localhost</Host>
|
||||||
|
<Port>5050</Port>
|
||||||
|
</configuration>
|
||||||
|
</component>
|
||||||
|
<component name="ShelveChangesManager" show_recycled="false"/>
|
||||||
|
<component name="SvnConfiguration" maxAnnotateRevisions="500">
|
||||||
|
<option name="USER" value=""/>
|
||||||
|
<option name="PASSWORD" value=""/>
|
||||||
|
<option name="LAST_MERGED_REVISION"/>
|
||||||
|
<option name="UPDATE_RUN_STATUS" value="false"/>
|
||||||
|
<option name="MERGE_DRY_RUN" value="false"/>
|
||||||
|
<option name="MERGE_DIFF_USE_ANCESTRY" value="true"/>
|
||||||
|
<option name="UPDATE_LOCK_ON_DEMAND" value="false"/>
|
||||||
|
<option name="IGNORE_SPACES_IN_MERGE" value="false"/>
|
||||||
|
<option name="DETECT_NESTED_COPIES" value="true"/>
|
||||||
|
<option name="IGNORE_SPACES_IN_ANNOTATE" value="true"/>
|
||||||
|
<option name="SHOW_MERGE_SOURCES_IN_ANNOTATE" value="true"/>
|
||||||
|
<myIsUseDefaultProxy>false</myIsUseDefaultProxy>
|
||||||
|
</component>
|
||||||
|
<component name="TaskManager">
|
||||||
|
<task active="true" id="Default" summary="Default task"/>
|
||||||
|
<servers/>
|
||||||
|
</component>
|
||||||
|
<component name="VcsManagerConfiguration">
|
||||||
|
<option name="OFFER_MOVE_TO_ANOTHER_CHANGELIST_ON_PARTIAL_COMMIT" value="true"/>
|
||||||
|
<option name="CHECK_CODE_SMELLS_BEFORE_PROJECT_COMMIT" value="true"/>
|
||||||
|
<option name="PERFORM_UPDATE_IN_BACKGROUND" value="true"/>
|
||||||
|
<option name="PERFORM_COMMIT_IN_BACKGROUND" value="true"/>
|
||||||
|
<option name="PERFORM_EDIT_IN_BACKGROUND" value="true"/>
|
||||||
|
<option name="PERFORM_CHECKOUT_IN_BACKGROUND" value="true"/>
|
||||||
|
<option name="PERFORM_ADD_REMOVE_IN_BACKGROUND" value="true"/>
|
||||||
|
<option name="PERFORM_ROLLBACK_IN_BACKGROUND" value="false"/>
|
||||||
|
<option name="CHECK_LOCALLY_CHANGED_CONFLICTS_IN_BACKGROUND" value="false"/>
|
||||||
|
<option name="ENABLE_BACKGROUND_PROCESSES" value="false"/>
|
||||||
|
<option name="CHANGED_ON_SERVER_INTERVAL" value="60"/>
|
||||||
|
<option name="FORCE_NON_EMPTY_COMMENT" value="false"/>
|
||||||
|
<option name="LAST_COMMIT_MESSAGE"/>
|
||||||
|
<option name="MAKE_NEW_CHANGELIST_ACTIVE" value="true"/>
|
||||||
|
<option name="OPTIMIZE_IMPORTS_BEFORE_PROJECT_COMMIT" value="false"/>
|
||||||
|
<option name="CHECK_FILES_UP_TO_DATE_BEFORE_COMMIT" value="false"/>
|
||||||
|
<option name="REFORMAT_BEFORE_PROJECT_COMMIT" value="false"/>
|
||||||
|
<option name="REFORMAT_BEFORE_FILE_COMMIT" value="false"/>
|
||||||
|
<option name="FILE_HISTORY_DIALOG_COMMENTS_SPLITTER_PROPORTION" value="0.8"/>
|
||||||
|
<option name="FILE_HISTORY_DIALOG_SPLITTER_PROPORTION" value="0.5"/>
|
||||||
|
<option name="ACTIVE_VCS_NAME"/>
|
||||||
|
<option name="UPDATE_GROUP_BY_PACKAGES" value="false"/>
|
||||||
|
<option name="UPDATE_GROUP_BY_CHANGELIST" value="false"/>
|
||||||
|
<option name="SHOW_FILE_HISTORY_AS_TREE" value="false"/>
|
||||||
|
<option name="FILE_HISTORY_SPLITTER_PROPORTION" value="0.6"/>
|
||||||
|
</component>
|
||||||
|
<component name="XDebuggerManager">
|
||||||
|
<breakpoint-manager/>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
|
|
@ -7,5 +7,5 @@ pluginManagement {
|
||||||
}
|
}
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id 'org.gradle.toolchains.foojay-resolver-convention' version '0.8.0'
|
id 'org.gradle.toolchains.foojay-resolver-convention' version '0.9.0'
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
// 1.21.1 2026-05-05T23:41:11.6384884 Item Models: mclschcannoncompat
|
// 1.21.1 2026-05-07T18:31:21.2712371 Item Models: mclschcannoncompat
|
||||||
52b70fbe9824ebbf99b2c3464e62faeb93a3ce63 assets/mclschcannoncompat/models/item/builder_assistant_staff.json
|
52b70fbe9824ebbf99b2c3464e62faeb93a3ce63 assets/mclschcannoncompat/models/item/builder_assistant_staff.json
|
||||||
acd5e3967cb0dcf277da711c0b8f0efbc6271d6c assets/mclschcannoncompat/models/item/builder_assistant_staff_t2.json
|
acd5e3967cb0dcf277da711c0b8f0efbc6271d6c assets/mclschcannoncompat/models/item/builder_assistant_staff_t2.json
|
||||||
d996164a02ec5598f0d421cc1ad0755b29621414 assets/mclschcannoncompat/models/item/builder_assistant_staff_t3.json
|
d996164a02ec5598f0d421cc1ad0755b29621414 assets/mclschcannoncompat/models/item/builder_assistant_staff_t3.json
|
||||||
|
a395cfa9425fbce9e6dad13f0044deceb4df8dcc assets/mclschcannoncompat/models/item/ornament_fabricator.json
|
||||||
|
|
|
||||||
|
|
@ -1,2 +1,2 @@
|
||||||
// 1.21.1 2026-05-07T13:46:09.9996673 Languages: ru_ru for mod: mclschcannoncompat
|
// 1.21.1 2026-05-09T02:10:42.4551668 Languages: ru_ru for mod: mclschcannoncompat
|
||||||
3deacd406d126128077ef1e97aa26c68ef1759e7 assets/mclschcannoncompat/lang/ru_ru.json
|
a1fbe8c5922e6b9c566a16b14d42d6c67cc7e9d2 assets/mclschcannoncompat/lang/ru_ru.json
|
||||||
|
|
|
||||||
|
|
@ -1,2 +1,2 @@
|
||||||
// 1.21.1 2026-05-07T13:46:10.0056649 Languages: en_us for mod: mclschcannoncompat
|
// 1.21.1 2026-05-09T02:10:42.4571469 Languages: en_us for mod: mclschcannoncompat
|
||||||
a01abd18da057bba316103cb554505de33093034 assets/mclschcannoncompat/lang/en_us.json
|
f808ba452243bef6c6dc1efa6ce3a9d2ae74cb9e assets/mclschcannoncompat/lang/en_us.json
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,9 @@
|
||||||
// 1.21.1 2026-05-05T23:41:11.6364906 Recipes
|
// 1.21.1 2026-05-07T18:31:21.2702367 Recipes
|
||||||
|
895b7a18109dacaaa77bafba58a50c941a9c2f56 data/mclschcannoncompat/advancement/recipes/decorations/ornament_fabricator.json
|
||||||
a4d166c9c7d5b081e15495f87588fa70f62bee84 data/mclschcannoncompat/advancement/recipes/tools/rec_fct1.json
|
a4d166c9c7d5b081e15495f87588fa70f62bee84 data/mclschcannoncompat/advancement/recipes/tools/rec_fct1.json
|
||||||
c1b2ebefe2e42c4a01db164c8fbf90dd0aadea78 data/mclschcannoncompat/advancement/recipes/tools/rec_fct2.json
|
c1b2ebefe2e42c4a01db164c8fbf90dd0aadea78 data/mclschcannoncompat/advancement/recipes/tools/rec_fct2.json
|
||||||
909da6934e35b03c890689105c7f29bae51ef330 data/mclschcannoncompat/advancement/recipes/tools/rec_fct3.json
|
909da6934e35b03c890689105c7f29bae51ef330 data/mclschcannoncompat/advancement/recipes/tools/rec_fct3.json
|
||||||
|
f42203a3bee2a747b9a5e1637a27fb043b1b97bd data/mclschcannoncompat/recipe/ornament_fabricator.json
|
||||||
594aec36a3be123023816c430342c9f081fd5bd4 data/mclschcannoncompat/recipe/rec_fct1.json
|
594aec36a3be123023816c430342c9f081fd5bd4 data/mclschcannoncompat/recipe/rec_fct1.json
|
||||||
4d05680c3a8c9923bf0610a8429a821cf57bbfff data/mclschcannoncompat/recipe/rec_fct2.json
|
4d05680c3a8c9923bf0610a8429a821cf57bbfff data/mclschcannoncompat/recipe/rec_fct2.json
|
||||||
e4bfc8d84f08ce1637c0d24090653218ba04f5be data/mclschcannoncompat/recipe/rec_fct3.json
|
e4bfc8d84f08ce1637c0d24090653218ba04f5be data/mclschcannoncompat/recipe/rec_fct3.json
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,13 @@
|
||||||
{
|
{
|
||||||
"item.asdf.assistantstaff.maxdepth": "Maximum depth: %s",
|
"block.mclschcannoncompat.ornament_fabricator": "Ornament Fabricator",
|
||||||
|
"item.assistantstaff.hover.maxdepth": "Maximum depth: %s",
|
||||||
"item.mclschcannoncompat.builder_assistant_staff": "Builder staff T1",
|
"item.mclschcannoncompat.builder_assistant_staff": "Builder staff T1",
|
||||||
"item.mclschcannoncompat.builder_assistant_staff_t2": "Builder staff T2",
|
"item.mclschcannoncompat.builder_assistant_staff_t2": "Builder staff T2",
|
||||||
"item.mclschcannoncompat.builder_assistant_staff_t3": "Builder staff T3"
|
"item.mclschcannoncompat.builder_assistant_staff_t3": "Builder staff T3",
|
||||||
|
"tooltip.btn.cyclestyle.down": "Cycle style backward",
|
||||||
|
"tooltip.btn.cyclestyle.up": "Cycle style forward",
|
||||||
|
"tooltip.btn.cyclevariant.down": "Cycle variant backward",
|
||||||
|
"tooltip.btn.cyclevariant.up": "Cycle variant forward",
|
||||||
|
"tooltip.btn.startcrafting": "Start crafting",
|
||||||
|
"tooltip.ornament_fabricator.no_preview": "Recipe is not supported for provided ingredients"
|
||||||
}
|
}
|
||||||
|
|
@ -1,6 +1,13 @@
|
||||||
{
|
{
|
||||||
"item.asdf.assistantstaff.maxdepth": "Максимальная блоков: %s",
|
"block.mclschcannoncompat.ornament_fabricator": "Орнаментный фабрикатор",
|
||||||
|
"item.assistantstaff.hover.maxdepth": "Максимальная глубина: %s",
|
||||||
"item.mclschcannoncompat.builder_assistant_staff": "Посох строителя T1",
|
"item.mclschcannoncompat.builder_assistant_staff": "Посох строителя T1",
|
||||||
"item.mclschcannoncompat.builder_assistant_staff_t2": "Посох строителя T2",
|
"item.mclschcannoncompat.builder_assistant_staff_t2": "Посох строителя T2",
|
||||||
"item.mclschcannoncompat.builder_assistant_staff_t3": "Посох строителя T3"
|
"item.mclschcannoncompat.builder_assistant_staff_t3": "Посох строителя T3",
|
||||||
|
"tooltip.btn.cyclestyle.down": "Переключить стиль назад",
|
||||||
|
"tooltip.btn.cyclestyle.up": "Переключить стиль вперёд",
|
||||||
|
"tooltip.btn.cyclevariant.down": "Переключить вариант назад",
|
||||||
|
"tooltip.btn.cyclevariant.up": "Переключить вариант вперёд",
|
||||||
|
"tooltip.btn.startcrafting": "Начать крафт",
|
||||||
|
"tooltip.ornament_fabricator.no_preview": "Рецепт не подходит этим ингредиентам"
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
{
|
||||||
|
"parent": "mclschcannoncompat:block/ornament_fabricator"
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
{
|
||||||
|
"parent": "minecraft:recipes/root",
|
||||||
|
"criteria": {
|
||||||
|
"has_amethyst": {
|
||||||
|
"conditions": {
|
||||||
|
"items": [
|
||||||
|
{
|
||||||
|
"items": "minecraft:amethyst_shard"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"trigger": "minecraft:inventory_changed"
|
||||||
|
},
|
||||||
|
"has_the_recipe": {
|
||||||
|
"conditions": {
|
||||||
|
"recipe": "mclschcannoncompat:ornament_fabricator"
|
||||||
|
},
|
||||||
|
"trigger": "minecraft:recipe_unlocked"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"requirements": [
|
||||||
|
[
|
||||||
|
"has_the_recipe",
|
||||||
|
"has_amethyst"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"rewards": {
|
||||||
|
"recipes": [
|
||||||
|
"mclschcannoncompat:ornament_fabricator"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
{
|
||||||
|
"type": "minecraft:crafting_shaped",
|
||||||
|
"category": "misc",
|
||||||
|
"key": {
|
||||||
|
"A": {
|
||||||
|
"item": "minecraft:amethyst_shard"
|
||||||
|
},
|
||||||
|
"C": {
|
||||||
|
"item": "minecraft:crafting_table"
|
||||||
|
},
|
||||||
|
"I": {
|
||||||
|
"item": "minecraft:iron_ingot"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"pattern": [
|
||||||
|
"III",
|
||||||
|
"ACA",
|
||||||
|
"III"
|
||||||
|
],
|
||||||
|
"result": {
|
||||||
|
"count": 1,
|
||||||
|
"id": "mclschcannoncompat:ornament_fabricator"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,54 @@
|
||||||
|
package xyz.nuark.mcmod.mclschcannoncompat.utils;
|
||||||
|
|
||||||
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import xyz.nuark.mcmod.mclschcannoncompat.Mclschcannoncompat;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.TreeMap;
|
||||||
|
|
||||||
|
public class ODBlockRecipiesCache {
|
||||||
|
private static final Logger LOGGER = LogManager.getLogger(Mclschcannoncompat.ID);
|
||||||
|
|
||||||
|
private static final List<ResourceLocation> blockTypesCache = new ArrayList<>();
|
||||||
|
private static final TreeMap<Integer, List<ItemStack>> blockVariantsCache = new TreeMap<>();
|
||||||
|
private static final TreeMap<ResourceLocation, List<ItemStack>> recipesCache = new TreeMap<>();
|
||||||
|
|
||||||
|
public static List<ResourceLocation> getBlockTypesCache() {
|
||||||
|
return blockTypesCache;
|
||||||
|
}
|
||||||
|
public static Map<Integer, List<ItemStack>> getBlockVariantsCache() {
|
||||||
|
return blockVariantsCache;
|
||||||
|
}
|
||||||
|
public static Map<ResourceLocation, List<ItemStack>> getRecipesCache() {
|
||||||
|
return recipesCache;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void initRecipesCache() {
|
||||||
|
if (!recipesCache.isEmpty()) return;
|
||||||
|
|
||||||
|
LOGGER.info("Started caching DO recipes...");
|
||||||
|
var startTime = System.currentTimeMillis();
|
||||||
|
var compIG = com.ldtteam.domumornamentum.block.ModBlocks.getInstance().getOrComputeItemGroups();
|
||||||
|
for (var ig : compIG.entrySet()) {
|
||||||
|
var loc = ig.getKey();
|
||||||
|
|
||||||
|
var variantsList = new ArrayList<ItemStack>();
|
||||||
|
for (var variant : ig.getValue()) {
|
||||||
|
variantsList.add(variant.copy());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (variantsList.isEmpty()) continue;
|
||||||
|
|
||||||
|
blockTypesCache.add(loc);
|
||||||
|
blockVariantsCache.put(blockTypesCache.size() - 1, variantsList);
|
||||||
|
recipesCache.put(loc, variantsList);
|
||||||
|
}
|
||||||
|
var elapsedTime = System.currentTimeMillis() - startTime;
|
||||||
|
LOGGER.info("Done caching DO recipes in $elapsedTime millis");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
package xyz.nuark.mcmod.mclschcannoncompat
|
package xyz.nuark.mcmod.mclschcannoncompat
|
||||||
|
|
||||||
import net.minecraft.client.Minecraft
|
|
||||||
import net.minecraft.resources.ResourceLocation
|
import net.minecraft.resources.ResourceLocation
|
||||||
import net.minecraft.world.item.CreativeModeTabs
|
import net.minecraft.world.item.CreativeModeTabs
|
||||||
import net.neoforged.bus.api.SubscribeEvent
|
import net.neoforged.bus.api.SubscribeEvent
|
||||||
|
|
@ -10,6 +9,7 @@ import net.neoforged.fml.common.Mod
|
||||||
import net.neoforged.fml.event.lifecycle.FMLClientSetupEvent
|
import net.neoforged.fml.event.lifecycle.FMLClientSetupEvent
|
||||||
import net.neoforged.fml.event.lifecycle.FMLCommonSetupEvent
|
import net.neoforged.fml.event.lifecycle.FMLCommonSetupEvent
|
||||||
import net.neoforged.fml.event.lifecycle.FMLDedicatedServerSetupEvent
|
import net.neoforged.fml.event.lifecycle.FMLDedicatedServerSetupEvent
|
||||||
|
import net.neoforged.neoforge.client.event.RegisterMenuScreensEvent
|
||||||
import net.neoforged.neoforge.data.event.GatherDataEvent
|
import net.neoforged.neoforge.data.event.GatherDataEvent
|
||||||
import net.neoforged.neoforge.event.BuildCreativeModeTabContentsEvent
|
import net.neoforged.neoforge.event.BuildCreativeModeTabContentsEvent
|
||||||
import net.neoforged.neoforge.event.RegisterCommandsEvent
|
import net.neoforged.neoforge.event.RegisterCommandsEvent
|
||||||
|
|
@ -19,12 +19,16 @@ import org.apache.logging.log4j.LogManager
|
||||||
import org.apache.logging.log4j.Logger
|
import org.apache.logging.log4j.Logger
|
||||||
import thedarkcolour.kotlinforforge.neoforge.forge.MOD_BUS
|
import thedarkcolour.kotlinforforge.neoforge.forge.MOD_BUS
|
||||||
import thedarkcolour.kotlinforforge.neoforge.forge.runForDist
|
import thedarkcolour.kotlinforforge.neoforge.forge.runForDist
|
||||||
|
import xyz.nuark.mcmod.mclschcannoncompat.block.ModBlockEntityTypes
|
||||||
import xyz.nuark.mcmod.mclschcannoncompat.block.ModBlocks
|
import xyz.nuark.mcmod.mclschcannoncompat.block.ModBlocks
|
||||||
import xyz.nuark.mcmod.mclschcannoncompat.comands.ModCommands
|
import xyz.nuark.mcmod.mclschcannoncompat.comands.ModCommands
|
||||||
import xyz.nuark.mcmod.mclschcannoncompat.datagen.ModItemModelProvider
|
import xyz.nuark.mcmod.mclschcannoncompat.datagen.ModItemModelProvider
|
||||||
import xyz.nuark.mcmod.mclschcannoncompat.datagen.ModLanguageProviders
|
import xyz.nuark.mcmod.mclschcannoncompat.datagen.ModLanguageProviders
|
||||||
import xyz.nuark.mcmod.mclschcannoncompat.datagen.ModRecipeProvider
|
import xyz.nuark.mcmod.mclschcannoncompat.datagen.ModRecipeProvider
|
||||||
import xyz.nuark.mcmod.mclschcannoncompat.item.ModItems
|
import xyz.nuark.mcmod.mclschcannoncompat.item.ModItems
|
||||||
|
import xyz.nuark.mcmod.mclschcannoncompat.menu.ModMenuTypes
|
||||||
|
import xyz.nuark.mcmod.mclschcannoncompat.menu.OrnamentFabricatorMenu
|
||||||
|
import xyz.nuark.mcmod.mclschcannoncompat.screen.OrnamentFabricatorScreen
|
||||||
|
|
||||||
@Mod(Mclschcannoncompat.ID)
|
@Mod(Mclschcannoncompat.ID)
|
||||||
@EventBusSubscriber
|
@EventBusSubscriber
|
||||||
|
|
@ -37,23 +41,28 @@ object Mclschcannoncompat {
|
||||||
LOGGER.log(Level.INFO, "Hello world!")
|
LOGGER.log(Level.INFO, "Hello world!")
|
||||||
|
|
||||||
ModBlocks.REGISTRY.register(MOD_BUS)
|
ModBlocks.REGISTRY.register(MOD_BUS)
|
||||||
|
ModBlockEntityTypes.REGISTRY.register(MOD_BUS)
|
||||||
val obj = runForDist(clientTarget = {
|
ModMenuTypes.REGISTRY.register(MOD_BUS)
|
||||||
MOD_BUS.addListener(::onClientSetup)
|
|
||||||
Minecraft.getInstance()
|
|
||||||
}, serverTarget = {
|
|
||||||
MOD_BUS.addListener(::onServerSetup)
|
|
||||||
"test"
|
|
||||||
})
|
|
||||||
|
|
||||||
ModItems.REGISTRY.register(MOD_BUS)
|
ModItems.REGISTRY.register(MOD_BUS)
|
||||||
|
|
||||||
println(obj)
|
runForDist(
|
||||||
|
clientTarget = {
|
||||||
|
MOD_BUS.addListener(::onClientSetup)
|
||||||
|
MOD_BUS.addListener(::onRegisterMenuScreens)
|
||||||
|
},
|
||||||
|
serverTarget = {
|
||||||
|
MOD_BUS.addListener(::onServerSetup)
|
||||||
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun onClientSetup(@Suppress("unused") event: FMLClientSetupEvent) {
|
private fun onClientSetup(@Suppress("unused") event: FMLClientSetupEvent) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun onRegisterMenuScreens(event: RegisterMenuScreensEvent) {
|
||||||
|
event.register(ModMenuTypes.ORNAMENT_FABRICATOR.get(), ::OrnamentFabricatorScreen)
|
||||||
|
}
|
||||||
|
|
||||||
private fun onServerSetup(@Suppress("unused") event: FMLDedicatedServerSetupEvent) {
|
private fun onServerSetup(@Suppress("unused") event: FMLDedicatedServerSetupEvent) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -68,6 +77,9 @@ object Mclschcannoncompat {
|
||||||
event.accept(ModItems.BUILDER_ASSISTANT_STAFF_T2.get())
|
event.accept(ModItems.BUILDER_ASSISTANT_STAFF_T2.get())
|
||||||
event.accept(ModItems.BUILDER_ASSISTANT_STAFF_T3.get())
|
event.accept(ModItems.BUILDER_ASSISTANT_STAFF_T3.get())
|
||||||
}
|
}
|
||||||
|
if (event.tabKey === CreativeModeTabs.FUNCTIONAL_BLOCKS) {
|
||||||
|
event.accept(ModItems.ORNAMENT_FABRICATOR_ITEM.get())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
|
|
@ -76,10 +88,9 @@ object Mclschcannoncompat {
|
||||||
}
|
}
|
||||||
|
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
fun onNetworkRegistry(event: RegisterPayloadHandlersEvent)
|
fun onNetworkRegistry(event: RegisterPayloadHandlersEvent) {
|
||||||
{
|
val modVersion = ModList.get().getModContainerById(ID).get().modInfo.version.toString()
|
||||||
val modVersion = ModList.get().getModContainerById(ID).get().getModInfo().getVersion().toString()
|
@Suppress("unused") val registrar = event.registrar(ID).versioned(modVersion)
|
||||||
@Suppress("unused") val registry = event.registrar(ID).versioned(modVersion)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
package xyz.nuark.mcmod.mclschcannoncompat.block
|
||||||
|
|
||||||
|
import net.minecraft.world.level.block.entity.BlockEntityType
|
||||||
|
import net.neoforged.neoforge.registries.DeferredRegister
|
||||||
|
import xyz.nuark.mcmod.mclschcannoncompat.Mclschcannoncompat
|
||||||
|
import xyz.nuark.mcmod.mclschcannoncompat.block.entity.OrnamentFabricatorBlockEntity
|
||||||
|
import java.util.function.Supplier
|
||||||
|
|
||||||
|
object ModBlockEntityTypes {
|
||||||
|
val REGISTRY = DeferredRegister.create(
|
||||||
|
net.minecraft.core.registries.BuiltInRegistries.BLOCK_ENTITY_TYPE,
|
||||||
|
Mclschcannoncompat.ID
|
||||||
|
)
|
||||||
|
|
||||||
|
val ORNAMENT_FABRICATOR: Supplier<BlockEntityType<OrnamentFabricatorBlockEntity>> = REGISTRY.register(
|
||||||
|
"ornament_fabricator",
|
||||||
|
Supplier {
|
||||||
|
BlockEntityType.Builder.of(
|
||||||
|
::OrnamentFabricatorBlockEntity,
|
||||||
|
ModBlocks.ORNAMENT_FABRICATOR.get()
|
||||||
|
).build(null) as BlockEntityType<OrnamentFabricatorBlockEntity>
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
@ -1,8 +1,19 @@
|
||||||
package xyz.nuark.mcmod.mclschcannoncompat.block
|
package xyz.nuark.mcmod.mclschcannoncompat.block
|
||||||
|
|
||||||
|
import net.minecraft.world.level.block.Blocks
|
||||||
|
import net.minecraft.world.level.block.state.BlockBehaviour
|
||||||
|
import net.minecraft.world.level.material.MapColor
|
||||||
import net.neoforged.neoforge.registries.DeferredRegister
|
import net.neoforged.neoforge.registries.DeferredRegister
|
||||||
import xyz.nuark.mcmod.mclschcannoncompat.Mclschcannoncompat
|
import xyz.nuark.mcmod.mclschcannoncompat.Mclschcannoncompat
|
||||||
|
|
||||||
object ModBlocks {
|
object ModBlocks {
|
||||||
val REGISTRY = DeferredRegister.createBlocks(Mclschcannoncompat.ID)
|
val REGISTRY = DeferredRegister.createBlocks(Mclschcannoncompat.ID)
|
||||||
|
|
||||||
|
val ORNAMENT_FABRICATOR = REGISTRY.registerBlock(
|
||||||
|
"ornament_fabricator",
|
||||||
|
::OrnamentFabricatorBlock,
|
||||||
|
BlockBehaviour.Properties.ofFullCopy(Blocks.STONE)
|
||||||
|
.mapColor(MapColor.STONE)
|
||||||
|
.strength(3.0f, 6.0f)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,61 @@
|
||||||
|
package xyz.nuark.mcmod.mclschcannoncompat.block
|
||||||
|
|
||||||
|
import com.mojang.serialization.MapCodec
|
||||||
|
import net.minecraft.core.BlockPos
|
||||||
|
import net.minecraft.server.level.ServerPlayer
|
||||||
|
import net.minecraft.world.InteractionResult
|
||||||
|
import net.minecraft.world.entity.player.Player
|
||||||
|
import net.minecraft.world.item.ItemStack
|
||||||
|
import net.minecraft.world.level.Level
|
||||||
|
import net.minecraft.world.level.LevelAccessor
|
||||||
|
import net.minecraft.world.level.block.BaseEntityBlock
|
||||||
|
import net.minecraft.world.level.block.RenderShape
|
||||||
|
import net.minecraft.world.level.block.entity.BlockEntity
|
||||||
|
import net.minecraft.world.level.block.entity.BlockEntityTicker
|
||||||
|
import net.minecraft.world.level.block.entity.BlockEntityType
|
||||||
|
import net.minecraft.world.level.block.state.BlockState
|
||||||
|
import net.minecraft.world.level.storage.loot.LootParams
|
||||||
|
import net.minecraft.world.phys.BlockHitResult
|
||||||
|
import net.neoforged.neoforge.common.extensions.IPlayerExtension
|
||||||
|
import xyz.nuark.mcmod.mclschcannoncompat.block.entity.OrnamentFabricatorBlockEntity
|
||||||
|
|
||||||
|
class OrnamentFabricatorBlock(properties: Properties) : BaseEntityBlock(properties) {
|
||||||
|
override fun codec(): MapCodec<out OrnamentFabricatorBlock> = simpleCodec(::OrnamentFabricatorBlock)
|
||||||
|
|
||||||
|
override fun newBlockEntity(pos: BlockPos, state: BlockState): BlockEntity =
|
||||||
|
OrnamentFabricatorBlockEntity(pos, state)
|
||||||
|
|
||||||
|
override fun getRenderShape(state: BlockState): RenderShape = RenderShape.MODEL
|
||||||
|
|
||||||
|
override fun useWithoutItem(
|
||||||
|
state: BlockState,
|
||||||
|
level: Level,
|
||||||
|
pos: BlockPos,
|
||||||
|
player: Player,
|
||||||
|
hitResult: BlockHitResult
|
||||||
|
): InteractionResult {
|
||||||
|
if (level.isClientSide) return InteractionResult.SUCCESS
|
||||||
|
|
||||||
|
if (player is ServerPlayer) {
|
||||||
|
player.openMenu(state.getMenuProvider(level, pos), pos)
|
||||||
|
}
|
||||||
|
|
||||||
|
return InteractionResult.sidedSuccess(level.isClientSide)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun <T : BlockEntity> getTicker(
|
||||||
|
level: Level,
|
||||||
|
state: BlockState,
|
||||||
|
type: BlockEntityType<T>
|
||||||
|
): BlockEntityTicker<T>? {
|
||||||
|
if (level.isClientSide) return null
|
||||||
|
return createTickerHelper(type, ModBlockEntityTypes.ORNAMENT_FABRICATOR.get()) { _, _, _, be ->
|
||||||
|
be.tick()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data class OrnamentFabricatorEntry(
|
||||||
|
val block: net.minecraft.world.level.block.Block,
|
||||||
|
val components: List<com.ldtteam.domumornamentum.block.IMateriallyTexturedBlockComponent>
|
||||||
|
)
|
||||||
|
|
@ -0,0 +1,310 @@
|
||||||
|
package xyz.nuark.mcmod.mclschcannoncompat.block.entity
|
||||||
|
|
||||||
|
import com.ldtteam.domumornamentum.block.IMateriallyTexturedBlock
|
||||||
|
import com.ldtteam.domumornamentum.client.model.data.MaterialTextureData
|
||||||
|
import com.ldtteam.domumornamentum.recipe.ModRecipeTypes
|
||||||
|
import com.ldtteam.domumornamentum.recipe.architectscutter.ArchitectsCutterRecipeInput
|
||||||
|
import com.minecolonies.api.util.ItemStackUtils
|
||||||
|
import net.minecraft.core.BlockPos
|
||||||
|
import net.minecraft.core.HolderLookup
|
||||||
|
import net.minecraft.core.component.DataComponents
|
||||||
|
import net.minecraft.nbt.CompoundTag
|
||||||
|
import net.minecraft.network.chat.Component
|
||||||
|
import net.minecraft.world.Containers
|
||||||
|
import net.minecraft.world.MenuProvider
|
||||||
|
import net.minecraft.world.SimpleContainer
|
||||||
|
import net.minecraft.world.entity.player.Inventory
|
||||||
|
import net.minecraft.world.entity.player.Player
|
||||||
|
import net.minecraft.world.inventory.AbstractContainerMenu
|
||||||
|
import net.minecraft.world.inventory.ContainerData
|
||||||
|
import net.minecraft.world.item.BlockItem
|
||||||
|
import net.minecraft.world.item.ItemStack
|
||||||
|
import net.minecraft.world.item.component.BlockItemStateProperties
|
||||||
|
import net.minecraft.world.level.block.entity.BlockEntity
|
||||||
|
import net.minecraft.world.level.block.state.BlockState
|
||||||
|
import net.neoforged.neoforge.items.ItemStackHandler
|
||||||
|
import xyz.nuark.mcmod.mclschcannoncompat.block.ModBlockEntityTypes
|
||||||
|
import xyz.nuark.mcmod.mclschcannoncompat.menu.OrnamentFabricatorMenu
|
||||||
|
import xyz.nuark.mcmod.mclschcannoncompat.utils.ODBlockRecipiesCache
|
||||||
|
|
||||||
|
class OrnamentFabricatorBlockEntity(
|
||||||
|
pos: BlockPos,
|
||||||
|
state: BlockState
|
||||||
|
) : BlockEntity(
|
||||||
|
ModBlockEntityTypes.ORNAMENT_FABRICATOR.get(), pos, state
|
||||||
|
), MenuProvider {
|
||||||
|
init {
|
||||||
|
ODBlockRecipiesCache.initRecipesCache()
|
||||||
|
}
|
||||||
|
|
||||||
|
val itemHandler = object : ItemStackHandler(TOTAL_SLOTS) {
|
||||||
|
override fun onContentsChanged(slot: Int) {
|
||||||
|
if (slot != SLOT_PREVIEW) {
|
||||||
|
updateRecipe()
|
||||||
|
}
|
||||||
|
setChanged()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun isItemValid(slot: Int, stack: ItemStack): Boolean =
|
||||||
|
slot != SLOT_PREVIEW
|
||||||
|
|
||||||
|
override fun extractItem(slot: Int, amount: Int, simulate: Boolean): ItemStack {
|
||||||
|
if (slot == SLOT_PREVIEW) return ItemStack.EMPTY
|
||||||
|
return super.extractItem(slot, amount, simulate)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var blockTypeIndex: Int = 0
|
||||||
|
set(value) {
|
||||||
|
field = value; setChanged()
|
||||||
|
}
|
||||||
|
|
||||||
|
var blockSubtypeIndex: Int = 0
|
||||||
|
set(value) {
|
||||||
|
field = value; setChanged()
|
||||||
|
}
|
||||||
|
|
||||||
|
var currentProcess: Int = 0
|
||||||
|
set(value) {
|
||||||
|
field = value; setChanged()
|
||||||
|
}
|
||||||
|
|
||||||
|
var maxProcess: Int = DEFAULT_PROCESS_TIME
|
||||||
|
set(value) {
|
||||||
|
field = value; setChanged()
|
||||||
|
}
|
||||||
|
|
||||||
|
var craftingEnabled: Boolean = false
|
||||||
|
set(value) {
|
||||||
|
field = value; setChanged()
|
||||||
|
}
|
||||||
|
|
||||||
|
private var cachedRecipe: FabricatorRecipe? = null
|
||||||
|
|
||||||
|
val containerData = object : ContainerData {
|
||||||
|
override fun get(index: Int): Int = when (index) {
|
||||||
|
DATA_BLOCK_TYPE -> blockTypeIndex
|
||||||
|
DATA_BLOCK_SUBTYPE -> blockSubtypeIndex
|
||||||
|
DATA_CURRENT -> currentProcess
|
||||||
|
DATA_MAX -> maxProcess
|
||||||
|
DATA_CRAFTING_ENABLED -> if (craftingEnabled) 1 else 0
|
||||||
|
else -> 0
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun set(index: Int, value: Int) {
|
||||||
|
when (index) {
|
||||||
|
DATA_BLOCK_TYPE -> blockTypeIndex = value
|
||||||
|
DATA_BLOCK_SUBTYPE -> blockSubtypeIndex = value
|
||||||
|
DATA_CURRENT -> currentProcess = value
|
||||||
|
DATA_MAX -> maxProcess = value
|
||||||
|
DATA_CRAFTING_ENABLED -> craftingEnabled = value == 1
|
||||||
|
}
|
||||||
|
|
||||||
|
updateRecipe()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getCount(): Int = DATA_SIZE
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getDisplayName(): Component =
|
||||||
|
Component.translatable("block.mclschcannoncompat.ornament_fabricator")
|
||||||
|
|
||||||
|
override fun createMenu(containerId: Int, playerInventory: Inventory, player: Player): AbstractContainerMenu =
|
||||||
|
OrnamentFabricatorMenu(containerId, playerInventory, this, containerData)
|
||||||
|
|
||||||
|
fun tick() {
|
||||||
|
val level = level ?: return
|
||||||
|
if (level.isClientSide) return
|
||||||
|
|
||||||
|
val inputA = itemHandler.getStackInSlot(SLOT_INPUT_A)
|
||||||
|
val inputB = itemHandler.getStackInSlot(SLOT_INPUT_B)
|
||||||
|
val output = itemHandler.getStackInSlot(SLOT_OUTPUT)
|
||||||
|
|
||||||
|
updateRecipe()
|
||||||
|
val recipe = cachedRecipe?.takeIf { ItemStackUtils.compareItemStacksIgnoreStackSize(it.result, itemHandler.getStackInSlot(SLOT_PREVIEW)) } ?: updateRecipe()
|
||||||
|
|
||||||
|
if (recipe != null && craftingEnabled) {
|
||||||
|
val canOutput = output.isEmpty ||
|
||||||
|
(ItemStack.isSameItemSameComponents(output, recipe.result) &&
|
||||||
|
output.count + recipe.result.count <= output.maxStackSize)
|
||||||
|
|
||||||
|
if (canOutput) {
|
||||||
|
currentProcess++
|
||||||
|
if (currentProcess >= maxProcess) {
|
||||||
|
currentProcess = 0
|
||||||
|
craftingEnabled = false
|
||||||
|
|
||||||
|
itemHandler.extractItem(SLOT_INPUT_A, 1, false)
|
||||||
|
itemHandler.extractItem(SLOT_INPUT_B, 1, false)
|
||||||
|
|
||||||
|
if (output.isEmpty) {
|
||||||
|
itemHandler.setStackInSlot(SLOT_OUTPUT, recipe.result.copy())
|
||||||
|
} else {
|
||||||
|
output.grow(recipe.result.count)
|
||||||
|
}
|
||||||
|
setChanged()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
currentProcess = 0
|
||||||
|
}
|
||||||
|
} else if (recipe == null) {
|
||||||
|
currentProcess = 0
|
||||||
|
maxProcess = DEFAULT_PROCESS_TIME
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private data class FabricatorRecipe(
|
||||||
|
val result: ItemStack,
|
||||||
|
val resultPreview: ItemStack,
|
||||||
|
val processTicks: Int
|
||||||
|
)
|
||||||
|
|
||||||
|
private fun findRecipe(inputA: ItemStack, inputB: ItemStack): FabricatorRecipe? {
|
||||||
|
if (inputA.isEmpty) return null
|
||||||
|
val level = level ?: return null
|
||||||
|
|
||||||
|
val input = ArchitectsCutterRecipeInput(SimpleContainer(inputA, inputB))
|
||||||
|
|
||||||
|
val type = ODBlockRecipiesCache.getBlockTypesCache().getOrNull(blockTypeIndex) ?: return null
|
||||||
|
val variant = ODBlockRecipiesCache.getBlockVariantsCache().getOrDefault(blockTypeIndex, emptyList())
|
||||||
|
.getOrNull(blockSubtypeIndex) ?: return null
|
||||||
|
|
||||||
|
val matchedRecipe = level.recipeManager.getAllRecipesFor(ModRecipeTypes.ARCHITECTS_CUTTER.get())
|
||||||
|
.firstNotNullOfOrNull { recipeHolder ->
|
||||||
|
val recipe = recipeHolder.value
|
||||||
|
val resultItem = recipe.getResultItem(level.registryAccess())
|
||||||
|
if (resultItem.item == variant.item) {
|
||||||
|
val resultBlockState =
|
||||||
|
resultItem.getOrDefault(DataComponents.BLOCK_STATE, BlockItemStateProperties.EMPTY)
|
||||||
|
val currentBlockState =
|
||||||
|
variant.getOrDefault(DataComponents.BLOCK_STATE, BlockItemStateProperties.EMPTY)
|
||||||
|
|
||||||
|
if (resultBlockState.isEmpty && currentBlockState.isEmpty || resultBlockState == currentBlockState) {
|
||||||
|
val output = recipe.assemble(input, level.registryAccess())
|
||||||
|
|
||||||
|
val textureData = MaterialTextureData.readFromItemStack(output)?.takeIf { !it.isEmpty }
|
||||||
|
?: return@firstNotNullOfOrNull null
|
||||||
|
|
||||||
|
val generatedBlock =
|
||||||
|
recipe.block as? IMateriallyTexturedBlock ?: return@firstNotNullOfOrNull null
|
||||||
|
val recipeComponents = generatedBlock.components.toList()
|
||||||
|
|
||||||
|
return@firstNotNullOfOrNull when (textureData.getTexturedComponents.size) {
|
||||||
|
2 if (!inputA.isEmpty && !inputB.isEmpty) -> {
|
||||||
|
val itemA = inputA.item.takeIf { it is BlockItem } as? BlockItem
|
||||||
|
?: return@firstNotNullOfOrNull null
|
||||||
|
val itemB = inputB.item.takeIf { it is BlockItem } as? BlockItem
|
||||||
|
?: return@firstNotNullOfOrNull null
|
||||||
|
|
||||||
|
val aOk = itemA.block.defaultBlockState().`is`(recipeComponents[0].validSkins)
|
||||||
|
val bOk = itemB.block.defaultBlockState().`is`(recipeComponents[1].validSkins)
|
||||||
|
|
||||||
|
aOk && bOk
|
||||||
|
recipeHolder to output
|
||||||
|
}
|
||||||
|
|
||||||
|
1 if (inputB.isEmpty) -> {
|
||||||
|
val itemA = inputA.item.takeIf { it is BlockItem } as? BlockItem
|
||||||
|
?: return@firstNotNullOfOrNull null
|
||||||
|
|
||||||
|
itemA.block.defaultBlockState().`is`(recipeComponents[0].validSkins)
|
||||||
|
recipeHolder to output
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
null
|
||||||
|
} ?: return null
|
||||||
|
|
||||||
|
val (recipeUsed, output) = matchedRecipe
|
||||||
|
|
||||||
|
return FabricatorRecipe(
|
||||||
|
output,
|
||||||
|
output,
|
||||||
|
100
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun updateRecipe(): FabricatorRecipe? {
|
||||||
|
val inputA = itemHandler.getStackInSlot(SLOT_INPUT_A)
|
||||||
|
val inputB = itemHandler.getStackInSlot(SLOT_INPUT_B)
|
||||||
|
|
||||||
|
val prevRecipe = cachedRecipe
|
||||||
|
val recipe = findRecipe(inputA, inputB)
|
||||||
|
cachedRecipe = recipe
|
||||||
|
|
||||||
|
recipe?.let {
|
||||||
|
val previewStack = recipe.resultPreview.copy().also { it.count = recipe.result.count }
|
||||||
|
itemHandler.setStackInSlot(SLOT_PREVIEW, previewStack)
|
||||||
|
|
||||||
|
maxProcess = recipe.processTicks
|
||||||
|
} ?: run {
|
||||||
|
if (!itemHandler.getStackInSlot(SLOT_PREVIEW).isEmpty) {
|
||||||
|
itemHandler.setStackInSlot(SLOT_PREVIEW, ItemStack.EMPTY)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
level.takeIf { it != null && !it.isClientSide && !ItemStackUtils.compareItemStacksIgnoreStackSize(prevRecipe?.result, cachedRecipe?.result) }?.let {
|
||||||
|
craftingEnabled = false
|
||||||
|
currentProcess = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
return recipe
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun saveAdditional(tag: CompoundTag, registries: HolderLookup.Provider) {
|
||||||
|
super.saveAdditional(tag, registries)
|
||||||
|
tag.put("Inventory", itemHandler.serializeNBT(registries))
|
||||||
|
tag.putInt("BlockTypeIndex", blockTypeIndex)
|
||||||
|
tag.putInt("BlockSubtypeIndex", blockSubtypeIndex)
|
||||||
|
tag.putInt("CurrentProcess", currentProcess)
|
||||||
|
tag.putInt("MaxProcess", maxProcess)
|
||||||
|
tag.putBoolean("CraftingEnabled", craftingEnabled)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun loadAdditional(tag: CompoundTag, registries: HolderLookup.Provider) {
|
||||||
|
super.loadAdditional(tag, registries)
|
||||||
|
itemHandler.deserializeNBT(registries, tag.getCompound("Inventory"))
|
||||||
|
blockTypeIndex = tag.getInt("BlockTypeIndex")
|
||||||
|
blockSubtypeIndex = tag.getInt("BlockSubtypeIndex")
|
||||||
|
currentProcess = tag.getInt("CurrentProcess")
|
||||||
|
maxProcess = tag.getInt("MaxProcess")
|
||||||
|
craftingEnabled = tag.getBoolean("CraftingEnabled")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onLoad() {
|
||||||
|
super.onLoad()
|
||||||
|
|
||||||
|
updateRecipe()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun drops() {
|
||||||
|
val inventory = SimpleContainer(TOTAL_SLOTS)
|
||||||
|
for (i in 0 until TOTAL_SLOTS) {
|
||||||
|
if (i == SLOT_PREVIEW) continue
|
||||||
|
|
||||||
|
inventory.setItem(i, itemHandler.getStackInSlot(i))
|
||||||
|
}
|
||||||
|
level?.let { Containers.dropContents(it, blockPos, inventory) }
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val SLOT_INPUT_A = 0
|
||||||
|
const val SLOT_INPUT_B = 1
|
||||||
|
const val SLOT_OUTPUT = 2
|
||||||
|
const val SLOT_PREVIEW = 3
|
||||||
|
const val TOTAL_SLOTS = 4
|
||||||
|
|
||||||
|
const val DATA_BLOCK_TYPE = 0
|
||||||
|
const val DATA_BLOCK_SUBTYPE = 1
|
||||||
|
const val DATA_CURRENT = 2
|
||||||
|
const val DATA_MAX = 3
|
||||||
|
const val DATA_CRAFTING_ENABLED = 4
|
||||||
|
const val DATA_SIZE = 5
|
||||||
|
|
||||||
|
const val DEFAULT_PROCESS_TIME = 200 // in ticks
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -4,6 +4,7 @@ import net.minecraft.data.PackOutput
|
||||||
import net.neoforged.neoforge.client.model.generators.ItemModelProvider
|
import net.neoforged.neoforge.client.model.generators.ItemModelProvider
|
||||||
import net.neoforged.neoforge.common.data.ExistingFileHelper
|
import net.neoforged.neoforge.common.data.ExistingFileHelper
|
||||||
import xyz.nuark.mcmod.mclschcannoncompat.Mclschcannoncompat
|
import xyz.nuark.mcmod.mclschcannoncompat.Mclschcannoncompat
|
||||||
|
import xyz.nuark.mcmod.mclschcannoncompat.block.ModBlocks
|
||||||
import xyz.nuark.mcmod.mclschcannoncompat.item.ModItems
|
import xyz.nuark.mcmod.mclschcannoncompat.item.ModItems
|
||||||
|
|
||||||
class ModItemModelProvider(output: PackOutput, existingFileHelper: ExistingFileHelper) : ItemModelProvider(output, Mclschcannoncompat.ID, existingFileHelper) {
|
class ModItemModelProvider(output: PackOutput, existingFileHelper: ExistingFileHelper) : ItemModelProvider(output, Mclschcannoncompat.ID, existingFileHelper) {
|
||||||
|
|
@ -11,5 +12,6 @@ class ModItemModelProvider(output: PackOutput, existingFileHelper: ExistingFileH
|
||||||
basicItem(ModItems.BUILDER_ASSISTANT_STAFF_T1.get())
|
basicItem(ModItems.BUILDER_ASSISTANT_STAFF_T1.get())
|
||||||
basicItem(ModItems.BUILDER_ASSISTANT_STAFF_T2.get())
|
basicItem(ModItems.BUILDER_ASSISTANT_STAFF_T2.get())
|
||||||
basicItem(ModItems.BUILDER_ASSISTANT_STAFF_T3.get())
|
basicItem(ModItems.BUILDER_ASSISTANT_STAFF_T3.get())
|
||||||
|
simpleBlockItem(ModBlocks.ORNAMENT_FABRICATOR.get())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -12,7 +12,15 @@ object ModLanguageProviders {
|
||||||
add(ModItems.BUILDER_ASSISTANT_STAFF_T1.get(), "Посох строителя T1")
|
add(ModItems.BUILDER_ASSISTANT_STAFF_T1.get(), "Посох строителя T1")
|
||||||
add(ModItems.BUILDER_ASSISTANT_STAFF_T2.get(), "Посох строителя T2")
|
add(ModItems.BUILDER_ASSISTANT_STAFF_T2.get(), "Посох строителя T2")
|
||||||
add(ModItems.BUILDER_ASSISTANT_STAFF_T3.get(), "Посох строителя T3")
|
add(ModItems.BUILDER_ASSISTANT_STAFF_T3.get(), "Посох строителя T3")
|
||||||
add("item.asdf.assistantstaff.maxdepth", "Максимальная блоков: %s")
|
add(ModItems.ORNAMENT_FABRICATOR_ITEM.get(), "Орнаментный фабрикатор")
|
||||||
|
add("item.assistantstaff.hover.maxdepth", "Максимальная глубина: %s")
|
||||||
|
|
||||||
|
add("tooltip.ornament_fabricator.no_preview", "Рецепт не подходит этим ингредиентам")
|
||||||
|
add("tooltip.btn.cyclestyle.up", "Переключить стиль вперёд")
|
||||||
|
add("tooltip.btn.cyclestyle.down", "Переключить стиль назад")
|
||||||
|
add("tooltip.btn.cyclevariant.up", "Переключить вариант вперёд")
|
||||||
|
add("tooltip.btn.cyclevariant.down", "Переключить вариант назад")
|
||||||
|
add("tooltip.btn.startcrafting", "Начать крафт")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -21,7 +29,15 @@ object ModLanguageProviders {
|
||||||
add(ModItems.BUILDER_ASSISTANT_STAFF_T1.get(), "Builder staff T1")
|
add(ModItems.BUILDER_ASSISTANT_STAFF_T1.get(), "Builder staff T1")
|
||||||
add(ModItems.BUILDER_ASSISTANT_STAFF_T2.get(), "Builder staff T2")
|
add(ModItems.BUILDER_ASSISTANT_STAFF_T2.get(), "Builder staff T2")
|
||||||
add(ModItems.BUILDER_ASSISTANT_STAFF_T3.get(), "Builder staff T3")
|
add(ModItems.BUILDER_ASSISTANT_STAFF_T3.get(), "Builder staff T3")
|
||||||
add("item.asdf.assistantstaff.maxdepth", "Maximum depth: %s")
|
add(ModItems.ORNAMENT_FABRICATOR_ITEM.get(), "Ornament Fabricator")
|
||||||
|
add("item.assistantstaff.hover.maxdepth", "Maximum depth: %s")
|
||||||
|
|
||||||
|
add("tooltip.ornament_fabricator.no_preview", "Recipe is not supported for provided ingredients")
|
||||||
|
add("tooltip.btn.cyclestyle.up", "Cycle style forward")
|
||||||
|
add("tooltip.btn.cyclestyle.down", "Cycle style backward")
|
||||||
|
add("tooltip.btn.cyclevariant.up", "Cycle variant forward")
|
||||||
|
add("tooltip.btn.cyclevariant.down", "Cycle variant backward")
|
||||||
|
add("tooltip.btn.startcrafting", "Start crafting")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,6 @@ import xyz.nuark.mcmod.mclschcannoncompat.Mclschcannoncompat
|
||||||
import xyz.nuark.mcmod.mclschcannoncompat.item.ModItems
|
import xyz.nuark.mcmod.mclschcannoncompat.item.ModItems
|
||||||
import java.util.concurrent.CompletableFuture
|
import java.util.concurrent.CompletableFuture
|
||||||
|
|
||||||
|
|
||||||
class ModRecipeProvider(output: PackOutput, registries: CompletableFuture<HolderLookup.Provider>) : RecipeProvider(output, registries) {
|
class ModRecipeProvider(output: PackOutput, registries: CompletableFuture<HolderLookup.Provider>) : RecipeProvider(output, registries) {
|
||||||
override fun buildRecipes(recipeOutput: RecipeOutput) {
|
override fun buildRecipes(recipeOutput: RecipeOutput) {
|
||||||
ShapedRecipeBuilder.shaped(RecipeCategory.TOOLS, ModItems.BUILDER_ASSISTANT_STAFF_T1.get())
|
ShapedRecipeBuilder.shaped(RecipeCategory.TOOLS, ModItems.BUILDER_ASSISTANT_STAFF_T1.get())
|
||||||
|
|
@ -43,5 +42,15 @@ class ModRecipeProvider(output: PackOutput, registries: CompletableFuture<Holder
|
||||||
.define('S', ModItems.BUILDER_ASSISTANT_STAFF_T2.get())
|
.define('S', ModItems.BUILDER_ASSISTANT_STAFF_T2.get())
|
||||||
.unlockedBy("has_netherite_block", has(Items.NETHERITE_BLOCK))
|
.unlockedBy("has_netherite_block", has(Items.NETHERITE_BLOCK))
|
||||||
.save(recipeOutput, Mclschcannoncompat.resource("rec_fct3"))
|
.save(recipeOutput, Mclschcannoncompat.resource("rec_fct3"))
|
||||||
|
|
||||||
|
ShapedRecipeBuilder.shaped(RecipeCategory.DECORATIONS, ModItems.ORNAMENT_FABRICATOR_ITEM.get())
|
||||||
|
.pattern("III")
|
||||||
|
.pattern("ACA")
|
||||||
|
.pattern("III")
|
||||||
|
.define('I', Items.IRON_INGOT)
|
||||||
|
.define('A', Items.AMETHYST_SHARD)
|
||||||
|
.define('C', Items.CRAFTING_TABLE)
|
||||||
|
.unlockedBy("has_amethyst", has(Items.AMETHYST_SHARD))
|
||||||
|
.save(recipeOutput, Mclschcannoncompat.resource("ornament_fabricator"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -82,7 +82,7 @@ class BuilderAssistantStaff(
|
||||||
flagIn: TooltipFlag
|
flagIn: TooltipFlag
|
||||||
) {
|
) {
|
||||||
tooltipList.add(
|
tooltipList.add(
|
||||||
Component.translatable("item.asdf.assistantstaff.maxdepth", reach * MAX_PROPAGATION_DEPTH).withStyle(ChatFormatting.BLUE)
|
Component.translatable("item.assistantstaff.hover.maxdepth", reach * MAX_PROPAGATION_DEPTH).withStyle(ChatFormatting.BLUE)
|
||||||
)
|
)
|
||||||
tooltipList.add(
|
tooltipList.add(
|
||||||
Component.translatable("item.minecolonies.assistanthammer.desc").withStyle(ChatFormatting.ITALIC)
|
Component.translatable("item.minecolonies.assistanthammer.desc").withStyle(ChatFormatting.ITALIC)
|
||||||
|
|
|
||||||
|
|
@ -2,11 +2,20 @@ package xyz.nuark.mcmod.mclschcannoncompat.item
|
||||||
|
|
||||||
import net.neoforged.neoforge.registries.DeferredRegister
|
import net.neoforged.neoforge.registries.DeferredRegister
|
||||||
import xyz.nuark.mcmod.mclschcannoncompat.Mclschcannoncompat
|
import xyz.nuark.mcmod.mclschcannoncompat.Mclschcannoncompat
|
||||||
|
import xyz.nuark.mcmod.mclschcannoncompat.block.ModBlocks
|
||||||
|
|
||||||
object ModItems {
|
object ModItems {
|
||||||
val REGISTRY = DeferredRegister.createItems(Mclschcannoncompat.ID)
|
val REGISTRY = DeferredRegister.createItems(Mclschcannoncompat.ID)
|
||||||
|
|
||||||
val BUILDER_ASSISTANT_STAFF_T1 = REGISTRY.registerItem("builder_assistant_staff") { props -> BuilderAssistantStaff("builder_assistant_staff", props, 1) }
|
val BUILDER_ASSISTANT_STAFF_T1 = REGISTRY.registerItem("builder_assistant_staff") { props ->
|
||||||
val BUILDER_ASSISTANT_STAFF_T2 = REGISTRY.registerItem("builder_assistant_staff_t2") { props -> BuilderAssistantStaff("builder_assistant_staff_t2", props, 3) }
|
BuilderAssistantStaff("builder_assistant_staff", props, 1)
|
||||||
val BUILDER_ASSISTANT_STAFF_T3 = REGISTRY.registerItem("builder_assistant_staff_t3") { props -> BuilderAssistantStaff("builder_assistant_staff_t3", props, 5) }
|
}
|
||||||
|
val BUILDER_ASSISTANT_STAFF_T2 = REGISTRY.registerItem("builder_assistant_staff_t2") { props ->
|
||||||
|
BuilderAssistantStaff("builder_assistant_staff_t2", props, 3)
|
||||||
|
}
|
||||||
|
val BUILDER_ASSISTANT_STAFF_T3 = REGISTRY.registerItem("builder_assistant_staff_t3") { props ->
|
||||||
|
BuilderAssistantStaff("builder_assistant_staff_t3", props, 5)
|
||||||
|
}
|
||||||
|
|
||||||
|
val ORNAMENT_FABRICATOR_ITEM = REGISTRY.registerSimpleBlockItem(ModBlocks.ORNAMENT_FABRICATOR)
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
package xyz.nuark.mcmod.mclschcannoncompat.menu
|
||||||
|
|
||||||
|
import net.minecraft.world.inventory.MenuType
|
||||||
|
import net.neoforged.neoforge.common.extensions.IMenuTypeExtension
|
||||||
|
import net.neoforged.neoforge.registries.DeferredRegister
|
||||||
|
import xyz.nuark.mcmod.mclschcannoncompat.Mclschcannoncompat
|
||||||
|
import java.util.function.Supplier
|
||||||
|
|
||||||
|
object ModMenuTypes {
|
||||||
|
val REGISTRY = DeferredRegister.create(
|
||||||
|
net.minecraft.core.registries.BuiltInRegistries.MENU,
|
||||||
|
Mclschcannoncompat.ID
|
||||||
|
)
|
||||||
|
|
||||||
|
val ORNAMENT_FABRICATOR: Supplier<MenuType<OrnamentFabricatorMenu>> =
|
||||||
|
REGISTRY.register("ornament_fabricator", Supplier {
|
||||||
|
IMenuTypeExtension.create(OrnamentFabricatorMenu::fromNetwork)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,191 @@
|
||||||
|
package xyz.nuark.mcmod.mclschcannoncompat.menu
|
||||||
|
|
||||||
|
import net.minecraft.client.player.LocalPlayer
|
||||||
|
import net.minecraft.network.FriendlyByteBuf
|
||||||
|
import net.minecraft.network.protocol.game.ServerboundContainerButtonClickPacket
|
||||||
|
import net.minecraft.world.entity.player.Inventory
|
||||||
|
import net.minecraft.world.entity.player.Player
|
||||||
|
import net.minecraft.world.inventory.AbstractContainerMenu
|
||||||
|
import net.minecraft.world.inventory.ContainerData
|
||||||
|
import net.minecraft.world.inventory.Slot
|
||||||
|
import net.minecraft.world.item.ItemStack
|
||||||
|
import net.neoforged.neoforge.items.SlotItemHandler
|
||||||
|
import xyz.nuark.mcmod.mclschcannoncompat.block.entity.OrnamentFabricatorBlockEntity
|
||||||
|
import xyz.nuark.mcmod.mclschcannoncompat.utils.ODBlockRecipiesCache
|
||||||
|
|
||||||
|
class OrnamentFabricatorMenu(
|
||||||
|
containerId: Int,
|
||||||
|
private val playerInventory: Inventory,
|
||||||
|
private val blockEntity: OrnamentFabricatorBlockEntity,
|
||||||
|
private val data: ContainerData
|
||||||
|
) : AbstractContainerMenu(
|
||||||
|
ModMenuTypes.ORNAMENT_FABRICATOR.get(), containerId
|
||||||
|
) {
|
||||||
|
init {
|
||||||
|
require(blockEntity.itemHandler.slots >= OrnamentFabricatorBlockEntity.TOTAL_SLOTS) { "Container size ${blockEntity.itemHandler.slots} is smaller than expected ${OrnamentFabricatorBlockEntity.TOTAL_SLOTS}" }
|
||||||
|
checkContainerDataCount(data, OrnamentFabricatorBlockEntity.DATA_SIZE)
|
||||||
|
|
||||||
|
addSlot(SlotItemHandler(blockEntity.itemHandler, OrnamentFabricatorBlockEntity.SLOT_INPUT_A, 12, 50))
|
||||||
|
addSlot(SlotItemHandler(blockEntity.itemHandler, OrnamentFabricatorBlockEntity.SLOT_INPUT_B, 30, 50))
|
||||||
|
addSlot(SlotItemHandler(blockEntity.itemHandler, OrnamentFabricatorBlockEntity.SLOT_OUTPUT, 84, 50))
|
||||||
|
|
||||||
|
addSlot(object : SlotItemHandler(
|
||||||
|
blockEntity.itemHandler, OrnamentFabricatorBlockEntity.SLOT_PREVIEW, 156, 50
|
||||||
|
) {
|
||||||
|
override fun mayPlace(stack: ItemStack) = false
|
||||||
|
override fun mayPickup(player: Player) = false
|
||||||
|
override fun isActive() = true
|
||||||
|
})
|
||||||
|
|
||||||
|
for (row in 0..2) {
|
||||||
|
for (col in 0..8) {
|
||||||
|
addSlot(Slot(playerInventory, col + row * 9 + 9, INV_X + col * 18, INV_Y + row * 18))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (col in 0..8) {
|
||||||
|
addSlot(Slot(playerInventory, col, INV_X + col * 18, HOTBAR_Y))
|
||||||
|
}
|
||||||
|
|
||||||
|
addDataSlots(data)
|
||||||
|
}
|
||||||
|
|
||||||
|
val blockTypeIndex: Int get() = data.get(OrnamentFabricatorBlockEntity.DATA_BLOCK_TYPE)
|
||||||
|
val blockSubtypeIndex: Int get() = data.get(OrnamentFabricatorBlockEntity.DATA_BLOCK_SUBTYPE)
|
||||||
|
val currentProcess: Int get() = data.get(OrnamentFabricatorBlockEntity.DATA_CURRENT)
|
||||||
|
val maxProcess: Int get() = data.get(OrnamentFabricatorBlockEntity.DATA_MAX)
|
||||||
|
val craftingEnabled: Boolean get() = data.get(OrnamentFabricatorBlockEntity.DATA_CRAFTING_ENABLED) == 1
|
||||||
|
|
||||||
|
val progressFraction: Float
|
||||||
|
get() = if (maxProcess > 0) currentProcess.toFloat() / maxProcess.toFloat() else 0f
|
||||||
|
|
||||||
|
override fun quickMoveStack(player: Player, slotIndex: Int): ItemStack {
|
||||||
|
var remainder = ItemStack.EMPTY
|
||||||
|
val slot = slots.getOrNull(slotIndex) ?: return remainder
|
||||||
|
if (!slot.hasItem()) return remainder
|
||||||
|
|
||||||
|
val stack = slot.item
|
||||||
|
remainder = stack.copy()
|
||||||
|
|
||||||
|
val beSlots = 0 until OrnamentFabricatorBlockEntity.TOTAL_SLOTS
|
||||||
|
val invSlots = OrnamentFabricatorBlockEntity.TOTAL_SLOTS until
|
||||||
|
OrnamentFabricatorBlockEntity.TOTAL_SLOTS + 27
|
||||||
|
val barSlots = OrnamentFabricatorBlockEntity.TOTAL_SLOTS + 27 until
|
||||||
|
OrnamentFabricatorBlockEntity.TOTAL_SLOTS + 36
|
||||||
|
|
||||||
|
if (slotIndex in beSlots) {
|
||||||
|
if (!moveItemStackTo(stack, invSlots.first, barSlots.last + 1, true))
|
||||||
|
return ItemStack.EMPTY
|
||||||
|
} else {
|
||||||
|
if (!moveItemStackTo(
|
||||||
|
stack, OrnamentFabricatorBlockEntity.SLOT_INPUT_A,
|
||||||
|
OrnamentFabricatorBlockEntity.SLOT_INPUT_B + 1, false
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
if (slotIndex in invSlots) {
|
||||||
|
if (!moveItemStackTo(stack, barSlots.first, barSlots.last + 1, false))
|
||||||
|
return ItemStack.EMPTY
|
||||||
|
} else {
|
||||||
|
if (!moveItemStackTo(stack, invSlots.first, invSlots.last + 1, false))
|
||||||
|
return ItemStack.EMPTY
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stack.isEmpty) slot.set(ItemStack.EMPTY) else slot.setChanged()
|
||||||
|
if (stack.count == remainder.count) return ItemStack.EMPTY
|
||||||
|
slot.onTake(player, stack)
|
||||||
|
return remainder
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun stillValid(player: Player): Boolean =
|
||||||
|
!blockEntity.isRemoved && player.canInteractWithBlock(blockEntity.blockPos, 8.0)
|
||||||
|
|
||||||
|
fun cycleBlockTypeUp() = sendTypeChangePacket(ButtonIds.BUTTON_TYPE_UP)
|
||||||
|
fun cycleBlockTypeDown() = sendTypeChangePacket(ButtonIds.BUTTON_TYPE_DOWN)
|
||||||
|
fun cycleSubtypeUp() = sendTypeChangePacket(ButtonIds.BUTTON_SUBTYPE_UP)
|
||||||
|
fun cycleSubtypeDown() = sendTypeChangePacket(ButtonIds.BUTTON_SUBTYPE_DOWN)
|
||||||
|
fun startCrafting() = sendTypeChangePacket(ButtonIds.BUTTON_BUTTON_START_CRAFTING)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Client-side handler for button clicks made by the user.
|
||||||
|
*/
|
||||||
|
private fun sendTypeChangePacket(buttonId: Int) {
|
||||||
|
(playerInventory.player as? LocalPlayer)?.connection?.send(
|
||||||
|
ServerboundContainerButtonClickPacket(containerId, buttonId)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Server-side handler for button clicks sent by the client.
|
||||||
|
*/
|
||||||
|
override fun clickMenuButton(player: Player, id: Int): Boolean {
|
||||||
|
when (id) {
|
||||||
|
ButtonIds.BUTTON_TYPE_UP -> {
|
||||||
|
blockEntity.blockTypeIndex = (blockEntity.blockTypeIndex + 1).coerceIn(
|
||||||
|
ODBlockRecipiesCache.getBlockTypesCache().indices
|
||||||
|
)
|
||||||
|
blockEntity.blockSubtypeIndex = 0
|
||||||
|
|
||||||
|
blockEntity.craftingEnabled = false
|
||||||
|
blockEntity.currentProcess = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
ButtonIds.BUTTON_TYPE_DOWN -> {
|
||||||
|
blockEntity.blockTypeIndex = (blockEntity.blockTypeIndex - 1).coerceIn(
|
||||||
|
ODBlockRecipiesCache.getBlockTypesCache().indices
|
||||||
|
)
|
||||||
|
blockEntity.blockSubtypeIndex = 0
|
||||||
|
|
||||||
|
blockEntity.craftingEnabled = false
|
||||||
|
blockEntity.currentProcess = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
ButtonIds.BUTTON_SUBTYPE_UP -> {
|
||||||
|
val range = ODBlockRecipiesCache.getBlockVariantsCache()[blockEntity.blockTypeIndex]?.indices ?: 0..0
|
||||||
|
blockEntity.blockSubtypeIndex = (blockEntity.blockSubtypeIndex + 1).coerceIn(range)
|
||||||
|
|
||||||
|
blockEntity.craftingEnabled = false
|
||||||
|
blockEntity.currentProcess = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
ButtonIds.BUTTON_SUBTYPE_DOWN -> {
|
||||||
|
val range = ODBlockRecipiesCache.getBlockVariantsCache()[blockEntity.blockTypeIndex]?.indices ?: 0..0
|
||||||
|
blockEntity.blockSubtypeIndex = (blockEntity.blockSubtypeIndex - 1).coerceIn(range)
|
||||||
|
|
||||||
|
blockEntity.craftingEnabled = false
|
||||||
|
blockEntity.currentProcess = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
ButtonIds.BUTTON_BUTTON_START_CRAFTING -> {
|
||||||
|
blockEntity.craftingEnabled = true
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
blockEntity.setChanged()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun fromNetwork(containerId: Int, playerInventory: Inventory, buf: FriendlyByteBuf): OrnamentFabricatorMenu {
|
||||||
|
val pos = buf.readBlockPos()
|
||||||
|
val be = playerInventory.player.level().getBlockEntity(pos) as OrnamentFabricatorBlockEntity
|
||||||
|
return OrnamentFabricatorMenu(containerId, playerInventory, be, be.containerData)
|
||||||
|
}
|
||||||
|
|
||||||
|
const val INV_X = 12
|
||||||
|
const val INV_Y = 81
|
||||||
|
const val HOTBAR_Y = 139
|
||||||
|
|
||||||
|
object ButtonIds {
|
||||||
|
const val BUTTON_TYPE_UP = 0
|
||||||
|
const val BUTTON_TYPE_DOWN = 1
|
||||||
|
const val BUTTON_SUBTYPE_UP = 2
|
||||||
|
const val BUTTON_SUBTYPE_DOWN = 3
|
||||||
|
const val BUTTON_BUTTON_START_CRAFTING = 4
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,181 @@
|
||||||
|
package xyz.nuark.mcmod.mclschcannoncompat.screen
|
||||||
|
|
||||||
|
import net.minecraft.client.gui.GuiGraphics
|
||||||
|
import net.minecraft.client.gui.components.Button
|
||||||
|
import net.minecraft.client.gui.components.Tooltip
|
||||||
|
import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen
|
||||||
|
import net.minecraft.network.chat.Component
|
||||||
|
import net.minecraft.resources.ResourceLocation
|
||||||
|
import net.minecraft.world.entity.player.Inventory
|
||||||
|
import xyz.nuark.mcmod.mclschcannoncompat.Mclschcannoncompat
|
||||||
|
import xyz.nuark.mcmod.mclschcannoncompat.block.entity.OrnamentFabricatorBlockEntity
|
||||||
|
import xyz.nuark.mcmod.mclschcannoncompat.menu.OrnamentFabricatorMenu
|
||||||
|
import xyz.nuark.mcmod.mclschcannoncompat.utils.ODBlockRecipiesCache
|
||||||
|
|
||||||
|
class OrnamentFabricatorScreen(
|
||||||
|
menu: OrnamentFabricatorMenu,
|
||||||
|
playerInventory: Inventory,
|
||||||
|
title: Component
|
||||||
|
) : AbstractContainerScreen<OrnamentFabricatorMenu>(menu, playerInventory, title) {
|
||||||
|
private lateinit var btnTypeUp: Button
|
||||||
|
private lateinit var btnTypeDown: Button
|
||||||
|
private lateinit var btnSubtypeUp: Button
|
||||||
|
private lateinit var btnSubtypeDown: Button
|
||||||
|
private lateinit var btnStartCrafting: Button
|
||||||
|
|
||||||
|
init {
|
||||||
|
imageWidth = BG_WIDTH
|
||||||
|
imageHeight = BG_HEIGHT
|
||||||
|
|
||||||
|
titleLabelX = 11
|
||||||
|
inventoryLabelY = 6
|
||||||
|
|
||||||
|
inventoryLabelX = 11
|
||||||
|
inventoryLabelY = 70
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun init() {
|
||||||
|
super.init()
|
||||||
|
|
||||||
|
val bx = leftPos
|
||||||
|
val by = topPos
|
||||||
|
|
||||||
|
btnTypeUp = Button.builder(Component.literal(">")) { menu.cycleBlockTypeUp() }
|
||||||
|
.pos(bx + 161, by + 17)
|
||||||
|
.size(BTN_W, BTN_H)
|
||||||
|
.tooltip(Tooltip.create(Component.translatable("tooltip.btn.cyclestyle.up")))
|
||||||
|
.build()
|
||||||
|
.also { addRenderableWidget(it) }
|
||||||
|
|
||||||
|
btnTypeDown = Button.builder(Component.literal("<")) { menu.cycleBlockTypeDown() }
|
||||||
|
.pos(bx + 11, by + 17)
|
||||||
|
.size(BTN_W, BTN_H)
|
||||||
|
.tooltip(Tooltip.create(Component.translatable("tooltip.btn.cyclestyle.down")))
|
||||||
|
.build()
|
||||||
|
.also { addRenderableWidget(it) }
|
||||||
|
|
||||||
|
btnSubtypeUp = Button.builder(Component.literal(">")) { menu.cycleSubtypeUp() }
|
||||||
|
.pos(bx + 161, by + 33)
|
||||||
|
.size(BTN_W, BTN_H)
|
||||||
|
.tooltip(Tooltip.create(Component.translatable("tooltip.btn.cyclevariant.up")))
|
||||||
|
.build()
|
||||||
|
.also { addRenderableWidget(it) }
|
||||||
|
|
||||||
|
btnSubtypeDown = Button.builder(Component.literal("<")) { menu.cycleSubtypeDown() }
|
||||||
|
.pos(bx + 11, by + 33)
|
||||||
|
.size(BTN_W, BTN_H)
|
||||||
|
.tooltip(Tooltip.create(Component.translatable("tooltip.btn.cyclevariant.down")))
|
||||||
|
.build()
|
||||||
|
.also { addRenderableWidget(it) }
|
||||||
|
|
||||||
|
btnStartCrafting = Button.builder(Component.literal("v")) { menu.startCrafting() }
|
||||||
|
.pos(bx + 105, by + 52)
|
||||||
|
.size(BTN_W, BTN_H)
|
||||||
|
.tooltip(Tooltip.create(Component.translatable("tooltip.btn.startcrafting")))
|
||||||
|
.build()
|
||||||
|
.also { addRenderableWidget(it) }
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun renderBg(graphics: GuiGraphics, partialTick: Float, mouseX: Int, mouseY: Int) {
|
||||||
|
graphics.blit(
|
||||||
|
TEXTURE,
|
||||||
|
leftPos, topPos, // screen position
|
||||||
|
0f, 0f, // UV origin of background
|
||||||
|
imageWidth, imageHeight, // size to blit
|
||||||
|
TEX_WIDTH, TEX_HEIGHT
|
||||||
|
)
|
||||||
|
|
||||||
|
val progressWidth = (PROGRESS_WIDTH * menu.progressFraction).toInt().coerceAtLeast(0)
|
||||||
|
if (progressWidth > 0) {
|
||||||
|
graphics.blit(
|
||||||
|
TEXTURE,
|
||||||
|
leftPos + PROGRESS_X,
|
||||||
|
topPos + PROGRESS_Y,
|
||||||
|
PROGRESS_U.toFloat(), PROGRESS_V.toFloat(),
|
||||||
|
progressWidth, PROGRESS_HEIGHT,
|
||||||
|
TEX_WIDTH, TEX_HEIGHT
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun render(graphics: GuiGraphics, mouseX: Int, mouseY: Int, partialTick: Float) {
|
||||||
|
super.render(graphics, mouseX, mouseY, partialTick)
|
||||||
|
renderTooltip(graphics, mouseX, mouseY)
|
||||||
|
|
||||||
|
val type = ODBlockRecipiesCache.getBlockTypesCache().getOrNull(menu.blockTypeIndex)
|
||||||
|
val variant = ODBlockRecipiesCache.getBlockVariantsCache().getOrDefault(menu.blockTypeIndex, emptyList()).getOrNull(menu.blockSubtypeIndex)
|
||||||
|
|
||||||
|
graphics.drawString(
|
||||||
|
font,
|
||||||
|
if (type != null) Component.literal("${menu.blockTypeIndex}. ").append(Component.translatable("cuttergroup.${type.namespace}.${type.path}")) else Component.translatable("tooltip.ornament_fabricator.no_preview"),
|
||||||
|
leftPos + 29, topPos + 19,
|
||||||
|
0xBEBEBE, false
|
||||||
|
)
|
||||||
|
graphics.drawString(
|
||||||
|
font,
|
||||||
|
if (variant != null) Component.literal("${menu.blockSubtypeIndex}. ${variant.displayName.string}") else Component.translatable("tooltip.ornament_fabricator.no_preview"),
|
||||||
|
leftPos + 29, topPos + 35,
|
||||||
|
0xBEBEBE, false
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun renderTooltip(graphics: GuiGraphics, mouseX: Int, mouseY: Int) {
|
||||||
|
super.renderTooltip(graphics, mouseX, mouseY)
|
||||||
|
|
||||||
|
val previewAbsX = leftPos + 156
|
||||||
|
val previewAbsY = topPos + 50
|
||||||
|
|
||||||
|
if (mouseX in previewAbsX..(previewAbsX + 16) &&
|
||||||
|
mouseY in previewAbsY..(previewAbsY + 16)
|
||||||
|
) {
|
||||||
|
val previewStack = menu.slots[3].item
|
||||||
|
if (!previewStack.isEmpty) {
|
||||||
|
graphics.renderTooltip(
|
||||||
|
this.font,
|
||||||
|
this.getTooltipFromContainerItem(previewStack),
|
||||||
|
previewStack.getTooltipImage(),
|
||||||
|
previewStack,
|
||||||
|
mouseX,
|
||||||
|
mouseY
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
graphics.renderTooltip(
|
||||||
|
font,
|
||||||
|
Component.translatable("tooltip.ornament_fabricator.no_preview"),
|
||||||
|
mouseX, mouseY
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun renderLabels(graphics: GuiGraphics, mouseX: Int, mouseY: Int) {
|
||||||
|
graphics.drawString(font, title, titleLabelX, titleLabelY, 0xBEBEBE, false)
|
||||||
|
graphics.drawString(font, playerInventoryTitle, inventoryLabelX, inventoryLabelY, 0xBEBEBE, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val TEXTURE = ResourceLocation.fromNamespaceAndPath(
|
||||||
|
Mclschcannoncompat.ID, "textures/gui/ornament_fabricator.png"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Background size (must match your PNG atlas dimensions you blit)
|
||||||
|
private const val BG_WIDTH = 184
|
||||||
|
private const val BG_HEIGHT = 163
|
||||||
|
|
||||||
|
// Progress bar (blitted as a partial sprite)
|
||||||
|
private const val PROGRESS_X = 51
|
||||||
|
private const val PROGRESS_Y = 53
|
||||||
|
private const val PROGRESS_U = 184 // UV X in texture
|
||||||
|
private const val PROGRESS_V = 0 // UV Y in texture
|
||||||
|
private const val PROGRESS_WIDTH = 28
|
||||||
|
private const val PROGRESS_HEIGHT = 10
|
||||||
|
|
||||||
|
// Texture sheet total size (usually 256×256)
|
||||||
|
private const val TEX_WIDTH = 256
|
||||||
|
private const val TEX_HEIGHT = 256
|
||||||
|
|
||||||
|
// Button positions (relative to background top-left, i.e. imageX / imageY)
|
||||||
|
private const val BTN_W = 12
|
||||||
|
private const val BTN_H = 12
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"variants": {
|
||||||
|
"": { "model": "mclschcannoncompat:block/ornament_fabricator" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"parent": "minecraft:block/cube_all",
|
||||||
|
"textures": {
|
||||||
|
"all": "mclschcannoncompat:block/ornament_fabricator"
|
||||||
|
}
|
||||||
|
}
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 6.5 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 1.7 KiB |
Loading…
Add table
Add a link
Reference in a new issue