Browse Source

1.0

Initial Commit
master 1.0+1.15.2
TheBrokenRail 1 year ago
commit
c19790efc4
  1. 27
      .gitignore
  2. 4
      CHANGELOG.md
  3. 19
      Jenkinsfile
  4. 21
      LICENSE
  5. 16
      README.md
  6. 105
      build.gradle
  7. 21
      gradle.properties
  8. BIN
      gradle/wrapper/gradle-wrapper.jar
  9. 6
      gradle/wrapper/gradle-wrapper.properties
  10. 188
      gradlew
  11. 100
      gradlew.bat
  12. 12
      settings.gradle
  13. 189
      src/main/java/com/thebrokenrail/reliccraft/RelicCraft.java
  14. 42
      src/main/java/com/thebrokenrail/reliccraft/RelicLootTableFunction.java
  15. 34
      src/main/java/com/thebrokenrail/reliccraft/advancement/ActivateTeleportationBeaconCriterion.java
  16. 34
      src/main/java/com/thebrokenrail/reliccraft/advancement/ActivateTeleportationRestrictorCriterion.java
  17. 34
      src/main/java/com/thebrokenrail/reliccraft/advancement/DilateTimeCriterion.java
  18. 34
      src/main/java/com/thebrokenrail/reliccraft/advancement/DuplicateTimeDilaterCriterion.java
  19. 34
      src/main/java/com/thebrokenrail/reliccraft/advancement/RevealRelicCriterion.java
  20. 34
      src/main/java/com/thebrokenrail/reliccraft/advancement/UseTargetedEnderPearlCriterion.java
  21. 34
      src/main/java/com/thebrokenrail/reliccraft/advancement/UseTeleportationBeaconCriterion.java
  22. 129
      src/main/java/com/thebrokenrail/reliccraft/block/AbstractDragonEggHolderBlock.java
  23. 121
      src/main/java/com/thebrokenrail/reliccraft/block/DragonEggHolderBlockEntity.java
  24. 27
      src/main/java/com/thebrokenrail/reliccraft/block/TeleportationBeaconBlock.java
  25. 42
      src/main/java/com/thebrokenrail/reliccraft/block/TeleportationRestrictorBlock.java
  26. 60
      src/main/java/com/thebrokenrail/reliccraft/client/RelicCraftClient.java
  27. 20
      src/main/java/com/thebrokenrail/reliccraft/client/entity/RelicEntityRenderer.java
  28. 23
      src/main/java/com/thebrokenrail/reliccraft/data/Action.java
  29. 357
      src/main/java/com/thebrokenrail/reliccraft/data/Actions.java
  30. 63
      src/main/java/com/thebrokenrail/reliccraft/data/RelicData.java
  31. 82
      src/main/java/com/thebrokenrail/reliccraft/entity/RelicEntity.java
  32. 221
      src/main/java/com/thebrokenrail/reliccraft/item/RelicItem.java
  33. 116
      src/main/java/com/thebrokenrail/reliccraft/item/TargetedEnderPearlItem.java
  34. 92
      src/main/java/com/thebrokenrail/reliccraft/item/TimeDilaterItem.java
  35. 14
      src/main/java/com/thebrokenrail/reliccraft/mixin/CriteriaRegistryHook.java
  36. 46
      src/main/java/com/thebrokenrail/reliccraft/mixin/MixinClientPlayNetworkHandler.java
  37. 17
      src/main/java/com/thebrokenrail/reliccraft/mixin/MixinEnderDragonFight.java
  38. 70
      src/main/java/com/thebrokenrail/reliccraft/mixin/MixinEnderPearlItem.java
  39. 33
      src/main/java/com/thebrokenrail/reliccraft/mixin/MixinEntity.java
  40. 19
      src/main/java/com/thebrokenrail/reliccraft/mixin/MixinItemStack.java
  41. 41
      src/main/java/com/thebrokenrail/reliccraft/mixin/MixinLevelProperties.java
  42. 18
      src/main/java/com/thebrokenrail/reliccraft/mixin/MixinLivingEntity.java
  43. 27
      src/main/java/com/thebrokenrail/reliccraft/mixin/MixinLocateCommand.java
  44. 16
      src/main/java/com/thebrokenrail/reliccraft/mixin/MixinNetherStarItem.java
  45. 19
      src/main/java/com/thebrokenrail/reliccraft/mixin/MixinServerWorld.java
  46. 23
      src/main/java/com/thebrokenrail/reliccraft/mixin/MixinThrownEnderpearlEntity.java
  47. 50
      src/main/java/com/thebrokenrail/reliccraft/mixin/MixinWorld.java
  48. 39
      src/main/java/com/thebrokenrail/reliccraft/packet/UpdateTimeDilationS2CPacket.java
  49. 102
      src/main/java/com/thebrokenrail/reliccraft/recipe/RevealRelicRecipe.java
  50. 51
      src/main/java/com/thebrokenrail/reliccraft/recipe/TimeDilaterRecipe.java
  51. 34
      src/main/java/com/thebrokenrail/reliccraft/structure/TimeTempleFeature.java
  52. 127
      src/main/java/com/thebrokenrail/reliccraft/structure/TimeTempleGenerator.java
  53. 26
      src/main/java/com/thebrokenrail/reliccraft/structure/TimeTempleStructureStart.java
  54. 10
      src/main/resources/assets/reliccraft/blockstates/teleportation_beacon.json
  55. 10
      src/main/resources/assets/reliccraft/blockstates/teleportation_restrictor.json
  56. 67
      src/main/resources/assets/reliccraft/lang/en_us.json
  57. 6
      src/main/resources/assets/reliccraft/models/block/active_teleportation_beacon.json
  58. 6
      src/main/resources/assets/reliccraft/models/block/active_teleportation_restrictor.json
  59. 6
      src/main/resources/assets/reliccraft/models/block/teleportation_beacon.json
  60. 6
      src/main/resources/assets/reliccraft/models/block/teleportation_restrictor.json
  61. 6
      src/main/resources/assets/reliccraft/models/item/orb.json
  62. 7
      src/main/resources/assets/reliccraft/models/item/staff.json
  63. 3
      src/main/resources/assets/reliccraft/models/item/targeted_ender_pearl.json
  64. 11
      src/main/resources/assets/reliccraft/models/item/teleportation_beacon.json
  65. 11
      src/main/resources/assets/reliccraft/models/item/teleportation_restrictor.json
  66. 6
      src/main/resources/assets/reliccraft/models/item/time_dilater.json
  67. BIN
      src/main/resources/assets/reliccraft/textures/block/active_teleportation_beacon.png
  68. BIN
      src/main/resources/assets/reliccraft/textures/block/active_teleportation_restrictor.png
  69. BIN
      src/main/resources/assets/reliccraft/textures/block/teleportation_beacon.png
  70. BIN
      src/main/resources/assets/reliccraft/textures/block/teleportation_restrictor.png
  71. BIN
      src/main/resources/assets/reliccraft/textures/item/orb.png
  72. BIN
      src/main/resources/assets/reliccraft/textures/item/staff_handle.png
  73. BIN
      src/main/resources/assets/reliccraft/textures/item/staff_orb.png
  74. BIN
      src/main/resources/assets/reliccraft/textures/item/time_dilater.png
  75. 33
      src/main/resources/data/reliccraft/advancements/activate_teleportation_beacon.json
  76. 27
      src/main/resources/data/reliccraft/advancements/activate_teleportation_restrictor.json
  77. 28
      src/main/resources/data/reliccraft/advancements/dilate_time.json
  78. 26
      src/main/resources/data/reliccraft/advancements/duplicate_time_dilater.json
  79. 26
      src/main/resources/data/reliccraft/advancements/reveal_relic.json
  80. 36
      src/main/resources/data/reliccraft/advancements/root.json
  81. 19
      src/main/resources/data/reliccraft/loot_tables/blocks/teleportation_beacon.json
  82. 19
      src/main/resources/data/reliccraft/loot_tables/blocks/teleportation_restrictor.json
  83. 3
      src/main/resources/data/reliccraft/recipes/reveal_relic.json
  84. 22
      src/main/resources/data/reliccraft/recipes/teleportation_beacon.json
  85. 22
      src/main/resources/data/reliccraft/recipes/teleportation_restrictor.json
  86. 3
      src/main/resources/data/reliccraft/recipes/time_dilater.json
  87. BIN
      src/main/resources/data/reliccraft/structures/time_temple.nbt
  88. 10
      src/main/resources/data/reliccraft/tags/items/relics.json
  89. 34
      src/main/resources/fabric.mod.json
  90. 25
      src/main/resources/reliccraft.mixins.json

27
.gitignore

@ -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

@ -0,0 +1,4 @@
# Changelog
**1.0**
* Initial Release

19
Jenkinsfile

@ -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

@ -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

@ -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

@ -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

@ -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

6
gradle/wrapper/gradle-wrapper.properties

@ -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

@ -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

@ -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

@ -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

@ -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});
}
}

42
src/main/java/com/thebrokenrail/reliccraft/RelicLootTableFunction.java

@ -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());
}
}
}

34
src/main/java/com/thebrokenrail/reliccraft/advancement/ActivateTeleportationBeaconCriterion.java

@ -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);
}
}
}

34
src/main/java/com/thebrokenrail/reliccraft/advancement/ActivateTeleportationRestrictorCriterion.java

@ -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);
}
}
}

34
src/main/java/com/thebrokenrail/reliccraft/advancement/DilateTimeCriterion.java

@ -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);
}
}
}

34
src/main/java/com/thebrokenrail/reliccraft/advancement/DuplicateTimeDilaterCriterion.java

@ -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);
}
}
}

34
src/main/java/com/thebrokenrail/reliccraft/advancement/RevealRelicCriterion.java

@ -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);
}
}
}

34
src/main/java/com/thebrokenrail/reliccraft/advancement/UseTargetedEnderPearlCriterion.java

@ -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);
}
}
}

34
src/main/java/com/thebrokenrail/reliccraft/advancement/UseTeleportationBeaconCriterion.java

@ -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);
}
}
}

129
src/main/java/com/thebrokenrail/reliccraft/block/AbstractDragonEggHolderBlock.java

@ -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);
}

121
src/main/java/com/thebrokenrail/reliccraft/block/DragonEggHolderBlockEntity.java

@ -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());
}
}
}
}

27
src/main/java/com/thebrokenrail/reliccraft/block/TeleportationBeaconBlock.java

@ -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);
}
}

42
src/main/java/com/thebrokenrail/reliccraft/block/TeleportationRestrictorBlock.java

@ -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);
}
}

60
src/main/java/com/thebrokenrail/reliccraft/client/RelicCraftClient.java

@ -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);
}
}

20
src/main/java/com/thebrokenrail/reliccraft/client/entity/RelicEntityRenderer.java

@ -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

@ -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

@ -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 exec