mirror of
https://github.com/Theta-Dev/ConstructionWand.git
synced 2025-04-21 00:50:04 +02:00
Compare commits
12 commits
1.20.2-2.1
...
1.18
Author | SHA1 | Date | |
---|---|---|---|
|
5d4fe7454a | ||
31bfbdb7f1 | |||
ce0012dc3c | |||
dc21a8882f | |||
2497f85800 | |||
|
d006a24ab7 | ||
|
e83cae7ae2 | ||
|
a9f703e28f | ||
d69901c0fa | |||
aefb3e138b | |||
710a6a7ba1 | |||
7a89175bf1 |
44 changed files with 430 additions and 627 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -19,7 +19,7 @@ build
|
||||||
|
|
||||||
# other
|
# other
|
||||||
eclipse
|
eclipse
|
||||||
/run*
|
run
|
||||||
|
|
||||||
# Files from Forge MDK
|
# Files from Forge MDK
|
||||||
forge*changelog.txt
|
forge*changelog.txt
|
||||||
|
|
20
README.md
20
README.md
|
@ -4,7 +4,7 @@ With a Construction Wand you can place multiple blocks (up to 1024) at once, ext
|
||||||
facing. If that's not enough: you can upgrade your wand with additional cores, allowing you to place a block behind the
|
facing. If that's not enough: you can upgrade your wand with additional cores, allowing you to place a block behind the
|
||||||
block you are facing, conjure blocks in mid air or destroy lots of blocks very fast.
|
block you are facing, conjure blocks in mid air or destroy lots of blocks very fast.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
**Note:** These are the instructions for ConstructionWand version 2.0+, which introduced some new features.
|
**Note:** These are the instructions for ConstructionWand version 2.0+, which introduced some new features.
|
||||||
If you are still using version 1.x, refer to [those](https://github.com/Theta-Dev/ConstructionWand/tree/1.16.2-1.7)
|
If you are still using version 1.x, refer to [those](https://github.com/Theta-Dev/ConstructionWand/tree/1.16.2-1.7)
|
||||||
|
@ -23,12 +23,12 @@ and last longer. These properties can be changed in the config.
|
||||||
| Infinity | Unbreakable | 1024 | Yes | 8 | 81 |
|
| Infinity | Unbreakable | 1024 | Yes | 8 | 81 |
|
||||||
|
|
||||||
## Crafting
|
## Crafting
|
||||||

|

|
||||||

|

|
||||||

|

|
||||||

|

|
||||||

|

|
||||||

|

|
||||||
|
|
||||||
## Keybindings
|
## Keybindings
|
||||||
|
|
||||||
|
@ -69,7 +69,7 @@ you can use the undo feature if you've made a mistake.
|
||||||
## Options
|
## Options
|
||||||
SNEAK+OPTKEY+Right clicking empty space opens the option screen of your wand.
|
SNEAK+OPTKEY+Right clicking empty space opens the option screen of your wand.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
**Restriction:** If restriction is enabled the wand will only place blocks in one row or column
|
**Restriction:** If restriction is enabled the wand will only place blocks in one row or column
|
||||||
(choose between North/South, East/West on a horizontal plane and Horizontal, Vertical on a vertical plane).
|
(choose between North/South, East/West on a horizontal plane and Horizontal, Vertical on a vertical plane).
|
||||||
|
@ -79,7 +79,7 @@ has no effect if the angel core is enabled.
|
||||||
**Direction:** If set to "Player" the wand places blocks in the same direction as if they were placed by yourself.
|
**Direction:** If set to "Player" the wand places blocks in the same direction as if they were placed by yourself.
|
||||||
Target mode places the blocks in the same direction as their supporting block. See the picture below:
|
Target mode places the blocks in the same direction as their supporting block. See the picture below:
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
**Replacement:** Enables/disables the replacement of replaceable blocks (Fluids, snow, tallgrass).
|
**Replacement:** Enables/disables the replacement of replaceable blocks (Fluids, snow, tallgrass).
|
||||||
|
|
||||||
|
@ -122,7 +122,7 @@ for TileEntities in CW Version 1.7. Chisels&Bits blocks are blacklisted by defau
|
||||||
There are probably a few other tile entities from other mods out there which may cause issues as well.
|
There are probably a few other tile entities from other mods out there which may cause issues as well.
|
||||||
If you find some of them you can tell me by creating
|
If you find some of them you can tell me by creating
|
||||||
an issue, commenting on Curse or editing the default blacklist yourself
|
an issue, commenting on Curse or editing the default blacklist yourself
|
||||||
(it is located at https://github.com/Theta-Dev/ConstructionWand/blob/1.19/src/main/java/thetadev/constructionwand/basics/ConfigServer.java#L25)
|
(it is located at https://github.com/Theta-Dev/ConstructionWand/blob/1.16.2/src/main/java/thetadev/constructionwand/basics/ConfigServer.java#L28)
|
||||||
and making a PR.
|
and making a PR.
|
||||||
|
|
||||||
## Contributions and #Hacktoberfest
|
## Contributions and #Hacktoberfest
|
||||||
|
|
57
build.gradle
57
build.gradle
|
@ -7,30 +7,20 @@ buildscript {
|
||||||
classpath group: 'net.minecraftforge.gradle', name: 'ForgeGradle', version: '5.1.+', changing: true
|
classpath group: 'net.minecraftforge.gradle', name: 'ForgeGradle', version: '5.1.+', changing: true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
apply plugin: 'net.minecraftforge.gradle'
|
||||||
plugins {
|
// Only edit below this line, the above code adds and enables the necessary things for Forge to be setup.
|
||||||
id 'eclipse'
|
apply plugin: 'eclipse'
|
||||||
id 'idea'
|
apply plugin: 'maven-publish'
|
||||||
id 'maven-publish'
|
|
||||||
id 'net.minecraftforge.gradle' version '[6.0.14,6.2)'
|
|
||||||
}
|
|
||||||
|
|
||||||
version = "${mcversion}-${version_major}.${version_minor}"
|
version = "${mcversion}-${version_major}.${version_minor}"
|
||||||
group = "${author}.${modid}"
|
group = "${author}.${modid}"
|
||||||
archivesBaseName = "${modid}"
|
archivesBaseName = "${modid}"
|
||||||
|
|
||||||
// Mojang ships Java 17 to end users in 1.18+, so your mod should target Java 17.
|
|
||||||
java.toolchain.languageVersion = JavaLanguageVersion.of(17)
|
java.toolchain.languageVersion = JavaLanguageVersion.of(17)
|
||||||
|
|
||||||
println "Java: ${System.getProperty 'java.version'}, JVM: ${System.getProperty 'java.vm.version'} (${System.getProperty 'java.vendor'}), Arch: ${System.getProperty 'os.arch'}"
|
|
||||||
minecraft {
|
minecraft {
|
||||||
mappings channel: project.mcp_channel, version: project.mcp_mappings
|
mappings channel: project.mcp_channel, version: project.mcp_mappings
|
||||||
|
|
||||||
// This property allows configuring Gradle's ProcessResources task(s) to run on IDE output locations before launching the game.
|
|
||||||
// It is REQUIRED to be set to true for this template to function.
|
|
||||||
// See https://docs.gradle.org/current/dsl/org.gradle.language.jvm.tasks.ProcessResources.html
|
|
||||||
copyIdeResources = true
|
|
||||||
|
|
||||||
runs {
|
runs {
|
||||||
client {
|
client {
|
||||||
workingDirectory project.file("run/client").canonicalPath
|
workingDirectory project.file("run/client").canonicalPath
|
||||||
|
@ -41,9 +31,6 @@ minecraft {
|
||||||
// Recommended logging level for the console
|
// Recommended logging level for the console
|
||||||
property 'forge.logging.console.level', 'debug'
|
property 'forge.logging.console.level', 'debug'
|
||||||
|
|
||||||
// Comma-separated list of namespaces to load gametests from. Empty = all namespaces.
|
|
||||||
// property 'forge.enabledGameTestNamespaces', modid
|
|
||||||
|
|
||||||
mods {
|
mods {
|
||||||
constructionwand {
|
constructionwand {
|
||||||
source sourceSets.main
|
source sourceSets.main
|
||||||
|
@ -60,8 +47,6 @@ minecraft {
|
||||||
// Recommended logging level for the console
|
// Recommended logging level for the console
|
||||||
property 'forge.logging.console.level', 'debug'
|
property 'forge.logging.console.level', 'debug'
|
||||||
|
|
||||||
// property 'forge.enabledGameTestNamespaces', modid
|
|
||||||
|
|
||||||
mods {
|
mods {
|
||||||
constructionwand {
|
constructionwand {
|
||||||
source sourceSets.main
|
source sourceSets.main
|
||||||
|
@ -69,25 +54,6 @@ minecraft {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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 {
|
|
||||||
workingDirectory project.file('run')
|
|
||||||
|
|
||||||
property 'forge.logging.markers', 'REGISTRIES'
|
|
||||||
|
|
||||||
property 'forge.logging.console.level', 'debug'
|
|
||||||
|
|
||||||
property 'forge.enabledGameTestNamespaces', modid
|
|
||||||
|
|
||||||
mods {
|
|
||||||
examplemod {
|
|
||||||
source sourceSets.main
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
data {
|
data {
|
||||||
workingDirectory project.file("run/client").canonicalPath
|
workingDirectory project.file("run/client").canonicalPath
|
||||||
|
|
||||||
|
@ -122,6 +88,10 @@ repositories {
|
||||||
maven {
|
maven {
|
||||||
url = "https://maven.theillusivec4.top/"
|
url = "https://maven.theillusivec4.top/"
|
||||||
}
|
}
|
||||||
|
maven {
|
||||||
|
name = "JEI Maven"
|
||||||
|
url "https://dvs1.progwml6.com/files/maven"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
@ -131,9 +101,8 @@ dependencies {
|
||||||
version: "${project.mcversion}-${project.forgeversion}"
|
version: "${project.mcversion}-${project.forgeversion}"
|
||||||
])
|
])
|
||||||
|
|
||||||
compileOnly fg.deobf("mezz.jei:jei-${mcversion}-common-api:${jei_version}")
|
compileOnly fg.deobf("mezz.jei:${jei_version}:api")
|
||||||
compileOnly fg.deobf("mezz.jei:jei-${mcversion}-forge-api:${jei_version}")
|
runtimeOnly fg.deobf("mezz.jei:${jei_version}")
|
||||||
runtimeOnly fg.deobf("mezz.jei:jei-${mcversion}-forge:${jei_version}")
|
|
||||||
|
|
||||||
compileOnly fg.deobf([
|
compileOnly fg.deobf([
|
||||||
group: "vazkii.botania",
|
group: "vazkii.botania",
|
||||||
|
@ -174,8 +143,4 @@ publishing {
|
||||||
url "file:///${project.projectDir}/mcmodsrepo"
|
url "file:///${project.projectDir}/mcmodsrepo"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.withType(JavaCompile).configureEach {
|
|
||||||
options.encoding = 'UTF-8' // Use the UTF-8 charset for Java compilation
|
|
||||||
}
|
|
|
@ -4,15 +4,15 @@ org.gradle.daemon=false
|
||||||
author=thetadev
|
author=thetadev
|
||||||
modid=constructionwand
|
modid=constructionwand
|
||||||
|
|
||||||
mcversion=1.20.2
|
mcversion=1.18.1
|
||||||
forgeversion=48.0.30
|
forgeversion=39.1.0
|
||||||
mcp_channel=official
|
mcp_channel=official
|
||||||
mcp_mappings=1.20.2
|
mcp_mappings=1.18.1
|
||||||
|
|
||||||
# Source: https://maven.blamejared.com/vazkii/botania/Botania/
|
# Source: https://maven.blamejared.com/vazkii/botania/Botania/
|
||||||
botania=1.20.1-441-FORGE-SNAPSHOT
|
botania=1.18.1-429
|
||||||
# Source: https://maven.blamejared.com/mezz/jei/
|
# Source: https://dvs1.progwml6.com/files/maven/mezz/jei/
|
||||||
jei_version=16.0.0.28
|
jei_version=jei-1.18.1:9.1.0.41
|
||||||
|
|
||||||
version_major=2
|
version_major=2
|
||||||
version_minor=12
|
version_minor=11
|
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Binary file not shown.
3
gradle/wrapper/gradle-wrapper.properties
vendored
3
gradle/wrapper/gradle-wrapper.properties
vendored
|
@ -1,6 +1,5 @@
|
||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.1.1-bin.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3-bin.zip
|
||||||
networkTimeout=10000
|
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
|
|
257
gradlew
vendored
257
gradlew
vendored
|
@ -1,7 +1,7 @@
|
||||||
#!/bin/sh
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
#
|
#
|
||||||
# Copyright © 2015-2021 the original authors.
|
# Copyright 2015 the original author or authors.
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
# you may not use this file except in compliance with the License.
|
# you may not use this file except in compliance with the License.
|
||||||
|
@ -17,101 +17,67 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
##############################################################################
|
##############################################################################
|
||||||
#
|
##
|
||||||
# Gradle start up script for POSIX generated by Gradle.
|
## Gradle start up script for UN*X
|
||||||
#
|
##
|
||||||
# Important for running:
|
|
||||||
#
|
|
||||||
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
|
|
||||||
# noncompliant, but you have some other compliant shell such as ksh or
|
|
||||||
# bash, then to run this script, type that shell name before the whole
|
|
||||||
# command line, like:
|
|
||||||
#
|
|
||||||
# ksh Gradle
|
|
||||||
#
|
|
||||||
# Busybox and similar reduced shells will NOT work, because this script
|
|
||||||
# requires all of these POSIX shell features:
|
|
||||||
# * functions;
|
|
||||||
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
|
|
||||||
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
|
|
||||||
# * compound commands having a testable exit status, especially «case»;
|
|
||||||
# * various built-in commands including «command», «set», and «ulimit».
|
|
||||||
#
|
|
||||||
# Important for patching:
|
|
||||||
#
|
|
||||||
# (2) This script targets any POSIX shell, so it avoids extensions provided
|
|
||||||
# by Bash, Ksh, etc; in particular arrays are avoided.
|
|
||||||
#
|
|
||||||
# The "traditional" practice of packing multiple parameters into a
|
|
||||||
# space-separated string is a well documented source of bugs and security
|
|
||||||
# problems, so this is (mostly) avoided, by progressively accumulating
|
|
||||||
# options in "$@", and eventually passing that to Java.
|
|
||||||
#
|
|
||||||
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
|
|
||||||
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
|
|
||||||
# see the in-line comments for details.
|
|
||||||
#
|
|
||||||
# There are tweaks for specific operating systems such as AIX, CygWin,
|
|
||||||
# Darwin, MinGW, and NonStop.
|
|
||||||
#
|
|
||||||
# (3) This script is generated from the Groovy template
|
|
||||||
# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
|
||||||
# within the Gradle project.
|
|
||||||
#
|
|
||||||
# You can find Gradle at https://github.com/gradle/gradle/.
|
|
||||||
#
|
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
# Attempt to set APP_HOME
|
# Attempt to set APP_HOME
|
||||||
|
|
||||||
# Resolve links: $0 may be a link
|
# Resolve links: $0 may be a link
|
||||||
app_path=$0
|
PRG="$0"
|
||||||
|
# Need this for relative symlinks.
|
||||||
# Need this for daisy-chained symlinks.
|
while [ -h "$PRG" ] ; do
|
||||||
while
|
ls=`ls -ld "$PRG"`
|
||||||
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
|
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||||
[ -h "$app_path" ]
|
if expr "$link" : '/.*' > /dev/null; then
|
||||||
do
|
PRG="$link"
|
||||||
ls=$( ls -ld "$app_path" )
|
else
|
||||||
link=${ls#*' -> '}
|
PRG=`dirname "$PRG"`"/$link"
|
||||||
case $link in #(
|
fi
|
||||||
/*) app_path=$link ;; #(
|
|
||||||
*) app_path=$APP_HOME$link ;;
|
|
||||||
esac
|
|
||||||
done
|
done
|
||||||
|
SAVED="`pwd`"
|
||||||
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
|
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||||
|
APP_HOME="`pwd -P`"
|
||||||
|
cd "$SAVED" >/dev/null
|
||||||
|
|
||||||
APP_NAME="Gradle"
|
APP_NAME="Gradle"
|
||||||
APP_BASE_NAME=${0##*/}
|
APP_BASE_NAME=`basename "$0"`
|
||||||
|
|
||||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||||
|
|
||||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||||
MAX_FD=maximum
|
MAX_FD="maximum"
|
||||||
|
|
||||||
warn () {
|
warn () {
|
||||||
echo "$*"
|
echo "$*"
|
||||||
} >&2
|
}
|
||||||
|
|
||||||
die () {
|
die () {
|
||||||
echo
|
echo
|
||||||
echo "$*"
|
echo "$*"
|
||||||
echo
|
echo
|
||||||
exit 1
|
exit 1
|
||||||
} >&2
|
}
|
||||||
|
|
||||||
# OS specific support (must be 'true' or 'false').
|
# OS specific support (must be 'true' or 'false').
|
||||||
cygwin=false
|
cygwin=false
|
||||||
msys=false
|
msys=false
|
||||||
darwin=false
|
darwin=false
|
||||||
nonstop=false
|
nonstop=false
|
||||||
case "$( uname )" in #(
|
case "`uname`" in
|
||||||
CYGWIN* ) cygwin=true ;; #(
|
CYGWIN* )
|
||||||
Darwin* ) darwin=true ;; #(
|
cygwin=true
|
||||||
MSYS* | MINGW* ) msys=true ;; #(
|
;;
|
||||||
NONSTOP* ) nonstop=true ;;
|
Darwin* )
|
||||||
|
darwin=true
|
||||||
|
;;
|
||||||
|
MSYS* | MINGW* )
|
||||||
|
msys=true
|
||||||
|
;;
|
||||||
|
NONSTOP* )
|
||||||
|
nonstop=true
|
||||||
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||||
|
@ -121,9 +87,9 @@ CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||||
if [ -n "$JAVA_HOME" ] ; then
|
if [ -n "$JAVA_HOME" ] ; then
|
||||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||||
# IBM's JDK on AIX uses strange locations for the executables
|
# IBM's JDK on AIX uses strange locations for the executables
|
||||||
JAVACMD=$JAVA_HOME/jre/sh/java
|
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||||
else
|
else
|
||||||
JAVACMD=$JAVA_HOME/bin/java
|
JAVACMD="$JAVA_HOME/bin/java"
|
||||||
fi
|
fi
|
||||||
if [ ! -x "$JAVACMD" ] ; then
|
if [ ! -x "$JAVACMD" ] ; then
|
||||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||||
|
@ -132,7 +98,7 @@ Please set the JAVA_HOME variable in your environment to match the
|
||||||
location of your Java installation."
|
location of your Java installation."
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
JAVACMD=java
|
JAVACMD="java"
|
||||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
|
|
||||||
Please set the JAVA_HOME variable in your environment to match the
|
Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
@ -140,95 +106,80 @@ location of your Java installation."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Increase the maximum file descriptors if we can.
|
# Increase the maximum file descriptors if we can.
|
||||||
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
||||||
case $MAX_FD in #(
|
MAX_FD_LIMIT=`ulimit -H -n`
|
||||||
max*)
|
if [ $? -eq 0 ] ; then
|
||||||
MAX_FD=$( ulimit -H -n ) ||
|
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||||
warn "Could not query maximum file descriptor limit"
|
MAX_FD="$MAX_FD_LIMIT"
|
||||||
esac
|
fi
|
||||||
case $MAX_FD in #(
|
ulimit -n $MAX_FD
|
||||||
'' | soft) :;; #(
|
if [ $? -ne 0 ] ; then
|
||||||
*)
|
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||||
ulimit -n "$MAX_FD" ||
|
fi
|
||||||
warn "Could not set maximum file descriptor limit to $MAX_FD"
|
else
|
||||||
esac
|
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Collect all arguments for the java command, stacking in reverse order:
|
# For Darwin, add options to specify how the application appears in the dock
|
||||||
# * args from the command line
|
if $darwin; then
|
||||||
# * the main class name
|
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||||
# * -classpath
|
fi
|
||||||
# * -D...appname settings
|
|
||||||
# * --module-path (only if needed)
|
|
||||||
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
|
|
||||||
|
|
||||||
# For Cygwin or MSYS, switch paths to Windows format before running java
|
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||||
if "$cygwin" || "$msys" ; then
|
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
|
||||||
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
|
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||||
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
|
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||||
|
|
||||||
JAVACMD=$( cygpath --unix "$JAVACMD" )
|
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||||
|
|
||||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
# We build the pattern for arguments to be converted via cygpath
|
||||||
for arg do
|
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||||
if
|
SEP=""
|
||||||
case $arg in #(
|
for dir in $ROOTDIRSRAW ; do
|
||||||
-*) false ;; # don't mess with options #(
|
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||||
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
|
SEP="|"
|
||||||
[ -e "$t" ] ;; #(
|
|
||||||
*) false ;;
|
|
||||||
esac
|
|
||||||
then
|
|
||||||
arg=$( cygpath --path --ignore --mixed "$arg" )
|
|
||||||
fi
|
|
||||||
# Roll the args list around exactly as many times as the number of
|
|
||||||
# args, so each arg winds up back in the position where it started, but
|
|
||||||
# possibly modified.
|
|
||||||
#
|
|
||||||
# NB: a `for` loop captures its iteration list before it begins, so
|
|
||||||
# changing the positional parameters here affects neither the number of
|
|
||||||
# iterations, nor the values presented in `arg`.
|
|
||||||
shift # remove old arg
|
|
||||||
set -- "$@" "$arg" # push replacement arg
|
|
||||||
done
|
done
|
||||||
|
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||||
|
# Add a user-defined pattern to the cygpath arguments
|
||||||
|
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||||
|
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||||
|
fi
|
||||||
|
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||||
|
i=0
|
||||||
|
for arg in "$@" ; do
|
||||||
|
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||||
|
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||||
|
|
||||||
|
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||||
|
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||||
|
else
|
||||||
|
eval `echo args$i`="\"$arg\""
|
||||||
|
fi
|
||||||
|
i=`expr $i + 1`
|
||||||
|
done
|
||||||
|
case $i in
|
||||||
|
0) set -- ;;
|
||||||
|
1) set -- "$args0" ;;
|
||||||
|
2) set -- "$args0" "$args1" ;;
|
||||||
|
3) set -- "$args0" "$args1" "$args2" ;;
|
||||||
|
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||||
|
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||||
|
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||||
|
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||||
|
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||||
|
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||||
|
esac
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Collect all arguments for the java command;
|
# Escape application args
|
||||||
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
|
save () {
|
||||||
# shell script including quotes and variable substitutions, so put them in
|
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||||
# double quotes to make sure that they get re-expanded; and
|
echo " "
|
||||||
# * put everything else in single quotes, so that it's not re-expanded.
|
}
|
||||||
|
APP_ARGS=`save "$@"`
|
||||||
|
|
||||||
set -- \
|
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||||
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||||
-classpath "$CLASSPATH" \
|
|
||||||
org.gradle.wrapper.GradleWrapperMain \
|
|
||||||
"$@"
|
|
||||||
|
|
||||||
# Use "xargs" to parse quoted args.
|
|
||||||
#
|
|
||||||
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
|
|
||||||
#
|
|
||||||
# In Bash we could simply go:
|
|
||||||
#
|
|
||||||
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
|
|
||||||
# set -- "${ARGS[@]}" "$@"
|
|
||||||
#
|
|
||||||
# but POSIX shell has neither arrays nor command substitution, so instead we
|
|
||||||
# post-process each arg (as a line of input to sed) to backslash-escape any
|
|
||||||
# character that might be a shell metacharacter, then use eval to reverse
|
|
||||||
# that process (while maintaining the separation between arguments), and wrap
|
|
||||||
# the whole thing up as a single "set" statement.
|
|
||||||
#
|
|
||||||
# This will of course break if any of these variables contains a newline or
|
|
||||||
# an unmatched quote.
|
|
||||||
#
|
|
||||||
|
|
||||||
eval "set -- $(
|
|
||||||
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
|
|
||||||
xargs -n1 |
|
|
||||||
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
|
|
||||||
tr '\n' ' '
|
|
||||||
)" '"$@"'
|
|
||||||
|
|
||||||
exec "$JAVACMD" "$@"
|
exec "$JAVACMD" "$@"
|
||||||
|
|
|
@ -1,13 +0,0 @@
|
||||||
# Builds
|
|
||||||
|
|
||||||
Overview of all builds of ConstructionWand and their properties.
|
|
||||||
|
|
||||||
| Build | Java version | Supported MC versions |
|
|
||||||
|--------|--------------|-----------------------|
|
|
||||||
| 1.14.4 | 8 | 1.14.4 |
|
|
||||||
| 1.15.2 | 8 | 1.15.2 |
|
|
||||||
| 1.16.1 | 8 | 1.16.1 |
|
|
||||||
| 1.16.5 | 8 | 1.16.2 - 1.16.5 |
|
|
||||||
| 1.17.1 | 16 | 1.17.1 |
|
|
||||||
| 1.18 | 17 | 1.18 |
|
|
||||||
| 1.19 | 17 | 1.19 - 1.19.2 |
|
|
|
@ -1,11 +0,0 @@
|
||||||
# Testing item containers
|
|
||||||
- Install the toolbelt mod (https://www.curseforge.com/minecraft/mc-mods/tool-belt)
|
|
||||||
- Place a chest on top of a command block and enter this command:
|
|
||||||
- Get a toolbeld with 2 stacks of diamond blocks in it
|
|
||||||
|
|
||||||
The reason for this hack is that the toolbelt mod gets updated very quickly and is available for almost every
|
|
||||||
MC version supported by ConstructionWand.
|
|
||||||
|
|
||||||
```
|
|
||||||
data merge block ~ ~1 ~ {Items: [{Slot: 0, id: "toolbelt:belt", Count: 1, tag: {Items: [{Slot: 0, id: "minecraft:diamond_block", Count: 64}, {Slot: 1, id: "minecraft:diamond_block", Count: 64}]}}]}
|
|
||||||
```
|
|
|
@ -1,6 +0,0 @@
|
||||||
pluginManagement {
|
|
||||||
repositories {
|
|
||||||
gradlePluginPortal()
|
|
||||||
maven { url = 'https://maven.minecraftforge.net/' }
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -8,27 +8,35 @@ import net.minecraftforge.fml.config.ModConfig;
|
||||||
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
|
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
|
||||||
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
|
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
|
||||||
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
|
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
|
||||||
|
import net.minecraftforge.network.NetworkRegistry;
|
||||||
|
import net.minecraftforge.network.simple.SimpleChannel;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import thetadev.constructionwand.basics.ConfigClient;
|
import thetadev.constructionwand.basics.ConfigClient;
|
||||||
import thetadev.constructionwand.basics.ConfigServer;
|
import thetadev.constructionwand.basics.ConfigServer;
|
||||||
import thetadev.constructionwand.basics.ModStats;
|
import thetadev.constructionwand.basics.ModStats;
|
||||||
|
import thetadev.constructionwand.basics.ReplacementRegistry;
|
||||||
import thetadev.constructionwand.client.ClientEvents;
|
import thetadev.constructionwand.client.ClientEvents;
|
||||||
import thetadev.constructionwand.client.RenderBlockPreview;
|
import thetadev.constructionwand.client.RenderBlockPreview;
|
||||||
import thetadev.constructionwand.containers.ContainerManager;
|
import thetadev.constructionwand.containers.ContainerManager;
|
||||||
import thetadev.constructionwand.containers.ContainerRegistrar;
|
import thetadev.constructionwand.containers.ContainerRegistrar;
|
||||||
import thetadev.constructionwand.items.ModItems;
|
import thetadev.constructionwand.items.ModItems;
|
||||||
import thetadev.constructionwand.network.ModMessages;
|
import thetadev.constructionwand.network.PacketQueryUndo;
|
||||||
|
import thetadev.constructionwand.network.PacketUndoBlocks;
|
||||||
|
import thetadev.constructionwand.network.PacketWandOption;
|
||||||
import thetadev.constructionwand.wand.undo.UndoHistory;
|
import thetadev.constructionwand.wand.undo.UndoHistory;
|
||||||
|
|
||||||
|
|
||||||
@Mod(ConstructionWand.MODID)
|
@Mod(ConstructionWand.MODID)
|
||||||
public class ConstructionWand {
|
public class ConstructionWand
|
||||||
|
{
|
||||||
public static final String MODID = "constructionwand";
|
public static final String MODID = "constructionwand";
|
||||||
public static final String MODNAME = "ConstructionWand";
|
public static final String MODNAME = "ConstructionWand";
|
||||||
|
|
||||||
public static ConstructionWand instance;
|
public static ConstructionWand instance;
|
||||||
public static final Logger LOGGER = LogManager.getLogger();
|
public static final Logger LOGGER = LogManager.getLogger();
|
||||||
|
private static final String PROTOCOL_VERSION = "1";
|
||||||
|
public SimpleChannel HANDLER;
|
||||||
|
|
||||||
public ContainerManager containerManager;
|
public ContainerManager containerManager;
|
||||||
public UndoHistory undoHistory;
|
public UndoHistory undoHistory;
|
||||||
|
@ -57,11 +65,18 @@ public class ConstructionWand {
|
||||||
LOGGER.info("ConstructionWand says hello - may the odds be ever in your favor.");
|
LOGGER.info("ConstructionWand says hello - may the odds be ever in your favor.");
|
||||||
|
|
||||||
// Register packets
|
// Register packets
|
||||||
ModMessages.register();
|
HANDLER = NetworkRegistry.newSimpleChannel(new ResourceLocation(MODID, "main"), () -> PROTOCOL_VERSION, PROTOCOL_VERSION::equals, PROTOCOL_VERSION::equals);
|
||||||
|
int packetIndex = 0;
|
||||||
|
HANDLER.registerMessage(packetIndex++, PacketUndoBlocks.class, PacketUndoBlocks::encode, PacketUndoBlocks::decode, PacketUndoBlocks.Handler::handle);
|
||||||
|
HANDLER.registerMessage(packetIndex++, PacketQueryUndo.class, PacketQueryUndo::encode, PacketQueryUndo::decode, PacketQueryUndo.Handler::handle);
|
||||||
|
HANDLER.registerMessage(packetIndex, PacketWandOption.class, PacketWandOption::encode, PacketWandOption::decode, PacketWandOption.Handler::handle);
|
||||||
|
|
||||||
// Container registry
|
// Container registry
|
||||||
ContainerRegistrar.register();
|
ContainerRegistrar.register();
|
||||||
|
|
||||||
|
//Replacement registry
|
||||||
|
ReplacementRegistry.init();
|
||||||
|
|
||||||
// Stats
|
// Stats
|
||||||
ModStats.register();
|
ModStats.register();
|
||||||
}
|
}
|
||||||
|
@ -72,6 +87,7 @@ public class ConstructionWand {
|
||||||
MinecraftForge.EVENT_BUS.register(new ClientEvents());
|
MinecraftForge.EVENT_BUS.register(new ClientEvents());
|
||||||
|
|
||||||
event.enqueueWork(ModItems::registerModelProperties);
|
event.enqueueWork(ModItems::registerModelProperties);
|
||||||
|
event.enqueueWork(ModItems::registerItemColors);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ResourceLocation loc(String name) {
|
public static ResourceLocation loc(String name) {
|
||||||
|
|
|
@ -2,7 +2,6 @@ package thetadev.constructionwand.basics;
|
||||||
|
|
||||||
import net.minecraft.world.entity.player.Player;
|
import net.minecraft.world.entity.player.Player;
|
||||||
import net.minecraftforge.event.entity.player.PlayerEvent;
|
import net.minecraftforge.event.entity.player.PlayerEvent;
|
||||||
import net.minecraftforge.event.server.ServerStartingEvent;
|
|
||||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||||
import net.minecraftforge.fml.common.Mod;
|
import net.minecraftforge.fml.common.Mod;
|
||||||
import thetadev.constructionwand.ConstructionWand;
|
import thetadev.constructionwand.ConstructionWand;
|
||||||
|
@ -10,15 +9,10 @@ import thetadev.constructionwand.ConstructionWand;
|
||||||
@Mod.EventBusSubscriber(modid = ConstructionWand.MODID)
|
@Mod.EventBusSubscriber(modid = ConstructionWand.MODID)
|
||||||
public class CommonEvents
|
public class CommonEvents
|
||||||
{
|
{
|
||||||
@SubscribeEvent
|
|
||||||
public static void serverStarting(ServerStartingEvent e) {
|
|
||||||
ReplacementRegistry.init();
|
|
||||||
}
|
|
||||||
|
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
public static void logOut(PlayerEvent.PlayerLoggedOutEvent e) {
|
public static void logOut(PlayerEvent.PlayerLoggedOutEvent e) {
|
||||||
Player player = e.getEntity();
|
Player player = e.getPlayer();
|
||||||
if(player.level().isClientSide) return;
|
if(player.level.isClientSide) return;
|
||||||
ConstructionWand.instance.undoHistory.removePlayer(player);
|
ConstructionWand.instance.undoHistory.removePlayer(player);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,6 @@ import net.minecraft.resources.ResourceLocation;
|
||||||
import net.minecraft.world.item.Item;
|
import net.minecraft.world.item.Item;
|
||||||
import net.minecraft.world.item.Tiers;
|
import net.minecraft.world.item.Tiers;
|
||||||
import net.minecraftforge.common.ForgeConfigSpec;
|
import net.minecraftforge.common.ForgeConfigSpec;
|
||||||
import net.minecraftforge.registries.ForgeRegistries;
|
|
||||||
import net.minecraftforge.registries.RegistryObject;
|
import net.minecraftforge.registries.RegistryObject;
|
||||||
import thetadev.constructionwand.items.ModItems;
|
import thetadev.constructionwand.items.ModItems;
|
||||||
|
|
||||||
|
@ -14,7 +13,7 @@ import java.util.List;
|
||||||
|
|
||||||
public class ConfigServer
|
public class ConfigServer
|
||||||
{
|
{
|
||||||
public static final ForgeConfigSpec SPEC;
|
private static final ForgeConfigSpec.Builder BUILDER = new ForgeConfigSpec.Builder();
|
||||||
|
|
||||||
public static final ForgeConfigSpec.IntValue LIMIT_CREATIVE;
|
public static final ForgeConfigSpec.IntValue LIMIT_CREATIVE;
|
||||||
public static final ForgeConfigSpec.IntValue MAX_RANGE;
|
public static final ForgeConfigSpec.IntValue MAX_RANGE;
|
||||||
|
@ -33,7 +32,7 @@ public class ConfigServer
|
||||||
private static final HashMap<ResourceLocation, WandProperties> wandProperties = new HashMap<>();
|
private static final HashMap<ResourceLocation, WandProperties> wandProperties = new HashMap<>();
|
||||||
|
|
||||||
public static WandProperties getWandProperties(Item wand) {
|
public static WandProperties getWandProperties(Item wand) {
|
||||||
return wandProperties.getOrDefault(ForgeRegistries.ITEMS.getKey(wand), WandProperties.DEFAULT);
|
return wandProperties.getOrDefault(wand.getRegistryName(), WandProperties.DEFAULT);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class WandProperties
|
public static class WandProperties
|
||||||
|
@ -101,41 +100,39 @@ public class ConfigServer
|
||||||
}
|
}
|
||||||
|
|
||||||
static {
|
static {
|
||||||
final var builder = new ForgeConfigSpec.Builder();
|
BUILDER.comment("This is the Server config for ConstructionWand.",
|
||||||
|
|
||||||
builder.comment("This is the Server config for ConstructionWand.",
|
|
||||||
"If you're not familiar with Forge's new split client/server config, let me explain:",
|
"If you're not familiar with Forge's new split client/server config, let me explain:",
|
||||||
"Client config is stored in the /config folder and only contains client specific settings like graphics and keybinds.",
|
"Client config is stored in the /config folder and only contains client specific settings like graphics and keybinds.",
|
||||||
"Mod behavior is configured in the Server config, which is world-specific and thus located",
|
"Mod behavior is configured in the Server config, which is world-specific and thus located",
|
||||||
"in the /saves/myworld/serverconfig folder. If you want to change the serverconfig for all",
|
"in the /saves/myworld/serverconfig folder. If you want to change the serverconfig for all",
|
||||||
"new worlds, copy the config files in the /defaultconfigs folder.");
|
"new worlds, copy the config files in the /defaultconfigs folder.");
|
||||||
|
|
||||||
new WandProperties(builder, ModItems.WAND_STONE, Tiers.STONE.getUses(), 9, 0, 0, false);
|
new WandProperties(BUILDER, ModItems.WAND_STONE, Tiers.STONE.getUses(), 9, 0, 0, false);
|
||||||
new WandProperties(builder, ModItems.WAND_IRON, Tiers.IRON.getUses(), 27, 2, 9, true);
|
new WandProperties(BUILDER, ModItems.WAND_IRON, Tiers.IRON.getUses(), 27, 2, 9, true);
|
||||||
new WandProperties(builder, ModItems.WAND_DIAMOND, Tiers.DIAMOND.getUses(), 128, 8, 25, true);
|
new WandProperties(BUILDER, ModItems.WAND_DIAMOND, Tiers.DIAMOND.getUses(), 128, 8, 25, true);
|
||||||
new WandProperties(builder, ModItems.WAND_INFINITY, 0, 1024, 16, 81, true);
|
new WandProperties(BUILDER, ModItems.WAND_INFINITY, 0, 1024, 16, 81, true);
|
||||||
|
|
||||||
builder.push("misc");
|
BUILDER.push("misc");
|
||||||
builder.comment("Block limit for Infinity Wand used in creative mode");
|
BUILDER.comment("Block limit for Infinity Wand used in creative mode");
|
||||||
LIMIT_CREATIVE = builder.defineInRange("InfinityWandCreative", 2048, 1, Integer.MAX_VALUE);
|
LIMIT_CREATIVE = BUILDER.defineInRange("InfinityWandCreative", 2048, 1, Integer.MAX_VALUE);
|
||||||
builder.comment("Maximum placement range (0: unlimited). Affects all wands and is meant for lag prevention, not game balancing.");
|
BUILDER.comment("Maximum placement range (0: unlimited). Affects all wands and is meant for lag prevention, not game balancing.");
|
||||||
MAX_RANGE = builder.defineInRange("MaxRange", 100, 0, Integer.MAX_VALUE);
|
MAX_RANGE = BUILDER.defineInRange("MaxRange", 100, 0, Integer.MAX_VALUE);
|
||||||
builder.comment("Number of operations that can be undone");
|
BUILDER.comment("Number of operations that can be undone");
|
||||||
UNDO_HISTORY = builder.defineInRange("UndoHistory", 3, 0, Integer.MAX_VALUE);
|
UNDO_HISTORY = BUILDER.defineInRange("UndoHistory", 3, 0, Integer.MAX_VALUE);
|
||||||
builder.comment("Place blocks below you while falling > 10 blocks with angel core (Can be used to save you from drops/the void)");
|
BUILDER.comment("Place blocks below you while falling > 10 blocks with angel core (Can be used to save you from drops/the void)");
|
||||||
ANGEL_FALLING = builder.define("AngelFalling", false);
|
ANGEL_FALLING = BUILDER.define("AngelFalling", false);
|
||||||
builder.comment("Blocks to treat equally when in Similar mode. Enter block IDs seperated by ;");
|
BUILDER.comment("Blocks to treat equally when in Similar mode. Enter block IDs seperated by ;");
|
||||||
SIMILAR_BLOCKS = builder.defineList("SimilarBlocks", Arrays.asList(SIMILAR_BLOCKS_DEFAULT), obj -> true);
|
SIMILAR_BLOCKS = BUILDER.defineList("SimilarBlocks", Arrays.asList(SIMILAR_BLOCKS_DEFAULT), obj -> true);
|
||||||
builder.pop();
|
BUILDER.pop();
|
||||||
|
|
||||||
builder.push("tileentity");
|
BUILDER.push("tileentity");
|
||||||
builder.comment("White/Blacklist for Tile Entities. Allow/Prevent blocks with TEs from being placed by wand.",
|
BUILDER.comment("White/Blacklist for Tile Entities. Allow/Prevent blocks with TEs from being placed by wand.",
|
||||||
"You can either add block ids like minecraft:chest or mod ids like minecraft");
|
"You can either add block ids like minecraft:chest or mod ids like minecraft");
|
||||||
TE_LIST = builder.defineList("TEList", Arrays.asList(TE_LIST_DEFAULT), obj -> true);
|
TE_LIST = BUILDER.defineList("TEList", Arrays.asList(TE_LIST_DEFAULT), obj -> true);
|
||||||
builder.comment("If set to TRUE, treat TEList as a whitelist, otherwise blacklist");
|
BUILDER.comment("If set to TRUE, treat TEList as a whitelist, otherwise blacklist");
|
||||||
TE_WHITELIST = builder.define("TEWhitelist", false);
|
TE_WHITELIST = BUILDER.define("TEWhitelist", false);
|
||||||
builder.pop();
|
BUILDER.pop();
|
||||||
|
|
||||||
SPEC = builder.build();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static final ForgeConfigSpec SPEC = BUILDER.build();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package thetadev.constructionwand.basics;
|
package thetadev.constructionwand.basics;
|
||||||
|
|
||||||
import net.minecraft.core.Registry;
|
import net.minecraft.core.Registry;
|
||||||
import net.minecraft.core.registries.BuiltInRegistries;
|
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
import net.minecraft.stats.StatFormatter;
|
import net.minecraft.stats.StatFormatter;
|
||||||
import net.minecraft.stats.Stats;
|
import net.minecraft.stats.Stats;
|
||||||
|
@ -17,7 +16,7 @@ public class ModStats
|
||||||
|
|
||||||
private static void registerStat(ResourceLocation registryName) {
|
private static void registerStat(ResourceLocation registryName) {
|
||||||
// Compare with net.minecraft.stats.Stats#registerCustom
|
// Compare with net.minecraft.stats.Stats#registerCustom
|
||||||
Registry.register(BuiltInRegistries.CUSTOM_STAT, registryName.getPath(), registryName);
|
Registry.register(Registry.CUSTOM_STAT, registryName.getPath(), registryName);
|
||||||
Stats.CUSTOM.get(registryName, StatFormatter.DEFAULT);
|
Stats.CUSTOM.get(registryName, StatFormatter.DEFAULT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,8 +16,6 @@ public class ReplacementRegistry
|
||||||
private static final HashSet<HashSet<Item>> replacements = new HashSet<>();
|
private static final HashSet<HashSet<Item>> replacements = new HashSet<>();
|
||||||
|
|
||||||
public static void init() {
|
public static void init() {
|
||||||
replacements.clear();
|
|
||||||
|
|
||||||
for(Object key : ConfigServer.SIMILAR_BLOCKS.get()) {
|
for(Object key : ConfigServer.SIMILAR_BLOCKS.get()) {
|
||||||
if(!(key instanceof String)) continue;
|
if(!(key instanceof String)) continue;
|
||||||
HashSet<Item> set = new HashSet<>();
|
HashSet<Item> set = new HashSet<>();
|
||||||
|
|
|
@ -20,8 +20,7 @@ import net.minecraft.world.phys.Vec3;
|
||||||
import net.minecraft.world.phys.shapes.VoxelShape;
|
import net.minecraft.world.phys.shapes.VoxelShape;
|
||||||
import net.minecraftforge.common.MinecraftForge;
|
import net.minecraftforge.common.MinecraftForge;
|
||||||
import net.minecraftforge.common.util.BlockSnapshot;
|
import net.minecraftforge.common.util.BlockSnapshot;
|
||||||
import net.minecraftforge.event.level.BlockEvent;
|
import net.minecraftforge.event.world.BlockEvent;
|
||||||
import net.minecraftforge.registries.ForgeRegistries;
|
|
||||||
import thetadev.constructionwand.ConstructionWand;
|
import thetadev.constructionwand.ConstructionWand;
|
||||||
import thetadev.constructionwand.containers.ContainerManager;
|
import thetadev.constructionwand.containers.ContainerManager;
|
||||||
import thetadev.constructionwand.items.wand.ItemWand;
|
import thetadev.constructionwand.items.wand.ItemWand;
|
||||||
|
@ -53,13 +52,12 @@ public class WandUtil
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static BlockPos posFromVec(Vec3 vec) {
|
public static BlockPos playerPos(Player player) {
|
||||||
return new BlockPos(
|
return new BlockPos(player.position());
|
||||||
(int) Math.round(vec.x), (int) Math.round(vec.y), (int) Math.round(vec.z));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Vec3 entityPositionVec(Entity entity) {
|
public static Vec3 entityPositionVec(Entity entity) {
|
||||||
return new Vec3(entity.getX(), entity.getY() + entity.getBbHeight() / 2, entity.getZ());
|
return new Vec3(entity.getX(), entity.getY() - entity.getMyRidingOffset() + entity.getBbHeight() / 2, entity.getZ());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Vec3 blockPosVec(BlockPos pos) {
|
public static Vec3 blockPosVec(BlockPos pos) {
|
||||||
|
@ -93,7 +91,7 @@ public class WandUtil
|
||||||
public static boolean isTEAllowed(BlockState state) {
|
public static boolean isTEAllowed(BlockState state) {
|
||||||
if(!state.hasBlockEntity()) return true;
|
if(!state.hasBlockEntity()) return true;
|
||||||
|
|
||||||
ResourceLocation name = ForgeRegistries.BLOCKS.getKey(state.getBlock());
|
ResourceLocation name = state.getBlock().getRegistryName();
|
||||||
if(name == null) return false;
|
if(name == null) return false;
|
||||||
|
|
||||||
String fullId = name.toString();
|
String fullId = name.toString();
|
||||||
|
|
|
@ -1,18 +1,17 @@
|
||||||
package thetadev.constructionwand.basics.pool;
|
package thetadev.constructionwand.basics.pool;
|
||||||
|
|
||||||
import net.minecraft.util.RandomSource;
|
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
public class RandomPool<T> implements IPool<T>
|
public class RandomPool<T> implements IPool<T>
|
||||||
{
|
{
|
||||||
private final RandomSource rng;
|
private final Random rng;
|
||||||
private final HashMap<T, Integer> elements;
|
private final HashMap<T, Integer> elements;
|
||||||
private HashSet<T> pool;
|
private HashSet<T> pool;
|
||||||
|
|
||||||
public RandomPool(RandomSource rng) {
|
public RandomPool(Random rng) {
|
||||||
this.rng = rng;
|
this.rng = rng;
|
||||||
elements = new HashMap<>();
|
elements = new HashMap<>();
|
||||||
reset();
|
reset();
|
||||||
|
|
|
@ -8,11 +8,11 @@ import net.minecraftforge.client.event.InputEvent;
|
||||||
import net.minecraftforge.event.entity.player.PlayerInteractEvent;
|
import net.minecraftforge.event.entity.player.PlayerInteractEvent;
|
||||||
import net.minecraftforge.eventbus.api.EventPriority;
|
import net.minecraftforge.eventbus.api.EventPriority;
|
||||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||||
|
import thetadev.constructionwand.ConstructionWand;
|
||||||
import thetadev.constructionwand.basics.ConfigClient;
|
import thetadev.constructionwand.basics.ConfigClient;
|
||||||
import thetadev.constructionwand.basics.WandUtil;
|
import thetadev.constructionwand.basics.WandUtil;
|
||||||
import thetadev.constructionwand.basics.option.WandOptions;
|
import thetadev.constructionwand.basics.option.WandOptions;
|
||||||
import thetadev.constructionwand.items.wand.ItemWand;
|
import thetadev.constructionwand.items.wand.ItemWand;
|
||||||
import thetadev.constructionwand.network.ModMessages;
|
|
||||||
import thetadev.constructionwand.network.PacketQueryUndo;
|
import thetadev.constructionwand.network.PacketQueryUndo;
|
||||||
import thetadev.constructionwand.network.PacketWandOption;
|
import thetadev.constructionwand.network.PacketWandOption;
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ public class ClientEvents
|
||||||
|
|
||||||
// Send state of OPT key to server
|
// Send state of OPT key to server
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
public void KeyEvent(InputEvent.Key event) {
|
public void KeyEvent(InputEvent.KeyInputEvent event) {
|
||||||
Player player = Minecraft.getInstance().player;
|
Player player = Minecraft.getInstance().player;
|
||||||
if(player == null) return;
|
if(player == null) return;
|
||||||
if(WandUtil.holdingWand(player) == null) return;
|
if(WandUtil.holdingWand(player) == null) return;
|
||||||
|
@ -34,16 +34,17 @@ public class ClientEvents
|
||||||
boolean optState = isOptKeyDown();
|
boolean optState = isOptKeyDown();
|
||||||
if(optPressed != optState) {
|
if(optPressed != optState) {
|
||||||
optPressed = optState;
|
optPressed = optState;
|
||||||
ModMessages.sendToServer(new PacketQueryUndo(optPressed));
|
PacketQueryUndo packet = new PacketQueryUndo(optPressed);
|
||||||
|
ConstructionWand.instance.HANDLER.sendToServer(packet);
|
||||||
//ConstructionWand.LOGGER.debug("OPT key update: " + optPressed);
|
//ConstructionWand.LOGGER.debug("OPT key update: " + optPressed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sneak+(OPT)+Scroll to change direction lock
|
// Sneak+(OPT)+Scroll to change direction lock
|
||||||
@SubscribeEvent(priority = EventPriority.HIGHEST)
|
@SubscribeEvent(priority = EventPriority.HIGHEST)
|
||||||
public void MouseScrollEvent(InputEvent.MouseScrollingEvent event) {
|
public void MouseScrollEvent(InputEvent.MouseScrollEvent event) {
|
||||||
Player player = Minecraft.getInstance().player;
|
Player player = Minecraft.getInstance().player;
|
||||||
double scroll = event.getDeltaY();
|
double scroll = event.getScrollDelta();
|
||||||
|
|
||||||
if(player == null || !modeKeyCombDown(player) || scroll == 0) return;
|
if(player == null || !modeKeyCombDown(player) || scroll == 0) return;
|
||||||
|
|
||||||
|
@ -52,14 +53,14 @@ public class ClientEvents
|
||||||
|
|
||||||
WandOptions wandOptions = new WandOptions(wand);
|
WandOptions wandOptions = new WandOptions(wand);
|
||||||
wandOptions.lock.next(scroll < 0);
|
wandOptions.lock.next(scroll < 0);
|
||||||
ModMessages.sendToServer(new PacketWandOption(wandOptions.lock, true));
|
ConstructionWand.instance.HANDLER.sendToServer(new PacketWandOption(wandOptions.lock, true));
|
||||||
event.setCanceled(true);
|
event.setCanceled(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sneak+(OPT)+Left click wand to change core
|
// Sneak+(OPT)+Left click wand to change core
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
public void onLeftClickEmpty(PlayerInteractEvent.LeftClickEmpty event) {
|
public void onLeftClickEmpty(PlayerInteractEvent.LeftClickEmpty event) {
|
||||||
Player player = event.getEntity();
|
Player player = event.getPlayer();
|
||||||
|
|
||||||
if(player == null || !modeKeyCombDown(player)) return;
|
if(player == null || !modeKeyCombDown(player)) return;
|
||||||
|
|
||||||
|
@ -68,7 +69,7 @@ public class ClientEvents
|
||||||
|
|
||||||
WandOptions wandOptions = new WandOptions(wand);
|
WandOptions wandOptions = new WandOptions(wand);
|
||||||
wandOptions.cores.next();
|
wandOptions.cores.next();
|
||||||
ModMessages.sendToServer(new PacketWandOption(wandOptions.cores, true));
|
ConstructionWand.instance.HANDLER.sendToServer(new PacketWandOption(wandOptions.cores, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sneak+(OPT)+Right click wand to open GUI
|
// Sneak+(OPT)+Right click wand to open GUI
|
||||||
|
@ -76,7 +77,7 @@ public class ClientEvents
|
||||||
public void onRightClickItem(PlayerInteractEvent.RightClickItem event) {
|
public void onRightClickItem(PlayerInteractEvent.RightClickItem event) {
|
||||||
if(event.getSide().isServer()) return;
|
if(event.getSide().isServer()) return;
|
||||||
|
|
||||||
Player player = event.getEntity();
|
Player player = event.getPlayer();
|
||||||
if(player == null || !guiKeyCombDown(player)) return;
|
if(player == null || !guiKeyCombDown(player)) return;
|
||||||
|
|
||||||
ItemStack wand = event.getItemStack();
|
ItemStack wand = event.getItemStack();
|
||||||
|
|
|
@ -12,7 +12,7 @@ import net.minecraft.world.item.ItemStack;
|
||||||
import net.minecraft.world.phys.AABB;
|
import net.minecraft.world.phys.AABB;
|
||||||
import net.minecraft.world.phys.BlockHitResult;
|
import net.minecraft.world.phys.BlockHitResult;
|
||||||
import net.minecraft.world.phys.HitResult;
|
import net.minecraft.world.phys.HitResult;
|
||||||
import net.minecraftforge.client.event.RenderHighlightEvent;
|
import net.minecraftforge.client.event.DrawSelectionEvent;
|
||||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||||
import thetadev.constructionwand.basics.WandUtil;
|
import thetadev.constructionwand.basics.WandUtil;
|
||||||
import thetadev.constructionwand.items.wand.ItemWand;
|
import thetadev.constructionwand.items.wand.ItemWand;
|
||||||
|
@ -26,7 +26,7 @@ public class RenderBlockPreview
|
||||||
public Set<BlockPos> undoBlocks;
|
public Set<BlockPos> undoBlocks;
|
||||||
|
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
public void renderBlockHighlight(RenderHighlightEvent.Block event) {
|
public void renderBlockHighlight(DrawSelectionEvent.HighlightBlock event) {
|
||||||
if(event.getTarget().getType() != HitResult.Type.BLOCK) return;
|
if(event.getTarget().getType() != HitResult.Type.BLOCK) return;
|
||||||
|
|
||||||
BlockHitResult rtr = event.getTarget();
|
BlockHitResult rtr = event.getTarget();
|
||||||
|
@ -44,7 +44,7 @@ public class RenderBlockPreview
|
||||||
// from the last placement are lagging
|
// from the last placement are lagging
|
||||||
if(wandJob == null || !compareRTR(wandJob.rayTraceResult, rtr) || !(wandJob.wand.equals(wand))
|
if(wandJob == null || !compareRTR(wandJob.rayTraceResult, rtr) || !(wandJob.wand.equals(wand))
|
||||||
|| wandJob.blockCount() < 2) {
|
|| wandJob.blockCount() < 2) {
|
||||||
wandJob = ItemWand.getWandJob(player, player.level(), rtr, wand);
|
wandJob = ItemWand.getWandJob(player, player.level, rtr, wand);
|
||||||
}
|
}
|
||||||
blocks = wandJob.getBlockPositions();
|
blocks = wandJob.getBlockPositions();
|
||||||
}
|
}
|
||||||
|
@ -59,7 +59,7 @@ public class RenderBlockPreview
|
||||||
MultiBufferSource buffer = event.getMultiBufferSource();
|
MultiBufferSource buffer = event.getMultiBufferSource();
|
||||||
VertexConsumer lineBuilder = buffer.getBuffer(RenderType.LINES);
|
VertexConsumer lineBuilder = buffer.getBuffer(RenderType.LINES);
|
||||||
|
|
||||||
double partialTicks = event.getPartialTick();
|
double partialTicks = event.getPartialTicks();
|
||||||
double d0 = player.xOld + (player.getX() - player.xOld) * partialTicks;
|
double d0 = player.xOld + (player.getX() - player.xOld) * partialTicks;
|
||||||
double d1 = player.yOld + player.getEyeHeight() + (player.getY() - player.yOld) * partialTicks;
|
double d1 = player.yOld + player.getEyeHeight() + (player.getY() - player.yOld) * partialTicks;
|
||||||
double d2 = player.zOld + (player.getZ() - player.zOld) * partialTicks;
|
double d2 = player.zOld + (player.getZ() - player.zOld) * partialTicks;
|
||||||
|
@ -72,10 +72,6 @@ public class RenderBlockPreview
|
||||||
event.setCanceled(true);
|
event.setCanceled(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void reset() {
|
|
||||||
wandJob = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean compareRTR(BlockHitResult rtr1, BlockHitResult rtr2) {
|
private static boolean compareRTR(BlockHitResult rtr1, BlockHitResult rtr2) {
|
||||||
return rtr1.getBlockPos().equals(rtr2.getBlockPos()) && rtr1.getDirection().equals(rtr2.getDirection());
|
return rtr1.getBlockPos().equals(rtr2.getBlockPos()) && rtr1.getDirection().equals(rtr2.getDirection());
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,20 +1,22 @@
|
||||||
package thetadev.constructionwand.client;
|
package thetadev.constructionwand.client;
|
||||||
|
|
||||||
|
import com.mojang.blaze3d.vertex.PoseStack;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.gui.GuiGraphics;
|
|
||||||
import net.minecraft.client.gui.components.Button;
|
import net.minecraft.client.gui.components.Button;
|
||||||
import net.minecraft.client.gui.components.Tooltip;
|
|
||||||
import net.minecraft.client.gui.screens.Screen;
|
import net.minecraft.client.gui.screens.Screen;
|
||||||
import net.minecraft.network.chat.Component;
|
import net.minecraft.network.chat.Component;
|
||||||
|
import net.minecraft.network.chat.TextComponent;
|
||||||
|
import net.minecraft.network.chat.TranslatableComponent;
|
||||||
import net.minecraft.world.item.ItemStack;
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
import thetadev.constructionwand.ConstructionWand;
|
||||||
import thetadev.constructionwand.basics.option.IOption;
|
import thetadev.constructionwand.basics.option.IOption;
|
||||||
import thetadev.constructionwand.basics.option.WandOptions;
|
import thetadev.constructionwand.basics.option.WandOptions;
|
||||||
import thetadev.constructionwand.network.ModMessages;
|
|
||||||
import thetadev.constructionwand.network.PacketWandOption;
|
import thetadev.constructionwand.network.PacketWandOption;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
public class ScreenWand extends Screen {
|
public class ScreenWand extends Screen
|
||||||
|
{
|
||||||
private final ItemStack wand;
|
private final ItemStack wand;
|
||||||
private final WandOptions wandOptions;
|
private final WandOptions wandOptions;
|
||||||
|
|
||||||
|
@ -29,7 +31,7 @@ public class ScreenWand extends Screen {
|
||||||
private static final int FIELD_HEIGHT = N_ROWS * (BUTTON_HEIGHT + SPACING_HEIGHT) - SPACING_HEIGHT;
|
private static final int FIELD_HEIGHT = N_ROWS * (BUTTON_HEIGHT + SPACING_HEIGHT) - SPACING_HEIGHT;
|
||||||
|
|
||||||
public ScreenWand(ItemStack wand) {
|
public ScreenWand(ItemStack wand) {
|
||||||
super(Component.literal("ScreenWand"));
|
super(new TextComponent("ScreenWand"));
|
||||||
this.wand = wand;
|
this.wand = wand;
|
||||||
wandOptions = new WandOptions(wand);
|
wandOptions = new WandOptions(wand);
|
||||||
}
|
}
|
||||||
|
@ -45,10 +47,10 @@ public class ScreenWand extends Screen {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void render(@Nonnull GuiGraphics guiGraphics, int mouseX, int mouseY, float partialTicks) {
|
public void render(@Nonnull PoseStack matrixStack, int mouseX, int mouseY, float partialTicks) {
|
||||||
renderBackground(guiGraphics, mouseX, mouseY, partialTicks);
|
renderBackground(matrixStack);
|
||||||
guiGraphics.drawCenteredString(font, wand.getDisplayName(), width / 2, height / 2 - FIELD_HEIGHT / 2 - SPACING_HEIGHT, 16777215);
|
drawCenteredString(matrixStack, font, wand.getDisplayName(), width / 2, height / 2 - FIELD_HEIGHT / 2 - SPACING_HEIGHT, 16777215);
|
||||||
super.render(guiGraphics, mouseX, mouseY, partialTicks);
|
super.render(matrixStack, mouseX, mouseY, partialTicks);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -62,21 +64,21 @@ public class ScreenWand extends Screen {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createButton(int cx, int cy, IOption<?> option) {
|
private void createButton(int cx, int cy, IOption<?> option) {
|
||||||
Button button = Button.builder(getButtonLabel(option), bt -> clickButton(bt, option))
|
Button button = new Button(getX(cx), getY(cy), BUTTON_WIDTH, BUTTON_HEIGHT, getButtonLabel(option), bt -> clickButton(bt, option), (bt, ms, x, y) -> drawTooltip(ms, x, y, option));
|
||||||
.pos(getX(cx), getY(cy))
|
|
||||||
.size(BUTTON_WIDTH, BUTTON_HEIGHT)
|
|
||||||
.tooltip(getButtonTooltip(option))
|
|
||||||
.build();
|
|
||||||
|
|
||||||
button.active = option.isEnabled();
|
button.active = option.isEnabled();
|
||||||
addRenderableWidget(button);
|
addRenderableWidget(button);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void clickButton(Button button, IOption<?> option) {
|
private void clickButton(Button button, IOption<?> option) {
|
||||||
option.next();
|
option.next();
|
||||||
ModMessages.sendToServer(new PacketWandOption(option, false));
|
ConstructionWand.instance.HANDLER.sendToServer(new PacketWandOption(option, false));
|
||||||
button.setMessage(getButtonLabel(option));
|
button.setMessage(getButtonLabel(option));
|
||||||
button.setTooltip(getButtonTooltip(option));
|
}
|
||||||
|
|
||||||
|
private void drawTooltip(PoseStack matrixStack, int mouseX, int mouseY, IOption<?> option) {
|
||||||
|
if(isMouseOver(mouseX, mouseY)) {
|
||||||
|
renderTooltip(matrixStack, new TranslatableComponent(option.getDescTranslation()), mouseX, mouseY);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private int getX(int n) {
|
private int getX(int n) {
|
||||||
|
@ -88,10 +90,6 @@ public class ScreenWand extends Screen {
|
||||||
}
|
}
|
||||||
|
|
||||||
private Component getButtonLabel(IOption<?> option) {
|
private Component getButtonLabel(IOption<?> option) {
|
||||||
return Component.translatable(option.getKeyTranslation()).append(Component.translatable(option.getValueTranslation()));
|
return new TranslatableComponent(option.getKeyTranslation()).append(new TranslatableComponent(option.getValueTranslation()));
|
||||||
}
|
|
||||||
|
|
||||||
private Tooltip getButtonTooltip(IOption<?> option) {
|
|
||||||
return Tooltip.create(Component.translatable(option.getDescTranslation()));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ import net.minecraft.world.item.ItemStack;
|
||||||
import net.minecraft.world.level.block.Block;
|
import net.minecraft.world.level.block.Block;
|
||||||
import thetadev.constructionwand.api.IContainerHandler;
|
import thetadev.constructionwand.api.IContainerHandler;
|
||||||
import vazkii.botania.api.BotaniaForgeCapabilities;
|
import vazkii.botania.api.BotaniaForgeCapabilities;
|
||||||
import vazkii.botania.api.item.BlockProvider;
|
import vazkii.botania.api.item.IBlockProvider;
|
||||||
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
|
@ -18,10 +18,10 @@ public class HandlerBotania implements IContainerHandler
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int countItems(Player player, ItemStack itemStack, ItemStack inventoryStack) {
|
public int countItems(Player player, ItemStack itemStack, ItemStack inventoryStack) {
|
||||||
Optional<BlockProvider> provOptional = inventoryStack.getCapability(BotaniaForgeCapabilities.BLOCK_PROVIDER).resolve();
|
Optional<IBlockProvider> provOptional = inventoryStack.getCapability(BotaniaForgeCapabilities.BLOCK_PROVIDER).resolve();
|
||||||
if(provOptional.isEmpty()) return 0;
|
if(provOptional.isEmpty()) return 0;
|
||||||
|
|
||||||
BlockProvider prov = provOptional.get();
|
IBlockProvider prov = provOptional.get();
|
||||||
int provCount = prov.getBlockCount(player, inventoryStack, Block.byItem(itemStack.getItem()));
|
int provCount = prov.getBlockCount(player, inventoryStack, Block.byItem(itemStack.getItem()));
|
||||||
if(provCount == -1)
|
if(provCount == -1)
|
||||||
return Integer.MAX_VALUE;
|
return Integer.MAX_VALUE;
|
||||||
|
@ -30,10 +30,10 @@ public class HandlerBotania implements IContainerHandler
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int useItems(Player player, ItemStack itemStack, ItemStack inventoryStack, int count) {
|
public int useItems(Player player, ItemStack itemStack, ItemStack inventoryStack, int count) {
|
||||||
Optional<BlockProvider> provOptional = inventoryStack.getCapability(BotaniaForgeCapabilities.BLOCK_PROVIDER).resolve();
|
Optional<IBlockProvider> provOptional = inventoryStack.getCapability(BotaniaForgeCapabilities.BLOCK_PROVIDER).resolve();
|
||||||
if(provOptional.isEmpty()) return 0;
|
if(provOptional.isEmpty()) return 0;
|
||||||
|
|
||||||
BlockProvider prov = provOptional.get();
|
IBlockProvider prov = provOptional.get();
|
||||||
if(prov.provideBlock(player, inventoryStack, Block.byItem(itemStack.getItem()), true))
|
if(prov.provideBlock(player, inventoryStack, Block.byItem(itemStack.getItem()), true))
|
||||||
return 0;
|
return 0;
|
||||||
return count;
|
return count;
|
||||||
|
|
|
@ -2,7 +2,7 @@ package thetadev.constructionwand.containers.handlers;
|
||||||
|
|
||||||
import net.minecraft.world.entity.player.Player;
|
import net.minecraft.world.entity.player.Player;
|
||||||
import net.minecraft.world.item.ItemStack;
|
import net.minecraft.world.item.ItemStack;
|
||||||
import net.minecraftforge.common.capabilities.ForgeCapabilities;
|
import net.minecraftforge.items.CapabilityItemHandler;
|
||||||
import net.minecraftforge.items.IItemHandler;
|
import net.minecraftforge.items.IItemHandler;
|
||||||
import thetadev.constructionwand.api.IContainerHandler;
|
import thetadev.constructionwand.api.IContainerHandler;
|
||||||
import thetadev.constructionwand.basics.WandUtil;
|
import thetadev.constructionwand.basics.WandUtil;
|
||||||
|
@ -13,12 +13,12 @@ public class HandlerCapability implements IContainerHandler
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
public boolean matches(Player player, ItemStack itemStack, ItemStack inventoryStack) {
|
public boolean matches(Player player, ItemStack itemStack, ItemStack inventoryStack) {
|
||||||
return inventoryStack != null && inventoryStack.getCapability(ForgeCapabilities.ITEM_HANDLER).isPresent();
|
return inventoryStack != null && inventoryStack.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY).isPresent();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int countItems(Player player, ItemStack itemStack, ItemStack inventoryStack) {
|
public int countItems(Player player, ItemStack itemStack, ItemStack inventoryStack) {
|
||||||
Optional<IItemHandler> itemHandlerOptional = inventoryStack.getCapability(ForgeCapabilities.ITEM_HANDLER).resolve();
|
Optional<IItemHandler> itemHandlerOptional = inventoryStack.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY).resolve();
|
||||||
if(itemHandlerOptional.isEmpty()) return 0;
|
if(itemHandlerOptional.isEmpty()) return 0;
|
||||||
|
|
||||||
int total = 0;
|
int total = 0;
|
||||||
|
@ -36,7 +36,7 @@ public class HandlerCapability implements IContainerHandler
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int useItems(Player player, ItemStack itemStack, ItemStack inventoryStack, int count) {
|
public int useItems(Player player, ItemStack itemStack, ItemStack inventoryStack, int count) {
|
||||||
Optional<IItemHandler> itemHandlerOptional = inventoryStack.getCapability(ForgeCapabilities.ITEM_HANDLER).resolve();
|
Optional<IItemHandler> itemHandlerOptional = inventoryStack.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY).resolve();
|
||||||
if(itemHandlerOptional.isEmpty()) return 0;
|
if(itemHandlerOptional.isEmpty()) return 0;
|
||||||
|
|
||||||
IItemHandler itemHandler = itemHandlerOptional.get();
|
IItemHandler itemHandler = itemHandlerOptional.get();
|
||||||
|
|
|
@ -1,12 +1,11 @@
|
||||||
package thetadev.constructionwand.crafting;
|
package thetadev.constructionwand.crafting;
|
||||||
|
|
||||||
import net.minecraft.core.RegistryAccess;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
import net.minecraft.world.inventory.CraftingContainer;
|
import net.minecraft.world.inventory.CraftingContainer;
|
||||||
import net.minecraft.world.item.ItemStack;
|
import net.minecraft.world.item.ItemStack;
|
||||||
import net.minecraft.world.item.crafting.CraftingBookCategory;
|
|
||||||
import net.minecraft.world.item.crafting.CustomRecipe;
|
import net.minecraft.world.item.crafting.CustomRecipe;
|
||||||
import net.minecraft.world.item.crafting.RecipeSerializer;
|
import net.minecraft.world.item.crafting.RecipeSerializer;
|
||||||
import net.minecraft.world.item.crafting.SimpleCraftingRecipeSerializer;
|
import net.minecraft.world.item.crafting.SimpleRecipeSerializer;
|
||||||
import net.minecraft.world.level.Level;
|
import net.minecraft.world.level.Level;
|
||||||
import thetadev.constructionwand.api.IWandUpgrade;
|
import thetadev.constructionwand.api.IWandUpgrade;
|
||||||
import thetadev.constructionwand.basics.ConfigServer;
|
import thetadev.constructionwand.basics.ConfigServer;
|
||||||
|
@ -17,10 +16,10 @@ import javax.annotation.Nonnull;
|
||||||
|
|
||||||
public class RecipeWandUpgrade extends CustomRecipe
|
public class RecipeWandUpgrade extends CustomRecipe
|
||||||
{
|
{
|
||||||
public static final SimpleCraftingRecipeSerializer<RecipeWandUpgrade> SERIALIZER = new SimpleCraftingRecipeSerializer<>(RecipeWandUpgrade::new);
|
public static final SimpleRecipeSerializer<RecipeWandUpgrade> SERIALIZER = new SimpleRecipeSerializer<>(RecipeWandUpgrade::new);
|
||||||
|
|
||||||
public RecipeWandUpgrade(CraftingBookCategory category) {
|
public RecipeWandUpgrade(ResourceLocation resourceLocation) {
|
||||||
super(category);
|
super(resourceLocation);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -44,7 +43,7 @@ public class RecipeWandUpgrade extends CustomRecipe
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public ItemStack assemble(@Nonnull CraftingContainer inv, @Nonnull RegistryAccess registryAccess) {
|
public ItemStack assemble(@Nonnull CraftingContainer inv) {
|
||||||
ItemStack wand = null;
|
ItemStack wand = null;
|
||||||
IWandUpgrade upgrade = null;
|
IWandUpgrade upgrade = null;
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
package thetadev.constructionwand.data;
|
package thetadev.constructionwand.data;
|
||||||
|
|
||||||
import net.minecraft.advancements.critereon.ItemPredicate;
|
import net.minecraft.advancements.critereon.ItemPredicate;
|
||||||
import net.minecraft.tags.TagKey;
|
import net.minecraft.tags.Tag;
|
||||||
import net.minecraft.world.item.Item;
|
import net.minecraft.world.item.Item;
|
||||||
import net.minecraft.world.item.crafting.Ingredient;
|
import net.minecraft.world.item.crafting.Ingredient;
|
||||||
import net.minecraft.world.level.ItemLike;
|
import net.minecraft.world.level.ItemLike;
|
||||||
import net.minecraftforge.registries.ForgeRegistries;
|
|
||||||
|
|
||||||
public class Inp
|
public class Inp
|
||||||
{
|
{
|
||||||
|
@ -20,10 +19,10 @@ public class Inp
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Inp fromItem(ItemLike in) {
|
public static Inp fromItem(ItemLike in) {
|
||||||
return new Inp(ForgeRegistries.ITEMS.getKey(in.asItem()).getPath(), Ingredient.of(in), ItemPredicate.Builder.item().of(in).build());
|
return new Inp(in.asItem().getRegistryName().getPath(), Ingredient.of(in), ItemPredicate.Builder.item().of(in).build());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Inp fromTag(TagKey<Item> in) {
|
public static Inp fromTag(Tag.Named<Item> in) {
|
||||||
return new Inp(in.location().getPath(), Ingredient.of(in), ItemPredicate.Builder.item().of(in).build());
|
return new Inp(in.getName().getPath(), Ingredient.of(in), ItemPredicate.Builder.item().of(in).build());
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,11 +1,10 @@
|
||||||
package thetadev.constructionwand.data;
|
package thetadev.constructionwand.data;
|
||||||
|
|
||||||
import net.minecraft.data.PackOutput;
|
import net.minecraft.data.DataGenerator;
|
||||||
import net.minecraft.world.item.BlockItem;
|
import net.minecraft.world.item.BlockItem;
|
||||||
import net.minecraft.world.item.Item;
|
import net.minecraft.world.item.Item;
|
||||||
import net.minecraftforge.client.model.generators.ItemModelProvider;
|
import net.minecraftforge.client.model.generators.ItemModelProvider;
|
||||||
import net.minecraftforge.common.data.ExistingFileHelper;
|
import net.minecraftforge.common.data.ExistingFileHelper;
|
||||||
import net.minecraftforge.registries.ForgeRegistries;
|
|
||||||
import net.minecraftforge.registries.RegistryObject;
|
import net.minecraftforge.registries.RegistryObject;
|
||||||
import thetadev.constructionwand.ConstructionWand;
|
import thetadev.constructionwand.ConstructionWand;
|
||||||
import thetadev.constructionwand.items.ModItems;
|
import thetadev.constructionwand.items.ModItems;
|
||||||
|
@ -14,15 +13,15 @@ import javax.annotation.Nonnull;
|
||||||
|
|
||||||
public class ItemModelGenerator extends ItemModelProvider
|
public class ItemModelGenerator extends ItemModelProvider
|
||||||
{
|
{
|
||||||
public ItemModelGenerator(PackOutput packOutput, ExistingFileHelper existingFileHelper) {
|
public ItemModelGenerator(DataGenerator generator, ExistingFileHelper existingFileHelper) {
|
||||||
super(packOutput, ConstructionWand.MODID, existingFileHelper);
|
super(generator, ConstructionWand.MODID, existingFileHelper);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void registerModels() {
|
protected void registerModels() {
|
||||||
for(RegistryObject<Item> itemObject : ModItems.ITEMS.getEntries()) {
|
for(RegistryObject<Item> itemObject : ModItems.ITEMS.getEntries()) {
|
||||||
Item item = itemObject.get();
|
Item item = itemObject.get();
|
||||||
String name = ForgeRegistries.ITEMS.getKey(item).getPath();
|
String name = item.getRegistryName().getPath();
|
||||||
|
|
||||||
if(item instanceof ICustomItemModel)
|
if(item instanceof ICustomItemModel)
|
||||||
((ICustomItemModel) item).generateCustomItemModel(this, name);
|
((ICustomItemModel) item).generateCustomItemModel(this, name);
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
package thetadev.constructionwand.data;
|
package thetadev.constructionwand.data;
|
||||||
|
|
||||||
import net.minecraft.data.DataGenerator;
|
import net.minecraft.data.DataGenerator;
|
||||||
import net.minecraft.data.PackOutput;
|
|
||||||
import net.minecraftforge.common.data.ExistingFileHelper;
|
import net.minecraftforge.common.data.ExistingFileHelper;
|
||||||
import net.minecraftforge.data.event.GatherDataEvent;
|
|
||||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||||
import net.minecraftforge.fml.common.Mod;
|
import net.minecraftforge.fml.common.Mod;
|
||||||
|
import net.minecraftforge.forge.event.lifecycle.GatherDataEvent;
|
||||||
|
|
||||||
@Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.MOD)
|
@Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.MOD)
|
||||||
public class ModData
|
public class ModData
|
||||||
|
@ -13,15 +12,14 @@ public class ModData
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
public static void gatherData(GatherDataEvent event) {
|
public static void gatherData(GatherDataEvent event) {
|
||||||
DataGenerator generator = event.getGenerator();
|
DataGenerator generator = event.getGenerator();
|
||||||
PackOutput packOutput = generator.getPackOutput();
|
|
||||||
ExistingFileHelper fileHelper = event.getExistingFileHelper();
|
ExistingFileHelper fileHelper = event.getExistingFileHelper();
|
||||||
|
|
||||||
if(event.includeServer()) {
|
if(event.includeServer()) {
|
||||||
generator.addProvider(true, new RecipeGenerator(packOutput));
|
generator.addProvider(new RecipeGenerator(generator));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(event.includeClient()) {
|
if(event.includeClient()) {
|
||||||
generator.addProvider(true, new ItemModelGenerator(packOutput, fileHelper));
|
generator.addProvider(new ItemModelGenerator(generator, fileHelper));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,20 +1,14 @@
|
||||||
package thetadev.constructionwand.data;
|
package thetadev.constructionwand.data;
|
||||||
|
|
||||||
import net.minecraft.advancements.CriteriaTriggers;
|
import net.minecraft.data.DataGenerator;
|
||||||
import net.minecraft.advancements.Criterion;
|
import net.minecraft.data.recipes.FinishedRecipe;
|
||||||
import net.minecraft.advancements.critereon.InventoryChangeTrigger;
|
|
||||||
import net.minecraft.advancements.critereon.ItemPredicate;
|
|
||||||
import net.minecraft.advancements.critereon.MinMaxBounds;
|
|
||||||
import net.minecraft.data.PackOutput;
|
|
||||||
import net.minecraft.data.recipes.RecipeCategory;
|
|
||||||
import net.minecraft.data.recipes.RecipeOutput;
|
|
||||||
import net.minecraft.data.recipes.RecipeProvider;
|
import net.minecraft.data.recipes.RecipeProvider;
|
||||||
import net.minecraft.data.recipes.ShapedRecipeBuilder;
|
import net.minecraft.data.recipes.ShapedRecipeBuilder;
|
||||||
import net.minecraft.data.recipes.SpecialRecipeBuilder;
|
import net.minecraft.data.recipes.SpecialRecipeBuilder;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
import net.minecraft.tags.ItemTags;
|
import net.minecraft.tags.ItemTags;
|
||||||
import net.minecraft.world.item.Items;
|
import net.minecraft.world.item.Items;
|
||||||
import net.minecraft.world.item.crafting.SimpleCraftingRecipeSerializer;
|
import net.minecraft.world.item.crafting.SimpleRecipeSerializer;
|
||||||
import net.minecraft.world.level.ItemLike;
|
import net.minecraft.world.level.ItemLike;
|
||||||
import net.minecraftforge.common.Tags;
|
import net.minecraftforge.common.Tags;
|
||||||
import net.minecraftforge.registries.ForgeRegistries;
|
import net.minecraftforge.registries.ForgeRegistries;
|
||||||
|
@ -22,40 +16,41 @@ import thetadev.constructionwand.ConstructionWand;
|
||||||
import thetadev.constructionwand.crafting.RecipeWandUpgrade;
|
import thetadev.constructionwand.crafting.RecipeWandUpgrade;
|
||||||
import thetadev.constructionwand.items.ModItems;
|
import thetadev.constructionwand.items.ModItems;
|
||||||
|
|
||||||
import java.util.List;
|
import javax.annotation.Nonnull;
|
||||||
import java.util.Optional;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
public class RecipeGenerator extends RecipeProvider {
|
public class RecipeGenerator extends RecipeProvider
|
||||||
public RecipeGenerator(PackOutput packOutput) {
|
{
|
||||||
super(packOutput);
|
public RecipeGenerator(DataGenerator generatorIn) {
|
||||||
|
super(generatorIn);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void buildRecipes(RecipeOutput output) {
|
protected void buildCraftingRecipes(@Nonnull Consumer<FinishedRecipe> consumer) {
|
||||||
wandRecipe(output, ModItems.WAND_STONE.get(), Inp.fromTag(ItemTags.STONE_TOOL_MATERIALS));
|
wandRecipe(consumer, ModItems.WAND_STONE.get(), Inp.fromTag(ItemTags.STONE_TOOL_MATERIALS));
|
||||||
wandRecipe(output, ModItems.WAND_IRON.get(), Inp.fromTag(Tags.Items.INGOTS_IRON));
|
wandRecipe(consumer, ModItems.WAND_IRON.get(), Inp.fromTag(Tags.Items.INGOTS_IRON));
|
||||||
wandRecipe(output, ModItems.WAND_DIAMOND.get(), Inp.fromTag(Tags.Items.GEMS_DIAMOND));
|
wandRecipe(consumer, ModItems.WAND_DIAMOND.get(), Inp.fromTag(Tags.Items.GEMS_DIAMOND));
|
||||||
wandRecipe(output, ModItems.WAND_INFINITY.get(), Inp.fromTag(Tags.Items.NETHER_STARS));
|
wandRecipe(consumer, ModItems.WAND_INFINITY.get(), Inp.fromTag(Tags.Items.NETHER_STARS));
|
||||||
|
|
||||||
coreRecipe(output, ModItems.CORE_ANGEL.get(), Inp.fromTag(Tags.Items.FEATHERS), Inp.fromTag(Tags.Items.INGOTS_GOLD));
|
coreRecipe(consumer, ModItems.CORE_ANGEL.get(), Inp.fromTag(Tags.Items.FEATHERS), Inp.fromTag(Tags.Items.INGOTS_GOLD));
|
||||||
coreRecipe(output, ModItems.CORE_DESTRUCTION.get(), Inp.fromTag(Tags.Items.STORAGE_BLOCKS_DIAMOND), Inp.fromItem(Items.DIAMOND_PICKAXE));
|
coreRecipe(consumer, ModItems.CORE_DESTRUCTION.get(), Inp.fromTag(Tags.Items.STORAGE_BLOCKS_DIAMOND), Inp.fromItem(Items.DIAMOND_PICKAXE));
|
||||||
|
|
||||||
specialRecipe(output, RecipeWandUpgrade.SERIALIZER);
|
specialRecipe(consumer, RecipeWandUpgrade.SERIALIZER);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void wandRecipe(RecipeOutput output, ItemLike wand, Inp material) {
|
private void wandRecipe(Consumer<FinishedRecipe> consumer, ItemLike wand, Inp material) {
|
||||||
ShapedRecipeBuilder.shaped(RecipeCategory.TOOLS, wand)
|
ShapedRecipeBuilder.shaped(wand)
|
||||||
.define('X', material.ingredient)
|
.define('X', material.ingredient)
|
||||||
.define('#', Tags.Items.RODS_WOODEN)
|
.define('#', Tags.Items.RODS_WOODEN)
|
||||||
.pattern(" X")
|
.pattern(" X")
|
||||||
.pattern(" # ")
|
.pattern(" # ")
|
||||||
.pattern("# ")
|
.pattern("# ")
|
||||||
.unlockedBy("has_item", inventoryTrigger(material.predicate))
|
.unlockedBy("has_item", inventoryTrigger(material.predicate))
|
||||||
.save(output);
|
.save(consumer);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void coreRecipe(RecipeOutput output, ItemLike core, Inp item1, Inp item2) {
|
private void coreRecipe(Consumer<FinishedRecipe> consumer, ItemLike core, Inp item1, Inp item2) {
|
||||||
ShapedRecipeBuilder.shaped(RecipeCategory.MISC, core)
|
ShapedRecipeBuilder.shaped(core)
|
||||||
.define('O', item1.ingredient)
|
.define('O', item1.ingredient)
|
||||||
.define('X', item2.ingredient)
|
.define('X', item2.ingredient)
|
||||||
.define('#', Tags.Items.GLASS_PANES)
|
.define('#', Tags.Items.GLASS_PANES)
|
||||||
|
@ -63,17 +58,17 @@ public class RecipeGenerator extends RecipeProvider {
|
||||||
.pattern("#O#")
|
.pattern("#O#")
|
||||||
.pattern("X# ")
|
.pattern("X# ")
|
||||||
.unlockedBy("has_item", inventoryTrigger(item1.predicate))
|
.unlockedBy("has_item", inventoryTrigger(item1.predicate))
|
||||||
.save(output);
|
.save(consumer);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void specialRecipe(RecipeOutput output, SimpleCraftingRecipeSerializer<?> serializer) {
|
private void specialRecipe(Consumer<FinishedRecipe> consumer, SimpleRecipeSerializer<?> serializer) {
|
||||||
ResourceLocation name = ForgeRegistries.RECIPE_SERIALIZERS.getKey(serializer);
|
ResourceLocation name = ForgeRegistries.RECIPE_SERIALIZERS.getKey(serializer);
|
||||||
SpecialRecipeBuilder.special(serializer).save(output, ConstructionWand.loc("dynamic/" + name.getPath()).toString());
|
SpecialRecipeBuilder.special(serializer).save(consumer, ConstructionWand.loc("dynamic/" + name.getPath()).toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Criterion<InventoryChangeTrigger.TriggerInstance> inventoryTrigger(ItemPredicate... predicate) {
|
@Nonnull
|
||||||
return CriteriaTriggers.INVENTORY_CHANGED.createCriterion(
|
@Override
|
||||||
new InventoryChangeTrigger.TriggerInstance(Optional.empty(), MinMaxBounds.Ints.ANY, MinMaxBounds.Ints.ANY, MinMaxBounds.Ints.ANY, List.of(predicate))
|
public String getName() {
|
||||||
);
|
return ConstructionWand.MODID + " crafting recipes";
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -7,12 +7,11 @@ import mezz.jei.api.constants.VanillaTypes;
|
||||||
import mezz.jei.api.registration.IRecipeRegistration;
|
import mezz.jei.api.registration.IRecipeRegistration;
|
||||||
import net.minecraft.ChatFormatting;
|
import net.minecraft.ChatFormatting;
|
||||||
import net.minecraft.network.chat.Component;
|
import net.minecraft.network.chat.Component;
|
||||||
|
import net.minecraft.network.chat.TranslatableComponent;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
import net.minecraft.world.item.Item;
|
import net.minecraft.world.item.Item;
|
||||||
import net.minecraft.world.item.ItemStack;
|
import net.minecraft.world.item.ItemStack;
|
||||||
import net.minecraftforge.registries.ForgeRegistries;
|
|
||||||
import net.minecraftforge.registries.RegistryObject;
|
import net.minecraftforge.registries.RegistryObject;
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import thetadev.constructionwand.ConstructionWand;
|
import thetadev.constructionwand.ConstructionWand;
|
||||||
import thetadev.constructionwand.basics.ConfigClient;
|
import thetadev.constructionwand.basics.ConfigClient;
|
||||||
import thetadev.constructionwand.basics.ConfigServer;
|
import thetadev.constructionwand.basics.ConfigServer;
|
||||||
|
@ -35,12 +34,12 @@ public class ConstructionWandJeiPlugin implements IModPlugin
|
||||||
|
|
||||||
private Component keyComboComponent(boolean shiftOpt, Component optkeyComponent) {
|
private Component keyComboComponent(boolean shiftOpt, Component optkeyComponent) {
|
||||||
String key = shiftOpt ? "sneak_opt" : "sneak";
|
String key = shiftOpt ? "sneak_opt" : "sneak";
|
||||||
return Component.translatable(baseKey + "key." + key, optkeyComponent).withStyle(ChatFormatting.BLUE);
|
return new TranslatableComponent(baseKey + "key." + key, optkeyComponent).withStyle(ChatFormatting.BLUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void registerRecipes(@NotNull IRecipeRegistration registration) {
|
public void registerRecipes(IRecipeRegistration registration) {
|
||||||
Component optkeyComponent = Component.translatable(InputConstants.getKey(ConfigClient.OPT_KEY.get(), -1).getName())
|
Component optkeyComponent = new TranslatableComponent(InputConstants.getKey(ConfigClient.OPT_KEY.get(), -1).getName())
|
||||||
.withStyle(ChatFormatting.BLUE);
|
.withStyle(ChatFormatting.BLUE);
|
||||||
Component wandModeComponent = keyComboComponent(ConfigClient.SHIFTOPT_MODE.get(), optkeyComponent);
|
Component wandModeComponent = keyComboComponent(ConfigClient.SHIFTOPT_MODE.get(), optkeyComponent);
|
||||||
Component wandGuiComponent = keyComboComponent(ConfigClient.SHIFTOPT_GUI.get(), optkeyComponent);
|
Component wandGuiComponent = keyComboComponent(ConfigClient.SHIFTOPT_GUI.get(), optkeyComponent);
|
||||||
|
@ -50,21 +49,21 @@ public class ConstructionWandJeiPlugin implements IModPlugin
|
||||||
ConfigServer.WandProperties wandProperties = ConfigServer.getWandProperties(wand);
|
ConfigServer.WandProperties wandProperties = ConfigServer.getWandProperties(wand);
|
||||||
|
|
||||||
String durabilityKey = wand == ModItems.WAND_INFINITY.get() ? "unlimited" : "limited";
|
String durabilityKey = wand == ModItems.WAND_INFINITY.get() ? "unlimited" : "limited";
|
||||||
Component durabilityComponent = Component.translatable(baseKey + "durability." + durabilityKey, wandProperties.getDurability());
|
Component durabilityComponent = new TranslatableComponent(baseKey + "durability." + durabilityKey, wandProperties.getDurability());
|
||||||
|
|
||||||
registration.addIngredientInfo(new ItemStack(wand), VanillaTypes.ITEM_STACK,
|
registration.addIngredientInfo(new ItemStack(wand), VanillaTypes.ITEM,
|
||||||
Component.translatable(baseKey + "wand",
|
new TranslatableComponent(baseKey + "wand",
|
||||||
Component.translatable(baseKeyItem + ForgeRegistries.ITEMS.getKey(wand).getPath()),
|
new TranslatableComponent(baseKeyItem + wand.getRegistryName().getPath()),
|
||||||
wandProperties.getLimit(), durabilityComponent, optkeyComponent, wandModeComponent, wandGuiComponent)
|
wandProperties.getLimit(), durabilityComponent,
|
||||||
|
optkeyComponent, wandModeComponent, wandGuiComponent)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
for(RegistryObject<Item> coreSupplier : ModItems.CORES) {
|
for(RegistryObject<Item> coreSupplier : ModItems.CORES) {
|
||||||
Item core = coreSupplier.get();
|
Item core = coreSupplier.get();
|
||||||
registration.addIngredientInfo(new ItemStack(core), VanillaTypes.ITEM_STACK,
|
registration.addIngredientInfo(new ItemStack(core), VanillaTypes.ITEM,
|
||||||
Component.translatable(baseKey + ForgeRegistries.ITEMS.getKey(core).getPath())
|
new TranslatableComponent(baseKey + core.getRegistryName().getPath()),
|
||||||
.append("\n\n")
|
new TranslatableComponent(baseKey + "core", wandModeComponent)
|
||||||
.append(Component.translatable(baseKey + "core", wandModeComponent))
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,19 +1,18 @@
|
||||||
package thetadev.constructionwand.items;
|
package thetadev.constructionwand.items;
|
||||||
|
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.client.color.item.ItemColors;
|
||||||
import net.minecraft.client.renderer.item.ItemProperties;
|
import net.minecraft.client.renderer.item.ItemProperties;
|
||||||
import net.minecraft.world.item.CreativeModeTabs;
|
import net.minecraft.world.item.CreativeModeTab;
|
||||||
import net.minecraft.world.item.Item;
|
import net.minecraft.world.item.Item;
|
||||||
import net.minecraft.world.item.Tiers;
|
import net.minecraft.world.item.Tiers;
|
||||||
|
import net.minecraft.world.item.crafting.RecipeSerializer;
|
||||||
import net.minecraftforge.api.distmarker.Dist;
|
import net.minecraftforge.api.distmarker.Dist;
|
||||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||||
import net.minecraftforge.client.event.RegisterColorHandlersEvent;
|
import net.minecraftforge.event.RegistryEvent;
|
||||||
import net.minecraftforge.event.BuildCreativeModeTabContentsEvent;
|
|
||||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||||
import net.minecraftforge.fml.common.Mod;
|
import net.minecraftforge.fml.common.Mod;
|
||||||
import net.minecraftforge.registries.DeferredRegister;
|
import net.minecraftforge.registries.*;
|
||||||
import net.minecraftforge.registries.ForgeRegistries;
|
|
||||||
import net.minecraftforge.registries.RegisterEvent;
|
|
||||||
import net.minecraftforge.registries.RegistryObject;
|
|
||||||
import thetadev.constructionwand.ConstructionWand;
|
import thetadev.constructionwand.ConstructionWand;
|
||||||
import thetadev.constructionwand.basics.option.WandOptions;
|
import thetadev.constructionwand.basics.option.WandOptions;
|
||||||
import thetadev.constructionwand.crafting.RecipeWandUpgrade;
|
import thetadev.constructionwand.crafting.RecipeWandUpgrade;
|
||||||
|
@ -43,18 +42,17 @@ public class ModItems
|
||||||
public static final RegistryObject<Item>[] CORES = new RegistryObject[] {CORE_ANGEL, CORE_DESTRUCTION};
|
public static final RegistryObject<Item>[] CORES = new RegistryObject[] {CORE_ANGEL, CORE_DESTRUCTION};
|
||||||
|
|
||||||
public static Item.Properties propWand() {
|
public static Item.Properties propWand() {
|
||||||
return new Item.Properties();
|
return new Item.Properties().tab(CreativeModeTab.TAB_TOOLS);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Item.Properties propUpgrade() {
|
private static Item.Properties propUpgrade() {
|
||||||
return new Item.Properties().stacksTo(1);
|
return new Item.Properties().tab(CreativeModeTab.TAB_MISC).stacksTo(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
public static void registerRecipeSerializers(RegisterEvent event) {
|
public static void registerRecipeSerializers(RegistryEvent.Register<RecipeSerializer<?>> event) {
|
||||||
event.register(ForgeRegistries.Keys.RECIPE_SERIALIZERS, registry -> {
|
IForgeRegistry<RecipeSerializer<?>> r = event.getRegistry();
|
||||||
registry.register("wand_upgrade", RecipeWandUpgrade.SERIALIZER);
|
register(r, "wand_upgrade", RecipeWandUpgrade.SERIALIZER);
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@OnlyIn(Dist.CLIENT)
|
@OnlyIn(Dist.CLIENT)
|
||||||
|
@ -70,25 +68,17 @@ public class ModItems
|
||||||
}
|
}
|
||||||
|
|
||||||
@OnlyIn(Dist.CLIENT)
|
@OnlyIn(Dist.CLIENT)
|
||||||
@SubscribeEvent
|
public static void registerItemColors() {
|
||||||
public static void registerItemColors(RegisterColorHandlersEvent.Item event) {
|
ItemColors colors = Minecraft.getInstance().getItemColors();
|
||||||
|
|
||||||
for(RegistryObject<Item> itemSupplier : WANDS) {
|
for(RegistryObject<Item> itemSupplier : WANDS) {
|
||||||
Item item = itemSupplier.get();
|
Item item = itemSupplier.get();
|
||||||
event.register((stack, layer) -> (layer == 1 && stack.getItem() instanceof ItemWand) ?
|
colors.register((stack, layer) -> (layer == 1 && stack.getItem() instanceof ItemWand) ?
|
||||||
new WandOptions(stack).cores.get().getColor() : -1, item);
|
new WandOptions(stack).cores.get().getColor() : -1, item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SubscribeEvent
|
private static <V extends IForgeRegistryEntry<V>> void register(IForgeRegistry<V> reg, String name, IForgeRegistryEntry<V> thing) {
|
||||||
public static void addCreative(BuildCreativeModeTabContentsEvent event) {
|
reg.register(thing.setRegistryName(ConstructionWand.loc(name)));
|
||||||
if (event.getTabKey() == CreativeModeTabs.TOOLS_AND_UTILITIES) {
|
|
||||||
for(RegistryObject<Item> itemSupplier : WANDS) {
|
|
||||||
event.accept(itemSupplier);
|
|
||||||
}
|
|
||||||
} else if (event.getTabKey() == CreativeModeTabs.INGREDIENTS) {
|
|
||||||
for(RegistryObject<Item> itemSupplier : CORES) {
|
|
||||||
event.accept(itemSupplier);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ package thetadev.constructionwand.items.core;
|
||||||
|
|
||||||
import net.minecraft.ChatFormatting;
|
import net.minecraft.ChatFormatting;
|
||||||
import net.minecraft.network.chat.Component;
|
import net.minecraft.network.chat.Component;
|
||||||
|
import net.minecraft.network.chat.TranslatableComponent;
|
||||||
import net.minecraft.world.item.Item;
|
import net.minecraft.world.item.Item;
|
||||||
import net.minecraft.world.item.ItemStack;
|
import net.minecraft.world.item.ItemStack;
|
||||||
import net.minecraft.world.item.TooltipFlag;
|
import net.minecraft.world.item.TooltipFlag;
|
||||||
|
@ -22,12 +23,9 @@ public abstract class ItemCore extends Item implements IWandCore
|
||||||
|
|
||||||
@OnlyIn(Dist.CLIENT)
|
@OnlyIn(Dist.CLIENT)
|
||||||
public void appendHoverText(@Nonnull ItemStack itemstack, Level worldIn, @Nonnull List<Component> lines, @Nonnull TooltipFlag extraInfo) {
|
public void appendHoverText(@Nonnull ItemStack itemstack, Level worldIn, @Nonnull List<Component> lines, @Nonnull TooltipFlag extraInfo) {
|
||||||
lines.add(
|
lines.add(new TranslatableComponent(ConstructionWand.MODID + ".option.cores." + getRegistryName().toString() + ".desc")
|
||||||
Component.translatable(ConstructionWand.MODID + ".option.cores." + getRegistryName().toString() + ".desc")
|
.withStyle(ChatFormatting.GRAY));
|
||||||
.withStyle(ChatFormatting.GRAY)
|
lines.add(new TranslatableComponent(ConstructionWand.MODID + ".tooltip.core_tip")
|
||||||
);
|
.withStyle(ChatFormatting.AQUA));
|
||||||
lines.add(
|
|
||||||
Component.translatable(ConstructionWand.MODID + ".tooltip.core_tip").withStyle(ChatFormatting.AQUA)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
package thetadev.constructionwand.items.core;
|
package thetadev.constructionwand.items.core;
|
||||||
|
|
||||||
import net.minecraft.resources.ResourceLocation;
|
|
||||||
import thetadev.constructionwand.ConstructionWand;
|
|
||||||
import thetadev.constructionwand.api.IWandAction;
|
import thetadev.constructionwand.api.IWandAction;
|
||||||
import thetadev.constructionwand.wand.action.ActionAngel;
|
import thetadev.constructionwand.wand.action.ActionAngel;
|
||||||
|
|
||||||
|
@ -20,9 +18,4 @@ public class ItemCoreAngel extends ItemCore
|
||||||
public IWandAction getWandAction() {
|
public IWandAction getWandAction() {
|
||||||
return new ActionAngel();
|
return new ActionAngel();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public ResourceLocation getRegistryName() {
|
|
||||||
return ConstructionWand.loc("core_angel");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
package thetadev.constructionwand.items.core;
|
package thetadev.constructionwand.items.core;
|
||||||
|
|
||||||
import net.minecraft.resources.ResourceLocation;
|
|
||||||
import thetadev.constructionwand.ConstructionWand;
|
|
||||||
import thetadev.constructionwand.api.IWandAction;
|
import thetadev.constructionwand.api.IWandAction;
|
||||||
import thetadev.constructionwand.wand.action.ActionDestruction;
|
import thetadev.constructionwand.wand.action.ActionDestruction;
|
||||||
|
|
||||||
|
@ -20,9 +18,4 @@ public class ItemCoreDestruction extends ItemCore
|
||||||
public IWandAction getWandAction() {
|
public IWandAction getWandAction() {
|
||||||
return new ActionDestruction();
|
return new ActionDestruction();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public ResourceLocation getRegistryName() {
|
|
||||||
return ConstructionWand.loc("core_destruction");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,8 @@ package thetadev.constructionwand.items.wand;
|
||||||
import net.minecraft.ChatFormatting;
|
import net.minecraft.ChatFormatting;
|
||||||
import net.minecraft.client.gui.screens.Screen;
|
import net.minecraft.client.gui.screens.Screen;
|
||||||
import net.minecraft.network.chat.Component;
|
import net.minecraft.network.chat.Component;
|
||||||
|
import net.minecraft.network.chat.TextComponent;
|
||||||
|
import net.minecraft.network.chat.TranslatableComponent;
|
||||||
import net.minecraft.world.InteractionHand;
|
import net.minecraft.world.InteractionHand;
|
||||||
import net.minecraft.world.InteractionResult;
|
import net.minecraft.world.InteractionResult;
|
||||||
import net.minecraft.world.InteractionResultHolder;
|
import net.minecraft.world.InteractionResultHolder;
|
||||||
|
@ -66,7 +68,7 @@ public abstract class ItemWand extends Item implements ICustomItemModel
|
||||||
|
|
||||||
// Right click: Place angel block
|
// Right click: Place angel block
|
||||||
WandJob job = getWandJob(player, world, BlockHitResult.miss(player.getLookAngle(),
|
WandJob job = getWandJob(player, world, BlockHitResult.miss(player.getLookAngle(),
|
||||||
WandUtil.fromVector(player.getLookAngle()), player.blockPosition()), stack);
|
WandUtil.fromVector(player.getLookAngle()), WandUtil.playerPos(player)), stack);
|
||||||
return job.doIt() ? InteractionResultHolder.success(stack) : InteractionResultHolder.fail(stack);
|
return job.doIt() ? InteractionResultHolder.success(stack) : InteractionResultHolder.fail(stack);
|
||||||
}
|
}
|
||||||
return InteractionResultHolder.fail(stack);
|
return InteractionResultHolder.fail(stack);
|
||||||
|
@ -105,35 +107,35 @@ public abstract class ItemWand extends Item implements ICustomItemModel
|
||||||
if(Screen.hasShiftDown()) {
|
if(Screen.hasShiftDown()) {
|
||||||
for(int i = 1; i < options.allOptions.length; i++) {
|
for(int i = 1; i < options.allOptions.length; i++) {
|
||||||
IOption<?> opt = options.allOptions[i];
|
IOption<?> opt = options.allOptions[i];
|
||||||
lines.add(Component.translatable(opt.getKeyTranslation()).withStyle(ChatFormatting.AQUA)
|
lines.add(new TranslatableComponent(opt.getKeyTranslation()).withStyle(ChatFormatting.AQUA)
|
||||||
.append(Component.translatable(opt.getValueTranslation()).withStyle(ChatFormatting.GRAY))
|
.append(new TranslatableComponent(opt.getValueTranslation()).withStyle(ChatFormatting.GRAY))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if(!options.cores.getUpgrades().isEmpty()) {
|
if(!options.cores.getUpgrades().isEmpty()) {
|
||||||
lines.add(Component.literal(""));
|
lines.add(new TextComponent(""));
|
||||||
lines.add(Component.translatable(langTooltip + "cores").withStyle(ChatFormatting.GRAY));
|
lines.add(new TranslatableComponent(langTooltip + "cores").withStyle(ChatFormatting.GRAY));
|
||||||
|
|
||||||
for(IWandCore core : options.cores.getUpgrades()) {
|
for(IWandCore core : options.cores.getUpgrades()) {
|
||||||
lines.add(Component.translatable(options.cores.getKeyTranslation() + "." + core.getRegistryName().toString()));
|
lines.add(new TranslatableComponent(options.cores.getKeyTranslation() + "." + core.getRegistryName().toString()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Default tooltip: show block limit + active wand core
|
// Default tooltip: show block limit + active wand core
|
||||||
else {
|
else {
|
||||||
IOption<?> opt = options.allOptions[0];
|
IOption<?> opt = options.allOptions[0];
|
||||||
lines.add(Component.translatable(langTooltip + "blocks", limit).withStyle(ChatFormatting.GRAY));
|
lines.add(new TranslatableComponent(langTooltip + "blocks", limit).withStyle(ChatFormatting.GRAY));
|
||||||
lines.add(Component.translatable(opt.getKeyTranslation()).withStyle(ChatFormatting.AQUA)
|
lines.add(new TranslatableComponent(opt.getKeyTranslation()).withStyle(ChatFormatting.AQUA)
|
||||||
.append(Component.translatable(opt.getValueTranslation()).withStyle(ChatFormatting.WHITE)));
|
.append(new TranslatableComponent(opt.getValueTranslation()).withStyle(ChatFormatting.WHITE)));
|
||||||
lines.add(Component.translatable(langTooltip + "shift").withStyle(ChatFormatting.AQUA));
|
lines.add(new TranslatableComponent(langTooltip + "shift").withStyle(ChatFormatting.AQUA));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void optionMessage(Player player, IOption<?> option) {
|
public static void optionMessage(Player player, IOption<?> option) {
|
||||||
player.displayClientMessage(
|
player.displayClientMessage(
|
||||||
Component.translatable(option.getKeyTranslation()).withStyle(ChatFormatting.AQUA)
|
new TranslatableComponent(option.getKeyTranslation()).withStyle(ChatFormatting.AQUA)
|
||||||
.append(Component.translatable(option.getValueTranslation()).withStyle(ChatFormatting.WHITE))
|
.append(new TranslatableComponent(option.getValueTranslation()).withStyle(ChatFormatting.WHITE))
|
||||||
.append(Component.literal(" - ").withStyle(ChatFormatting.GRAY))
|
.append(new TextComponent(" - ").withStyle(ChatFormatting.GRAY))
|
||||||
.append(Component.translatable(option.getDescTranslation()).withStyle(ChatFormatting.WHITE))
|
.append(new TranslatableComponent(option.getDescTranslation()).withStyle(ChatFormatting.WHITE))
|
||||||
, true);
|
, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,50 +0,0 @@
|
||||||
package thetadev.constructionwand.network;
|
|
||||||
|
|
||||||
import net.minecraft.resources.ResourceLocation;
|
|
||||||
import net.minecraft.server.level.ServerPlayer;
|
|
||||||
import net.minecraftforge.network.ChannelBuilder;
|
|
||||||
import net.minecraftforge.network.NetworkDirection;
|
|
||||||
import net.minecraftforge.network.PacketDistributor;
|
|
||||||
import net.minecraftforge.network.SimpleChannel;
|
|
||||||
|
|
||||||
import static thetadev.constructionwand.ConstructionWand.MODID;
|
|
||||||
|
|
||||||
public final class ModMessages {
|
|
||||||
private static SimpleChannel INSTANCE;
|
|
||||||
private static final int PROTOCOL_VERSION = 1;
|
|
||||||
|
|
||||||
private ModMessages() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void register() {
|
|
||||||
INSTANCE = ChannelBuilder.named(new ResourceLocation(MODID, "main")).networkProtocolVersion(PROTOCOL_VERSION).simpleChannel();
|
|
||||||
int packetIndex = 0;
|
|
||||||
|
|
||||||
// Server -> Client
|
|
||||||
INSTANCE.messageBuilder(PacketUndoBlocks.class, packetIndex++, NetworkDirection.PLAY_TO_CLIENT)
|
|
||||||
.encoder(PacketUndoBlocks::encode)
|
|
||||||
.decoder(PacketUndoBlocks::decode)
|
|
||||||
.consumerMainThread(PacketUndoBlocks.Handler::handle)
|
|
||||||
.add();
|
|
||||||
|
|
||||||
// Client -> Server
|
|
||||||
INSTANCE.messageBuilder(PacketQueryUndo.class, packetIndex++, NetworkDirection.PLAY_TO_SERVER)
|
|
||||||
.encoder(PacketQueryUndo::encode)
|
|
||||||
.decoder(PacketQueryUndo::decode)
|
|
||||||
.consumerMainThread(PacketQueryUndo.Handler::handle)
|
|
||||||
.add();
|
|
||||||
INSTANCE.messageBuilder(PacketWandOption.class, packetIndex, NetworkDirection.PLAY_TO_SERVER)
|
|
||||||
.encoder(PacketWandOption::encode)
|
|
||||||
.decoder(PacketWandOption::decode)
|
|
||||||
.consumerMainThread(PacketWandOption.Handler::handle)
|
|
||||||
.add();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <MSG> void sendToServer(MSG message) {
|
|
||||||
INSTANCE.send(message, PacketDistributor.SERVER.noArg());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <MSG> void sendToPlayer(MSG message, ServerPlayer player) {
|
|
||||||
INSTANCE.send(message, PacketDistributor.PLAYER.with(player));
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -2,9 +2,11 @@ package thetadev.constructionwand.network;
|
||||||
|
|
||||||
import net.minecraft.network.FriendlyByteBuf;
|
import net.minecraft.network.FriendlyByteBuf;
|
||||||
import net.minecraft.server.level.ServerPlayer;
|
import net.minecraft.server.level.ServerPlayer;
|
||||||
import net.minecraftforge.event.network.CustomPayloadEvent;
|
import net.minecraftforge.network.NetworkEvent;
|
||||||
import thetadev.constructionwand.ConstructionWand;
|
import thetadev.constructionwand.ConstructionWand;
|
||||||
|
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
public class PacketQueryUndo
|
public class PacketQueryUndo
|
||||||
{
|
{
|
||||||
public boolean undoPressed;
|
public boolean undoPressed;
|
||||||
|
@ -23,10 +25,10 @@ public class PacketQueryUndo
|
||||||
|
|
||||||
public static class Handler
|
public static class Handler
|
||||||
{
|
{
|
||||||
public static void handle(final PacketQueryUndo msg, final CustomPayloadEvent.Context ctx) {
|
public static void handle(final PacketQueryUndo msg, final Supplier<NetworkEvent.Context> ctx) {
|
||||||
if(!ctx.getDirection().getReceptionSide().isServer()) return;
|
if(!ctx.get().getDirection().getReceptionSide().isServer()) return;
|
||||||
|
|
||||||
ServerPlayer player = ctx.getSender();
|
ServerPlayer player = ctx.get().getSender();
|
||||||
if(player == null) return;
|
if(player == null) return;
|
||||||
|
|
||||||
ConstructionWand.instance.undoHistory.updateClient(player, msg.undoPressed);
|
ConstructionWand.instance.undoHistory.updateClient(player, msg.undoPressed);
|
||||||
|
|
|
@ -2,11 +2,12 @@ package thetadev.constructionwand.network;
|
||||||
|
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.network.FriendlyByteBuf;
|
import net.minecraft.network.FriendlyByteBuf;
|
||||||
import net.minecraftforge.event.network.CustomPayloadEvent;
|
import net.minecraftforge.network.NetworkEvent;
|
||||||
import thetadev.constructionwand.ConstructionWand;
|
import thetadev.constructionwand.ConstructionWand;
|
||||||
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
public class PacketUndoBlocks
|
public class PacketUndoBlocks
|
||||||
{
|
{
|
||||||
|
@ -37,13 +38,13 @@ public class PacketUndoBlocks
|
||||||
|
|
||||||
public static class Handler
|
public static class Handler
|
||||||
{
|
{
|
||||||
public static void handle(final PacketUndoBlocks msg, final CustomPayloadEvent.Context ctx) {
|
public static void handle(final PacketUndoBlocks msg, final Supplier<NetworkEvent.Context> ctx) {
|
||||||
if(!ctx.getDirection().getReceptionSide().isClient()) return;
|
if(!ctx.get().getDirection().getReceptionSide().isClient()) return;
|
||||||
|
|
||||||
//ConstructionWand.LOGGER.debug("PacketUndoBlocks received, Blocks: " + msg.undoBlocks.size());
|
//ConstructionWand.LOGGER.debug("PacketUndoBlocks received, Blocks: " + msg.undoBlocks.size());
|
||||||
ConstructionWand.instance.renderBlockPreview.undoBlocks = msg.undoBlocks;
|
ConstructionWand.instance.renderBlockPreview.undoBlocks = msg.undoBlocks;
|
||||||
|
|
||||||
ctx.setPacketHandled(true);
|
ctx.get().setPacketHandled(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,12 +3,14 @@ package thetadev.constructionwand.network;
|
||||||
import net.minecraft.network.FriendlyByteBuf;
|
import net.minecraft.network.FriendlyByteBuf;
|
||||||
import net.minecraft.server.level.ServerPlayer;
|
import net.minecraft.server.level.ServerPlayer;
|
||||||
import net.minecraft.world.item.ItemStack;
|
import net.minecraft.world.item.ItemStack;
|
||||||
import net.minecraftforge.event.network.CustomPayloadEvent;
|
import net.minecraftforge.network.NetworkEvent;
|
||||||
import thetadev.constructionwand.basics.WandUtil;
|
import thetadev.constructionwand.basics.WandUtil;
|
||||||
import thetadev.constructionwand.basics.option.IOption;
|
import thetadev.constructionwand.basics.option.IOption;
|
||||||
import thetadev.constructionwand.basics.option.WandOptions;
|
import thetadev.constructionwand.basics.option.WandOptions;
|
||||||
import thetadev.constructionwand.items.wand.ItemWand;
|
import thetadev.constructionwand.items.wand.ItemWand;
|
||||||
|
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
public class PacketWandOption
|
public class PacketWandOption
|
||||||
{
|
{
|
||||||
public final String key;
|
public final String key;
|
||||||
|
@ -37,10 +39,10 @@ public class PacketWandOption
|
||||||
|
|
||||||
public static class Handler
|
public static class Handler
|
||||||
{
|
{
|
||||||
public static void handle(final PacketWandOption msg, final CustomPayloadEvent.Context ctx) {
|
public static void handle(final PacketWandOption msg, final Supplier<NetworkEvent.Context> ctx) {
|
||||||
if(!ctx.getDirection().getReceptionSide().isServer()) return;
|
if(!ctx.get().getDirection().getReceptionSide().isServer()) return;
|
||||||
|
|
||||||
ServerPlayer player = ctx.getSender();
|
ServerPlayer player = ctx.get().getSender();
|
||||||
if(player == null) return;
|
if(player == null) return;
|
||||||
|
|
||||||
ItemStack wand = WandUtil.holdingWand(player);
|
ItemStack wand = WandUtil.holdingWand(player);
|
||||||
|
|
|
@ -16,6 +16,7 @@ import thetadev.constructionwand.api.IWandAction;
|
||||||
import thetadev.constructionwand.api.IWandSupplier;
|
import thetadev.constructionwand.api.IWandSupplier;
|
||||||
import thetadev.constructionwand.basics.ConfigServer;
|
import thetadev.constructionwand.basics.ConfigServer;
|
||||||
import thetadev.constructionwand.basics.ModStats;
|
import thetadev.constructionwand.basics.ModStats;
|
||||||
|
import thetadev.constructionwand.basics.WandUtil;
|
||||||
import thetadev.constructionwand.basics.option.WandOptions;
|
import thetadev.constructionwand.basics.option.WandOptions;
|
||||||
import thetadev.constructionwand.items.ModItems;
|
import thetadev.constructionwand.items.ModItems;
|
||||||
import thetadev.constructionwand.items.wand.ItemWand;
|
import thetadev.constructionwand.items.wand.ItemWand;
|
||||||
|
@ -118,7 +119,7 @@ public class WandJob
|
||||||
// Play place sound
|
// Play place sound
|
||||||
if(!placeSnapshots.isEmpty()) {
|
if(!placeSnapshots.isEmpty()) {
|
||||||
SoundType sound = placeSnapshots.get(0).getBlockState().getSoundType();
|
SoundType sound = placeSnapshots.get(0).getBlockState().getSoundType();
|
||||||
world.playSound(null, player.blockPosition(), sound.getPlaceSound(), SoundSource.BLOCKS, sound.volume, sound.pitch);
|
world.playSound(null, WandUtil.playerPos(player), sound.getPlaceSound(), SoundSource.BLOCKS, sound.volume, sound.pitch);
|
||||||
|
|
||||||
// Add to job history for undo
|
// Add to job history for undo
|
||||||
ConstructionWand.instance.undoHistory.add(player, world, placeSnapshots);
|
ConstructionWand.instance.undoHistory.add(player, world, placeSnapshots);
|
||||||
|
|
|
@ -60,7 +60,8 @@ public class ActionAngel implements IWandAction
|
||||||
Vec3 playerVec = WandUtil.entityPositionVec(player);
|
Vec3 playerVec = WandUtil.entityPositionVec(player);
|
||||||
Vec3 lookVec = player.getLookAngle().multiply(2, 2, 2);
|
Vec3 lookVec = player.getLookAngle().multiply(2, 2, 2);
|
||||||
Vec3 placeVec = playerVec.add(lookVec);
|
Vec3 placeVec = playerVec.add(lookVec);
|
||||||
BlockPos currentPos = WandUtil.posFromVec(placeVec);
|
|
||||||
|
BlockPos currentPos = new BlockPos(placeVec);
|
||||||
|
|
||||||
PlaceSnapshot snapshot = supplier.getPlaceSnapshot(world, currentPos, rayTraceResult, null);
|
PlaceSnapshot snapshot = supplier.getPlaceSnapshot(world, currentPos, rayTraceResult, null);
|
||||||
if(snapshot != null) placeSnapshots.add(snapshot);
|
if(snapshot != null) placeSnapshots.add(snapshot);
|
||||||
|
|
|
@ -11,7 +11,7 @@ import net.minecraft.world.level.Level;
|
||||||
import net.minecraftforge.network.PacketDistributor;
|
import net.minecraftforge.network.PacketDistributor;
|
||||||
import thetadev.constructionwand.ConstructionWand;
|
import thetadev.constructionwand.ConstructionWand;
|
||||||
import thetadev.constructionwand.basics.ConfigServer;
|
import thetadev.constructionwand.basics.ConfigServer;
|
||||||
import thetadev.constructionwand.network.ModMessages;
|
import thetadev.constructionwand.basics.WandUtil;
|
||||||
import thetadev.constructionwand.network.PacketUndoBlocks;
|
import thetadev.constructionwand.network.PacketUndoBlocks;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
@ -40,7 +40,7 @@ public class UndoHistory
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateClient(Player player, boolean ctrlDown) {
|
public void updateClient(Player player, boolean ctrlDown) {
|
||||||
Level world = player.level();
|
Level world = player.level;
|
||||||
if(world.isClientSide) return;
|
if(world.isClientSide) return;
|
||||||
|
|
||||||
// Set state of CTRL key
|
// Set state of CTRL key
|
||||||
|
@ -60,7 +60,7 @@ public class UndoHistory
|
||||||
}
|
}
|
||||||
|
|
||||||
PacketUndoBlocks packet = new PacketUndoBlocks(positions);
|
PacketUndoBlocks packet = new PacketUndoBlocks(positions);
|
||||||
ModMessages.sendToPlayer(packet, (ServerPlayer) player);
|
ConstructionWand.instance.HANDLER.send(PacketDistributor.PLAYER.with(() -> (ServerPlayer) player), packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isUndoActive(Player player) {
|
public boolean isUndoActive(Player player) {
|
||||||
|
@ -142,7 +142,7 @@ public class UndoHistory
|
||||||
|
|
||||||
// Play teleport sound
|
// Play teleport sound
|
||||||
SoundEvent sound = SoundEvents.CHORUS_FRUIT_TELEPORT;
|
SoundEvent sound = SoundEvents.CHORUS_FRUIT_TELEPORT;
|
||||||
world.playSound(null, player.blockPosition(), sound, SoundSource.PLAYERS, 1.0F, 1.0F);
|
world.playSound(null, WandUtil.playerPos(player), sound, SoundSource.PLAYERS, 1.0F, 1.0F);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
modLoader = "javafml"
|
modLoader = "javafml"
|
||||||
loaderVersion = "[48,)"
|
loaderVersion = "[38,)"
|
||||||
license = "MIT License"
|
license = "MIT License"
|
||||||
[[mods]]
|
[[mods]]
|
||||||
modId="constructionwand"
|
modId="constructionwand"
|
||||||
|
@ -20,12 +20,12 @@ This is my first minecraft mod. May the odds be ever in your favor.
|
||||||
[[dependencies.constructionwand]]
|
[[dependencies.constructionwand]]
|
||||||
modId="forge"
|
modId="forge"
|
||||||
mandatory = true
|
mandatory = true
|
||||||
versionRange = "[48,)"
|
versionRange = "[38,)"
|
||||||
ordering = "NONE"
|
ordering = "NONE"
|
||||||
side="BOTH"
|
side="BOTH"
|
||||||
[[dependencies.constructionwand]]
|
[[dependencies.constructionwand]]
|
||||||
modId="minecraft"
|
modId="minecraft"
|
||||||
mandatory = true
|
mandatory = true
|
||||||
versionRange = "[1.20.2, 1.21)"
|
versionRange = "[1.18, 1.19)"
|
||||||
ordering = "NONE"
|
ordering = "NONE"
|
||||||
side="BOTH"
|
side="BOTH"
|
||||||
|
|
|
@ -1,70 +0,0 @@
|
||||||
{
|
|
||||||
"item.constructionwand.stone_wand": "石の杖",
|
|
||||||
"item.constructionwand.iron_wand": "鉄の杖",
|
|
||||||
"item.constructionwand.diamond_wand": "ダイヤモンドの杖",
|
|
||||||
"item.constructionwand.infinity_wand": "無限の杖",
|
|
||||||
"item.constructionwand.core_angel": "天使の杖のコア",
|
|
||||||
"item.constructionwand.core_destruction": "破壊の杖のコア",
|
|
||||||
|
|
||||||
"constructionwand.tooltip.blocks": "最大%dブロック",
|
|
||||||
"constructionwand.tooltip.shift": "Shiftを押す",
|
|
||||||
"constructionwand.tooltip.cores": "杖のコア:",
|
|
||||||
"constructionwand.tooltip.core_tip": "クラフト画面上で杖とコアを組み合わせてください。",
|
|
||||||
|
|
||||||
"constructionwand.option.cores": "",
|
|
||||||
"constructionwand.option.cores.constructionwand:default": "建築のコア",
|
|
||||||
"constructionwand.option.cores.constructionwand:default.desc": "建築の効果を正面方向に拡大します。",
|
|
||||||
"constructionwand.option.cores.constructionwand:core_angel": "§6天使のコア",
|
|
||||||
"constructionwand.option.cores.constructionwand:core_angel.desc": "ブロックの後ろや中空にブロックを設置します。",
|
|
||||||
"constructionwand.option.cores.constructionwand:core_destruction": "§c破壊のコア",
|
|
||||||
"constructionwand.option.cores.constructionwand:core_destruction.desc": "正面方向のブロックを破壊します。",
|
|
||||||
|
|
||||||
"constructionwand.option.lock": "設置の制限: ",
|
|
||||||
"constructionwand.option.lock.horizontal": "§a水平方向",
|
|
||||||
"constructionwand.option.lock.horizontal.desc": "目標ブロックの前に水平方向に設置します。",
|
|
||||||
"constructionwand.option.lock.vertical": "§a垂直方向",
|
|
||||||
"constructionwand.option.lock.vertical.desc": "目標ブロックの前に垂直方向に設置します。",
|
|
||||||
"constructionwand.option.lock.northsouth": "§6南北方向",
|
|
||||||
"constructionwand.option.lock.northsouth.desc": "目標ブロックの上に南北方向に設置します。",
|
|
||||||
"constructionwand.option.lock.eastwest": "§6東西方向",
|
|
||||||
"constructionwand.option.lock.eastwest.desc": "目標ブロックの上に東西方向に設置します。",
|
|
||||||
"constructionwand.option.lock.nolock": "§cなし",
|
|
||||||
"constructionwand.option.lock.nolock.desc": "目標ブロックからどんな方向にも拡張できます。",
|
|
||||||
|
|
||||||
"constructionwand.option.direction": "設置する向き: ",
|
|
||||||
"constructionwand.option.direction.target": "§6目標ブロック基準",
|
|
||||||
"constructionwand.option.direction.target.desc": "目標ブロックと同じ向きに設置します。",
|
|
||||||
"constructionwand.option.direction.player": "§aプレイヤー基準",
|
|
||||||
"constructionwand.option.direction.player.desc": "プレイヤーに向かって設置します。",
|
|
||||||
|
|
||||||
"constructionwand.option.replace": "ブロックの置換: ",
|
|
||||||
"constructionwand.option.replace.yes": "§a置換する",
|
|
||||||
"constructionwand.option.replace.yes.desc": "液体、雪、背の高い草など特定のブロックを置換します。",
|
|
||||||
"constructionwand.option.replace.no": "§c置換しない",
|
|
||||||
"constructionwand.option.replace.no.desc": "ブロックを置換しません。",
|
|
||||||
|
|
||||||
"constructionwand.option.match": "適合条件: ",
|
|
||||||
"constructionwand.option.match.exact": "§a完全一致",
|
|
||||||
"constructionwand.option.match.exact.desc": "厳密に一致するブロックのみが拡張できます。",
|
|
||||||
"constructionwand.option.match.similar": "§6類似",
|
|
||||||
"constructionwand.option.match.similar.desc": "土ブロックと草ブロックなど、似たブロックを同じものとして扱います。",
|
|
||||||
"constructionwand.option.match.any": "§c全て",
|
|
||||||
"constructionwand.option.match.any.desc": "どんなブロックも拡張できます。",
|
|
||||||
|
|
||||||
"constructionwand.option.random": "ランダム設置: ",
|
|
||||||
"constructionwand.option.random.yes": "§aランダム設置する",
|
|
||||||
"constructionwand.option.random.yes.desc": "ホットバー内にあるブロックをランダムに設置します。",
|
|
||||||
"constructionwand.option.random.no": "§cランダム設置しない",
|
|
||||||
"constructionwand.option.random.no.desc": "ランダム設置を行いません。",
|
|
||||||
|
|
||||||
"constructionwand.description.wand": "%1$sは、向かっている面に%2$dブロック設置でき、%3$s使用できます。\n\n%5$を押しながらホイールスクロールすると設置方向(水平、垂直、南北、東西、無制限)を変更できます。\n\n%6$s§9を押しながら使用§0でオプション画面を開きます。\n\n§5§n取消§0§r\nブロックの方を向きながら§9スニークしながら§0%4$sを押し続けると、最後に設置したブロックが緑の境界線ととともに表示されます。§9スニークしながら§0%4$s§9を押して使用ボタンを押す§0と、処理を取り消すことができ、すべてのブロックはインベントリに戻ります。破壊の杖を使用していた場合もブロックはもとに戻ります。\n\n§5§コンテナ§0§r\nシュルカーボックス、バンドル、その他のModで追加されたコンテナは杖で建築を行った際に資材を供給できます。\n\n§5§nオフハンド優先§0§r\nオフハンドにブロックを持っている場合、設置されているブロックよりそちらが優先されます。",
|
|
||||||
"constructionwand.description.durability.limited": "残り%dブロック",
|
|
||||||
"constructionwand.description.durability.unlimited": "無制限に",
|
|
||||||
"constructionwand.description.key.sneak": "スニーク",
|
|
||||||
"constructionwand.description.key.sneak_opt": "スニーク+%s",
|
|
||||||
"constructionwand.description.core": "§5§nセッティング§0§r\n新しいコアと杖を一緒にクラフトが麺に設置することでセッティングできます。コアを交換するためには、杖を持って何もない空間を%sを押しながら攻撃するか、オプション画面を使用してください。",
|
|
||||||
"constructionwand.description.core_angel": "天使のコアはブロックの反対側にブロックを設置します。最大距離は杖の段階に依存します。オフハンドにブロックを持った状態で、何もない空間に使用すると空中にそのブロックを設置できます。",
|
|
||||||
"constructionwand.description.core_destruction": "破壊のコアは正面のブロック(タイルエンティティは不可)を破壊できます。破壊できる最大ブロック数は杖の段階に依存します。破壊されたブロックは消滅しますが、間違えたときは取り消すことができます。",
|
|
||||||
|
|
||||||
"stat.constructionwand.use_wand": "杖を用いてブロックを設置"
|
|
||||||
}
|
|
70
src/main/resources/assets/constructionwand/lang/tr_tr.json
Normal file
70
src/main/resources/assets/constructionwand/lang/tr_tr.json
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
{
|
||||||
|
"item.constructionwand.stone_wand": "Taş Asa",
|
||||||
|
"item.constructionwand.iron_wand": "Demir Asa",
|
||||||
|
"item.constructionwand.diamond_wand": "Elmas Asa",
|
||||||
|
"item.constructionwand.infinity_wand": "Sonsuzluk Asası",
|
||||||
|
"item.constructionwand.core_angel": "Melek Asa Çekirdeği",
|
||||||
|
"item.constructionwand.core_destruction": "Yıkım Asa Çekirdeği",
|
||||||
|
|
||||||
|
"constructionwand.tooltip.blocks": "Maks. %d blok",
|
||||||
|
"constructionwand.tooltip.shift": "[SHIFT] bas",
|
||||||
|
"constructionwand.tooltip.cores": "Asa çekirdekleri:",
|
||||||
|
"constructionwand.tooltip.core_tip": "Çekirdeği asanızla birlikte üretim ızgarasında birleştirin",
|
||||||
|
|
||||||
|
"constructionwand.option.cores": "",
|
||||||
|
"constructionwand.option.cores.constructionwand:default": "İnşa Çekirdeği",
|
||||||
|
"constructionwand.option.cores.constructionwand:default.desc": "Yapınızın size bakan tarafını uzatır",
|
||||||
|
"constructionwand.option.cores.constructionwand:core_angel": "§6Melek Çekirdeği",
|
||||||
|
"constructionwand.option.cores.constructionwand:core_angel.desc": "Blokların arkasına ve havaya yerleştirir",
|
||||||
|
"constructionwand.option.cores.constructionwand:core_destruction": "§cYıkım Çekirdeği",
|
||||||
|
"constructionwand.option.cores.constructionwand:core_destruction.desc": "Size bakan taraftaki blokları yok eder",
|
||||||
|
|
||||||
|
"constructionwand.option.lock": "Sınırlama: ",
|
||||||
|
"constructionwand.option.lock.horizontal": "§aSol/Sağ",
|
||||||
|
"constructionwand.option.lock.horizontal.desc": "Orijinal bloğun önüne yatay bir sütun oluşturur",
|
||||||
|
"constructionwand.option.lock.vertical": "§aYukarı/Aşağı",
|
||||||
|
"constructionwand.option.lock.vertical.desc": "Orijinal bloğun önünde dikey bir sütun oluşturur",
|
||||||
|
"constructionwand.option.lock.northsouth": "§6Kuzey/Güney",
|
||||||
|
"constructionwand.option.lock.northsouth.desc": "Orijinal bloğun üstüne K/G yönünde bir sıra oluşturun",
|
||||||
|
"constructionwand.option.lock.eastwest": "§6Doğu/Batı",
|
||||||
|
"constructionwand.option.lock.eastwest.desc": "Orijinal bloğun üstüne D/B yönünde bir sıra oluşturur",
|
||||||
|
"constructionwand.option.lock.nolock": "§cYok",
|
||||||
|
"constructionwand.option.lock.nolock.desc": "Orijinal bloğun herhangi bir tarafından uzatır",
|
||||||
|
|
||||||
|
"constructionwand.option.direction": "Yön: ",
|
||||||
|
"constructionwand.option.direction.target": "§6Hedef",
|
||||||
|
"constructionwand.option.direction.target.desc": "Blokları hedef blokla aynı yönde yerleştirir",
|
||||||
|
"constructionwand.option.direction.player": "§aOyuncu",
|
||||||
|
"constructionwand.option.direction.player.desc": "Blokları oyuncuya bakacak şekilde yerleştirir",
|
||||||
|
|
||||||
|
"constructionwand.option.replace": "Değiştirme: ",
|
||||||
|
"constructionwand.option.replace.yes": "§aEvet",
|
||||||
|
"constructionwand.option.replace.yes.desc": "Sıvılar, kar ve uzun otlar gibi belirli blokları değiştirir",
|
||||||
|
"constructionwand.option.replace.no": "§cHayır",
|
||||||
|
"constructionwand.option.replace.no.desc": "Blokları değiştirmez",
|
||||||
|
|
||||||
|
"constructionwand.option.match": "Eşleşen: ",
|
||||||
|
"constructionwand.option.match.exact": "§aAynı",
|
||||||
|
"constructionwand.option.match.exact.desc": "Yalnızca tamamen aynı olan blokları uzatır",
|
||||||
|
"constructionwand.option.match.similar": "§6Benzer",
|
||||||
|
"constructionwand.option.match.similar.desc": "Benzer bloklara (toprak/çimen türleri) eşit davranır",
|
||||||
|
"constructionwand.option.match.any": "§cHerhangi",
|
||||||
|
"constructionwand.option.match.any.desc": "Herhangi bir bloğu uzatır",
|
||||||
|
|
||||||
|
"constructionwand.option.random": "Rastgele: ",
|
||||||
|
"constructionwand.option.random.yes": "§aEvet",
|
||||||
|
"constructionwand.option.random.yes.desc": "Hotbar'ınızdan rastgele bloklar yerleştirir",
|
||||||
|
"constructionwand.option.random.no": "§cHayır",
|
||||||
|
"constructionwand.option.random.no.desc": "Yerleştirilen blokları rastgeleleştirmez",
|
||||||
|
|
||||||
|
"constructionwand.description.wand": "%1$s, bir yapının size bakan tarafına en fazla %2$d blok yerleştirebilir ve %3$s dayanıklılığı vardır.\n\n%5$s tuşunu basılı tutun ve yerleştirme sınırlamasını değiştirmek için kaydırın (Yatay, Dikey, Kuzey/Güney, Doğu/Batı, Kilitsiz).\n\n%6$s§9+Sağ tıklama ile seçenek ekranını açın§0.\n\n§5§nGERİ ALMA§0§r\nBir bloğa bakarken §9Eğil+§0%4$s tuşunu basılı tuttuğunuzda, yerleştirdiğiniz son bloklar, çevresinde yeşil bir çerçeveyle gösterilecektir. §9Eğil+§0%4$s§9+Bunlardan herhangi birine sağ tıklama§0 işlemi geri alacak ve tüm öğeleri size geri verecektir. Yıkım çekirdeğini kullandıysanız blokları geri koyacaktır.\n\n§5§nKONTEYNERLER§0§r\nShulker kutuları, paketler ve diğer modlardan birçok konteyner, asa için yapı taşları sağlar.\n\n§5§nBOŞTAKİ EL ÖNCELİĞݧ0§r\nBoştaki elinizde blok olduğunda, baktığınız blok yerine boştaki elinizdekini yerleştirirsiniz.",
|
||||||
|
"constructionwand.description.durability.limited": "%d blok için",
|
||||||
|
"constructionwand.description.durability.unlimited": "sonsuza kadar",
|
||||||
|
"constructionwand.description.key.sneak": "Eğil",
|
||||||
|
"constructionwand.description.key.sneak_opt": "Eğil+%s",
|
||||||
|
"constructionwand.description.core": "§5§nKURULUM§0§r\nTakmak için yeni çekirdeğinizi asanızla birlikte bir üretim ızgarasına koyun. Çekirdekler arasında geçiş yapmak için %s tuşunu basılı tutun ve asanızla boş alana sol tıklayın veya seçenek ekranını kullanın",
|
||||||
|
"constructionwand.description.core_angel": "Melek çekirdeği, karşı karşıya olduğunuz bloğun (veya blok sırasının) karşı tarafına bir blok yerleştirir. Maksimum mesafe asa seviyesine bağlıdır. Havada bir blok yerleştirmek için boş alana sağ tıklayın. Bunu yapmak için, yerleştirmek istediğiniz bloğu boştaki elinize almalısınız.",
|
||||||
|
"constructionwand.description.core_destruction": "Yıkım çekirdeği, size bakan taraftaki blokları (tile entities haricinde) yok eder. Maksimum blok sayısı asa seviyesine bağlıdır. Yok edilen bloklar boşluğa kaybolur, hata yaptıysanız geri alma özelliğini kullanabilirsiniz.",
|
||||||
|
|
||||||
|
"stat.constructionwand.use_wand": "Asa kullanılarak yerleştirilen bloklar"
|
||||||
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"pack": {
|
"pack": {
|
||||||
"description": "ConstructionWand resources",
|
"description": "ConstructionWand resources",
|
||||||
"pack_format": 18
|
"pack_format": 8
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue