Initial Commit
27
.gitignore
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
# gradle
|
||||
|
||||
.gradle/
|
||||
build/
|
||||
out/
|
||||
classes/
|
||||
|
||||
# idea
|
||||
|
||||
.idea/
|
||||
*.iml
|
||||
*.ipr
|
||||
*.iws
|
||||
|
||||
# vscode
|
||||
|
||||
.settings/
|
||||
.vscode/
|
||||
bin/
|
||||
.classpath
|
||||
.project
|
||||
|
||||
# fabric
|
||||
|
||||
run/
|
||||
|
||||
remappedSrc/
|
4
CHANGELOG.md
Normal file
@ -0,0 +1,4 @@
|
||||
# Changelog
|
||||
|
||||
**1.0**
|
||||
* Initial Release
|
19
Jenkinsfile
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
pipeline {
|
||||
agent {
|
||||
docker {
|
||||
image 'openjdk:8-jdk'
|
||||
}
|
||||
}
|
||||
stages {
|
||||
stage('Build') {
|
||||
steps {
|
||||
sh './gradlew build'
|
||||
}
|
||||
post {
|
||||
success {
|
||||
archiveArtifacts artifacts: 'build/libs/*', fingerprint: true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
21
LICENSE
Normal file
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020 TheBrokenRail
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
16
README.md
Normal file
@ -0,0 +1,16 @@
|
||||
# RelicCraft
|
||||
Find magical relics throughout the world!
|
||||
|
||||
This mod adds several magical items and blocks that can be found randomly throughout the world.
|
||||
|
||||
This mod was created for [ModFest 1.15](https://modfest.github.io/1.15/)
|
||||
|
||||
## Features
|
||||
* Magical Orbs and Staffs With Randomly-Generated Actions
|
||||
* Randomly-Generated Time Temples
|
||||
* Time Dilaters
|
||||
* Teleportation Restrictors
|
||||
* Teleportation Beacons
|
||||
|
||||
## Changelog
|
||||
[View Changelog](CHANGELOG.md)
|
105
build.gradle
Normal file
@ -0,0 +1,105 @@
|
||||
plugins {
|
||||
id 'fabric-loom' version '0.2.7-SNAPSHOT'
|
||||
id 'com.matthewprenger.cursegradle' version '1.4.0'
|
||||
id "com.github.johnrengelman.shadow" version "5.2.0"
|
||||
}
|
||||
|
||||
compileJava {
|
||||
sourceCompatibility = JavaVersion.VERSION_1_8
|
||||
targetCompatibility = JavaVersion.VERSION_1_8
|
||||
}
|
||||
|
||||
archivesBaseName = project.archives_base_name
|
||||
def mod_version = project.mod_version as Object
|
||||
version = "${mod_version}+${project.minecraft_version}"
|
||||
group = project.maven_group as Object
|
||||
|
||||
minecraft {
|
||||
}
|
||||
|
||||
repositories {
|
||||
jcenter()
|
||||
maven {
|
||||
url "https://dl.bintray.com/shedaniel/autoconfig1u/"
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
minecraft "com.mojang:minecraft:${project.minecraft_version}"
|
||||
mappings "net.fabricmc:yarn:${project.minecraft_version}+build.${project.yarn_build}:v2"
|
||||
modImplementation "net.fabricmc:fabric-loader:${project.fabric_loader_version}"
|
||||
modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_api_version}"
|
||||
|
||||
modImplementation "io.github.prospector:modmenu:${project.mod_menu_version}"
|
||||
|
||||
implementation "com.squareup.moshi:moshi:${project.moshi_version}"
|
||||
shadow "com.squareup.moshi:moshi:${project.moshi_version}"
|
||||
}
|
||||
|
||||
processResources {
|
||||
inputs.property 'version', mod_version
|
||||
inputs.property 'name', rootProject.name
|
||||
|
||||
from(sourceSets.main.resources.srcDirs) {
|
||||
include 'fabric.mod.json'
|
||||
expand 'version': mod_version, 'name': rootProject.name
|
||||
}
|
||||
|
||||
from(sourceSets.main.resources.srcDirs) {
|
||||
exclude 'fabric.mod.json'
|
||||
}
|
||||
}
|
||||
|
||||
// ensure that the encoding is set to UTF-8, no matter what the system default is
|
||||
// this fixes some edge cases with special characters not displaying correctly
|
||||
// see http://yodaconditions.net/blog/fix-for-java-file-encoding-problems-with-gradle.html
|
||||
tasks.withType(JavaCompile) {
|
||||
options.encoding = 'UTF-8'
|
||||
}
|
||||
|
||||
// Loom will automatically attach sourcesJar to a RemapSourcesJar task and to the "build" task
|
||||
// if it is present.
|
||||
// If you remove this task, sources will not be generated.
|
||||
task sourcesJar(type: Jar, dependsOn: classes) {
|
||||
classifier 'sources'
|
||||
from sourceSets.main.allSource
|
||||
}
|
||||
|
||||
task javadocJar(type: Jar, dependsOn: javadoc) {
|
||||
classifier 'javadoc'
|
||||
from javadoc.destinationDir
|
||||
}
|
||||
|
||||
artifacts {
|
||||
archives sourcesJar
|
||||
archives javadocJar
|
||||
}
|
||||
|
||||
jar {
|
||||
from "LICENSE"
|
||||
}
|
||||
|
||||
if (project.hasProperty('curseforge.api_key')) {
|
||||
curseforge {
|
||||
apiKey = project.getProperty('curseforge.api_key')
|
||||
project {
|
||||
id = project.curseforge_id
|
||||
changelog = 'A changelog can be found at https://gitea.thebrokenrail.com/TheBrokenRail/RelicCraft/src/branch/master/CHANGELOG.md'
|
||||
releaseType = 'release'
|
||||
addGameVersion project.simple_minecraft_version
|
||||
addGameVersion 'Fabric'
|
||||
mainArtifact(remapJar) {
|
||||
displayName = "RelicCraft v${mod_version} for ${project.minecraft_version}"
|
||||
}
|
||||
afterEvaluate {
|
||||
uploadTask.dependsOn('remapJar')
|
||||
}
|
||||
relations {
|
||||
requiredDependency 'fabric-api'
|
||||
}
|
||||
}
|
||||
options {
|
||||
forgeGradleIntegration = false
|
||||
}
|
||||
}
|
||||
}
|
21
gradle.properties
Normal file
@ -0,0 +1,21 @@
|
||||
# Done to increase the memory available to gradle.
|
||||
org.gradle.jvmargs = -Xmx1G
|
||||
|
||||
# Fabric Properties
|
||||
# check these on https://fabricmc.net/use
|
||||
minecraft_version = 1.15.2
|
||||
curseforge_id = 373074
|
||||
simple_minecraft_version = 1.15.2
|
||||
yarn_build = 14
|
||||
fabric_loader_version = 0.7.9+build.190
|
||||
|
||||
# Mod Properties
|
||||
mod_version = 1.0.0
|
||||
maven_group = com.thebrokenrail
|
||||
archives_base_name = reliccraft
|
||||
|
||||
# Dependencies
|
||||
# currently not on the main fabric site, check on the maven: https://maven.fabricmc.net/net/fabricmc/fabric-api/fabric-api
|
||||
fabric_api_version = 0.5.1+build.294-1.15
|
||||
mod_menu_version = 1.10.2+build.32
|
||||
moshi_version = 1.9.2
|
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
6
gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
#Sat Feb 29 21:58:32 EST 2020
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.2.2-all.zip
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStorePath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
188
gradlew
vendored
Executable file
@ -0,0 +1,188 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
#
|
||||
# Copyright 2015 the original author or authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
##############################################################################
|
||||
##
|
||||
## Gradle start up script for UN*X
|
||||
##
|
||||
##############################################################################
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
# Resolve links: $0 may be a link
|
||||
PRG="$0"
|
||||
# Need this for relative symlinks.
|
||||
while [ -h "$PRG" ] ; do
|
||||
ls=`ls -ld "$PRG"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
PRG="$link"
|
||||
else
|
||||
PRG=`dirname "$PRG"`"/$link"
|
||||
fi
|
||||
done
|
||||
SAVED="`pwd`"
|
||||
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||
APP_HOME="`pwd -P`"
|
||||
cd "$SAVED" >/dev/null
|
||||
|
||||
APP_NAME="Gradle"
|
||||
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.
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
|
||||
warn () {
|
||||
echo "$*"
|
||||
}
|
||||
|
||||
die () {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
}
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
nonstop=false
|
||||
case "`uname`" in
|
||||
CYGWIN* )
|
||||
cygwin=true
|
||||
;;
|
||||
Darwin* )
|
||||
darwin=true
|
||||
;;
|
||||
MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
NONSTOP* )
|
||||
nonstop=true
|
||||
;;
|
||||
esac
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
else
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
fi
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD="java"
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
||||
MAX_FD_LIMIT=`ulimit -H -n`
|
||||
if [ $? -eq 0 ] ; then
|
||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||
MAX_FD="$MAX_FD_LIMIT"
|
||||
fi
|
||||
ulimit -n $MAX_FD
|
||||
if [ $? -ne 0 ] ; then
|
||||
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||
fi
|
||||
else
|
||||
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||
fi
|
||||
fi
|
||||
|
||||
# For Darwin, add options to specify how the application appears in the dock
|
||||
if $darwin; then
|
||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||
fi
|
||||
|
||||
# For Cygwin, switch paths to Windows format before running java
|
||||
if $cygwin ; then
|
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||
|
||||
# We build the pattern for arguments to be converted via cygpath
|
||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||
SEP=""
|
||||
for dir in $ROOTDIRSRAW ; do
|
||||
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||
SEP="|"
|
||||
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=$((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
|
||||
|
||||
# Escape application args
|
||||
save () {
|
||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||
echo " "
|
||||
}
|
||||
APP_ARGS=$(save "$@")
|
||||
|
||||
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||
|
||||
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
|
||||
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
|
||||
cd "$(dirname "$0")"
|
||||
fi
|
||||
|
||||
exec "$JAVACMD" "$@"
|
100
gradlew.bat
vendored
Normal file
@ -0,0 +1,100 @@
|
||||
@rem
|
||||
@rem Copyright 2015 the original author or authors.
|
||||
@rem
|
||||
@rem Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@rem you may not use this file except in compliance with the License.
|
||||
@rem You may obtain a copy of the License at
|
||||
@rem
|
||||
@rem https://www.apache.org/licenses/LICENSE-2.0
|
||||
@rem
|
||||
@rem Unless required by applicable law or agreed to in writing, software
|
||||
@rem distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@rem See the License for the specific language governing permissions and
|
||||
@rem limitations under the License.
|
||||
@rem
|
||||
|
||||
@if "%DEBUG%" == "" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:init
|
||||
@rem Get command-line arguments, handling Windows variants
|
||||
|
||||
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||
|
||||
:win9xME_args
|
||||
@rem Slurp the command line arguments.
|
||||
set CMD_LINE_ARGS=
|
||||
set _SKIP=2
|
||||
|
||||
:win9xME_args_slurp
|
||||
if "x%~1" == "x" goto execute
|
||||
|
||||
set CMD_LINE_ARGS=%*
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||
exit /b 1
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
12
settings.gradle
Normal file
@ -0,0 +1,12 @@
|
||||
pluginManagement {
|
||||
repositories {
|
||||
jcenter()
|
||||
maven {
|
||||
name = 'Fabric'
|
||||
url = 'https://maven.fabricmc.net/'
|
||||
}
|
||||
gradlePluginPortal()
|
||||
}
|
||||
}
|
||||
|
||||
rootProject.name = 'RelicCraft'
|
189
src/main/java/com/thebrokenrail/reliccraft/RelicCraft.java
Normal file
@ -0,0 +1,189 @@
|
||||
package com.thebrokenrail.reliccraft;
|
||||
|
||||
import com.thebrokenrail.reliccraft.advancement.ActivateTeleportationBeaconCriterion;
|
||||
import com.thebrokenrail.reliccraft.advancement.ActivateTeleportationRestrictorCriterion;
|
||||
import com.thebrokenrail.reliccraft.advancement.DilateTimeCriterion;
|
||||
import com.thebrokenrail.reliccraft.advancement.DuplicateTimeDilaterCriterion;
|
||||
import com.thebrokenrail.reliccraft.advancement.RevealRelicCriterion;
|
||||
import com.thebrokenrail.reliccraft.advancement.UseTargetedEnderPearlCriterion;
|
||||
import com.thebrokenrail.reliccraft.advancement.UseTeleportationBeaconCriterion;
|
||||
import com.thebrokenrail.reliccraft.block.DragonEggHolderBlockEntity;
|
||||
import com.thebrokenrail.reliccraft.block.TeleportationBeaconBlock;
|
||||
import com.thebrokenrail.reliccraft.block.TeleportationRestrictorBlock;
|
||||
import com.thebrokenrail.reliccraft.entity.RelicEntity;
|
||||
import com.thebrokenrail.reliccraft.item.TargetedEnderPearlItem;
|
||||
import com.thebrokenrail.reliccraft.item.TimeDilaterItem;
|
||||
import com.thebrokenrail.reliccraft.item.RelicItem;
|
||||
import com.thebrokenrail.reliccraft.mixin.CriteriaRegistryHook;
|
||||
import com.thebrokenrail.reliccraft.recipe.RevealRelicRecipe;
|
||||
import com.thebrokenrail.reliccraft.recipe.TimeDilaterRecipe;
|
||||
import com.thebrokenrail.reliccraft.structure.TimeTempleFeature;
|
||||
import com.thebrokenrail.reliccraft.structure.TimeTempleGenerator;
|
||||
import net.fabricmc.api.ModInitializer;
|
||||
import net.fabricmc.fabric.api.entity.FabricEntityTypeBuilder;
|
||||
import net.fabricmc.fabric.api.loot.v1.FabricLootPoolBuilder;
|
||||
import net.fabricmc.fabric.api.loot.v1.event.LootTableLoadingCallback;
|
||||
import net.fabricmc.fabric.api.tag.TagRegistry;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.entity.BlockEntityType;
|
||||
import net.minecraft.entity.EntityCategory;
|
||||
import net.minecraft.entity.EntityDimensions;
|
||||
import net.minecraft.entity.EntityType;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.item.BlockItem;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemGroup;
|
||||
import net.minecraft.loot.BinomialLootTableRange;
|
||||
import net.minecraft.loot.LootTables;
|
||||
import net.minecraft.loot.entry.ItemEntry;
|
||||
import net.minecraft.recipe.SpecialRecipeSerializer;
|
||||
import net.minecraft.sound.SoundCategory;
|
||||
import net.minecraft.sound.SoundEvent;
|
||||
import net.minecraft.sound.SoundEvents;
|
||||
import net.minecraft.structure.StructurePieceType;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.Rarity;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.biome.Biome;
|
||||
import net.minecraft.world.gen.GenerationStep;
|
||||
import net.minecraft.world.gen.chunk.FlatChunkGeneratorConfig;
|
||||
import net.minecraft.world.gen.decorator.Decorator;
|
||||
import net.minecraft.world.gen.decorator.DecoratorConfig;
|
||||
import net.minecraft.world.gen.feature.ConfiguredFeature;
|
||||
import net.minecraft.world.gen.feature.DefaultFeatureConfig;
|
||||
import net.minecraft.world.gen.feature.Feature;
|
||||
import net.minecraft.world.gen.feature.FeatureConfig;
|
||||
import net.minecraft.world.gen.feature.StructureFeature;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
public class RelicCraft implements ModInitializer {
|
||||
public static final String NAMESPACE = "reliccraft";
|
||||
|
||||
public static Item ORB_ITEM;
|
||||
public static Item STAFF_ITEM;
|
||||
public static Item TIME_DILATER_ITEM;
|
||||
|
||||
public static Item TARGETED_ENDER_PEARL_ITEM;
|
||||
|
||||
public static EntityType<RelicEntity> RELIC_ENTITY;
|
||||
|
||||
public static SpecialRecipeSerializer<RevealRelicRecipe> REVEAL_RELIC_RECIPE;
|
||||
public static SpecialRecipeSerializer<TimeDilaterRecipe> TIME_DILATER_RECIPE;
|
||||
|
||||
public static Block TELEPORTATION_RESTRICTOR_BLOCK;
|
||||
public static Block TELEPORTATION_BEACON_BLOCK;
|
||||
public static BlockEntityType<DragonEggHolderBlockEntity> DRAGON_EGG_HOLDER_BLOCK_ENTITY;
|
||||
|
||||
public static final Identifier[] LOOT_TABLES = new Identifier[]{
|
||||
LootTables.SIMPLE_DUNGEON_CHEST,
|
||||
LootTables.END_CITY_TREASURE_CHEST,
|
||||
LootTables.NETHER_BRIDGE_CHEST,
|
||||
LootTables.ABANDONED_MINESHAFT_CHEST,
|
||||
LootTables.SHIPWRECK_TREASURE_CHEST,
|
||||
LootTables.DESERT_PYRAMID_CHEST,
|
||||
LootTables.JUNGLE_TEMPLE_CHEST,
|
||||
LootTables.STRONGHOLD_LIBRARY_CHEST,
|
||||
LootTables.PILLAGER_OUTPOST_CHEST,
|
||||
LootTables.WOODLAND_MANSION_CHEST,
|
||||
LootTables.BURIED_TREASURE_CHEST,
|
||||
LootTables.FISHING_TREASURE_GAMEPLAY
|
||||
};
|
||||
|
||||
public static ActivateTeleportationRestrictorCriterion ACTIVATE_TELEPORTATION_RESTRICTOR_CRITERION;
|
||||
public static RevealRelicCriterion REVEAL_RELIC_CRITERION;
|
||||
public static DilateTimeCriterion DILATE_TIME_CRITERION;
|
||||
public static DuplicateTimeDilaterCriterion DUPLICATE_TIME_DILATER_CRITERION;
|
||||
public static ActivateTeleportationBeaconCriterion ACTIVATE_TELEPORTATION_BEACON_CRITERION;
|
||||
public static UseTeleportationBeaconCriterion USE_TELEPORTATION_BEACON_CRITERION;
|
||||
public static UseTargetedEnderPearlCriterion USE_TARGETED_ENDER_PEARL;
|
||||
|
||||
private boolean isSelectedLootTable(Identifier lootTable) {
|
||||
for (Identifier id : LOOT_TABLES) {
|
||||
if (id.equals(lootTable)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static final SoundEvent RELIC_SOUND_EFFECT = SoundEvents.BLOCK_ENCHANTMENT_TABLE_USE;
|
||||
private static final SoundEvent INTERACT_TELEPORT_RESTRICTOR_SOUND_EFFECT = SoundEvents.BLOCK_END_PORTAL_FRAME_FILL;
|
||||
|
||||
public static void playRelicSound(PlayerEntity player) {
|
||||
player.playSound(RELIC_SOUND_EFFECT, SoundCategory.PLAYERS, 1.0f, 1.0f);
|
||||
}
|
||||
|
||||
public static void playInteractTeleportRestrictorSound(World world, BlockPos pos) {
|
||||
world.playSound(null, pos, INTERACT_TELEPORT_RESTRICTOR_SOUND_EFFECT, SoundCategory.BLOCKS, 1.0f, 1.0f);
|
||||
}
|
||||
|
||||
public static StructureFeature<DefaultFeatureConfig> TIME_TEMPLE_STRUCTURE_FEATURE;
|
||||
public static StructurePieceType TIME_TEMPLE_STRUCTURE_PIECE;
|
||||
public static final String TIME_TEMPLE_ID = "RelicCraft Time Temple";
|
||||
|
||||
@Override
|
||||
public void onInitialize() {
|
||||
ORB_ITEM = Registry.register(Registry.ITEM, new Identifier(NAMESPACE, "orb"), new RelicItem());
|
||||
STAFF_ITEM = Registry.register(Registry.ITEM, new Identifier(NAMESPACE, "staff"), new RelicItem());
|
||||
TIME_DILATER_ITEM = Registry.register(Registry.ITEM, new Identifier(NAMESPACE, "time_dilater"), new TimeDilaterItem());
|
||||
|
||||
TARGETED_ENDER_PEARL_ITEM = Registry.register(Registry.ITEM, new Identifier(NAMESPACE, "targeted_ender_pearl"), new TargetedEnderPearlItem());
|
||||
|
||||
RELIC_ENTITY = FabricEntityTypeBuilder.create(EntityCategory.MISC, (EntityType.EntityFactory<RelicEntity>) RelicEntity::new).size(EntityDimensions.fixed(0.25f, 0.25f)).build();
|
||||
|
||||
LootTableLoadingCallback.EVENT.register((resourceManager, lootManager, id, supplier, setter) -> {
|
||||
if (isSelectedLootTable(id)) {
|
||||
FabricLootPoolBuilder poolBuilder = FabricLootPoolBuilder.builder()
|
||||
.withRolls(new BinomialLootTableRange(2, 0.5f))
|
||||
.withEntry(ItemEntry.builder(ORB_ITEM))
|
||||
.withEntry(ItemEntry.builder(STAFF_ITEM))
|
||||
.withFunction(new RelicLootTableFunction.Builder());
|
||||
|
||||
supplier.withPool(poolBuilder);
|
||||
}
|
||||
});
|
||||
|
||||
REVEAL_RELIC_RECIPE = Registry.register(Registry.RECIPE_SERIALIZER, new Identifier(NAMESPACE, "reveal_relic"), new SpecialRecipeSerializer<>(RevealRelicRecipe::new));
|
||||
TIME_DILATER_RECIPE = Registry.register(Registry.RECIPE_SERIALIZER, new Identifier(NAMESPACE, "time_dilater"), new SpecialRecipeSerializer<>(TimeDilaterRecipe::new));
|
||||
|
||||
TELEPORTATION_RESTRICTOR_BLOCK = Registry.register(Registry.BLOCK, new Identifier(NAMESPACE, "teleportation_restrictor"), new TeleportationRestrictorBlock());
|
||||
TELEPORTATION_BEACON_BLOCK = Registry.register(Registry.BLOCK, new Identifier(NAMESPACE, "teleportation_beacon"), new TeleportationBeaconBlock());
|
||||
DRAGON_EGG_HOLDER_BLOCK_ENTITY = Registry.register(Registry.BLOCK_ENTITY_TYPE, new Identifier(NAMESPACE, "dragon_egg_holder"), BlockEntityType.Builder.create(DragonEggHolderBlockEntity::new, TELEPORTATION_RESTRICTOR_BLOCK, TELEPORTATION_BEACON_BLOCK).build(null));
|
||||
|
||||
Registry.register(Registry.ITEM, new Identifier(NAMESPACE, "teleportation_restrictor"), new BlockItem(TELEPORTATION_RESTRICTOR_BLOCK, new Item.Settings().group(ItemGroup.MISC).rarity(Rarity.UNCOMMON)));
|
||||
Registry.register(Registry.ITEM, new Identifier(NAMESPACE, "teleportation_beacon"), new BlockItem(TELEPORTATION_BEACON_BLOCK, new Item.Settings().group(ItemGroup.MISC).rarity(Rarity.UNCOMMON)));
|
||||
|
||||
ACTIVATE_TELEPORTATION_RESTRICTOR_CRITERION = CriteriaRegistryHook.callRegister(new ActivateTeleportationRestrictorCriterion());
|
||||
REVEAL_RELIC_CRITERION = CriteriaRegistryHook.callRegister(new RevealRelicCriterion());
|
||||
DILATE_TIME_CRITERION = CriteriaRegistryHook.callRegister(new DilateTimeCriterion());
|
||||
DUPLICATE_TIME_DILATER_CRITERION = CriteriaRegistryHook.callRegister(new DuplicateTimeDilaterCriterion());
|
||||
ACTIVATE_TELEPORTATION_BEACON_CRITERION = CriteriaRegistryHook.callRegister(new ActivateTeleportationBeaconCriterion());
|
||||
USE_TELEPORTATION_BEACON_CRITERION = CriteriaRegistryHook.callRegister(new UseTeleportationBeaconCriterion());
|
||||
USE_TARGETED_ENDER_PEARL = CriteriaRegistryHook.callRegister(new UseTargetedEnderPearlCriterion());
|
||||
|
||||
//noinspection ResultOfMethodCallIgnored
|
||||
TagRegistry.item(new Identifier(NAMESPACE, "relics"));
|
||||
|
||||
TIME_TEMPLE_STRUCTURE_PIECE = Registry.register(Registry.STRUCTURE_PIECE, new Identifier(NAMESPACE, "time_temple"), TimeTempleGenerator.Piece::new);
|
||||
TIME_TEMPLE_STRUCTURE_FEATURE = Registry.register(Registry.FEATURE, new Identifier(NAMESPACE, "time_temple"), new TimeTempleFeature(DefaultFeatureConfig::deserialize));
|
||||
Registry.register(Registry.STRUCTURE_FEATURE, new Identifier(NAMESPACE, "time_temple"), TIME_TEMPLE_STRUCTURE_FEATURE);
|
||||
|
||||
Feature.STRUCTURES.put(TIME_TEMPLE_ID.toLowerCase(Locale.ROOT), TIME_TEMPLE_STRUCTURE_FEATURE);
|
||||
|
||||
ConfiguredFeature<?, ?> configuredFeature = TIME_TEMPLE_STRUCTURE_FEATURE.configure(FeatureConfig.DEFAULT).createDecoratedFeature(Decorator.NOPE.configure(DecoratorConfig.DEFAULT));
|
||||
|
||||
for (Biome biome : Registry.BIOME) {
|
||||
biome.addFeature(GenerationStep.Feature.SURFACE_STRUCTURES, configuredFeature);
|
||||
if (biome.getCategory() == Biome.Category.PLAINS) {
|
||||
biome.addStructureFeature(TIME_TEMPLE_STRUCTURE_FEATURE.configure(FeatureConfig.DEFAULT));
|
||||
}
|
||||
}
|
||||
|
||||
FlatChunkGeneratorConfig.FEATURE_TO_GENERATION_STEP.put(configuredFeature, GenerationStep.Feature.SURFACE_STRUCTURES);
|
||||
FlatChunkGeneratorConfig.FEATURE_TO_FEATURE_CONFIG.put(configuredFeature, FeatureConfig.DEFAULT);
|
||||
FlatChunkGeneratorConfig.STRUCTURE_TO_FEATURES.put(NAMESPACE + "_time_temple", new ConfiguredFeature[]{configuredFeature});
|
||||
}
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
package com.thebrokenrail.reliccraft;
|
||||
|
||||
import com.squareup.moshi.JsonAdapter;
|
||||
import com.squareup.moshi.Moshi;
|
||||
import com.thebrokenrail.reliccraft.data.RelicData;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.loot.condition.LootCondition;
|
||||
import net.minecraft.loot.context.LootContext;
|
||||
import net.minecraft.loot.function.ConditionalLootFunction;
|
||||
import net.minecraft.loot.function.LootFunction;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
|
||||
public class RelicLootTableFunction extends ConditionalLootFunction {
|
||||
private RelicLootTableFunction(LootCondition[] conditions) {
|
||||
super(conditions);
|
||||
}
|
||||
|
||||
public ItemStack process(ItemStack stack, LootContext context) {
|
||||
CompoundTag tag = new CompoundTag();
|
||||
Moshi moshi = new Moshi.Builder().build();
|
||||
JsonAdapter<RelicData> jsonAdapter = moshi.adapter(RelicData.class);
|
||||
tag.putString("RelicData", jsonAdapter.toJson(RelicData.generate(context.getRandom())));
|
||||
stack.setTag(tag);
|
||||
double chance = 1.0d;
|
||||
while (!(context.getRandom().nextDouble() > chance)) {
|
||||
chance = chance * 0.25d;
|
||||
}
|
||||
return stack;
|
||||
}
|
||||
|
||||
public static class Builder extends ConditionalLootFunction.Builder<RelicLootTableFunction.Builder> {
|
||||
@Override
|
||||
protected RelicLootTableFunction.Builder getThisBuilder() {
|
||||
return this;
|
||||
}
|
||||
|
||||
public LootFunction build() {
|
||||
return new RelicLootTableFunction(getConditions());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,34 @@
|
||||
package com.thebrokenrail.reliccraft.advancement;
|
||||
|
||||
import com.google.gson.JsonDeserializationContext;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.thebrokenrail.reliccraft.RelicCraft;
|
||||
import net.minecraft.advancement.criterion.AbstractCriterion;
|
||||
import net.minecraft.advancement.criterion.AbstractCriterionConditions;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
public class ActivateTeleportationBeaconCriterion extends AbstractCriterion<ActivateTeleportationBeaconCriterion.Conditions> {
|
||||
private static final Identifier ID = new Identifier(RelicCraft.NAMESPACE, "activate_teleportation_beacon");
|
||||
|
||||
public ActivateTeleportationBeaconCriterion() {
|
||||
}
|
||||
|
||||
public Identifier getId() {
|
||||
return ID;
|
||||
}
|
||||
|
||||
public Conditions conditionsFromJson(JsonObject jsonObject, JsonDeserializationContext jsonDeserializationContext) {
|
||||
return new Conditions();
|
||||
}
|
||||
|
||||
public void trigger(ServerPlayerEntity player) {
|
||||
test(player.getAdvancementTracker(), conditions -> true);
|
||||
}
|
||||
|
||||
public static class Conditions extends AbstractCriterionConditions {
|
||||
public Conditions() {
|
||||
super(ID);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
package com.thebrokenrail.reliccraft.advancement;
|
||||
|
||||
import com.google.gson.JsonDeserializationContext;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.thebrokenrail.reliccraft.RelicCraft;
|
||||
import net.minecraft.advancement.criterion.AbstractCriterion;
|
||||
import net.minecraft.advancement.criterion.AbstractCriterionConditions;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
public class ActivateTeleportationRestrictorCriterion extends AbstractCriterion<ActivateTeleportationRestrictorCriterion.Conditions> {
|
||||
private static final Identifier ID = new Identifier(RelicCraft.NAMESPACE, "activate_teleportation_restrictor");
|
||||
|
||||
public ActivateTeleportationRestrictorCriterion() {
|
||||
}
|
||||
|
||||
public Identifier getId() {
|
||||
return ID;
|
||||
}
|
||||
|
||||
public Conditions conditionsFromJson(JsonObject jsonObject, JsonDeserializationContext jsonDeserializationContext) {
|
||||
return new Conditions();
|
||||
}
|
||||
|
||||
public void trigger(ServerPlayerEntity player) {
|
||||
test(player.getAdvancementTracker(), conditions -> true);
|
||||
}
|
||||
|
||||
public static class Conditions extends AbstractCriterionConditions {
|
||||
public Conditions() {
|
||||
super(ID);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
package com.thebrokenrail.reliccraft.advancement;
|
||||
|
||||
import com.google.gson.JsonDeserializationContext;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.thebrokenrail.reliccraft.RelicCraft;
|
||||
import net.minecraft.advancement.criterion.AbstractCriterion;
|
||||
import net.minecraft.advancement.criterion.AbstractCriterionConditions;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
public class DilateTimeCriterion extends AbstractCriterion<DilateTimeCriterion.Conditions> {
|
||||
private static final Identifier ID = new Identifier(RelicCraft.NAMESPACE, "dilate_time");
|
||||
|
||||
public DilateTimeCriterion() {
|
||||
}
|
||||
|
||||
public Identifier getId() {
|
||||
return ID;
|
||||
}
|
||||
|
||||
public Conditions conditionsFromJson(JsonObject jsonObject, JsonDeserializationContext jsonDeserializationContext) {
|
||||
return new Conditions();
|
||||
}
|
||||
|
||||
public void trigger(ServerPlayerEntity player) {
|
||||
test(player.getAdvancementTracker(), conditions -> true);
|
||||
}
|
||||
|
||||
public static class Conditions extends AbstractCriterionConditions {
|
||||
public Conditions() {
|
||||
super(ID);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
package com.thebrokenrail.reliccraft.advancement;
|
||||
|
||||
import com.google.gson.JsonDeserializationContext;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.thebrokenrail.reliccraft.RelicCraft;
|
||||
import net.minecraft.advancement.criterion.AbstractCriterion;
|
||||
import net.minecraft.advancement.criterion.AbstractCriterionConditions;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
public class DuplicateTimeDilaterCriterion extends AbstractCriterion<DuplicateTimeDilaterCriterion.Conditions> {
|
||||
private static final Identifier ID = new Identifier(RelicCraft.NAMESPACE, "duplicate_time_dilater");
|
||||
|
||||
public DuplicateTimeDilaterCriterion() {
|
||||
}
|
||||
|
||||
public Identifier getId() {
|
||||
return ID;
|
||||
}
|
||||
|
||||
public Conditions conditionsFromJson(JsonObject jsonObject, JsonDeserializationContext jsonDeserializationContext) {
|
||||
return new Conditions();
|
||||
}
|
||||
|
||||
public void trigger(ServerPlayerEntity player) {
|
||||
test(player.getAdvancementTracker(), conditions -> true);
|
||||
}
|
||||
|
||||
public static class Conditions extends AbstractCriterionConditions {
|
||||
public Conditions() {
|
||||
super(ID);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
package com.thebrokenrail.reliccraft.advancement;
|
||||
|
||||
import com.google.gson.JsonDeserializationContext;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.thebrokenrail.reliccraft.RelicCraft;
|
||||
import net.minecraft.advancement.criterion.AbstractCriterion;
|
||||
import net.minecraft.advancement.criterion.AbstractCriterionConditions;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
public class RevealRelicCriterion extends AbstractCriterion<RevealRelicCriterion.Conditions> {
|
||||
private static final Identifier ID = new Identifier(RelicCraft.NAMESPACE, "reveal_relic");
|
||||
|
||||
public RevealRelicCriterion() {
|
||||
}
|
||||
|
||||
public Identifier getId() {
|
||||
return ID;
|
||||
}
|
||||
|
||||
public Conditions conditionsFromJson(JsonObject jsonObject, JsonDeserializationContext jsonDeserializationContext) {
|
||||
return new Conditions();
|
||||
}
|
||||
|
||||
public void trigger(ServerPlayerEntity player) {
|
||||
test(player.getAdvancementTracker(), conditions -> true);
|
||||
}
|
||||
|
||||
public static class Conditions extends AbstractCriterionConditions {
|
||||
public Conditions() {
|
||||
super(ID);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
package com.thebrokenrail.reliccraft.advancement;
|
||||
|
||||
import com.google.gson.JsonDeserializationContext;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.thebrokenrail.reliccraft.RelicCraft;
|
||||
import net.minecraft.advancement.criterion.AbstractCriterion;
|
||||
import net.minecraft.advancement.criterion.AbstractCriterionConditions;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
public class UseTargetedEnderPearlCriterion extends AbstractCriterion<UseTargetedEnderPearlCriterion.Conditions> {
|
||||
private static final Identifier ID = new Identifier(RelicCraft.NAMESPACE, "use_targeted_ender_pearl");
|
||||
|
||||
public UseTargetedEnderPearlCriterion() {
|
||||
}
|
||||
|
||||
public Identifier getId() {
|
||||
return ID;
|
||||
}
|
||||
|
||||
public Conditions conditionsFromJson(JsonObject jsonObject, JsonDeserializationContext jsonDeserializationContext) {
|
||||
return new Conditions();
|
||||
}
|
||||
|
||||
public void trigger(ServerPlayerEntity player) {
|
||||
test(player.getAdvancementTracker(), conditions -> true);
|
||||
}
|
||||
|
||||
public static class Conditions extends AbstractCriterionConditions {
|
||||
public Conditions() {
|
||||
super(ID);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
package com.thebrokenrail.reliccraft.advancement;
|
||||
|
||||
import com.google.gson.JsonDeserializationContext;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.thebrokenrail.reliccraft.RelicCraft;
|
||||
import net.minecraft.advancement.criterion.AbstractCriterion;
|
||||
import net.minecraft.advancement.criterion.AbstractCriterionConditions;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
public class UseTeleportationBeaconCriterion extends AbstractCriterion<UseTeleportationBeaconCriterion.Conditions> {
|
||||
private static final Identifier ID = new Identifier(RelicCraft.NAMESPACE, "use_teleportation_beacon");
|
||||
|
||||
public UseTeleportationBeaconCriterion() {
|
||||
}
|
||||
|
||||
public Identifier getId() {
|
||||
return ID;
|
||||
}
|
||||
|
||||
public Conditions conditionsFromJson(JsonObject jsonObject, JsonDeserializationContext jsonDeserializationContext) {
|
||||
return new Conditions();
|
||||
}
|
||||
|
||||
public void trigger(ServerPlayerEntity player) {
|
||||
test(player.getAdvancementTracker(), conditions -> true);
|
||||
}
|
||||
|
||||
public static class Conditions extends AbstractCriterionConditions {
|
||||
public Conditions() {
|
||||
super(ID);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,129 @@
|
||||
package com.thebrokenrail.reliccraft.block;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockEntityProvider;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.entity.BlockEntity;
|
||||
import net.minecraft.container.Container;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.inventory.Inventory;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.particle.ParticleTypes;
|
||||
import net.minecraft.sound.SoundCategory;
|
||||
import net.minecraft.sound.SoundEvents;
|
||||
import net.minecraft.state.StateManager;
|
||||
import net.minecraft.state.property.BooleanProperty;
|
||||
import net.minecraft.util.ActionResult;
|
||||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.ItemScatterer;
|
||||
import net.minecraft.util.hit.BlockHitResult;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.BlockView;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public abstract class AbstractDragonEggHolderBlock extends Block implements BlockEntityProvider {
|
||||
public static final BooleanProperty ACTIVE = BooleanProperty.of("active");
|
||||
|
||||
public AbstractDragonEggHolderBlock(Settings settings) {
|
||||
super(settings);
|
||||
setDefaultState(getStateManager().getDefaultState().with(ACTIVE, false));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLuminance(BlockState state) {
|
||||
return state.get(ACTIVE) ? 7 : 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockEntity createBlockEntity(BlockView view) {
|
||||
return new DragonEggHolderBlockEntity();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) {
|
||||
Inventory blockEntity = (Inventory) world.getBlockEntity(pos);
|
||||
|
||||
if (blockEntity != null) {
|
||||
ItemStack stack = player.getStackInHand(hand);
|
||||
|
||||
if (!stack.isEmpty()) {
|
||||
if (blockEntity.isValidInvStack(0, stack) && blockEntity.getInvStack(0).isEmpty()) {
|
||||
blockEntity.setInvStack(0, stack.split(1));
|
||||
if (!world.isClient()) {
|
||||
grantAdvancement(player);
|
||||
}
|
||||
return ActionResult.SUCCESS;
|
||||
} else {
|
||||
return ActionResult.PASS;
|
||||
}
|
||||
} else {
|
||||
if (!blockEntity.getInvStack(0).isEmpty()) {
|
||||
player.inventory.offerOrDrop(world, blockEntity.getInvStack(0));
|
||||
blockEntity.removeInvStack(0);
|
||||
return ActionResult.SUCCESS;
|
||||
} else {
|
||||
return ActionResult.PASS;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return ActionResult.PASS;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isActive(World world, BlockPos pos) {
|
||||
return world.getBlockState(pos).get(ACTIVE);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Environment(EnvType.CLIENT)
|
||||
public void randomDisplayTick(BlockState state, World world, BlockPos pos, Random random) {
|
||||
if (isActive(world, pos)) {
|
||||
if (random.nextInt(100) == 0) {
|
||||
world.playSound(null, pos, SoundEvents.BLOCK_PORTAL_AMBIENT, SoundCategory.BLOCKS, 0.5F, random.nextFloat() * 0.4F + 0.8F);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 24; ++i) {
|
||||
double x = (double) pos.getX() + 0.5D + (double) (0.5F - random.nextFloat());
|
||||
double y = (double) pos.getY() + 0.5D + (double) (0.5F - random.nextFloat());
|
||||
double z = (double) pos.getZ() + 0.5D + (double) (0.5F - random.nextFloat());
|
||||
world.addParticle(ParticleTypes.PORTAL, x, y, z, (random.nextDouble() - 0.5D) * 2.0D, -random.nextDouble(), (random.nextDouble() - 0.5D) * 2.0D);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBlockRemoved(BlockState state, World world, BlockPos pos, BlockState newState, boolean moved) {
|
||||
if (state.getBlock() != newState.getBlock()) {
|
||||
BlockEntity blockEntity = world.getBlockEntity(pos);
|
||||
if (blockEntity instanceof Inventory) {
|
||||
ItemScatterer.spawn(world, pos, (Inventory) blockEntity);
|
||||
}
|
||||
|
||||
super.onBlockRemoved(state, world, pos, newState, moved);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
|
||||
builder.add(ACTIVE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasComparatorOutput(BlockState state) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getComparatorOutput(BlockState state, World world, BlockPos pos) {
|
||||
return Container.calculateComparatorOutput(world.getBlockEntity(pos));
|
||||
}
|
||||
|
||||
public abstract void tick(World world, BlockPos pos, Inventory inventory);
|
||||
|
||||
public abstract void grantAdvancement(PlayerEntity player);
|
||||
}
|
@ -0,0 +1,121 @@
|
||||
package com.thebrokenrail.reliccraft.block;
|
||||
|
||||
import com.thebrokenrail.reliccraft.RelicCraft;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.entity.BlockEntity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.inventory.Inventories;
|
||||
import net.minecraft.inventory.Inventory;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.util.DefaultedList;
|
||||
import net.minecraft.util.Tickable;
|
||||
|
||||
public class DragonEggHolderBlockEntity extends BlockEntity implements Inventory, Tickable {
|
||||
public DragonEggHolderBlockEntity() {
|
||||
super(RelicCraft.DRAGON_EGG_HOLDER_BLOCK_ENTITY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fromTag(CompoundTag tag) {
|
||||
super.fromTag(tag);
|
||||
DefaultedList<ItemStack> list = DefaultedList.ofSize(getInvSize(), ItemStack.EMPTY);
|
||||
Inventories.fromTag(tag, list);
|
||||
stack = list.get(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundTag toTag(CompoundTag tag) {
|
||||
DefaultedList<ItemStack> list = DefaultedList.ofSize(getInvSize(), ItemStack.EMPTY);
|
||||
list.set(0, stack);
|
||||
Inventories.toTag(tag, list);
|
||||
return super.toTag(tag);
|
||||
}
|
||||
|
||||
private ItemStack stack = ItemStack.EMPTY;
|
||||
|
||||
@Override
|
||||
public int getInvSize() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getInvMaxStackAmount() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInvEmpty() {
|
||||
return stack.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getInvStack(int slot) {
|
||||
return stack;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack takeInvStack(int slot, int amount) {
|
||||
ItemStack newStack = getInvStack(0).split(amount);
|
||||
markDirty();
|
||||
return newStack;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack removeInvStack(int slot) {
|
||||
ItemStack newStack = getInvStack(0).copy();
|
||||
setInvStack(0, ItemStack.EMPTY);
|
||||
return newStack;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setInvStack(int slot, ItemStack stack) {
|
||||
this.stack = stack;
|
||||
if (stack.getCount() > getInvMaxStackAmount()) {
|
||||
stack.setCount(getInvMaxStackAmount());
|
||||
}
|
||||
markDirty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canPlayerUseInv(PlayerEntity player) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
setInvStack(0, ItemStack.EMPTY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
if (hasWorld()) {
|
||||
assert getWorld() != null;
|
||||
Block block = getWorld().getBlockState(getPos()).getBlock();
|
||||
if (block instanceof AbstractDragonEggHolderBlock) {
|
||||
((AbstractDragonEggHolderBlock) block).tick(getWorld(), getPos(), this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValidInvStack(int slot, ItemStack stack) {
|
||||
return stack.getItem() == Items.DRAGON_EGG;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void markDirty() {
|
||||
super.markDirty();
|
||||
if (hasWorld()) {
|
||||
assert getWorld() != null;
|
||||
BlockState state = getWorld().getBlockState(pos);
|
||||
boolean active = !getInvStack(0).isEmpty();
|
||||
if (state.get(TeleportationRestrictorBlock.ACTIVE) != active) {
|
||||
getWorld().setBlockState(getPos(), state.with(TeleportationRestrictorBlock.ACTIVE, active));
|
||||
RelicCraft.playInteractTeleportRestrictorSound(getWorld(), getPos());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
package com.thebrokenrail.reliccraft.block;
|
||||
|
||||
import com.thebrokenrail.reliccraft.RelicCraft;
|
||||
import net.fabricmc.fabric.api.block.FabricBlockSettings;
|
||||
import net.minecraft.block.Material;
|
||||
import net.minecraft.block.MaterialColor;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.inventory.Inventory;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.sound.BlockSoundGroup;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class TeleportationBeaconBlock extends AbstractDragonEggHolderBlock {
|
||||
public TeleportationBeaconBlock() {
|
||||
super(FabricBlockSettings.of(Material.METAL, MaterialColor.IRON).strength(5.0F, 6.0F).sounds(BlockSoundGroup.METAL).build());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick(World world, BlockPos pos, Inventory inventory) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void grantAdvancement(PlayerEntity player) {
|
||||
RelicCraft.ACTIVATE_TELEPORTATION_BEACON_CRITERION.trigger((ServerPlayerEntity) player);
|
||||
}
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
package com.thebrokenrail.reliccraft.block;
|
||||
|
||||
import com.thebrokenrail.reliccraft.RelicCraft;
|
||||
import net.fabricmc.fabric.api.block.FabricBlockSettings;
|
||||
import net.minecraft.block.Material;
|
||||
import net.minecraft.block.MaterialColor;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.inventory.Inventory;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Box;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class TeleportationRestrictorBlock extends AbstractDragonEggHolderBlock {
|
||||
public interface TeleportingEntity {
|
||||
boolean cannotTeleport();
|
||||
|
||||
void resetTeleportCooldown();
|
||||
}
|
||||
|
||||
public TeleportationRestrictorBlock() {
|
||||
super(FabricBlockSettings.of(Material.STONE, MaterialColor.BLACK).strength(50.0F, 1200.0F).build());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick(World world, BlockPos pos, Inventory inventory) {
|
||||
int radius = !inventory.getInvStack(0).isEmpty() ? 128 : 0;
|
||||
Box box = new Box(pos).expand(radius);
|
||||
List<LivingEntity> list = world.getNonSpectatingEntities(LivingEntity.class, box);
|
||||
for (LivingEntity entity : list) {
|
||||
((TeleportingEntity) entity).resetTeleportCooldown();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void grantAdvancement(PlayerEntity player) {
|
||||
RelicCraft.ACTIVATE_TELEPORTATION_RESTRICTOR_CRITERION.trigger((ServerPlayerEntity) player);
|
||||
}
|
||||
}
|
@ -0,0 +1,60 @@
|
||||
package com.thebrokenrail.reliccraft.client;
|
||||
|
||||
import com.thebrokenrail.reliccraft.RelicCraft;
|
||||
import com.thebrokenrail.reliccraft.client.entity.RelicEntityRenderer;
|
||||
import com.thebrokenrail.reliccraft.item.RelicItem;
|
||||
import com.thebrokenrail.reliccraft.packet.UpdateTimeDilationS2CPacket;
|
||||
import net.fabricmc.api.ClientModInitializer;
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.fabricmc.fabric.api.client.rendereregistry.v1.EntityRendererRegistry;
|
||||
import net.fabricmc.fabric.api.client.rendering.v1.ColorProviderRegistry;
|
||||
import net.fabricmc.fabric.impl.networking.ClientSidePacketRegistryImpl;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.Util;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@Environment(EnvType.CLIENT)
|
||||
public class RelicCraftClient implements ClientModInitializer {
|
||||
public static int generateColor(float h, float s, float v) {
|
||||
float r, g, b, i, f, p, q, t;
|
||||
i = (float) Math.floor(h * 6);
|
||||
f = h * 6 - i;
|
||||
p = v * (1 - s);
|
||||
q = v * (1 - f * s);
|
||||
t = v * (1 - (1 - f) * s);
|
||||
switch ((int) (i % 6)) {
|
||||
case 0: r = v; g = t; b = p; break;
|
||||
case 1: r = q; g = v; b = p; break;
|
||||
case 2: r = p; g = v; b = t; break;
|
||||
case 3: r = p; g = q; b = v; break;
|
||||
case 4: r = t; g = p; b = v; break;
|
||||
case 5: r = v; g = p; b = q; break;
|
||||
default: throw new UnsupportedOperationException();
|
||||
}
|
||||
return rgbToDecimal(Math.round(r * 255), Math.round(g * 255), Math.round(b * 255));
|
||||
}
|
||||
|
||||
private static int rgbToDecimal(int r, int g, int b) {
|
||||
return (r << 16) | (g << 8) | b;
|
||||
}
|
||||
|
||||
private static int getStackColor(ItemStack stack) {
|
||||
if (stack.getName().asString().equals("jeb_")) {
|
||||
return generateColor(Util.getMeasuringTimeMs() / 3600f, 1f, 1f);
|
||||
} else {
|
||||
return RelicItem.getData(stack).color;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInitializeClient() {
|
||||
ColorProviderRegistry.ITEM.register((stack, tintIndex) -> tintIndex > 0 ? -1 : getStackColor(stack), RelicCraft.ORB_ITEM);
|
||||
ColorProviderRegistry.ITEM.register((stack, tintIndex) -> tintIndex > 0 ? -1 : getStackColor(stack), RelicCraft.STAFF_ITEM);
|
||||
|
||||
EntityRendererRegistry.INSTANCE.register(RelicCraft.RELIC_ENTITY, (entityRenderDispatcher, context) -> new RelicEntityRenderer(entityRenderDispatcher));
|
||||
|
||||
ClientSidePacketRegistryImpl.INSTANCE.register(new Identifier(RelicCraft.NAMESPACE, "update_time_dilation"), UpdateTimeDilationS2CPacket::handle);
|
||||
}
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
package com.thebrokenrail.reliccraft.client.entity;
|
||||
|
||||
import com.thebrokenrail.reliccraft.entity.RelicEntity;
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.minecraft.client.render.entity.EntityRenderDispatcher;
|
||||
import net.minecraft.client.render.entity.EntityRenderer;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public class RelicEntityRenderer extends EntityRenderer<RelicEntity> {
|
||||
public RelicEntityRenderer(EntityRenderDispatcher entityRenderDispatcher) {
|
||||
super(entityRenderDispatcher);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Identifier getTexture(RelicEntity relicEntity) {
|
||||
return null;
|
||||
}
|
||||
}
|
23
src/main/java/com/thebrokenrail/reliccraft/data/Action.java
Normal file
@ -0,0 +1,23 @@
|
||||
package com.thebrokenrail.reliccraft.data;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public interface Action {
|
||||
void execute(World world, LivingEntity attacker, Entity target);
|
||||
|
||||
void execute(World world, LivingEntity attacker, BlockPos pos);
|
||||
|
||||
int getCost();
|
||||
|
||||
default PlayerEntity convertToPlayer(LivingEntity entity) {
|
||||
if (entity instanceof PlayerEntity) {
|
||||
return (PlayerEntity) entity;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
357
src/main/java/com/thebrokenrail/reliccraft/data/Actions.java
Normal file
@ -0,0 +1,357 @@
|
||||
package com.thebrokenrail.reliccraft.data;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityType;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.entity.SpawnType;
|
||||
import net.minecraft.entity.mob.ZombieEntity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.dimension.DimensionType;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
|
||||
public class Actions {
|
||||
private static final Map<String, Action> actions = new HashMap<>();
|
||||
|
||||
public static void register(String id, Action action) {
|
||||
actions.put(id, action);
|
||||
}
|
||||
|
||||
public static Action get(String id) {
|
||||
return actions.get(id);
|
||||
}
|
||||
|
||||
private static String getRandomAction(int budget, Random random) {
|
||||
List<String> options = new ArrayList<>();
|
||||
|
||||
for (Map.Entry<String, Action> entry : actions.entrySet()) {
|
||||
if (budget >= entry.getValue().getCost()) {
|
||||
options.add(entry.getKey());
|
||||
}
|
||||
}
|
||||
|
||||
if (options.size() < 1) {
|
||||
return null;
|
||||
} else {
|
||||
return options.get(random.nextInt(options.size()));
|
||||
}
|
||||
}
|
||||
|
||||
public static String[] getRandomActions(Random random) {
|
||||
List<String> chosen = new ArrayList<>();
|
||||
int amount = random.nextInt(3) + 1;
|
||||
for (int i = 0; i < amount; i++) {
|
||||
int budget = random.nextInt(100) + 1;
|
||||
String action = getRandomAction(budget, random);
|
||||
if (action != null) {
|
||||
chosen.add(action);
|
||||
}
|
||||
}
|
||||
return chosen.toArray(new String[0]);
|
||||
}
|
||||
|
||||
public static class HalfHeartAction implements Action {
|
||||
@Override
|
||||
public int getCost() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(World world, LivingEntity attacker, Entity target) {
|
||||
if (target instanceof LivingEntity) {
|
||||
((LivingEntity) target).setHealth(1f);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(World world, LivingEntity attacker, BlockPos pos) {
|
||||
}
|
||||
}
|
||||
|
||||
public static class SwapBlockAction implements Action {
|
||||
@Override
|
||||
public void execute(World world, LivingEntity attacker, Entity target) {
|
||||
execute(world, attacker, target.getBlockPos().down());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(World world, LivingEntity attacker, BlockPos pos) {
|
||||
BlockState state1 = world.getBlockState(attacker.getBlockPos().down());
|
||||
BlockState state2 = world.getBlockState(pos);
|
||||
world.setBlockState(attacker.getBlockPos().down(), state2);
|
||||
world.setBlockState(pos, state1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCost() {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public static class DirtAction implements Action {
|
||||
@Override
|
||||
public int getCost() {
|
||||
return 15;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(World world, LivingEntity attacker, Entity target) {
|
||||
target.remove();
|
||||
target.kill();
|
||||
world.setBlockState(target.getBlockPos(), Blocks.DIRT.getDefaultState());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(World world, LivingEntity attacker, BlockPos pos) {
|
||||
world.setBlockState(pos, Blocks.DIRT.getDefaultState());
|
||||
}
|
||||
}
|
||||
|
||||
public static class NetherAction implements Action {
|
||||
@Override
|
||||
public int getCost() {
|
||||
return 25;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(World world, LivingEntity attacker, Entity target) {
|
||||
BlockPos pos = target.getBlockPos();
|
||||
BlockState state = world.getBlockState(pos);
|
||||
world.setBlockState(pos, Blocks.NETHER_PORTAL.getDefaultState());
|
||||
target.changeDimension(world.dimension.getType() == DimensionType.THE_NETHER ? DimensionType.OVERWORLD : DimensionType.THE_NETHER);
|
||||
world.setBlockState(pos, state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(World world, LivingEntity attacker, BlockPos pos) {
|
||||
world.setBlockState(pos, Blocks.LAVA.getDefaultState());
|
||||
}
|
||||
}
|
||||
|
||||
public static class EndAction implements Action {
|
||||
@Override
|
||||
public int getCost() {
|
||||
return 50;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(World world, LivingEntity attacker, Entity target) {
|
||||
target.changeDimension(world.dimension.getType() == DimensionType.THE_END ? DimensionType.OVERWORLD : DimensionType.THE_END);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(World world, LivingEntity attacker, BlockPos pos) {
|
||||
world.setBlockState(pos, Blocks.END_STONE.getDefaultState());
|
||||
}
|
||||
}
|
||||
|
||||
public static class DiamondAction extends ConversionAction {
|
||||
@Override
|
||||
public int getCost() {
|
||||
return 99;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Item getTargetItem() {
|
||||
return Items.GOLD_INGOT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Item getConvertedItem() {
|
||||
return Items.DIAMOND;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Block getTargetBlock() {
|
||||
return Blocks.GOLD_BLOCK;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Block getConvertedBlock() {
|
||||
return Blocks.DIAMOND_BLOCK;
|
||||
}
|
||||
}
|
||||
|
||||
public abstract static class ConversionAction implements Action {
|
||||
@Override
|
||||
public abstract int getCost();
|
||||
|
||||
public abstract Item getTargetItem();
|
||||
|
||||
public abstract Item getConvertedItem();
|
||||
|
||||
public abstract Block getTargetBlock();
|
||||
|
||||
public abstract Block getConvertedBlock();
|
||||
|
||||
@Override
|
||||
public void execute(World world, LivingEntity attacker, Entity target) {
|
||||
if (target instanceof PlayerEntity) {
|
||||
PlayerEntity player = (PlayerEntity) target;
|
||||
for (int i = 0; i < player.inventory.getInvSize(); i++) {
|
||||
ItemStack stack = player.inventory.getInvStack(i);
|
||||
if (stack.getItem() == getTargetItem()) {
|
||||
player.inventory.setInvStack(i, new ItemStack(getConvertedItem(), stack.getCount()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(World world, LivingEntity attacker, BlockPos pos) {
|
||||
if (world.getBlockState(pos).getBlock() == getTargetBlock()) {
|
||||
world.setBlockState(pos, getConvertedBlock().getDefaultState());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class GoldAction extends ConversionAction {
|
||||
@Override
|
||||
public int getCost() {
|
||||
return 45;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Item getTargetItem() {
|
||||
return Items.COAL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Item getConvertedItem() {
|
||||
return Items.GOLD_INGOT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Block getTargetBlock() {
|
||||
return Blocks.COAL_BLOCK;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Block getConvertedBlock() {
|
||||
return Blocks.GOLD_BLOCK;
|
||||
}
|
||||
}
|
||||
|
||||
public static class BedrockAction implements Action {
|
||||
@Override
|
||||
public int getCost() {
|
||||
return 60;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(World world, LivingEntity attacker, Entity target) {
|
||||
target.remove();
|
||||
target.kill();
|
||||
world.setBlockState(target.getBlockPos(), Blocks.BEDROCK.getDefaultState());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(World world, LivingEntity attacker, BlockPos pos) {
|
||||
world.setBlockState(pos, Blocks.BEDROCK.getDefaultState());
|
||||
}
|
||||
}
|
||||
|
||||
public static class HealAction implements Action {
|
||||
@Override
|
||||
public int getCost() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(World world, LivingEntity attacker, Entity target) {
|
||||
if (target instanceof LivingEntity) {
|
||||
((LivingEntity) target).heal(Float.MAX_VALUE);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(World world, LivingEntity attacker, BlockPos pos) {
|
||||
}
|
||||
}
|
||||
|
||||
public static class ZombifyAction implements Action {
|
||||
@Override
|
||||
public void execute(World world, LivingEntity attacker, Entity target) {
|
||||
ZombieEntity zombie = new ZombieEntity(world);
|
||||
zombie.updatePosition(target.getX(), target.getY(), target.getZ());
|
||||
world.spawnEntity(zombie);
|
||||
target.remove();
|
||||
target.kill();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(World world, LivingEntity attacker, BlockPos pos) {
|
||||
ZombieEntity zombie = new ZombieEntity(world);
|
||||
zombie.updatePosition(attacker.getX(), attacker.getY(), attacker.getZ());
|
||||
world.spawnEntity(zombie);
|
||||
attacker.remove();
|
||||
attacker.kill();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCost() {
|
||||
return 50;
|
||||
}
|
||||
}
|
||||
|
||||
public static class RandomAction implements Action {
|
||||
@Override
|
||||
public void execute(World world, LivingEntity attacker, Entity target) {
|
||||
if (!target.removed) {
|
||||
target.remove();
|
||||
target.kill();
|
||||
}
|
||||
int entityID = new Random().nextInt(Registry.ENTITY_TYPE.getIds().size());
|
||||
EntityType<?> entityType = Registry.ENTITY_TYPE.get(entityID);
|
||||
if (entityType.isSummonable()) {
|
||||
Entity entity = entityType.spawn(world, null, null, convertToPlayer(attacker), target.getBlockPos(), SpawnType.CONVERSION, false, false);
|
||||
if (entity != null) {
|
||||
entity.updatePosition(target.getX(), target.getY(), target.getZ());
|
||||
} else {
|
||||
execute(world, attacker, target);
|
||||
}
|
||||
} else {
|
||||
execute(world, attacker, target);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(World world, LivingEntity attacker, BlockPos pos) {
|
||||
int blockID = new Random().nextInt(Registry.BLOCK.getIds().size());
|
||||
Block block = Registry.BLOCK.get(blockID);
|
||||
world.setBlockState(pos, block.getDefaultState());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCost() {
|
||||
return 70;
|
||||
}
|
||||
}
|
||||
|
||||
static {
|
||||
register("half_heart_action", new HalfHeartAction());
|
||||
register("swap_block_action", new SwapBlockAction());
|
||||
register("heal_action", new HealAction());
|
||||
register("bedrock_action", new BedrockAction());
|
||||
register("gold_action", new GoldAction());
|
||||
register("diamond_action", new DiamondAction());
|
||||
register("end_action", new EndAction());
|
||||
register("nether_action", new NetherAction());
|
||||
register("dirt_action", new DirtAction());
|
||||
register("zombify_action", new ZombifyAction());
|
||||
register("random_action", new RandomAction());
|
||||
}
|
||||
}
|
@ -0,0 +1,63 @@
|
||||
package com.thebrokenrail.reliccraft.data;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
public class RelicData {
|
||||
public static class NameData {
|
||||
public static final int VARIANT_MAX = 3;
|
||||
public int variant = 0;
|
||||
public static final int MAGIC_WORD_MAX = 7;
|
||||
public int magicWord = 0;
|
||||
}
|
||||
|
||||
public static final int[] COLORS = new int[]{
|
||||
65535,
|
||||
65280,
|
||||
16776960,
|
||||
16711935,
|
||||
255,
|
||||
16711680
|
||||
};
|
||||
|
||||
public int color = COLORS[0];
|
||||
|
||||
public NameData name = new NameData();
|
||||
|
||||
public boolean enchantmentGlint = false;
|
||||
|
||||
public static final int MIN_DURABILITY = 20;
|
||||
public static final int MAX_DURABILITY = 40;
|
||||
|
||||
public int maxDurability = 0;
|
||||
|
||||
public String[] attack = new String[0];
|
||||
|
||||
public static class UseData {
|
||||
public enum Mode {
|
||||
PROJECTILE,
|
||||
TARGET,
|
||||
SELF
|
||||
}
|
||||
public String[] actions = new String[0];
|
||||
public Mode mode = Mode.SELF;
|
||||
}
|
||||
|
||||
public UseData use = new UseData();
|
||||
|
||||
public static RelicData generate(Random random) {
|
||||
RelicData data = new RelicData();
|
||||
NameData name = new NameData();
|
||||
name.variant = random.nextInt(NameData.VARIANT_MAX);
|
||||
name.magicWord = random.nextInt(NameData.MAGIC_WORD_MAX);
|
||||
data.name = name;
|
||||
data.enchantmentGlint = random.nextBoolean();
|
||||
data.maxDurability = random.nextInt(MAX_DURABILITY + 1) + MIN_DURABILITY;
|
||||
data.attack = Actions.getRandomActions(random);
|
||||
UseData use = new UseData();
|
||||
use.mode = UseData.Mode.values()[random.nextInt(UseData.Mode.values().length)];
|
||||
use.actions = Actions.getRandomActions(random);
|
||||
data.use = use;
|
||||
data.color = COLORS[random.nextInt(COLORS.length)];
|
||||
return data;
|
||||
}
|
||||
}
|
@ -0,0 +1,82 @@
|
||||
package com.thebrokenrail.reliccraft.entity;
|
||||
|
||||
import com.thebrokenrail.reliccraft.RelicCraft;
|
||||
import com.thebrokenrail.reliccraft.data.Action;
|
||||
import com.thebrokenrail.reliccraft.data.Actions;
|
||||
import com.thebrokenrail.reliccraft.item.RelicItem;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityType;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.entity.thrown.ThrownItemEntity;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.network.Packet;
|
||||
import net.minecraft.network.packet.s2c.play.EntitySpawnS2CPacket;
|
||||
import net.minecraft.particle.ParticleTypes;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
import net.minecraft.util.hit.BlockHitResult;
|
||||
import net.minecraft.util.hit.EntityHitResult;
|
||||
import net.minecraft.util.hit.HitResult;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public class RelicEntity extends ThrownItemEntity {
|
||||
public RelicEntity(EntityType<RelicEntity> entityType, World world) {
|
||||
super(entityType, world);
|
||||
}
|
||||
|
||||
public RelicEntity(World world, LivingEntity owner) {
|
||||
super(RelicCraft.RELIC_ENTITY, owner, world);
|
||||
}
|
||||
|
||||
public RelicEntity(World world, double x, double y, double z) {
|
||||
super(RelicCraft.RELIC_ENTITY, x, y, z, world);
|
||||
}
|
||||
|
||||
public RelicEntity(World world) {
|
||||
super(RelicCraft.RELIC_ENTITY, world);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCollision(HitResult hitResult) {
|
||||
if (!getEntityWorld().isClient()) {
|
||||
String[] actions = RelicItem.getData(getItem()).use.actions;
|
||||
String id = actions[random.nextInt(actions.length)];
|
||||
Action action = Actions.get(id);
|
||||
if (action != null) {
|
||||
if (hitResult.getType() == HitResult.Type.BLOCK) {
|
||||
BlockHitResult blockHitResult = (BlockHitResult) hitResult;
|
||||
action.execute(getEntityWorld(), getOwner(), blockHitResult.getBlockPos());
|
||||
} else if (hitResult.getType() == HitResult.Type.ENTITY) {
|
||||
Entity entity = ((EntityHitResult) hitResult).getEntity();
|
||||
action.execute(world, getOwner(), entity);
|
||||
}
|
||||
}
|
||||
remove();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
super.tick();
|
||||
if (!getEntityWorld().isClient()) {
|
||||
List<ServerPlayerEntity> viewers = Objects.requireNonNull(getServer()).getPlayerManager().getPlayerList();
|
||||
for (ServerPlayerEntity viewer : viewers) {
|
||||
((ServerWorld) getEntityWorld()).spawnParticles(viewer, ParticleTypes.WITCH, true, getX(), getY(), getZ(), 8, 0.1d, 0.1d, 0.1d, 0d);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Item getDefaultItem() {
|
||||
return RelicCraft.STAFF_ITEM;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Packet<?> createSpawnPacket() {
|
||||
return new EntitySpawnS2CPacket(this);
|
||||
}
|
||||
}
|
221
src/main/java/com/thebrokenrail/reliccraft/item/RelicItem.java
Normal file
@ -0,0 +1,221 @@
|
||||
package com.thebrokenrail.reliccraft.item;
|
||||
|
||||
import com.squareup.moshi.JsonAdapter;
|
||||
import com.squareup.moshi.Moshi;
|
||||
import com.thebrokenrail.reliccraft.RelicCraft;
|
||||
import com.thebrokenrail.reliccraft.data.Action;
|
||||
import com.thebrokenrail.reliccraft.data.Actions;
|
||||
import com.thebrokenrail.reliccraft.data.RelicData;
|
||||
import com.thebrokenrail.reliccraft.entity.RelicEntity;
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.client.item.TooltipContext;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.ItemUsageContext;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.text.TranslatableText;
|
||||
import net.minecraft.util.ActionResult;
|
||||
import net.minecraft.util.Formatting;
|
||||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.Rarity;
|
||||
import net.minecraft.util.TypedActionResult;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class RelicItem extends Item {
|
||||
public RelicItem() {
|
||||
super(new Settings().rarity(Rarity.UNCOMMON).maxDamage(1));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Text getName(ItemStack stack) {
|
||||
RelicData data = getData(stack);
|
||||
return new TranslatableText("text." + RelicCraft.NAMESPACE + ".relic.title_variant." + data.name.variant, super.getName(stack), new TranslatableText("text." + RelicCraft.NAMESPACE + ".relic.magic_word." + data.name.magicWord));
|
||||
}
|
||||
|
||||
public static RelicData getData(ItemStack stack) {
|
||||
CompoundTag tag = stack.getTag();
|
||||
if (tag == null) {
|
||||
return new RelicData();
|
||||
}
|
||||
|
||||
Moshi moshi = new Moshi.Builder().build();
|
||||
JsonAdapter<RelicData> jsonAdapter = moshi.adapter(RelicData.class);
|
||||
|
||||
try {
|
||||
return jsonAdapter.fromJson(tag.getString("RelicData"));
|
||||
} catch (Throwable e) {
|
||||
return new RelicData();
|
||||
}
|
||||
}
|
||||
|
||||
public int getMaxDamage(ItemStack stack) {
|
||||
return getData(stack).maxDurability;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasEnchantmentGlint(ItemStack stack) {
|
||||
RelicData data = getData(stack);
|
||||
return super.hasEnchantmentGlint(stack) || data.enchantmentGlint;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean postHit(ItemStack stack, LivingEntity target, LivingEntity attacker) {
|
||||
if (attacker instanceof PlayerEntity) {
|
||||
RelicData data = getData(stack);
|
||||
if (!attacker.getEntityWorld().isClient()) {
|
||||
String id = data.attack[RANDOM.nextInt(data.attack.length)];
|
||||
Action action = Actions.get(id);
|
||||
action.execute(attacker.getEntityWorld(), attacker, target);
|
||||
}
|
||||
|
||||
damage(stack, (PlayerEntity) attacker, Hand.MAIN_HAND);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canMine(BlockState state, World world, BlockPos pos, PlayerEntity miner) {
|
||||
RelicData data = getData(miner.getMainHandStack());
|
||||
if (!world.isClient()) {
|
||||
String id = data.attack[RANDOM.nextInt(data.attack.length)];
|
||||
Action action = Actions.get(id);
|
||||
action.execute(miner.getEntityWorld(), miner, pos);
|
||||
}
|
||||
|
||||
damage(miner.getMainHandStack(), miner, Hand.MAIN_HAND);
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypedActionResult<ItemStack> use(World world, PlayerEntity user, Hand hand) {
|
||||
ItemStack stack = user.getStackInHand(hand);
|
||||
RelicData data = getData(stack);
|
||||
if (data.use.mode == RelicData.UseData.Mode.PROJECTILE) {
|
||||
if (!world.isClient()) {
|
||||
RelicEntity entity = new RelicEntity(world, user);
|
||||
entity.setItem(stack);
|
||||
entity.setProperties(user, user.pitch, user.yaw, 0.0f, 1.5f, 1.0f);
|
||||
world.spawnEntity(entity);
|
||||
}
|
||||
|
||||
damage(stack, user, hand);
|
||||
return new TypedActionResult<>(ActionResult.SUCCESS, stack);
|
||||
} else if (data.use.mode == RelicData.UseData.Mode.SELF) {
|
||||
if (!world.isClient()) {
|
||||
String id = data.use.actions[RANDOM.nextInt(data.use.actions.length)];
|
||||
Action action = Actions.get(id);
|
||||
action.execute(user.getEntityWorld(), user, user);
|
||||
}
|
||||
|
||||
damage(stack, user, hand);
|
||||
return new TypedActionResult<>(ActionResult.SUCCESS, stack);
|
||||
} else {
|
||||
return new TypedActionResult<>(ActionResult.PASS, stack);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean useOnEntity(ItemStack stack, PlayerEntity user, LivingEntity entity, Hand hand) {
|
||||
RelicData data = getData(stack);
|
||||
if (data.use.mode == RelicData.UseData.Mode.TARGET) {
|
||||
if (!user.getEntityWorld().isClient()) {
|
||||
String id = data.use.actions[RANDOM.nextInt(data.use.actions.length)];
|
||||
Action action = Actions.get(id);
|
||||
action.execute(user.getEntityWorld(), user, entity);
|
||||
}
|
||||
|
||||
damage(stack, user, hand);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActionResult useOnBlock(ItemUsageContext context) {
|
||||
assert context.getPlayer() != null;
|
||||
RelicData data = getData(context.getStack());
|
||||
if (data.use.mode == RelicData.UseData.Mode.TARGET) {
|
||||
if (!context.getWorld().isClient()) {
|
||||
String id = data.use.actions[RANDOM.nextInt(data.use.actions.length)];
|
||||
Action action = Actions.get(id);
|
||||
action.execute(context.getPlayer().getEntityWorld(), context.getPlayer(), context.getBlockPos());
|
||||
}
|
||||
|
||||
damage(context.getStack(), context.getPlayer(), context.getHand());
|
||||
return ActionResult.SUCCESS;
|
||||
} else {
|
||||
return ActionResult.PASS;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canRepair(ItemStack stack, ItemStack ingredient) {
|
||||
return ingredient.getItem() == Items.BLAZE_POWDER;
|
||||
}
|
||||
|
||||
public static final String RELIC_REVEALED_KEY = "RelicRevealed";
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
@Override
|
||||
public void appendTooltip(ItemStack stack, World world, List<Text> tooltip, TooltipContext context) {
|
||||
super.appendTooltip(stack, world, tooltip, context);
|
||||
|
||||
CompoundTag tag = stack.getTag();
|
||||
if (tag == null) {
|
||||
tag = new CompoundTag();
|
||||
}
|
||||
byte revealed = tag.getByte(RELIC_REVEALED_KEY);
|
||||
|
||||
if (revealed >= 2) {
|
||||
RelicData data = getData(stack);
|
||||
tooltip.add(new TranslatableText("item." + RelicCraft.NAMESPACE + ".tooltip.relic.on_attack").formatted(Formatting.WHITE));
|
||||
for (String action : data.attack) {
|
||||
tooltip.add(new TranslatableText("item." + RelicCraft.NAMESPACE + ".tooltip.relic.on_attack.action", new TranslatableText("text." + RelicCraft.NAMESPACE + ".relic.action." + action).formatted(Formatting.GRAY)));
|
||||
}
|
||||
tooltip.add(new TranslatableText("item." + RelicCraft.NAMESPACE + ".tooltip.relic.on_use").formatted(Formatting.WHITE));
|
||||
tooltip.add(new TranslatableText("item." + RelicCraft.NAMESPACE + ".tooltip.relic.on_use.mode", new TranslatableText("item." + RelicCraft.NAMESPACE + ".tooltip.relic.on_use.mode." + data.use.mode.name().toLowerCase()).formatted(Formatting.GRAY)).formatted(Formatting.WHITE));
|
||||
tooltip.add(new TranslatableText("item." + RelicCraft.NAMESPACE + ".tooltip.relic.on_use.actions").formatted(Formatting.WHITE));
|
||||
for (String action : data.use.actions) {
|
||||
tooltip.add(new TranslatableText("item." + RelicCraft.NAMESPACE + ".tooltip.relic.on_use.actions.action", new TranslatableText("text." + RelicCraft.NAMESPACE + ".relic.action." + action).formatted(Formatting.GRAY)));
|
||||
}
|
||||
} else if (revealed == 1) {
|
||||
tooltip.add(new TranslatableText("item." + RelicCraft.NAMESPACE + ".tooltip.relic.not_crafted").formatted(Formatting.WHITE));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void inventoryTick(ItemStack stack, World world, Entity entity, int slot, boolean selected) {
|
||||
CompoundTag tag = stack.getTag();
|
||||
if (tag == null) {
|
||||
tag = new CompoundTag();
|
||||
}
|
||||
byte revealed = tag.getByte(RELIC_REVEALED_KEY);
|
||||
if (revealed == 1) {
|
||||
if (entity instanceof ServerPlayerEntity) {
|
||||
RelicCraft.REVEAL_RELIC_CRITERION.trigger((ServerPlayerEntity) entity);
|
||||
}
|
||||
tag.putByte(RELIC_REVEALED_KEY, (byte) 2);
|
||||
}
|
||||
stack.setTag(tag);
|
||||
}
|
||||
|
||||
private void damage(ItemStack stack, PlayerEntity player, Hand hand) {
|
||||
stack.damage(RANDOM.nextInt(4) + 1, player, e -> e.sendToolBreakStatus(hand));
|
||||
player.getItemCooldownManager().set(this, 10);
|
||||
RelicCraft.playRelicSound(player);
|
||||
}
|
||||
}
|
@ -0,0 +1,116 @@
|
||||
package com.thebrokenrail.reliccraft.item;
|
||||
|
||||
import com.thebrokenrail.reliccraft.RelicCraft;
|
||||
import com.thebrokenrail.reliccraft.block.AbstractDragonEggHolderBlock;
|
||||
import com.thebrokenrail.reliccraft.block.TeleportationRestrictorBlock;
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.minecraft.client.item.TooltipContext;
|
||||
import net.minecraft.entity.damage.DamageSource;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.sound.SoundCategory;
|
||||
import net.minecraft.sound.SoundEvents;
|
||||
import net.minecraft.text.LiteralText;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.text.TranslatableText;
|
||||
import net.minecraft.util.ActionResult;
|
||||
import net.minecraft.util.Formatting;
|
||||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.Language;
|
||||
import net.minecraft.util.Rarity;
|
||||
import net.minecraft.util.TypedActionResult;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.dimension.DimensionType;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class TargetedEnderPearlItem extends Item {
|
||||
public TargetedEnderPearlItem() {
|
||||
super(new Settings().rarity(Rarity.UNCOMMON).maxCount(16));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasEnchantmentGlint(ItemStack stack) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypedActionResult<ItemStack> use(World world, PlayerEntity user, Hand hand) {
|
||||
ItemStack stack = user.getStackInHand(hand);
|
||||
|
||||
if (!world.isClient()) {
|
||||
RelicCraft.playRelicSound(user);
|
||||
|
||||
CompoundTag tag = stack.getTag();
|
||||
if (tag == null) {
|
||||
tag = new CompoundTag();
|
||||
}
|
||||
|
||||
BlockPos target = new BlockPos(tag.getInt("TargetX"), tag.getInt("TargetY"), tag.getInt("TargetZ"));
|
||||
Vec3d teleportTarget = new Vec3d(target.getX() + 0.5d, target.getY() + 1.0d, target.getZ() + 0.5d);
|
||||
DimensionType dimension = DimensionType.byId(new Identifier(tag.getString("TargetDimension")));
|
||||
|
||||
if (user.dimension != dimension || dimension == null) {
|
||||
user.sendMessage(new TranslatableText("chat." + RelicCraft.NAMESPACE + ".teleportation_beacon_in_different_dimension"));
|
||||
} else {
|
||||
if (((TeleportationRestrictorBlock.TeleportingEntity) user).cannotTeleport()) {
|
||||
user.sendMessage(new TranslatableText("chat." + RelicCraft.NAMESPACE + ".teleportation_beacon_restricted"));
|
||||
} else if (world.getBlockState(target).getBlock() != RelicCraft.TELEPORTATION_BEACON_BLOCK || !world.getBlockState(target).get(AbstractDragonEggHolderBlock.ACTIVE)) {
|
||||
user.sendMessage(new TranslatableText("chat." + RelicCraft.NAMESPACE + ".missing_teleportation_beacon"));
|
||||
} else {
|
||||
Vec3d oldPos = user.getPos();
|
||||
if (user.teleport(teleportTarget.getX(), teleportTarget.getY(), teleportTarget.getZ(), true)) {
|
||||
world.playSound(null, oldPos.getX(), oldPos.getY(), oldPos.getZ(), SoundEvents.ITEM_CHORUS_FRUIT_TELEPORT, SoundCategory.PLAYERS, 1.0f, 1.0f);
|
||||
world.playSound(null, teleportTarget.getX(), teleportTarget.getY(), teleportTarget.getZ(), SoundEvents.ITEM_CHORUS_FRUIT_TELEPORT, SoundCategory.PLAYERS, 1.0f, 1.0f);
|
||||
|
||||
RelicCraft.USE_TARGETED_ENDER_PEARL.trigger((ServerPlayerEntity) user);
|
||||
|
||||
user.damage(DamageSource.FALL, 16.0f);
|
||||
|
||||
user.fallDistance = 0f;
|
||||
} else {
|
||||
user.sendMessage(new TranslatableText("chat." + RelicCraft.NAMESPACE + ".teleportation_beacon_obstructed"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!user.isCreative()) {
|
||||
stack.decrement(1);
|
||||
}
|
||||
|
||||
return new TypedActionResult<>(ActionResult.SUCCESS, stack);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Environment(EnvType.CLIENT)
|
||||
public void appendTooltip(ItemStack stack, World world, List<Text> tooltip, TooltipContext context) {
|
||||
super.appendTooltip(stack, world, tooltip, context);
|
||||
|
||||
CompoundTag tag = stack.getTag();
|
||||
if (tag == null) {
|
||||
tag = new CompoundTag();
|
||||
}
|
||||
tooltip.add(new TranslatableText("item." + RelicCraft.NAMESPACE + ".tooltip.targeted_ender_pearl.x", new LiteralText(String.valueOf(tag.getInt("TargetX"))).formatted(Formatting.GRAY)).formatted(Formatting.WHITE));
|
||||
tooltip.add(new TranslatableText("item." + RelicCraft.NAMESPACE + ".tooltip.targeted_ender_pearl.y", new LiteralText(String.valueOf(tag.getInt("TargetY"))).formatted(Formatting.GRAY)).formatted(Formatting.WHITE));
|
||||
tooltip.add(new TranslatableText("item." + RelicCraft.NAMESPACE + ".tooltip.targeted_ender_pearl.z", new LiteralText(String.valueOf(tag.getInt("TargetZ"))).formatted(Formatting.GRAY)).formatted(Formatting.WHITE));
|
||||
|
||||
Identifier id = new Identifier(tag.getString("TargetDimension"));
|
||||
String key = "text." + RelicCraft.NAMESPACE + ".dimension." + id.getNamespace() + '.' + id.getPath();
|
||||
Text dimensionText;
|
||||
if (Language.getInstance().hasTranslation(key)) {
|
||||
dimensionText = new TranslatableText(key);
|
||||
} else {
|
||||
dimensionText = new LiteralText(id.toString());
|
||||
}
|
||||
dimensionText.formatted(Formatting.GRAY);
|
||||
tooltip.add(new TranslatableText("item." + RelicCraft.NAMESPACE + ".tooltip.targeted_ender_pearl.dimension", dimensionText).formatted(Formatting.WHITE));
|
||||
}
|
||||
}
|
@ -0,0 +1,92 @@
|
||||
package com.thebrokenrail.reliccraft.item;
|
||||
|
||||
import com.thebrokenrail.reliccraft.RelicCraft;
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.minecraft.client.item.TooltipContext;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemGroup;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.text.LiteralText;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.text.TranslatableText;
|
||||
import net.minecraft.util.ActionResult;
|
||||
import net.minecraft.util.Formatting;
|
||||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.Rarity;
|
||||
import net.minecraft.util.TypedActionResult;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class TimeDilaterItem extends Item {
|
||||
public enum TimeSpeed {
|
||||
NORMAL,
|
||||
FAST,
|
||||
VERY_FAST
|
||||
}
|
||||
|
||||
public interface DilatedWorld {
|
||||
void setTimeSpeed(TimeSpeed speed);
|
||||
TimeSpeed getTimeSpeed();
|
||||
}
|
||||
|
||||
public TimeDilaterItem() {
|
||||
super(new Settings().group(ItemGroup.MISC).maxDamage(9).rarity(Rarity.UNCOMMON));
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypedActionResult<ItemStack> use(World world, PlayerEntity user, Hand hand) {
|
||||
ItemStack stack = user.getStackInHand(hand);
|
||||
if (!world.isClient()) {
|
||||
DilatedWorld dilatedWorld = (DilatedWorld) world;
|
||||
switch (dilatedWorld.getTimeSpeed()) {
|
||||
case FAST: {
|
||||
dilatedWorld.setTimeSpeed(TimeSpeed.VERY_FAST);
|
||||
break;
|
||||
}
|
||||
case VERY_FAST: {
|
||||
dilatedWorld.setTimeSpeed(TimeSpeed.NORMAL);
|
||||
break;
|
||||
}
|
||||
case NORMAL: {
|
||||
dilatedWorld.setTimeSpeed(TimeSpeed.FAST);
|
||||
break;
|
||||
}
|
||||
}
|
||||
assert world.getServer() != null;
|
||||
world.getServer().getPlayerManager().sendToAll(new TranslatableText("chat." + RelicCraft.NAMESPACE + ".announce_time_speed_change", user.getDisplayName(), new LiteralText("[").append(new TranslatableText("chat." + RelicCraft.NAMESPACE + ".announce_time_speed_change." + dilatedWorld.getTimeSpeed().name().toLowerCase())).append("]").formatted(Formatting.YELLOW)));
|
||||
RelicCraft.DILATE_TIME_CRITERION.trigger((ServerPlayerEntity) user);
|
||||
}
|
||||
|
||||
RelicCraft.playRelicSound(user);
|
||||
stack.damage(1, user, e -> e.sendToolBreakStatus(hand));
|
||||
return new TypedActionResult<>(ActionResult.SUCCESS, stack);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Environment(EnvType.CLIENT)
|
||||
public void appendTooltip(ItemStack stack, World world, List<Text> tooltip, TooltipContext context) {
|
||||
super.appendTooltip(stack, world, tooltip, context);
|
||||
|
||||
if (world != null) {
|
||||
tooltip.add(new TranslatableText("item." + RelicCraft.NAMESPACE + ".tooltip.time_dilater", new TranslatableText("chat." + RelicCraft.NAMESPACE + ".announce_time_speed_change." + ((DilatedWorld) world).getTimeSpeed().name().toLowerCase()).formatted(Formatting.GRAY)).formatted(Formatting.WHITE));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void inventoryTick(ItemStack stack, World world, Entity entity, int slot, boolean selected) {
|
||||
CompoundTag tag = stack.getTag();
|
||||
if (tag == null) {
|
||||
tag = new CompoundTag();
|
||||
}
|
||||
if (entity instanceof ServerPlayerEntity && tag.getByte("Artificial") == 1) {
|
||||
RelicCraft.DUPLICATE_TIME_DILATER_CRITERION.trigger((ServerPlayerEntity) entity);
|
||||
tag.putByte("Artificial", (byte) 2);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
package com.thebrokenrail.reliccraft.mixin;
|
||||
|
||||
import net.minecraft.advancement.criterion.Criterion;
|
||||
import net.minecraft.advancement.criterion.Criterions;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Invoker;
|
||||
|
||||
@Mixin(Criterions.class)
|
||||
public interface CriteriaRegistryHook {
|
||||
@Invoker("register")
|
||||
static <T extends Criterion<?>> T callRegister(T criterion) {
|
||||
return criterion;
|
||||
}
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
package com.thebrokenrail.reliccraft.mixin;
|
||||
|
||||
import com.thebrokenrail.reliccraft.RelicCraft;
|
||||
import com.thebrokenrail.reliccraft.entity.RelicEntity;
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.minecraft.client.network.ClientPlayNetworkHandler;
|
||||
import net.minecraft.client.world.ClientWorld;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityType;
|
||||
import net.minecraft.network.packet.s2c.play.EntitySpawnS2CPacket;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@Environment(EnvType.CLIENT)
|
||||
@Mixin(ClientPlayNetworkHandler.class)
|
||||
public class MixinClientPlayNetworkHandler {
|
||||
@Shadow
|
||||
private ClientWorld world;
|
||||
|
||||
@Inject(method = "onEntitySpawn", at = @At(value = "TAIL"))
|
||||
public void onEntitySpawn(EntitySpawnS2CPacket packet, CallbackInfo info) {
|
||||
EntityType<?> entityType = packet.getEntityTypeId();
|
||||
Entity entity = null;
|
||||
|
||||
if (entityType == RelicCraft.RELIC_ENTITY) {
|
||||
entity = new RelicEntity(world, packet.getX(), packet.getY(), packet.getZ());
|
||||
}
|
||||
|
||||
if (entity != null) {
|
||||
double x = packet.getX();
|
||||
double y = packet.getY();
|
||||
double z = packet.getZ();
|
||||
entity.updateTrackedPosition(x, y, z);
|
||||
entity.pitch = (float) (packet.getPitch() * 360) / 250F;
|
||||
entity.yaw = (float) (packet.getYaw() * 360) / 250F;
|
||||
entity.setEntityId(packet.getId());
|
||||
entity.setUuid(packet.getUuid());
|
||||
world.addEntity(packet.getId(), entity);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
package com.thebrokenrail.reliccraft.mixin;
|
||||
|
||||
import net.minecraft.entity.boss.dragon.EnderDragonFight;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@Mixin(EnderDragonFight.class)
|
||||
public class MixinEnderDragonFight {
|
||||
@SuppressWarnings("SameReturnValue")
|
||||
@Redirect(at = @At(value = "FIELD", target = "Lnet/minecraft/entity/boss/dragon/EnderDragonFight;previouslyKilled:Z", opcode = Opcodes.GETFIELD), method = "dragonKilled")
|
||||
public boolean forceDragonEggSpawn(EnderDragonFight enderDragonFight) {
|
||||
return false;
|
||||
}
|
||||
}
|
@ -0,0 +1,70 @@
|
||||
package com.thebrokenrail.reliccraft.mixin;
|
||||
|
||||
import com.thebrokenrail.reliccraft.RelicCraft;
|
||||
import com.thebrokenrail.reliccraft.block.AbstractDragonEggHolderBlock;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.item.EnderPearlItem;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.ItemUsageContext;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.util.ActionResult;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.dimension.DimensionType;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@Mixin(EnderPearlItem.class)
|
||||
public class MixinEnderPearlItem extends Item {
|
||||
public MixinEnderPearlItem(Settings settings) {
|
||||
super(settings);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActionResult useOnBlock(ItemUsageContext context) {
|
||||
World world = context.getWorld();
|
||||
BlockPos pos = context.getBlockPos();
|
||||
String dimension = Objects.requireNonNull(DimensionType.getId(world.getDimension().getType())).toString();
|
||||
BlockState state = world.getBlockState(pos);
|
||||
PlayerEntity user = context.getPlayer();
|
||||
|
||||
if (!world.isClient()) {
|
||||
assert user != null;
|
||||
RelicCraft.playRelicSound(user);
|
||||
}
|
||||
|
||||
if (user != null && state.getBlock() == RelicCraft.TELEPORTATION_BEACON_BLOCK && state.get(AbstractDragonEggHolderBlock.ACTIVE)) {
|
||||
CompoundTag tag = new CompoundTag();
|
||||
tag.putInt("TargetX", pos.getX());
|
||||
tag.putInt("TargetY", pos.getY());
|
||||
tag.putInt("TargetZ", pos.getZ());
|
||||
tag.putString("TargetDimension", dimension);
|
||||
|
||||
ItemStack itemStack = new ItemStack(RelicCraft.TARGETED_ENDER_PEARL_ITEM);
|
||||
itemStack.setTag(tag);
|
||||
|
||||
ItemStack itemStack2 = user.getStackInHand(context.getHand());
|
||||
|
||||
if (!user.isCreative()) {
|
||||
itemStack2.decrement(1);
|
||||
}
|
||||
|
||||
if (!user.inventory.insertStack(itemStack.copy())) {
|
||||
user.dropItem(itemStack, false);
|
||||
}
|
||||
|
||||
if (!world.isClient()) {
|
||||
RelicCraft.USE_TELEPORTATION_BEACON_CRITERION.trigger((ServerPlayerEntity) user);
|
||||
}
|
||||
|
||||
return ActionResult.SUCCESS;
|
||||
} else {
|
||||
return ActionResult.PASS;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
package com.thebrokenrail.reliccraft.mixin;
|
||||
|
||||
import com.thebrokenrail.reliccraft.block.TeleportationRestrictorBlock;
|
||||
import net.minecraft.entity.Entity;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@Mixin(Entity.class)
|
||||
public class MixinEntity implements TeleportationRestrictorBlock.TeleportingEntity {
|
||||
@Unique
|
||||
private int teleportCooldown = 0;
|
||||
|
||||
@Override
|
||||
public void resetTeleportCooldown() {
|
||||
teleportCooldown = 5;
|
||||
}
|
||||
|
||||
@Inject(at = @At("HEAD"), method = "tick")
|
||||
public void tick(CallbackInfo info) {
|
||||
if (teleportCooldown > 0) {
|
||||
teleportCooldown--;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean cannotTeleport() {
|
||||
return teleportCooldown > 0;
|
||||
}
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
package com.thebrokenrail.reliccraft.mixin;
|
||||
|
||||
import com.thebrokenrail.reliccraft.item.RelicItem;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@Mixin(ItemStack.class)
|
||||
public class MixinItemStack {
|
||||
@Inject(at = @At("HEAD"), method = "getMaxDamage", cancellable = true)
|
||||
public void getMaxDamage(CallbackInfoReturnable<Integer> info) {
|
||||
if (((ItemStack) (Object) this).getItem() instanceof RelicItem) {
|
||||
info.setReturnValue(((RelicItem) ((ItemStack) (Object) this).getItem()).getMaxDamage((ItemStack) (Object) this));
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
package com.thebrokenrail.reliccraft.mixin;
|
||||
|
||||
import com.mojang.datafixers.DataFixer;
|
||||
import com.thebrokenrail.reliccraft.item.TimeDilaterItem;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.world.level.LevelProperties;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@Mixin(LevelProperties.class)
|
||||
public class MixinLevelProperties implements TimeDilaterItem.DilatedWorld {
|
||||
@Unique
|
||||
private TimeDilaterItem.TimeSpeed timeSpeed = TimeDilaterItem.TimeSpeed.NORMAL;
|
||||
|
||||
@Inject(at = @At("RETURN"), method = "<init>(Lnet/minecraft/nbt/CompoundTag;Lcom/mojang/datafixers/DataFixer;ILnet/minecraft/nbt/CompoundTag;)V")
|
||||
public void init(CompoundTag compoundTag, DataFixer dataFixer, int i, CompoundTag compoundTag2, CallbackInfo info) {
|
||||
try {
|
||||
timeSpeed = TimeDilaterItem.TimeSpeed.valueOf(compoundTag.getString("RelicCraftTimeSpeed"));
|
||||
} catch (IllegalArgumentException ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(at = @At("RETURN"), method = "updateProperties")
|
||||
public void updateProperties(CompoundTag levelTag, CompoundTag playerTag, CallbackInfo ci) {
|
||||
levelTag.putString("RelicCraftTimeSpeed", timeSpeed.name());
|
||||
}
|
||||
|
||||
@Override
|
||||
public TimeDilaterItem.TimeSpeed getTimeSpeed() {
|
||||
return timeSpeed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTimeSpeed(TimeDilaterItem.TimeSpeed timeSpeed) {
|
||||
this.timeSpeed = timeSpeed;
|
||||
}
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
package com.thebrokenrail.reliccraft.mixin;
|
||||
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@Mixin(LivingEntity.class)
|
||||
public class MixinLivingEntity extends MixinEntity {
|
||||
@Inject(at = @At("HEAD"), method = "teleport", cancellable = true)
|
||||
public void teleport(double x, double y, double z, boolean particleEffects, CallbackInfoReturnable<Boolean> info) {
|
||||
if (cannotTeleport()) {
|
||||
info.setReturnValue(false);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
package com.thebrokenrail.reliccraft.mixin;
|
||||
|
||||
import com.mojang.brigadier.CommandDispatcher;
|
||||
import com.thebrokenrail.reliccraft.RelicCraft;
|
||||
import net.minecraft.server.command.CommandManager;
|
||||
import net.minecraft.server.command.LocateCommand;
|
||||
import net.minecraft.server.command.ServerCommandSource;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@Mixin(LocateCommand.class)
|
||||
public abstract class MixinLocateCommand {
|
||||
@Shadow
|
||||
private static int execute(ServerCommandSource source, String structure) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Inject(method = "register", at = @At(value = "RETURN"))
|
||||
private static void onRegister(CommandDispatcher<ServerCommandSource> dispatcher, CallbackInfo info) {
|
||||
dispatcher.register(CommandManager.literal("locate").requires(source -> source.hasPermissionLevel(2))
|
||||
.then(CommandManager.literal("RelicCraft_Time_Temple").executes(ctx -> execute(ctx.getSource(), RelicCraft.TIME_TEMPLE_ID))));
|
||||
}
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
package com.thebrokenrail.reliccraft.mixin;
|
||||
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.NetherStarItem;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.ModifyVariable;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@Mixin(NetherStarItem.class)
|
||||
public class MixinNetherStarItem {
|
||||
@ModifyVariable(at = @At("HEAD"), method = "<init>", argsOnly = true)
|
||||
private static Item.Settings init(Item.Settings settings) {
|
||||
return settings.maxDamage(6);
|
||||
}
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
package com.thebrokenrail.reliccraft.mixin;
|
||||
|
||||
import com.thebrokenrail.reliccraft.packet.UpdateTimeDilationS2CPacket;
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import java.util.function.BooleanSupplier;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@Mixin(ServerWorld.class)
|
||||
public abstract class MixinServerWorld extends MixinWorld {
|
||||
@Inject(at = @At("RETURN"), method = "tick")
|
||||
public void tick(BooleanSupplier shouldKeepTicking, CallbackInfo info) {
|
||||
UpdateTimeDilationS2CPacket.send((ServerWorld) (Object) this, getTimeSpeed());
|
||||
}
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
package com.thebrokenrail.reliccraft.mixin;
|
||||
|
||||
import com.thebrokenrail.reliccraft.block.TeleportationRestrictorBlock;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.entity.thrown.ThrownEnderpearlEntity;
|
||||
import net.minecraft.util.hit.HitResult;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@Mixin(ThrownEnderpearlEntity.class)
|
||||
public class MixinThrownEnderpearlEntity {
|
||||
@Inject(at = @At("HEAD"), method = "onCollision", cancellable = true)
|
||||
public void onCollision(HitResult hitResult, CallbackInfo info) {
|
||||
LivingEntity owner = ((ThrownEnderpearlEntity) (Object) this).getOwner();
|
||||
if (owner != null && ((TeleportationRestrictorBlock.TeleportingEntity) owner).cannotTeleport()) {
|
||||
((ThrownEnderpearlEntity) (Object) this).remove();
|
||||
info.cancel();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
package com.thebrokenrail.reliccraft.mixin;
|
||||
|
||||
import com.thebrokenrail.reliccraft.item.TimeDilaterItem;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.level.LevelProperties;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.Constant;
|
||||
import org.spongepowered.asm.mixin.injection.ModifyConstant;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@Mixin(World.class)
|
||||
public abstract class MixinWorld implements TimeDilaterItem.DilatedWorld {
|
||||
@Shadow
|
||||
public abstract boolean isClient();
|
||||
|
||||
@Shadow
|
||||
@Final
|
||||
protected LevelProperties properties;
|
||||
|
||||
@Shadow
|
||||
public abstract long getTime();
|
||||
|
||||
@ModifyConstant(constant = @Constant(longValue = 1L), method = "tickTime")
|
||||
public long tickTime(long value) {
|
||||
switch (getTimeSpeed()) {
|
||||
case FAST: {
|
||||
return value * 4L;
|
||||
}
|
||||
case VERY_FAST: {
|
||||
return value * 8L;
|
||||
}
|
||||
default:
|
||||
case NORMAL: {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTimeSpeed(TimeDilaterItem.TimeSpeed timeSpeed) {
|
||||
((TimeDilaterItem.DilatedWorld) properties).setTimeSpeed(timeSpeed);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TimeDilaterItem.TimeSpeed getTimeSpeed() {
|
||||
return ((TimeDilaterItem.DilatedWorld) properties).getTimeSpeed();
|
||||
}
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
package com.thebrokenrail.reliccraft.packet;
|
||||
|
||||
import com.thebrokenrail.reliccraft.RelicCraft;
|
||||
import com.thebrokenrail.reliccraft.item.TimeDilaterItem;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.fabricmc.fabric.api.network.PacketContext;
|
||||
import net.fabricmc.fabric.api.network.ServerSidePacketRegistry;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.network.Packet;
|
||||
import net.minecraft.network.packet.s2c.play.CustomPayloadS2CPacket;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.PacketByteBuf;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public class UpdateTimeDilationS2CPacket {
|
||||
public static void send(World world, TimeDilaterItem.TimeSpeed speed) {
|
||||
PacketByteBuf buf = new PacketByteBuf(Unpooled.buffer());
|
||||
buf.writeString(speed.name());
|
||||
|
||||
Packet<?> packet = new CustomPayloadS2CPacket(new Identifier(RelicCraft.NAMESPACE, "update_time_dilation"), buf);
|
||||
for (PlayerEntity player : world.getPlayers()) {
|
||||
ServerSidePacketRegistry.INSTANCE.sendToPlayer(player, packet);
|
||||
}
|
||||
}
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public static void handle(PacketContext context, PacketByteBuf buf) {
|
||||
TimeDilaterItem.TimeSpeed speed = TimeDilaterItem.TimeSpeed.valueOf(buf.readString());
|
||||
|
||||
MinecraftClient client = MinecraftClient.getInstance();
|
||||
assert client.world != null;
|
||||
|
||||
((TimeDilaterItem.DilatedWorld) client.world).setTimeSpeed(speed);
|
||||
}
|
||||
}
|
@ -0,0 +1,102 @@
|
||||
package com.thebrokenrail.reliccraft.recipe;
|
||||
|
||||
import com.thebrokenrail.reliccraft.RelicCraft;
|
||||
import com.thebrokenrail.reliccraft.item.RelicItem;
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.minecraft.inventory.CraftingInventory;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.recipe.RecipeSerializer;
|
||||
import net.minecraft.recipe.SpecialCraftingRecipe;
|
||||
import net.minecraft.util.DefaultedList;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
public class RevealRelicRecipe extends SpecialCraftingRecipe {
|
||||
public RevealRelicRecipe(Identifier id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
public boolean matches(CraftingInventory craftingInventory, World world) {
|
||||
ItemStack itemStack = ItemStack.EMPTY;
|
||||
int netherStar = 0;
|
||||
|
||||
for (int i = 0; i < craftingInventory.getInvSize(); ++i) {
|
||||
ItemStack itemStack2 = craftingInventory.getInvStack(i);
|
||||
if (!itemStack2.isEmpty()) {
|
||||
if (itemStack2.getItem() instanceof RelicItem) {
|
||||
if (!itemStack.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
itemStack = itemStack2;
|
||||
} else if (itemStack2.getItem() == Items.NETHER_STAR) {
|
||||
netherStar++;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return !itemStack.isEmpty() && netherStar == 1;
|
||||
}
|
||||
|
||||
public ItemStack craft(CraftingInventory craftingInventory) {
|
||||
ItemStack itemStack = ItemStack.EMPTY;
|
||||
|
||||
for (int i = 0; i < craftingInventory.getInvSize(); i++) {
|
||||
ItemStack itemStack2 = craftingInventory.getInvStack(i);
|
||||
if (!itemStack2.isEmpty()) {
|
||||
Item item = itemStack2.getItem();
|
||||
if (item instanceof RelicItem) {
|
||||
if (!itemStack.isEmpty()) {
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
itemStack = itemStack2.copy();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!itemStack.isEmpty()) {
|
||||
CompoundTag tag = itemStack.getTag();
|
||||
if (tag == null) {
|
||||
tag = new CompoundTag();
|
||||
}
|
||||
tag.putByte(RelicItem.RELIC_REVEALED_KEY, (byte) 1);
|
||||
itemStack.setTag(tag);
|
||||
return itemStack;
|
||||
} else {
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
}
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public boolean fits(int width, int height) {
|
||||
return width * height >= 2;
|
||||
}
|
||||
|
||||
public RecipeSerializer<?> getSerializer() {
|
||||
return RelicCraft.REVEAL_RELIC_RECIPE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DefaultedList<ItemStack> getRemainingStacks(CraftingInventory inventory) {
|
||||
DefaultedList<ItemStack> defaultedList = DefaultedList.ofSize(inventory.getInvSize(), ItemStack.EMPTY);
|
||||
for (int i = 0; i < defaultedList.size(); i++) {
|
||||
ItemStack stack = inventory.getInvStack(i);
|
||||
if (stack.getItem().hasRecipeRemainder()) {
|
||||
defaultedList.set(i, new ItemStack(stack.getItem().getRecipeRemainder()));
|
||||
} else if (stack.getItem() == Items.NETHER_STAR && !stack.damage(1, new Random(), null)) {
|
||||
defaultedList.set(i, stack.copy());
|
||||
}
|
||||
}
|
||||
return defaultedList;
|
||||
}
|
||||
}
|
@ -0,0 +1,51 @@
|
||||
package com.thebrokenrail.reliccraft.recipe;
|
||||
|
||||
import com.thebrokenrail.reliccraft.RelicCraft;
|
||||
import net.minecraft.inventory.CraftingInventory;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.recipe.Ingredient;
|
||||
import net.minecraft.recipe.RecipeSerializer;
|
||||
import net.minecraft.recipe.ShapelessRecipe;
|
||||
import net.minecraft.util.DefaultedList;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
public class TimeDilaterRecipe extends ShapelessRecipe {
|
||||
private static final DefaultedList<Ingredient> INGREDIENTS;
|
||||
private static final ItemStack OUTPUT;
|
||||
|
||||
static {
|
||||
INGREDIENTS = DefaultedList.of();
|
||||
INGREDIENTS.add(Ingredient.ofItems(Items.NETHER_STAR));
|
||||
INGREDIENTS.add(Ingredient.ofItems(RelicCraft.TIME_DILATER_ITEM));
|
||||
INGREDIENTS.add(Ingredient.ofItems(Items.CLOCK));
|
||||
|
||||
OUTPUT = new ItemStack(RelicCraft.TIME_DILATER_ITEM);
|
||||
CompoundTag tag = new CompoundTag();
|
||||
tag.putByte("Artificial", (byte) 1);
|
||||
OUTPUT.setTag(tag);
|
||||
}
|
||||
|
||||
public TimeDilaterRecipe(Identifier id) {
|
||||
super(id, "", OUTPUT, INGREDIENTS);
|
||||
}
|
||||
|
||||
public RecipeSerializer<?> getSerializer() {
|
||||
return RelicCraft.TIME_DILATER_RECIPE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DefaultedList<ItemStack> getRemainingStacks(CraftingInventory inventory) {
|
||||
DefaultedList<ItemStack> defaultedList = DefaultedList.ofSize(inventory.getInvSize(), ItemStack.EMPTY);
|
||||
for (int i = 0; i < defaultedList.size(); i++) {
|
||||
ItemStack stack = inventory.getInvStack(i);
|
||||
if (stack.getItem() == Items.NETHER_STAR && !stack.damage(1, new Random(), null) || stack.getItem() == RelicCraft.TIME_DILATER_ITEM) {
|
||||
defaultedList.set(i, stack.copy());
|
||||
}
|
||||
}
|
||||
return defaultedList;
|
||||
}
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
package com.thebrokenrail.reliccraft.structure;
|
||||
|
||||
import com.mojang.datafixers.Dynamic;
|
||||
import com.thebrokenrail.reliccraft.RelicCraft;
|
||||
import net.minecraft.world.gen.feature.AbstractTempleFeature;
|
||||
import net.minecraft.world.gen.feature.DefaultFeatureConfig;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
public class TimeTempleFeature extends AbstractTempleFeature<DefaultFeatureConfig> {
|
||||
public TimeTempleFeature(Function<Dynamic<?>, ? extends DefaultFeatureConfig> configFactory) {
|
||||
super(configFactory);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getSeedModifier() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public StructureStartFactory getStructureStartFactory() {
|
||||
return TimeTempleStructureStart::new;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return RelicCraft.TIME_TEMPLE_ID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRadius() {
|
||||
return 8;
|
||||
}
|
||||
}
|
@ -0,0 +1,127 @@
|
||||
package com.thebrokenrail.reliccraft.structure;
|
||||
|
||||
import com.thebrokenrail.reliccraft.RelicCraft;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.state.property.Property;
|
||||
import net.minecraft.structure.SimpleStructurePiece;
|
||||
import net.minecraft.structure.Structure;
|
||||
import net.minecraft.structure.StructureManager;
|
||||
import net.minecraft.structure.StructurePiece;
|
||||
import net.minecraft.structure.StructurePlacementData;
|
||||
import net.minecraft.structure.processor.BlockIgnoreStructureProcessor;
|
||||
import net.minecraft.util.BlockMirror;
|
||||
import net.minecraft.util.BlockRotation;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.math.BlockBox;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.ChunkPos;
|
||||
import net.minecraft.world.Heightmap;
|
||||
import net.minecraft.world.IWorld;
|
||||
import net.minecraft.world.gen.chunk.ChunkGenerator;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
public class TimeTempleGenerator {
|
||||
public static void addPieces(StructureManager structureManager, BlockPos blockPos, BlockRotation rotation, List<StructurePiece> list) {
|
||||
list.add(new Piece(structureManager, new Identifier(RelicCraft.NAMESPACE, "time_temple"), blockPos, rotation));
|
||||
}
|
||||
|
||||
public static class Piece extends SimpleStructurePiece {
|
||||
private final Identifier template;
|
||||
private final BlockRotation rotation;
|
||||
|
||||
public Piece(StructureManager manager, Identifier identifier, BlockPos pos, BlockRotation rotation) {
|
||||
super(RelicCraft.TIME_TEMPLE_STRUCTURE_PIECE, 0);
|
||||
this.template = identifier;
|
||||
this.pos = pos;
|
||||
this.rotation = rotation;
|
||||
initializeStructureData(manager);
|
||||
}
|
||||
|
||||
public Piece(StructureManager manager, CompoundTag tag) {
|
||||
super(RelicCraft.TIME_TEMPLE_STRUCTURE_PIECE, tag);
|
||||
template = new Identifier(tag.getString("Template"));
|
||||
rotation = BlockRotation.valueOf(tag.getString("Rot"));
|
||||
initializeStructureData(manager);
|
||||
}
|
||||
|
||||
private void initializeStructureData(StructureManager manager) {
|
||||
Structure structure = manager.getStructureOrBlank(template);
|
||||
StructurePlacementData structurePlacementData = new StructurePlacementData().setRotation(rotation).setMirrored(BlockMirror.NONE).setIgnoreEntities(true).addProcessor(BlockIgnoreStructureProcessor.IGNORE_STRUCTURE_BLOCKS);
|
||||
setStructureData(structure, pos, structurePlacementData);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void toNbt(CompoundTag tag) {
|
||||
super.toNbt(tag);
|
||||
tag.putString("Template", template.toString());
|
||||
tag.putString("Rot", rotation.name());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean generate(IWorld world, ChunkGenerator<?> generator, Random random, BlockBox box, ChunkPos chunkPos) {
|
||||
int yHeight = 0;
|
||||
int area = 0;
|
||||
for (int x = getBoundingBox().minX; x <= getBoundingBox().maxX; x++) {
|
||||
for (int z = getBoundingBox().minZ; z <= getBoundingBox().maxZ; z++) {
|
||||
yHeight = yHeight + world.getTopY(Heightmap.Type.WORLD_SURFACE_WG, x, z);
|
||||
area++;
|
||||
}
|
||||
}
|
||||
yHeight = yHeight / area;
|
||||
|
||||
BlockPos originalPos = pos;
|
||||
pos = pos.add(0, yHeight - 90, 0);
|
||||
|
||||
boolean result = super.generate(world, generator, random, box, chunkPos);
|
||||
|
||||
if (result) {
|
||||
for (int x = getBoundingBox().minX; x <= getBoundingBox().maxX; x++) {
|
||||
for (int y = getBoundingBox().minY; y <= getBoundingBox().maxY; y++) {
|
||||
for (int z = getBoundingBox().minZ; z <= getBoundingBox().maxZ; z++) {
|
||||
BlockPos blockPos = new BlockPos(x, y, z);
|
||||
if (box.contains(blockPos)) {
|
||||
BlockState state = world.getBlockState(blockPos);
|
||||
|
||||
boolean damaged = random.nextFloat() < 0.6f;
|
||||
if (damaged) {
|
||||
if (state.getBlock() == Blocks.STONE_BRICKS) {
|
||||
boolean mossy = random.nextFloat() < 0.5f;
|
||||
world.setBlockState(blockPos, convertState(state, mossy ? Blocks.MOSSY_STONE_BRICKS : Blocks.CRACKED_STONE_BRICKS), 3);
|
||||
} else if (world.getBlockState(blockPos).getBlock() == Blocks.STONE_BRICK_STAIRS) {
|
||||
world.setBlockState(blockPos, convertState(state, Blocks.MOSSY_STONE_BRICK_STAIRS), 3);
|
||||
} else if (world.getBlockState(blockPos).getBlock() == Blocks.STONE_BRICK_SLAB) {
|
||||
world.setBlockState(blockPos, convertState(state, Blocks.MOSSY_STONE_BRICK_SLAB), 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pos = originalPos;
|
||||
return result;
|
||||
}
|
||||
|
||||
private BlockState convertState(BlockState oldState, Block newBlock) {
|
||||
BlockState newState = newBlock.getDefaultState();
|
||||
Collection<Property<?>> properties = oldState.getProperties();
|
||||
//noinspection rawtypes
|
||||
for (Property property : properties) {
|
||||
//noinspection unchecked
|
||||
newState = newState.with(property, oldState.get(property));
|
||||
}
|
||||
return newState;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void handleMetadata(String metadata, BlockPos pos, IWorld world, Random random, BlockBox boundingBox) {
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
package com.thebrokenrail.reliccraft.structure;
|
||||
|
||||
import net.minecraft.structure.StructureManager;
|
||||
import net.minecraft.structure.StructureStart;
|
||||
import net.minecraft.util.BlockRotation;
|
||||
import net.minecraft.util.math.BlockBox;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.biome.Biome;
|
||||
import net.minecraft.world.gen.chunk.ChunkGenerator;
|
||||
import net.minecraft.world.gen.feature.StructureFeature;
|
||||
|
||||
public class TimeTempleStructureStart extends StructureStart {
|
||||
public TimeTempleStructureStart(StructureFeature<?> feature, int chunkX, int chunkZ, BlockBox box, int references, long l) {
|
||||
super(feature, chunkX, chunkZ, box, references, l);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize(ChunkGenerator<?> chunkGenerator, StructureManager structureManager, int x, int z, Biome biome) {
|
||||
int i = x * 16;
|
||||
int j = z * 16;
|
||||
BlockPos blockPos = new BlockPos(i, 90, j);
|
||||
BlockRotation blockRotation = BlockRotation.values()[random.nextInt(BlockRotation.values().length)];
|
||||
TimeTempleGenerator.addPieces(structureManager, blockPos, blockRotation, children);
|
||||
setBoundingBoxFromChildren();
|
||||
}
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
{
|
||||
"variants": {
|
||||
"active=false": {
|
||||
"model": "reliccraft:block/teleportation_beacon"
|
||||
},
|
||||
"active=true": {
|
||||
"model": "reliccraft:block/active_teleportation_beacon"
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
{
|
||||
"variants": {
|
||||
"active=false": {
|
||||
"model": "reliccraft:block/teleportation_restrictor"
|
||||
},
|
||||
"active=true": {
|
||||
"model": "reliccraft:block/active_teleportation_restrictor"
|
||||
}
|
||||
}
|
||||
}
|
67
src/main/resources/assets/reliccraft/lang/en_us.json
Normal file
@ -0,0 +1,67 @@
|
||||
{
|
||||
"text.reliccraft.relic.title_variant.0": "The %s of %s",
|
||||
"text.reliccraft.relic.title_variant.1": "%s of %s",
|
||||
"text.reliccraft.relic.title_variant.2": "The %s %s",
|
||||
"text.reliccraft.relic.magic_word.0": "Solarus",
|
||||
"text.reliccraft.relic.magic_word.1": "Galagus",
|
||||
"text.reliccraft.relic.magic_word.2": "Galactus",
|
||||
"text.reliccraft.relic.magic_word.3": "Galagon",
|
||||
"text.reliccraft.relic.magic_word.4": "Extremus",
|
||||
"text.reliccraft.relic.magic_word.5": "Enchantus",
|
||||
"text.reliccraft.relic.magic_word.6": "Magicus",
|
||||
"item.reliccraft.orb": "Orb",
|
||||
"item.reliccraft.staff": "Staff",
|
||||
"item.reliccraft.targeted_ender_pearl": "Targeted Ender Pearl",
|
||||
"item.reliccraft.time_dilater": "Time Dilater",
|
||||
"chat.reliccraft.announce_time_speed_change": "%s has dilated the world's speed to %s",
|
||||
"chat.reliccraft.announce_time_speed_change.fast": "Fast",
|
||||
"chat.reliccraft.announce_time_speed_change.very_fast": "Very Fast",
|
||||
"chat.reliccraft.announce_time_speed_change.normal": "Normal",
|
||||
"chat.reliccraft.missing_teleportation_beacon": "Your Teleportation Beacon has been deactivated or destroyed",
|
||||
"chat.reliccraft.teleportation_beacon_obstructed": "Your Teleportation Beacon is obstructed",
|
||||
"chat.reliccraft.teleportation_beacon_restricted": "A Teleportation Restrictor is im effect",
|
||||
"chat.reliccraft.teleportation_beacon_in_different_dimension": "Your Teleportation Beacon is in a different dimension",
|
||||
"item.reliccraft.tooltip.relic.on_use": "On Use:",
|
||||
"item.reliccraft.tooltip.relic.on_use.mode": " Mode: %s",
|
||||
"item.reliccraft.tooltip.relic.on_use.mode.projectile": "Shoot Projectile",
|
||||
"item.reliccraft.tooltip.relic.on_use.mode.target": "Use On Target",
|
||||
"item.reliccraft.tooltip.relic.on_use.mode.self": "Use On Self",
|
||||
"item.reliccraft.tooltip.relic.on_use.actions": " Actions:",
|
||||
"item.reliccraft.tooltip.relic.on_use.actions.action": " %s",
|
||||
"item.reliccraft.tooltip.relic.on_attack": "On Attack:",
|
||||
"item.reliccraft.tooltip.relic.on_attack.action": " %s",
|
||||
"item.reliccraft.tooltip.relic.not_crafted": "Craft To Reveal Secrets",
|
||||
"item.reliccraft.tooltip.time_dilater": "Current Time Dilation: %s",
|
||||
"item.reliccraft.tooltip.targeted_ender_pearl.x": "X: %s",
|
||||
"item.reliccraft.tooltip.targeted_ender_pearl.y": "Y: %s",
|
||||
"item.reliccraft.tooltip.targeted_ender_pearl.z": "Z: %s",
|
||||
"item.reliccraft.tooltip.targeted_ender_pearl.dimension": "Dimension: %s",
|
||||
"text.reliccraft.relic.action.heal_action": "Heal",
|
||||
"text.reliccraft.relic.action.bedrock_action": "Turn To Bedrock",
|
||||
"text.reliccraft.relic.action.gold_action": "Turn Coal To Gold",
|
||||
"text.reliccraft.relic.action.diamond_action": "Turn Gold To Diamond",
|
||||
"text.reliccraft.relic.action.end_action": "Go To The End",
|
||||
"text.reliccraft.relic.action.nether_action": "Go To The Nether",
|
||||
"text.reliccraft.relic.action.dirt_action": "Turn To Dirt",
|
||||
"text.reliccraft.relic.action.zombify_action": "Zombify",
|
||||
"text.reliccraft.relic.action.random_action": "Randomize",
|
||||
"text.reliccraft.relic.action.half_heart_action": "Half-Heart",
|
||||
"text.reliccraft.relic.action.swap_block_action": "Swap Blocks",
|
||||
"block.reliccraft.teleportation_restrictor": "Teleportation Restrictor",
|
||||
"block.reliccraft.teleportation_beacon": "Teleportation Beacon",
|
||||
"advancements.reliccraft.root.title": "RelicCraft",
|
||||
"advancements.reliccraft.root.description": "Explore Ancient Relics and Magic!",
|
||||
"advancements.reliccraft.activate_teleportation_restrictor.title": "Teleportation Ban",
|
||||
"advancements.reliccraft.activate_teleportation_restrictor.description": "Activate a Teleportation Restrictor with a Dragon Egg",
|
||||
"advancements.reliccraft.activate_teleportation_beacon.title": "Teleportation Master",
|
||||
"advancements.reliccraft.activate_teleportation_beacon.description": "Activate a Teleportation Beacon with a Dragon Egg, then create a Targeted Ender Pearl by using an Ender Pearl on it, and then finally use the Targeted Ender Pearl",
|
||||
"advancements.reliccraft.reveal_relic.title": "Master Archaeologist",
|
||||
"advancements.reliccraft.reveal_relic.description": "Combine a Relic with a Nether Star",
|
||||
"advancements.reliccraft.dilate_time.title": "Time Master",
|
||||
"advancements.reliccraft.dilate_time.description": "Use a Time Dilater",
|
||||
"advancements.reliccraft.duplicate_time_dilater.title": "Time Lord",
|
||||
"advancements.reliccraft.duplicate_time_dilater.description": "Duplicate a Time Dilater",
|
||||
"text.reliccraft.dimension.minecraft.overworld": "The Overworld",
|
||||
"text.reliccraft.dimension.minecraft.the_nether": "The Nether",
|
||||
"text.reliccraft.dimension.minecraft.the_end": "The End"
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
{
|
||||
"parent": "minecraft:block/cube_all",
|
||||
"textures": {
|
||||
"all": "reliccraft:block/active_teleportation_beacon"
|
||||
}
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
{
|
||||
"parent": "minecraft:block/cube_all",
|
||||
"textures": {
|
||||
"all": "reliccraft:block/active_teleportation_restrictor"
|
||||
}
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
{
|
||||
"parent": "minecraft:block/cube_all",
|
||||
"textures": {
|
||||
"all": "reliccraft:block/teleportation_beacon"
|
||||
}
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
{
|
||||
"parent": "minecraft:block/cube_all",
|
||||
"textures": {
|
||||
"all": "reliccraft:block/teleportation_restrictor"
|
||||
}
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
{
|
||||
"parent": "minecraft:item/generated",
|
||||
"textures": {
|
||||
"layer0": "reliccraft:item/orb"
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
{
|
||||
"parent": "minecraft:item/handheld",
|
||||
"textures": {
|
||||
"layer0": "reliccraft:item/staff_orb",
|
||||
"layer1": "reliccraft:item/staff_handle"
|
||||
}
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
{
|
||||
"parent": "minecraft:item/ender_pearl"
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
{
|
||||
"parent": "reliccraft:block/teleportation_beacon",
|
||||
"overrides": [
|
||||
{
|
||||
"predicate": {
|
||||
"custom_model_data": 1
|
||||
},
|
||||
"model": "reliccraft:block/active_teleportation_beacon"
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
{
|
||||
"parent": "reliccraft:block/teleportation_restrictor",
|
||||
"overrides": [
|
||||
{
|
||||
"predicate": {
|
||||
"custom_model_data": 1
|
||||
},
|
||||
"model": "reliccraft:block/active_teleportation_restrictor"
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
{
|
||||
"parent": "minecraft:item/generated",
|
||||
"textures": {
|
||||
"layer0": "reliccraft:item/time_dilater"
|
||||
}
|
||||
}
|
After Width: | Height: | Size: 748 B |
After Width: | Height: | Size: 266 B |
After Width: | Height: | Size: 726 B |
After Width: | Height: | Size: 229 B |
BIN
src/main/resources/assets/reliccraft/textures/item/orb.png
Normal file
After Width: | Height: | Size: 306 B |
After Width: | Height: | Size: 299 B |
BIN
src/main/resources/assets/reliccraft/textures/item/staff_orb.png
Normal file
After Width: | Height: | Size: 289 B |
After Width: | Height: | Size: 391 B |
@ -0,0 +1,33 @@
|
||||
{
|
||||
"parent": "reliccraft:root",
|
||||
"display": {
|
||||
"icon": {
|
||||
"item": "reliccraft:teleportation_beacon",
|
||||
"nbt": "{CustomModelData: 1}"
|
||||
},
|
||||
"title": {
|
||||
"translate": "advancements.reliccraft.activate_teleportation_beacon.title"
|
||||
},
|
||||
"description": {
|
||||
"translate": "advancements.reliccraft.activate_teleportation_beacon.description"
|
||||
},
|
||||
"frame": "challenge",
|
||||
"show_toast": true,
|
||||
"announce_to_chat": true,
|
||||
"hidden": false
|
||||
},
|
||||
"criteria": {
|
||||
"activate": {
|
||||
"trigger": "reliccraft:activate_teleportation_beacon"
|
||||
},
|
||||
"create_pearl": {
|
||||
"trigger": "reliccraft:use_teleportation_beacon"
|
||||
},
|
||||
"use_pearl": {
|
||||
"trigger": "reliccraft:use_targeted_ender_pearl"
|
||||
}
|
||||
},
|
||||
"rewards": {
|
||||
"experience": 100
|
||||
}
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
{
|
||||
"parent": "reliccraft:root",
|
||||
"display": {
|
||||
"icon": {
|
||||
"item": "reliccraft:teleportation_restrictor",
|
||||
"nbt": "{CustomModelData: 1}"
|
||||
},
|
||||
"title": {
|
||||
"translate": "advancements.reliccraft.activate_teleportation_restrictor.title"
|
||||
},
|
||||
"description": {
|
||||
"translate": "advancements.reliccraft.activate_teleportation_restrictor.description"
|
||||
},
|
||||
"frame": "challenge",
|
||||
"show_toast": true,
|
||||
"announce_to_chat": true,
|
||||
"hidden": false
|
||||
},
|
||||
"criteria": {
|
||||
"activate": {
|
||||
"trigger": "reliccraft:activate_teleportation_restrictor"
|
||||
}
|
||||
},
|
||||
"rewards": {
|
||||
"experience": 100
|
||||
}
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
{
|
||||
"parent": "reliccraft:root",
|
||||
"display": {
|
||||
"icon": {
|
||||
"item": "reliccraft:time_dilater"
|
||||
},
|
||||
"title": {
|
||||
"translate": "advancements.reliccraft.dilate_time.title"
|
||||
},
|
||||
"description": {
|
||||
"translate": "advancements.reliccraft.dilate_time.description"
|
||||
},
|
||||
"frame": "task",
|
||||
"show_toast": true,
|
||||
"announce_to_chat": true,
|
||||
"hidden": false
|
||||
},
|
||||
"criteria": {
|
||||
"dilate_time": {
|
||||
"trigger": "reliccraft:dilate_time"
|
||||
}
|
||||
},
|
||||
"rewards": {
|
||||
"recipes": [
|
||||
"sorcerycraft:time_dilater"
|
||||
]
|
||||
}
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
{
|
||||
"parent": "reliccraft:dilate_time",
|
||||
"display": {
|
||||
"icon": {
|
||||
"item": "reliccraft:time_dilater"
|
||||
},
|
||||
"title": {
|
||||
"translate": "advancements.reliccraft.duplicate_time_dilater.title"
|
||||
},
|
||||
"description": {
|
||||
"translate": "advancements.reliccraft.duplicate_time_dilater.description"
|
||||
},
|
||||
"frame": "challenge",
|
||||
"show_toast": true,
|
||||
"announce_to_chat": true,
|
||||
"hidden": false
|
||||
},
|
||||
"criteria": {
|
||||
"duplicate_time_dilater": {
|
||||
"trigger": "reliccraft:duplicate_time_dilater"
|
||||
}
|
||||
},
|
||||
"rewards": {
|
||||
"experience": 100
|
||||
}
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
{
|
||||
"parent": "reliccraft:root",
|
||||
"display": {
|
||||
"icon": {
|
||||
"item": "minecraft:nether_star"
|
||||
},
|
||||
"title": {
|
||||
"translate": "advancements.reliccraft.reveal_relic.title"
|
||||
},
|
||||
"description": {
|
||||
"translate": "advancements.reliccraft.reveal_relic.description"
|
||||
},
|
||||
"frame": "challenge",
|
||||
"show_toast": true,
|
||||
"announce_to_chat": true,
|
||||
"hidden": false
|
||||
},
|
||||
"criteria": {
|
||||
"reveal_relic": {
|
||||
"trigger": "reliccraft:reveal_relic"
|
||||
}
|
||||
},
|
||||
"rewards": {
|
||||
"experience": 100
|
||||
}
|
||||
}
|
36
src/main/resources/data/reliccraft/advancements/root.json
Normal file
@ -0,0 +1,36 @@
|
||||
{
|
||||
"display": {
|
||||
"icon": {
|
||||
"item": "minecraft:ender_chest"
|
||||
},
|
||||
"title": {
|
||||
"translate": "advancements.reliccraft.root.title"
|
||||
},
|
||||
"description": {
|
||||
"translate": "advancements.reliccraft.root.description"
|
||||
},
|
||||
"frame": "task",
|
||||
"show_toast": false,
|
||||
"announce_to_chat": false,
|
||||
"hidden": false,
|
||||
"background": "minecraft:textures/gui/advancements/backgrounds/stone.png"
|
||||
},
|
||||
"criteria": {
|
||||
"obtain_relic": {
|
||||
"trigger": "minecraft:inventory_changed",
|
||||
"conditions": {
|
||||
"items": [
|
||||
{
|
||||
"tag": "reliccraft:relics"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"rewards": {
|
||||
"recipes": [
|
||||
"reliccraft:teleportation_restrictor",
|
||||
"reliccraft:teleportation_beacon"
|
||||
]
|
||||
}
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
{
|
||||
"type": "minecraft:block",
|
||||
"pools": [
|
||||
{
|
||||
"rolls": 1,
|
||||
"entries": [
|
||||
{
|
||||
"type": "minecraft:item",
|
||||
"name": "reliccraft:teleportation_beacon"
|
||||
}
|
||||
],
|
||||
"conditions": [
|
||||
{
|
||||
"condition": "minecraft:survives_explosion"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
{
|
||||
"type": "minecraft:block",
|
||||
"pools": [
|
||||
{
|
||||
"rolls": 1,
|
||||
"entries": [
|
||||
{
|
||||
"type": "minecraft:item",
|
||||
"name": "reliccraft:teleportation_restrictor"
|
||||
}
|
||||
],
|
||||
"conditions": [
|
||||
{
|
||||
"condition": "minecraft:survives_explosion"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
{
|
||||
"type": "reliccraft:reveal_relic"
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
{
|
||||
"type": "minecraft:crafting_shaped",
|
||||
"pattern": [
|
||||
"BIB",
|
||||
"ISI",
|
||||
"BIB"
|
||||
],
|
||||
"key": {
|
||||
"B": {
|
||||
"item": "minecraft:blaze_powder"
|
||||
},
|
||||
"S": {
|
||||
"item": "minecraft:nether_star"
|
||||
},
|
||||
"I": {
|
||||
"item": "minecraft:iron_ingot"
|
||||
}
|
||||
},
|
||||
"result": {
|
||||
"item": "reliccraft:teleportation_beacon"
|
||||
}
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
{
|
||||
"type": "minecraft:crafting_shaped",
|
||||
"pattern": [
|
||||
"OIO",
|
||||
"ISI",
|
||||
"OIO"
|
||||
],
|
||||
"key": {
|
||||
"O": {
|
||||
"item": "minecraft:obsidian"
|
||||
},
|
||||
"S": {
|
||||
"item": "minecraft:nether_star"
|
||||
},
|
||||
"I": {
|
||||
"item": "minecraft:iron_ingot"
|
||||
}
|
||||
},
|
||||
"result": {
|
||||
"item": "reliccraft:teleportation_restrictor"
|
||||
}
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
{
|
||||
"type": "reliccraft:time_dilater"
|
||||
}
|
BIN
src/main/resources/data/reliccraft/structures/time_temple.nbt
Normal file
10
src/main/resources/data/reliccraft/tags/items/relics.json
Normal file
@ -0,0 +1,10 @@
|
||||
{
|
||||
"replace": false,
|
||||
"values": [
|
||||
"reliccraft:staff",
|
||||
"reliccraft:orb",
|
||||
"reliccraft:time_dilater",
|
||||
"reliccraft:teleportation_restrictor",
|
||||
"reliccraft:teleportation_beacon"
|
||||
]
|
||||
}
|
34
src/main/resources/fabric.mod.json
Normal file
@ -0,0 +1,34 @@
|
||||
{
|
||||
"schemaVersion": 1,
|
||||
"id": "reliccraft",
|
||||
"version": "${version}",
|
||||
"name": "${name}",
|
||||
"description": "Find magical relics throughout the world!",
|
||||
"authors": [
|
||||
"TheBrokenRail"
|
||||
],
|
||||
"contact": {
|
||||
"homepage": "https://thebrokenrail.com/",
|
||||
"sources": "https://gitea.thebrokenrail.com/TheBrokenRail/RelicCraft.git",
|
||||
"issues": "https://gitea.thebrokenrail.com/TheBrokenRail/RelicCraft/issues"
|
||||
},
|
||||
"license": "MIT",
|
||||
"icon": "assets/reliccraft/textures/item/time_dilater.png",
|
||||
"environment": "*",
|
||||
"entrypoints": {
|
||||
"main": [
|
||||
"com.thebrokenrail.reliccraft.RelicCraft"
|
||||
],
|
||||
"client": [
|
||||
"com.thebrokenrail.reliccraft.client.RelicCraftClient"
|
||||
]
|
||||
},
|
||||
"mixins": [
|
||||
"reliccraft.mixins.json"
|
||||
],
|
||||
"depends": {
|
||||
"fabricloader": ">=0.7.4",
|
||||
"fabric": "*",
|
||||
"minecraft": "1.15.x"
|
||||
}
|
||||
}
|
25
src/main/resources/reliccraft.mixins.json
Normal file
@ -0,0 +1,25 @@
|
||||
{
|
||||
"required": true,
|
||||
"package": "com.thebrokenrail.reliccraft.mixin",
|
||||
"compatibilityLevel": "JAVA_8",
|
||||
"client": [
|
||||
"MixinClientPlayNetworkHandler"
|
||||
],
|
||||
"mixins": [
|
||||
"CriteriaRegistryHook",
|
||||
"MixinEnderDragonFight",
|
||||
"MixinEnderPearlItem",
|
||||
"MixinEntity",
|
||||
"MixinItemStack",
|
||||
"MixinLevelProperties",
|
||||
"MixinLivingEntity",
|
||||
"MixinLocateCommand",
|
||||
"MixinNetherStarItem",
|
||||
"MixinServerWorld",
|
||||
"MixinThrownEnderpearlEntity",
|
||||
"MixinWorld"
|
||||
],
|
||||
"injectors": {
|
||||
"defaultRequire": 1
|
||||
}
|
||||
}
|