mirror of
https://github.com/peter-tanner/nuke-mod.git
synced 2024-11-30 11:10:19 +08:00
Initial commit - basic functionality
This commit is contained in:
commit
53af69ce43
41
.github/workflows/build.yml
vendored
Normal file
41
.github/workflows/build.yml
vendored
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
# Automatically build the project and run any configured tests for every push
|
||||||
|
# and submitted pull request. This can help catch issues that only occur on
|
||||||
|
# certain platforms or Java versions, and provides a first line of defence
|
||||||
|
# against bad commits.
|
||||||
|
|
||||||
|
name: build
|
||||||
|
on: [pull_request, push]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
# Use these Java versions
|
||||||
|
java: [
|
||||||
|
1.8, # Minimum supported by Minecraft
|
||||||
|
11, # Current Java LTS
|
||||||
|
15 # Latest version
|
||||||
|
]
|
||||||
|
# and run on both Linux and Windows
|
||||||
|
os: [ubuntu-20.04, windows-latest]
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
steps:
|
||||||
|
- name: checkout repository
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
- name: validate gradle wrapper
|
||||||
|
uses: gradle/wrapper-validation-action@v1
|
||||||
|
- name: setup jdk ${{ matrix.java }}
|
||||||
|
uses: actions/setup-java@v1
|
||||||
|
with:
|
||||||
|
java-version: ${{ matrix.java }}
|
||||||
|
- name: make gradle wrapper executable
|
||||||
|
if: ${{ runner.os != 'Windows' }}
|
||||||
|
run: chmod +x ./gradlew
|
||||||
|
- name: build
|
||||||
|
run: ./gradlew build
|
||||||
|
- name: capture build artifacts
|
||||||
|
if: ${{ runner.os == 'Linux' && matrix.java == '11' }} # Only upload artifacts built from LTS java on one OS
|
||||||
|
uses: actions/upload-artifact@v2
|
||||||
|
with:
|
||||||
|
name: Artifacts
|
||||||
|
path: build/libs/
|
33
.gitignore
vendored
Normal file
33
.gitignore
vendored
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
# gradle
|
||||||
|
|
||||||
|
.gradle/
|
||||||
|
build/
|
||||||
|
out/
|
||||||
|
classes/
|
||||||
|
|
||||||
|
# eclipse
|
||||||
|
|
||||||
|
*.launch
|
||||||
|
|
||||||
|
# idea
|
||||||
|
|
||||||
|
.idea/
|
||||||
|
*.iml
|
||||||
|
*.ipr
|
||||||
|
*.iws
|
||||||
|
|
||||||
|
# vscode
|
||||||
|
|
||||||
|
.settings/
|
||||||
|
.vscode/
|
||||||
|
bin/
|
||||||
|
.classpath
|
||||||
|
.project
|
||||||
|
|
||||||
|
# macos
|
||||||
|
|
||||||
|
*.DS_Store
|
||||||
|
|
||||||
|
# fabric
|
||||||
|
|
||||||
|
run/
|
82
build.gradle
Normal file
82
build.gradle
Normal file
|
@ -0,0 +1,82 @@
|
||||||
|
plugins {
|
||||||
|
id 'fabric-loom' version '0.5-SNAPSHOT'
|
||||||
|
id 'maven-publish'
|
||||||
|
}
|
||||||
|
|
||||||
|
sourceCompatibility = JavaVersion.VERSION_1_8
|
||||||
|
targetCompatibility = JavaVersion.VERSION_1_8
|
||||||
|
|
||||||
|
archivesBaseName = project.archives_base_name
|
||||||
|
version = project.mod_version
|
||||||
|
group = project.maven_group
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
// To change the versions see the gradle.properties file
|
||||||
|
minecraft "com.mojang:minecraft:${project.minecraft_version}"
|
||||||
|
mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2"
|
||||||
|
modImplementation "net.fabricmc:fabric-loader:${project.loader_version}"
|
||||||
|
|
||||||
|
// Fabric API. This is technically optional, but you probably want it anyway.
|
||||||
|
modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}"
|
||||||
|
|
||||||
|
// PSA: Some older mods, compiled on Loom 0.2.1, might have outdated Maven POMs.
|
||||||
|
// You may need to force-disable transitiveness on them.
|
||||||
|
}
|
||||||
|
|
||||||
|
processResources {
|
||||||
|
inputs.property "version", project.version
|
||||||
|
|
||||||
|
filesMatching("fabric.mod.json") {
|
||||||
|
expand "version": project.version
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.withType(JavaCompile).configureEach {
|
||||||
|
// 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
|
||||||
|
// If Javadoc is generated, this must be specified in that task too.
|
||||||
|
it.options.encoding = "UTF-8"
|
||||||
|
|
||||||
|
// The Minecraft launcher currently installs Java 8 for users, so your mod probably wants to target Java 8 too
|
||||||
|
// JDK 9 introduced a new way of specifying this that will make sure no newer classes or methods are used.
|
||||||
|
// We'll use that if it's available, but otherwise we'll use the older option.
|
||||||
|
def targetVersion = 8
|
||||||
|
if (JavaVersion.current().isJava9Compatible()) {
|
||||||
|
it.options.release = targetVersion
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
java {
|
||||||
|
// Loom will automatically attach sourcesJar to a RemapSourcesJar task and to the "build" task
|
||||||
|
// if it is present.
|
||||||
|
// If you remove this line, sources will not be generated.
|
||||||
|
withSourcesJar()
|
||||||
|
}
|
||||||
|
|
||||||
|
jar {
|
||||||
|
from("LICENSE") {
|
||||||
|
rename { "${it}_${project.archivesBaseName}"}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// configure the maven publication
|
||||||
|
publishing {
|
||||||
|
publications {
|
||||||
|
mavenJava(MavenPublication) {
|
||||||
|
// add all the jars that should be included when publishing to maven
|
||||||
|
artifact(remapJar) {
|
||||||
|
builtBy remapJar
|
||||||
|
}
|
||||||
|
artifact(sourcesJar) {
|
||||||
|
builtBy remapSourcesJar
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Select the repositories you want to publish to
|
||||||
|
// To publish to maven local, no extra repositories are necessary. Just use the task `publishToMavenLocal`.
|
||||||
|
repositories {
|
||||||
|
// See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing.
|
||||||
|
}
|
||||||
|
}
|
16
gradle.properties
Normal file
16
gradle.properties
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
# Done to increase the memory available to gradle.
|
||||||
|
org.gradle.jvmargs=-Xmx1G
|
||||||
|
|
||||||
|
# Fabric Properties
|
||||||
|
# https://modmuss50.me/fabric.html
|
||||||
|
minecraft_version=1.16.4
|
||||||
|
yarn_mappings=1.16.4+build.7
|
||||||
|
loader_version=0.10.8
|
||||||
|
|
||||||
|
#Fabric api
|
||||||
|
fabric_version=0.28.4+1.16
|
||||||
|
|
||||||
|
# Mod Properties
|
||||||
|
mod_version = 0.1.0
|
||||||
|
maven_group = io.github.npc_strider.NukeMod
|
||||||
|
archives_base_name = NukeMod
|
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
Binary file not shown.
5
gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
5
gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
distributionBase=GRADLE_USER_HOME
|
||||||
|
distributionPath=wrapper/dists
|
||||||
|
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-bin.zip
|
||||||
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
|
zipStorePath=wrapper/dists
|
185
gradlew
vendored
Normal file
185
gradlew
vendored
Normal file
|
@ -0,0 +1,185 @@
|
||||||
|
#!/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 or MSYS, switch paths to Windows format before running java
|
||||||
|
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; 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=`expr $i + 1`
|
||||||
|
done
|
||||||
|
case $i in
|
||||||
|
0) set -- ;;
|
||||||
|
1) set -- "$args0" ;;
|
||||||
|
2) set -- "$args0" "$args1" ;;
|
||||||
|
3) set -- "$args0" "$args1" "$args2" ;;
|
||||||
|
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||||
|
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||||
|
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||||
|
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||||
|
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||||
|
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 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"
|
||||||
|
|
||||||
|
exec "$JAVACMD" "$@"
|
89
gradlew.bat
vendored
Normal file
89
gradlew.bat
vendored
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
@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 Resolve any "." and ".." in APP_HOME to make it shorter.
|
||||||
|
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
|
||||||
|
|
||||||
|
@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 execute
|
||||||
|
|
||||||
|
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 execute
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
: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 %*
|
||||||
|
|
||||||
|
: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
|
10
settings.gradle
Normal file
10
settings.gradle
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
pluginManagement {
|
||||||
|
repositories {
|
||||||
|
jcenter()
|
||||||
|
maven {
|
||||||
|
name = 'Fabric'
|
||||||
|
url = 'https://maven.fabricmc.net/'
|
||||||
|
}
|
||||||
|
gradlePluginPortal()
|
||||||
|
}
|
||||||
|
}
|
47
src/main/java/io/github/npc_strider/NukeMod/NukeMod.java
Normal file
47
src/main/java/io/github/npc_strider/NukeMod/NukeMod.java
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
package io.github.npc_strider.NukeMod;
|
||||||
|
|
||||||
|
import io.github.npc_strider.NukeMod.fission.FissionBlock;
|
||||||
|
import io.github.npc_strider.NukeMod.fission.FissionEntity;
|
||||||
|
import net.fabricmc.api.ModInitializer;
|
||||||
|
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
||||||
|
import net.fabricmc.fabric.api.object.builder.v1.entity.FabricEntityTypeBuilder;
|
||||||
|
import net.fabricmc.fabric.api.registry.FlammableBlockRegistry;
|
||||||
|
import net.minecraft.block.Blocks;
|
||||||
|
import net.minecraft.entity.EntityDimensions;
|
||||||
|
import net.minecraft.entity.EntityType;
|
||||||
|
import net.minecraft.entity.SpawnGroup;
|
||||||
|
import net.minecraft.item.BlockItem;
|
||||||
|
import net.minecraft.item.Item;
|
||||||
|
import net.minecraft.item.ItemGroup;
|
||||||
|
import net.minecraft.sound.SoundEvent;
|
||||||
|
import net.minecraft.util.Identifier;
|
||||||
|
import net.minecraft.util.registry.Registry;
|
||||||
|
|
||||||
|
public class NukeMod implements ModInitializer {
|
||||||
|
|
||||||
|
public static final String MOD_ID = "nuke-mod";
|
||||||
|
// public static final EntityType<FissionEntity> FISSION_ENTITY;
|
||||||
|
|
||||||
|
public static final Identifier FISSION_BLOCK_ID = new Identifier(MOD_ID, "fission-device");
|
||||||
|
public static final FissionBlock FISSION_BLOCK = new FissionBlock(FabricBlockSettings.copy(Blocks.TNT));
|
||||||
|
|
||||||
|
public static final EntityType FISSION_ENTITY_TYPE = FabricEntityTypeBuilder.create(SpawnGroup.MISC, FissionEntity::new).dimensions(new EntityDimensions(0.98F, 0.98F, false)).trackRangeBlocks(10).trackedUpdateRate(10).fireImmune().build();
|
||||||
|
public static final EntityType<FissionEntity> FISSION_ENTITY = FISSION_ENTITY_TYPE;
|
||||||
|
|
||||||
|
public static final Identifier FISSION_ALARM_ID = new Identifier(MOD_ID, "fission-alarm");
|
||||||
|
public static final Identifier FISSION_EXPLOSION_ID = new Identifier(MOD_ID, "fission-explosion");
|
||||||
|
public static SoundEvent FISSION_ALARM = new SoundEvent(FISSION_ALARM_ID);
|
||||||
|
public static SoundEvent FISSION_EXPLOSION = new SoundEvent(FISSION_EXPLOSION_ID);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onInitialize() {
|
||||||
|
Registry.register(Registry.BLOCK, FISSION_BLOCK_ID, FISSION_BLOCK);
|
||||||
|
Registry.register(Registry.ITEM, FISSION_BLOCK_ID, new BlockItem(FISSION_BLOCK, new Item.Settings().group(ItemGroup.REDSTONE)));
|
||||||
|
FlammableBlockRegistry.getDefaultInstance().add(FISSION_BLOCK, 15, 100); //Copy TNT settings
|
||||||
|
|
||||||
|
Registry.register(Registry.ENTITY_TYPE, new Identifier(MOD_ID, "fission-entity"), FISSION_ENTITY);
|
||||||
|
|
||||||
|
Registry.register(Registry.SOUND_EVENT, FISSION_ALARM_ID, FISSION_ALARM);
|
||||||
|
Registry.register(Registry.SOUND_EVENT, FISSION_EXPLOSION_ID, FISSION_EXPLOSION);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,45 @@
|
||||||
|
package io.github.npc_strider.NukeMod;
|
||||||
|
|
||||||
|
|
||||||
|
import io.github.npc_strider.NukeMod.client.particle.BigFookingExplosionEmitterParticle;
|
||||||
|
import io.github.npc_strider.NukeMod.client.particle.BigFookingExplosionParticle;
|
||||||
|
import io.github.npc_strider.NukeMod.client.particle.BigFookingSmokeEmitterParticle;
|
||||||
|
import io.github.npc_strider.NukeMod.client.particle.BigFookingSmokeParticle;
|
||||||
|
import io.github.npc_strider.NukeMod.client.particle.FissioningParticle;
|
||||||
|
import io.github.npc_strider.NukeMod.render.entity.FissionEntityRenderer;
|
||||||
|
import net.fabricmc.api.ClientModInitializer;
|
||||||
|
import net.fabricmc.api.EnvType;
|
||||||
|
import net.fabricmc.api.Environment;
|
||||||
|
import net.fabricmc.fabric.api.client.particle.v1.ParticleFactoryRegistry;
|
||||||
|
import net.fabricmc.fabric.api.client.rendereregistry.v1.EntityRendererRegistry;
|
||||||
|
import net.fabricmc.fabric.api.particle.v1.FabricParticleTypes;
|
||||||
|
import net.minecraft.particle.DefaultParticleType;
|
||||||
|
import net.minecraft.util.Identifier;
|
||||||
|
import net.minecraft.util.registry.Registry;
|
||||||
|
|
||||||
|
@Environment(EnvType.CLIENT)
|
||||||
|
public class NukeModClient implements ClientModInitializer {
|
||||||
|
public static final DefaultParticleType FISSION_PARTICLE = FabricParticleTypes.simple(false);
|
||||||
|
public static final DefaultParticleType BIG_FOOKING_EXPLOSION = FabricParticleTypes.simple(false);
|
||||||
|
public static final DefaultParticleType BIG_FOOKING_EXPLOSION_EMITTER = FabricParticleTypes.simple(false);
|
||||||
|
public static final DefaultParticleType BIG_FOOKING_SMOKE = FabricParticleTypes.simple(false);
|
||||||
|
public static final DefaultParticleType BIG_FOOKING_SMOKE_EMITTER = FabricParticleTypes.simple(false);
|
||||||
|
|
||||||
|
private static final String MOD_ID = NukeMod.MOD_ID;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onInitializeClient() {
|
||||||
|
Registry.register(Registry.PARTICLE_TYPE, new Identifier(MOD_ID, "fission-emission"), FISSION_PARTICLE);
|
||||||
|
Registry.register(Registry.PARTICLE_TYPE, new Identifier(MOD_ID, "big-explosion"), BIG_FOOKING_EXPLOSION);
|
||||||
|
Registry.register(Registry.PARTICLE_TYPE, new Identifier(MOD_ID, "big-explosion-emitter"), BIG_FOOKING_EXPLOSION_EMITTER);
|
||||||
|
Registry.register(Registry.PARTICLE_TYPE, new Identifier(MOD_ID, "big-smoke"), BIG_FOOKING_SMOKE);
|
||||||
|
Registry.register(Registry.PARTICLE_TYPE, new Identifier(MOD_ID, "big-smoke-emitter"), BIG_FOOKING_SMOKE_EMITTER);
|
||||||
|
ParticleFactoryRegistry.getInstance().register(FISSION_PARTICLE, FissioningParticle.Factory::new);
|
||||||
|
ParticleFactoryRegistry.getInstance().register(BIG_FOOKING_EXPLOSION, BigFookingExplosionParticle.Factory::new);
|
||||||
|
ParticleFactoryRegistry.getInstance().register(BIG_FOOKING_EXPLOSION_EMITTER, BigFookingExplosionEmitterParticle.Factory::new);
|
||||||
|
ParticleFactoryRegistry.getInstance().register(BIG_FOOKING_SMOKE, BigFookingSmokeParticle.Factory::new);
|
||||||
|
ParticleFactoryRegistry.getInstance().register(BIG_FOOKING_SMOKE_EMITTER, BigFookingSmokeEmitterParticle.Factory::new);
|
||||||
|
|
||||||
|
EntityRendererRegistry.INSTANCE.register(NukeMod.FISSION_ENTITY, (dispatcher, context) -> new FissionEntityRenderer(dispatcher));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,64 @@
|
||||||
|
package io.github.npc_strider.NukeMod.client.particle;
|
||||||
|
|
||||||
|
import io.github.npc_strider.NukeMod.NukeModClient;
|
||||||
|
import net.fabricmc.api.EnvType;
|
||||||
|
import net.fabricmc.api.Environment;
|
||||||
|
import net.fabricmc.fabric.api.client.particle.v1.FabricSpriteProvider;
|
||||||
|
import net.minecraft.block.Material;
|
||||||
|
import net.minecraft.client.particle.NoRenderParticle;
|
||||||
|
import net.minecraft.client.particle.Particle;
|
||||||
|
import net.minecraft.client.particle.ParticleFactory;
|
||||||
|
import net.minecraft.client.world.ClientWorld;
|
||||||
|
import net.minecraft.particle.DefaultParticleType;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
|
||||||
|
@Environment(EnvType.CLIENT)
|
||||||
|
public class BigFookingExplosionEmitterParticle extends NoRenderParticle {
|
||||||
|
private int age_;
|
||||||
|
private final int maxAge_;
|
||||||
|
|
||||||
|
private BigFookingExplosionEmitterParticle(ClientWorld world, double x, double y, double z) {
|
||||||
|
super(world, x, y, z, 0.0D, 0.0D, 0.0D);
|
||||||
|
this.maxAge_ = 10;//80;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void tick() {
|
||||||
|
double r = 40.0D;
|
||||||
|
// for (int i = 0; i < (int)Math.floor(32*(float)this.age_/(float)this.maxAge_); ++i) {
|
||||||
|
for (int i = 0; i < (int)Math.floor(64/(age_+1)); ++i) {
|
||||||
|
// double d = this.x + (this.random.nextDouble() - this.random.nextDouble()) * r;
|
||||||
|
// double e = this.y + (this.random.nextDouble() - this.random.nextDouble()) * r;
|
||||||
|
// double f = this.z + (this.random.nextDouble() - this.random.nextDouble()) * r;
|
||||||
|
float alpha = this.random.nextFloat() * 360;
|
||||||
|
float beta = this.random.nextFloat() * 360;
|
||||||
|
// Vec3d position = Vec3d.fromPolar(alpha, beta).multiply((this.random.nextDouble() - this.random.nextDouble()) * r).add(this.x, this.y, this.z); //Keeps our explosion spherical, rather than in a 3d box as with the vanilla method.
|
||||||
|
double r_ = Math.sqrt(this.random.nextDouble()) * r;
|
||||||
|
Vec3d position = Vec3d.fromPolar(alpha, beta).multiply(r_).add(this.x, this.y, this.z); //Keeps our explosion spherical, rather than in a 3d box as with the vanilla method.
|
||||||
|
if (world.getBlockState(new BlockPos(position)).getMaterial() == Material.AIR) {
|
||||||
|
Vec3d v = Vec3d.fromPolar(alpha, beta).normalize().multiply(r_*0.05F+0.05F*this.random.nextFloat());
|
||||||
|
this.world.addParticle(NukeModClient.BIG_FOOKING_EXPLOSION, true, position.getX(), position.getY(), position.getZ(), v.getX(), v.getY(), v.getZ());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
++this.age_;
|
||||||
|
if (this.age_ == this.maxAge_) {
|
||||||
|
this.markDead();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Environment(EnvType.CLIENT)
|
||||||
|
public static class Factory implements ParticleFactory<DefaultParticleType> {
|
||||||
|
private final FabricSpriteProvider sprites;
|
||||||
|
|
||||||
|
public Factory(FabricSpriteProvider sprites) {
|
||||||
|
this.sprites = sprites;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Particle createParticle(DefaultParticleType defaultParticleType, ClientWorld clientWorld, double d, double e, double f, double g, double h, double i) {
|
||||||
|
return new BigFookingExplosionEmitterParticle(clientWorld, d, e, f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,79 @@
|
||||||
|
package io.github.npc_strider.NukeMod.client.particle;
|
||||||
|
|
||||||
|
import net.fabricmc.api.EnvType;
|
||||||
|
import net.fabricmc.api.Environment;
|
||||||
|
import net.minecraft.client.particle.Particle;
|
||||||
|
import net.minecraft.client.particle.ParticleFactory;
|
||||||
|
import net.minecraft.client.particle.ParticleTextureSheet;
|
||||||
|
import net.minecraft.client.particle.SpriteBillboardParticle;
|
||||||
|
import net.minecraft.client.particle.SpriteProvider;
|
||||||
|
import net.minecraft.client.world.ClientWorld;
|
||||||
|
import net.minecraft.particle.DefaultParticleType;
|
||||||
|
|
||||||
|
@Environment(EnvType.CLIENT)
|
||||||
|
public class BigFookingExplosionParticle extends SpriteBillboardParticle {
|
||||||
|
private final SpriteProvider spriteProvider;
|
||||||
|
private final float scale_;
|
||||||
|
|
||||||
|
private BigFookingExplosionParticle(ClientWorld world, double x, double y, double z, double vx, double vy, double vz, SpriteProvider spriteProvider) {
|
||||||
|
super(world, x, y, z, vx, vy, vz);
|
||||||
|
// this.maxAge = 6 + this.random.nextInt(4);
|
||||||
|
this.maxAge = 10 + this.random.nextInt(10);
|
||||||
|
float f = this.random.nextFloat() * 0.6F + 0.4F;
|
||||||
|
this.colorRed = f;
|
||||||
|
this.colorGreen = f;
|
||||||
|
this.colorBlue = f;
|
||||||
|
this.velocityX = vx;
|
||||||
|
this.velocityY = vy;
|
||||||
|
this.velocityZ = vz;
|
||||||
|
this.prevAngle = this.angle = this.random.nextFloat()*2*(float)Math.PI;
|
||||||
|
// this.move((float)new Vec3d(vx, vy, vz).length());
|
||||||
|
// this.move(100.0F);
|
||||||
|
this.scale = this.scale_ = 15.0F*this.random.nextFloat()+20.0F; //* (1.0F - (float)d * 0.5F); //Change maximum scale factor from 2.0F to 10.0F
|
||||||
|
this.collidesWithWorld = false;
|
||||||
|
this.spriteProvider = spriteProvider;
|
||||||
|
this.setSpriteForAge(spriteProvider);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getColorMultiplier(float tint) {
|
||||||
|
return 15728880;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void tick() {
|
||||||
|
this.prevPosX = this.x;
|
||||||
|
this.prevPosY = this.y;
|
||||||
|
this.prevPosZ = this.z;
|
||||||
|
if (this.age++ >= this.maxAge) {
|
||||||
|
this.markDead();
|
||||||
|
} else {
|
||||||
|
float factor = (float)age/(float)maxAge;
|
||||||
|
// this.scale = scale_*(float)(1.0F-factor);
|
||||||
|
// this.setColorAlpha(1.0F-factor*factor);
|
||||||
|
this.move(this.velocityX, this.velocityY, this.velocityZ);
|
||||||
|
// this.setColor(
|
||||||
|
// // this.random.nextFloat(), this.random.nextFloat(), this.random.nextFloat()
|
||||||
|
// (float)(1.0F-factor),
|
||||||
|
// (float)(1.0F-factor),
|
||||||
|
// (float)(1.0F-factor)
|
||||||
|
// );
|
||||||
|
this.setSpriteForAge(this.spriteProvider);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public ParticleTextureSheet getType() {
|
||||||
|
return ParticleTextureSheet.PARTICLE_SHEET_LIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Environment(EnvType.CLIENT)
|
||||||
|
public static class Factory implements ParticleFactory<DefaultParticleType> {
|
||||||
|
private final SpriteProvider spriteProvider;
|
||||||
|
|
||||||
|
public Factory(SpriteProvider spriteProvider) {
|
||||||
|
this.spriteProvider = spriteProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Particle createParticle(DefaultParticleType defaultParticleType, ClientWorld clientWorld, double d, double e, double f, double g, double h, double i) {
|
||||||
|
return new BigFookingExplosionParticle(clientWorld, d, e, f, g, h, i, this.spriteProvider);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,81 @@
|
||||||
|
package io.github.npc_strider.NukeMod.client.particle;
|
||||||
|
|
||||||
|
import io.github.npc_strider.NukeMod.NukeModClient;
|
||||||
|
import net.fabricmc.api.EnvType;
|
||||||
|
import net.fabricmc.api.Environment;
|
||||||
|
import net.fabricmc.fabric.api.client.particle.v1.FabricSpriteProvider;
|
||||||
|
import net.minecraft.client.particle.NoRenderParticle;
|
||||||
|
import net.minecraft.client.particle.Particle;
|
||||||
|
import net.minecraft.client.particle.ParticleFactory;
|
||||||
|
import net.minecraft.client.world.ClientWorld;
|
||||||
|
import net.minecraft.particle.DefaultParticleType;
|
||||||
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
|
||||||
|
public class BigFookingSmokeEmitterParticle extends NoRenderParticle {
|
||||||
|
private int age_;
|
||||||
|
private final int maxAge_;
|
||||||
|
|
||||||
|
private double RADIUS_X = 60;
|
||||||
|
private final float m = 1.0F;
|
||||||
|
private final int[][] radiuses = { //For the big fission cloud
|
||||||
|
{(int)Math.floor(64*m), (int)Math.floor(RADIUS_X/2) },
|
||||||
|
{(int)Math.floor(32*m), (int)Math.floor(RADIUS_X/3) },
|
||||||
|
{(int)Math.floor(16*m), (int)Math.floor(RADIUS_X/4) },
|
||||||
|
{(int)Math.floor(16*m), (int)Math.floor(RADIUS_X/5) },
|
||||||
|
{(int)Math.floor(16*m), (int)Math.floor(RADIUS_X/6) },
|
||||||
|
{(int)Math.floor(12*m), (int)Math.floor(RADIUS_X/7) },
|
||||||
|
{(int)Math.floor(8*m), (int)Math.floor(RADIUS_X/8) },
|
||||||
|
{(int)Math.floor(8*m), (int)Math.floor(RADIUS_X/9) },
|
||||||
|
{(int)Math.floor(8*m), (int)Math.floor(RADIUS_X/10) },
|
||||||
|
|
||||||
|
{(int)Math.floor(32*m), (int)Math.floor(RADIUS_X/2) },
|
||||||
|
{(int)Math.floor(32*m), (int)Math.floor(RADIUS_X/2) },
|
||||||
|
{(int)Math.floor(32*m), (int)Math.floor(RADIUS_X/2) },
|
||||||
|
{(int)Math.floor(32*m), (int)Math.floor(RADIUS_X/2.2) },
|
||||||
|
{(int)Math.floor(24*m), (int)Math.floor(RADIUS_X/2.5) },
|
||||||
|
{(int)Math.floor(16*m), (int)Math.floor(RADIUS_X/2.7) },
|
||||||
|
{(int)Math.floor(8*m), (int)Math.floor(RADIUS_X/3) },
|
||||||
|
{(int)Math.floor(8*m), (int)Math.floor(RADIUS_X/5.5) },
|
||||||
|
{(int)Math.floor(8*m), (int)Math.floor(RADIUS_X/8) },
|
||||||
|
}; // {(y+0n)=>r0,(y+1n)=>r1,(y+2n)=>r2, ... }
|
||||||
|
|
||||||
|
private BigFookingSmokeEmitterParticle(ClientWorld world, double x, double y, double z) {
|
||||||
|
super(world, x, y, z, 0.0D, 0.0D, 0.0D);
|
||||||
|
this.maxAge_ = 1;//80;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void tick() {
|
||||||
|
double dy = 8.0D;
|
||||||
|
for (int j = 0; j < radiuses.length; ++j) {
|
||||||
|
for (int i = 0; i < radiuses[j][0]; ++i) {
|
||||||
|
float theta = this.random.nextFloat() * 360;
|
||||||
|
double r_ = Math.sqrt(this.random.nextDouble()) * radiuses[j][1];
|
||||||
|
Vec3d position = Vec3d.fromPolar(0, theta).multiply(r_).add(this.x, this.y+(dy*(double)(j)), this.z); //Keeps our explosion spherical, rather than in a 3d box as with the vanilla method.
|
||||||
|
// if (world.getBlockState(new BlockPos(position)).getMaterial() == Material.AIR) {
|
||||||
|
Vec3d v = Vec3d.fromPolar(0, theta).normalize().multiply(r_*0.05F+0.05F*this.random.nextFloat());
|
||||||
|
this.world.addParticle(NukeModClient.BIG_FOOKING_SMOKE, true, position.getX(), position.getY(), position.getZ(), v.getX(), v.getY()-0.25F, v.getZ());
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
++this.age_;
|
||||||
|
if (this.age_ == this.maxAge_) {
|
||||||
|
this.markDead();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Environment(EnvType.CLIENT)
|
||||||
|
public static class Factory implements ParticleFactory<DefaultParticleType> {
|
||||||
|
private final FabricSpriteProvider sprites;
|
||||||
|
|
||||||
|
public Factory(FabricSpriteProvider sprites) {
|
||||||
|
this.sprites = sprites;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Particle createParticle(DefaultParticleType defaultParticleType, ClientWorld clientWorld, double d, double e, double f, double g, double h, double i) {
|
||||||
|
return new BigFookingSmokeEmitterParticle(clientWorld, d, e, f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
package io.github.npc_strider.NukeMod.client.particle;
|
||||||
|
|
||||||
|
import net.fabricmc.api.EnvType;
|
||||||
|
import net.fabricmc.api.Environment;
|
||||||
|
import net.minecraft.client.particle.AscendingParticle;
|
||||||
|
import net.minecraft.client.particle.Particle;
|
||||||
|
import net.minecraft.client.particle.ParticleFactory;
|
||||||
|
import net.minecraft.client.particle.SpriteProvider;
|
||||||
|
import net.minecraft.client.world.ClientWorld;
|
||||||
|
import net.minecraft.particle.DefaultParticleType;
|
||||||
|
|
||||||
|
@Environment(EnvType.CLIENT)
|
||||||
|
public class BigFookingSmokeParticle extends AscendingParticle {
|
||||||
|
protected BigFookingSmokeParticle(ClientWorld world, double x, double y, double z, double velocityX, double velocityY, double velocityZ, SpriteProvider spriteProvider) {
|
||||||
|
// super(world, x, y, z, velocityX, velocityY, velocityZ, 2.5F, spriteProvider);
|
||||||
|
super(world, x, y, z, 0.1F, 0.1F, 0.1F, velocityX, velocityY, velocityZ, 1.0F, spriteProvider, 0.3F, 20*60, 0.0005D, false);
|
||||||
|
this.scale = 10.0F;
|
||||||
|
this.age = random.nextInt(160);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Environment(EnvType.CLIENT)
|
||||||
|
public static class Factory implements ParticleFactory<DefaultParticleType> {
|
||||||
|
private final SpriteProvider spriteProvider;
|
||||||
|
|
||||||
|
public Factory(SpriteProvider spriteProvider) {
|
||||||
|
this.spriteProvider = spriteProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Particle createParticle(DefaultParticleType defaultParticleType, ClientWorld clientWorld, double d, double e, double f, double g, double h, double i) {
|
||||||
|
return new BigFookingSmokeParticle(clientWorld, d, e, f, g, h, i, this.spriteProvider);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
package io.github.npc_strider.NukeMod.client.particle;
|
||||||
|
|
||||||
|
import net.fabricmc.api.EnvType;
|
||||||
|
import net.fabricmc.api.Environment;
|
||||||
|
import net.fabricmc.fabric.api.client.particle.v1.FabricSpriteProvider;
|
||||||
|
import net.minecraft.client.particle.Particle;
|
||||||
|
import net.minecraft.client.particle.ParticleFactory;
|
||||||
|
import net.minecraft.client.particle.ParticleTextureSheet;
|
||||||
|
import net.minecraft.client.particle.SpriteBillboardParticle;
|
||||||
|
import net.minecraft.client.particle.SpriteProvider;
|
||||||
|
import net.minecraft.client.world.ClientWorld;
|
||||||
|
import net.minecraft.particle.DefaultParticleType;
|
||||||
|
|
||||||
|
@Environment(EnvType.CLIENT)
|
||||||
|
public class FissioningParticle extends SpriteBillboardParticle {
|
||||||
|
|
||||||
|
protected FissioningParticle(ClientWorld clientWorld, double d, double e, double f, double g, double h, double i, SpriteProvider sprites) {
|
||||||
|
super(clientWorld, d, e, f, g, h, i);
|
||||||
|
setSprite(sprites.getSprite(world.random));
|
||||||
|
float j = this.random.nextFloat() * 0.3F + 0.7F;
|
||||||
|
scale(2.0F * j);
|
||||||
|
this.setMaxAge((int)(10.0F / (this.random.nextFloat() * 0.9F + 0.1F))); //Just increasing the maxAge by increasing the max from 4.0F to 10.0F
|
||||||
|
this.colorRed = 1.0F * j;
|
||||||
|
this.colorGreen = 0.0F;
|
||||||
|
this.colorBlue = 0.0F;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ParticleTextureSheet getType() {
|
||||||
|
return ParticleTextureSheet.PARTICLE_SHEET_OPAQUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Environment(EnvType.CLIENT)
|
||||||
|
public static class Factory implements ParticleFactory<DefaultParticleType> {
|
||||||
|
private final FabricSpriteProvider sprites;
|
||||||
|
|
||||||
|
public Factory(FabricSpriteProvider sprites) {
|
||||||
|
this.sprites = sprites;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Particle createParticle(DefaultParticleType type, ClientWorld world, double x, double y, double z, double vX, double vY, double vZ) {
|
||||||
|
return new FissioningParticle(world, x, y, z, vX, vY, vZ, sprites);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,52 @@
|
||||||
|
package io.github.npc_strider.NukeMod.constant;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import net.minecraft.block.Block;
|
||||||
|
import net.minecraft.block.Blocks;
|
||||||
|
import net.minecraft.block.Material;
|
||||||
|
|
||||||
|
public class TransformConstants {
|
||||||
|
|
||||||
|
// private static final Map<Block,Block> transform = ImmutableMap.of(
|
||||||
|
// Blocks.STONE, Blocks.COBBLESTONE,
|
||||||
|
// Blocks.DIRT, Blocks.SAND,
|
||||||
|
// Blocks.GRASS_BLOCK, Blocks.SAND,
|
||||||
|
// Blocks.SAND, Blocks.GLASS
|
||||||
|
// );
|
||||||
|
|
||||||
|
// private static final Map<BlockTags,Block> transformBlockTag = ImmutableMap.of( //Nah this is dumb. Have to look up each tag (one block can have multiple tags) which consumes time.
|
||||||
|
// BlockTags.BASE_STONE_OVERWORLD, Blocks.COBBLESTONE,
|
||||||
|
// );
|
||||||
|
|
||||||
|
public static Map<Material,Block> transformMaterial; //We're using JAVA 8 so we can't use the new notation :(
|
||||||
|
static {
|
||||||
|
transformMaterial = new HashMap<>();
|
||||||
|
// transformMaterial.put( Material.STONE, Blocks.GRAVEL ); //Bad idea - creates a shitton of lag due to FallingSand entities.
|
||||||
|
// transformMaterial.put( Material.SOLID_ORGANIC, Blocks.SAND );
|
||||||
|
// transformMaterial.put( Material.SOIL, Blocks.SAND );
|
||||||
|
transformMaterial.put( Material.AGGREGATE, Blocks.GLASS );
|
||||||
|
transformMaterial.put( Material.PORTAL, Blocks.AIR );
|
||||||
|
transformMaterial.put( Material.METAL, Blocks.LAVA );
|
||||||
|
transformMaterial.put( Material.SNOW_BLOCK, Blocks.WATER );
|
||||||
|
transformMaterial.put( Material.SNOW_LAYER, Blocks.WATER );
|
||||||
|
transformMaterial.put( Material.ICE, Blocks.WATER );
|
||||||
|
transformMaterial.put( Material.DENSE_ICE, Blocks.WATER );
|
||||||
|
transformMaterial.put( Material.WOOD, Blocks.COAL_BLOCK );
|
||||||
|
transformMaterial.put( Material.NETHER_WOOD, Blocks.COAL_BLOCK );
|
||||||
|
transformMaterial.put( Material.NETHER_SHOOTS, Blocks.COAL_BLOCK );
|
||||||
|
transformMaterial.put( Material.SOLID_ORGANIC, Blocks.COAL_BLOCK );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Map<Material,List<Block>> transformToFallingTile;
|
||||||
|
static {
|
||||||
|
transformToFallingTile = new HashMap<>();
|
||||||
|
transformToFallingTile.put( Material.STONE, Arrays.asList(Blocks.GRAVEL, Blocks.COBBLESTONE) );
|
||||||
|
transformToFallingTile.put( Material.SOLID_ORGANIC, Arrays.asList(Blocks.SAND, Blocks.SANDSTONE) );
|
||||||
|
transformToFallingTile.put( Material.SOIL, Arrays.asList(Blocks.SAND, Blocks.SANDSTONE) );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,157 @@
|
||||||
|
package io.github.npc_strider.NukeMod.entity;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import io.github.npc_strider.NukeMod.NukeMod;
|
||||||
|
import io.github.npc_strider.NukeMod.NukeModClient;
|
||||||
|
import io.github.npc_strider.NukeMod.constant.TransformConstants;
|
||||||
|
import io.github.npc_strider.NukeMod.constant.TransformConstants.*;
|
||||||
|
import net.minecraft.block.Block;
|
||||||
|
import net.minecraft.block.BlockState;
|
||||||
|
import net.minecraft.block.Blocks;
|
||||||
|
import net.minecraft.block.Material;
|
||||||
|
import net.minecraft.entity.Entity;
|
||||||
|
import net.minecraft.entity.EntityType;
|
||||||
|
import net.minecraft.entity.LivingEntity;
|
||||||
|
import net.minecraft.entity.damage.DamageSource;
|
||||||
|
import net.minecraft.entity.effect.StatusEffectInstance;
|
||||||
|
import net.minecraft.entity.effect.StatusEffects;
|
||||||
|
import net.minecraft.sound.SoundCategory;
|
||||||
|
import net.minecraft.sound.SoundEvents;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.Box;
|
||||||
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
|
public class FastExplosion {
|
||||||
|
private final Vec3d radius;
|
||||||
|
private final Vec3d effectRadius;
|
||||||
|
private final World world;
|
||||||
|
private final Vec3d origin;
|
||||||
|
private final Entity entity;
|
||||||
|
|
||||||
|
public FastExplosion(Entity entity, Vec3d radius, Vec3d effectRadius, Vec3d origin, World world) {
|
||||||
|
this.radius = radius;
|
||||||
|
this.effectRadius = effectRadius;
|
||||||
|
this.origin = origin;
|
||||||
|
this.world = world;
|
||||||
|
this.entity = entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void removeTiles() {
|
||||||
|
double radiusX = this.radius.getX();
|
||||||
|
double radiusY = this.radius.getY();
|
||||||
|
double radiusZ = this.radius.getZ();
|
||||||
|
World wld = this.world;
|
||||||
|
for (double z = -radiusZ; z <= radiusZ; ++z) { //Note to self - don't try and parallize things...
|
||||||
|
for (double y = -radiusY; y <= radiusY; ++y) {
|
||||||
|
for (double x = -radiusX; x <= radiusX; ++x) {
|
||||||
|
Vec3d d = new Vec3d(x, y, z);
|
||||||
|
Vec3d ellipse_ = d.multiply(1/radiusZ, 1/radiusY, 1/radiusX);
|
||||||
|
double ellipseFactor = ellipse_.dotProduct(ellipse_);
|
||||||
|
BlockPos pos = new BlockPos(d.add(this.origin));
|
||||||
|
BlockState blockState = wld.getBlockState(pos);
|
||||||
|
Block block = blockState.getBlock();
|
||||||
|
// System.out.println("Position "+x+","+y+","+z+" "+ellipseFactor );
|
||||||
|
if (blockState.getMaterial() != Material.AIR && ellipseFactor < 1 && block.getBlastResistance() < 1e6) { //Barrier and Adminium has a blast resistance of 3.6e+6 -- So this is OK!
|
||||||
|
// System.out.println("Removed "+block.getName().asString() );
|
||||||
|
if (!wld.removeBlock(pos, false)) {
|
||||||
|
// System.out.println("Fluid");
|
||||||
|
wld.setBlockState(pos, Blocks.AIR.getDefaultState(), 3); //This handles fluid.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Map<Material,Block> transformMaterial = TransformConstants.transformMaterial;
|
||||||
|
private static Map<Material,List<Block>> transformToFallingTile = TransformConstants.transformToFallingTile;
|
||||||
|
|
||||||
|
private void effectTiles() {
|
||||||
|
double radiusX = this.effectRadius.getX();
|
||||||
|
double radiusY = this.effectRadius.getY();
|
||||||
|
double radiusZ = this.effectRadius.getZ();
|
||||||
|
World wld = this.world;
|
||||||
|
for (double z = -radiusZ; z <= radiusZ; ++z) { //Note to self - don't try and parallize things...
|
||||||
|
for (double y = -radiusY; y <= radiusY; ++y) {
|
||||||
|
for (double x = -radiusX; x <= radiusX; ++x) {
|
||||||
|
Vec3d d = new Vec3d(x, y, z);
|
||||||
|
Vec3d ellipse_ = d.multiply(1/radiusZ, 1/radiusY, 1/radiusX);
|
||||||
|
double ellipseFactor = ellipse_.dotProduct(ellipse_);
|
||||||
|
BlockPos pos = new BlockPos(d.add(this.origin));
|
||||||
|
BlockState blockState = wld.getBlockState(pos);
|
||||||
|
Block block = blockState.getBlock();
|
||||||
|
Material mat = blockState.getMaterial();
|
||||||
|
if (mat != Material.AIR && block.getBlastResistance() < 1e6 && ellipseFactor < wld.random.nextDouble() && ellipseFactor < 1) {
|
||||||
|
if (transformMaterial.containsKey(mat)) {
|
||||||
|
wld.setBlockState(pos, transformMaterial.get(mat).getDefaultState());
|
||||||
|
} else if (transformToFallingTile.containsKey(mat)) { //Prevent massive lag from creating falling entities - ensures gravity affected tiles have a solid tile beneath.
|
||||||
|
Material matBelow = wld.getBlockState(pos.down()).getMaterial();
|
||||||
|
if (matBelow != Material.AIR && matBelow != Material.AGGREGATE) {
|
||||||
|
wld.setBlockState(pos, transformToFallingTile.get(mat).get(0).getDefaultState());
|
||||||
|
} else {
|
||||||
|
wld.setBlockState(pos, transformToFallingTile.get(mat).get(1).getDefaultState());
|
||||||
|
}
|
||||||
|
} else if (mat.isBurnable() && wld.getBlockState(pos.up()).getMaterial() == Material.AIR) {
|
||||||
|
wld.setBlockState(pos.up(), Blocks.FIRE.getDefaultState());
|
||||||
|
}
|
||||||
|
|
||||||
|
//else if (transform.containsKey(block)) {
|
||||||
|
// wld.setBlockState(pos, transform.get(block).getDefaultState());
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void damageEntities() {
|
||||||
|
List<Entity> list = this.world.getOtherEntities(this.entity, new Box(this.origin.subtract(effectRadius), this.origin.add(effectRadius)));
|
||||||
|
for (int x = 0; x < list.size(); ++x) {
|
||||||
|
Entity entity = (Entity)list.get(x);
|
||||||
|
Double distance = entity.getPos().distanceTo(this.origin);
|
||||||
|
Double effectFactor = Math.exp(-(0.01*distance)*(0.01*distance)); //IMPORTANT NOTE: We're treating all distances with the same effect falloff, but we need to use the ellipse formulae to calculate different falloffs that follow the ellipse shape.
|
||||||
|
entity.setVelocity(entity.getVelocity().add(entity.getPos().subtract(this.origin).add(0,0.2,0)).normalize().multiply(20*effectFactor)); //Knockback
|
||||||
|
if (!entity.isImmuneToExplosion() && entity.isLiving()) {
|
||||||
|
LivingEntity liveEntity = (LivingEntity)entity;
|
||||||
|
StatusEffects.POISON.applyUpdateEffect((LivingEntity)entity, 5);
|
||||||
|
// System.out.println(effectFactor);
|
||||||
|
liveEntity.damage(DamageSource.GENERIC, (float)(liveEntity.getMaxHealth()*effectFactor+2)); //Yeah, probably should use explosion damage source but whatever.
|
||||||
|
if (liveEntity.getHealth() <= 0) {
|
||||||
|
liveEntity.kill();
|
||||||
|
} else {
|
||||||
|
liveEntity.addStatusEffect(new StatusEffectInstance(StatusEffects.POISON, (int)Math.floor(120*20*effectFactor), (int)Math.ceil(5*effectFactor)));
|
||||||
|
if (!liveEntity.isFireImmune()) {
|
||||||
|
liveEntity.setFireTicks(20);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (entity.getType() == EntityType.ITEM) {
|
||||||
|
int rand = this.world.random.nextInt(11);
|
||||||
|
if (rand < 8) { //20% chance of item surviving
|
||||||
|
entity.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// List<? extends PlayerEntity> players = this.world.getPlayers(); //Was going to try some stuff with rendering a bright flash, but that seems way too hard...
|
||||||
|
// for (int x = 0; x < list.size(); ++x) {
|
||||||
|
// PlayerEntity player = players.get(x);
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
public void damageBlocksAndEntities() {
|
||||||
|
if (this.world.isClient) {
|
||||||
|
//this.world.playSound(this.origin.getX(), this.origin.getY(), this.origin.getZ(), SoundEvents.ENTITY_GENERIC_EXPLODE, SoundCategory.BLOCKS, 25.0F, (1.0F + (this.world.random.nextFloat() - this.world.random.nextFloat()) * 0.2F) * 0.7F, false);
|
||||||
|
this.world.playSound(this.origin.getX(), this.origin.getY(), this.origin.getZ(), NukeMod.FISSION_EXPLOSION, SoundCategory.BLOCKS, 25.0F, (1.0F + (this.world.random.nextFloat() - this.world.random.nextFloat()) * 0.2F) * 0.7F, false);
|
||||||
|
this.world.addParticle(NukeModClient.BIG_FOOKING_EXPLOSION_EMITTER, true, this.origin.getX(), this.origin.getY(), this.origin.getZ(), 1.0D, 0.0D, 0.0D);
|
||||||
|
this.world.addParticle(NukeModClient.BIG_FOOKING_SMOKE_EMITTER, true, this.origin.getX(), this.origin.getY(), this.origin.getZ(), 1.0D, 0.0D, 0.0D);
|
||||||
|
} else {
|
||||||
|
removeTiles();
|
||||||
|
effectTiles();
|
||||||
|
damageEntities(); //Apply damage to items created to reduce lag.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,104 @@
|
||||||
|
package io.github.npc_strider.NukeMod.fission;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import net.minecraft.block.Block;
|
||||||
|
import net.minecraft.block.BlockState;
|
||||||
|
import net.minecraft.entity.Entity;
|
||||||
|
import net.minecraft.entity.LivingEntity;
|
||||||
|
import net.minecraft.entity.TntEntity;
|
||||||
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
|
import net.minecraft.entity.projectile.ProjectileEntity;
|
||||||
|
// import net.minecraft.sound.SoundCategory;
|
||||||
|
// import net.minecraft.sound.SoundEvents;
|
||||||
|
import net.minecraft.text.LiteralText;
|
||||||
|
import net.minecraft.util.ActionResult;
|
||||||
|
import net.minecraft.util.Hand;
|
||||||
|
import net.minecraft.util.hit.BlockHitResult;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
import net.minecraft.world.explosion.Explosion;
|
||||||
|
|
||||||
|
public class FissionBlock extends Block { //Copying code from TntBlock because I can't override some static stuff (private static void primeTnt method)
|
||||||
|
public FissionBlock(Settings settings) {
|
||||||
|
super(settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onBlockAdded(BlockState state, World world, BlockPos pos, BlockState oldState, boolean notify) {
|
||||||
|
if (!oldState.isOf(state.getBlock())) {
|
||||||
|
if (world.isReceivingRedstonePower(pos)) {
|
||||||
|
primeNuke(world, pos);
|
||||||
|
world.removeBlock(pos, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void neighborUpdate(BlockState state, World world, BlockPos pos, Block block, BlockPos fromPos, boolean notify) {
|
||||||
|
if (world.isReceivingRedstonePower(pos)) {
|
||||||
|
primeNuke(world, pos);
|
||||||
|
world.removeBlock(pos, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void primeNuke(World world, BlockPos pos) {
|
||||||
|
primeNuke(world, pos, (LivingEntity)null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void primeNuke(World world, BlockPos pos, @Nullable LivingEntity igniter) {
|
||||||
|
if (!world.isClient) {
|
||||||
|
FissionEntity fissionEntity = new FissionEntity(world, (double)pos.getX() + 0.5D, (double)pos.getY(), (double)pos.getZ() + 0.5D, igniter);
|
||||||
|
// FissionEntity fissionEntity = NukeMod.FISSION_ENTITY.create(world).updateFissionEntity(world, (double)pos.getX() + 0.5D, (double)pos.getY(), (double)pos.getZ() + 0.5D, igniter);
|
||||||
|
|
||||||
|
world.spawnEntity(fissionEntity);
|
||||||
|
// world.playSound((PlayerEntity)null, fissionEntity.getX(), fissionEntity.getY(), fissionEntity.getZ(), SoundEvents.BLOCK_CONDUIT_ACTIVATE, SoundCategory.BLOCKS, 1.0F, 1.0F); //test audio
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Only explosive lenses
|
||||||
|
public void onDestroyedByExplosion(World world, BlockPos pos, Explosion explosion) {
|
||||||
|
if (!world.isClient) {
|
||||||
|
spawnFizzle(
|
||||||
|
world,
|
||||||
|
(double)pos.getX() + 0.5D, (double)pos.getY(), (double)pos.getZ() + 0.5D,
|
||||||
|
explosion.getCausingEntity()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only explosive lenses
|
||||||
|
public void onProjectileHit(World world, BlockState state, BlockHitResult hit, ProjectileEntity projectile) {
|
||||||
|
if (!world.isClient && projectile.isOnFire()) {
|
||||||
|
Entity entity = projectile.getOwner();
|
||||||
|
BlockPos blockPos = hit.getBlockPos();
|
||||||
|
spawnFizzle(
|
||||||
|
world,
|
||||||
|
(double)blockPos.getX() + 0.5D, (double)blockPos.getY(), (double)blockPos.getZ() + 0.5D,
|
||||||
|
entity instanceof LivingEntity ? (LivingEntity)entity : null
|
||||||
|
);
|
||||||
|
world.removeBlock(blockPos, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Incomplete explosion - only explosive lenses detonate in a way that does not intiate fission
|
||||||
|
private static void spawnFizzle(World world, Double x, Double y, Double z, LivingEntity igniter) {
|
||||||
|
TntEntity tntEntity = new TntEntity(world, x, y, z, igniter);
|
||||||
|
// tntEntity.setFuse((short)(world.random.nextInt(tntEntity.getFuseTimer() / 4) + tntEntity.getFuseTimer() / 8));
|
||||||
|
tntEntity.setFuse((short)(world.random.nextInt(tntEntity.getFuseTimer() / 24) + tntEntity.getFuseTimer() / 20));
|
||||||
|
world.spawnEntity(tntEntity);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) {
|
||||||
|
if (!world.isClient) {
|
||||||
|
player.sendMessage(new LiteralText("Device ready: awaiting redstone signal . . ."), true);
|
||||||
|
}
|
||||||
|
return ActionResult.SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean shouldDropItemsOnExplosion(Explosion explosion) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,186 @@
|
||||||
|
package io.github.npc_strider.NukeMod.fission;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import io.github.npc_strider.NukeMod.NukeMod;
|
||||||
|
import io.github.npc_strider.NukeMod.NukeModClient;
|
||||||
|
import io.github.npc_strider.NukeMod.entity.FastExplosion;
|
||||||
|
import net.minecraft.entity.Entity;
|
||||||
|
import net.minecraft.entity.EntityDimensions;
|
||||||
|
import net.minecraft.entity.EntityPose;
|
||||||
|
import net.minecraft.entity.EntityType;
|
||||||
|
import net.minecraft.entity.LivingEntity;
|
||||||
|
import net.minecraft.entity.MovementType;
|
||||||
|
import net.minecraft.entity.TntEntity;
|
||||||
|
import net.minecraft.entity.data.DataTracker;
|
||||||
|
import net.minecraft.entity.data.TrackedData;
|
||||||
|
import net.minecraft.entity.data.TrackedDataHandlerRegistry;
|
||||||
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
|
import net.minecraft.nbt.CompoundTag;
|
||||||
|
import net.minecraft.network.Packet;
|
||||||
|
import net.minecraft.network.packet.s2c.play.EntitySpawnS2CPacket;
|
||||||
|
import net.minecraft.sound.SoundCategory;
|
||||||
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
|
public class FissionEntity extends Entity { // I frankly don't have time to mess about with extending TntEntity - just CTRL+C'd it
|
||||||
|
|
||||||
|
private static final int FUSE_TIMER = 20*15; //Ticks
|
||||||
|
|
||||||
|
private static final TrackedData<Integer> FUSE;
|
||||||
|
@Nullable
|
||||||
|
private LivingEntity causingEntity;
|
||||||
|
private int fuseTimer;
|
||||||
|
|
||||||
|
// private double RADIUS_X = 16;
|
||||||
|
private double RADIUS_X = 60;
|
||||||
|
private double RADIUS_Z = RADIUS_X; //Keep these the same!
|
||||||
|
// private double RADIUS_Y = 16; //I keep forgetting that minecraft vectors are weird and Z isn't the vertical axis...
|
||||||
|
private double RADIUS_Y = 96; //I keep forgetting that minecraft vectors are weird and Z isn't the vertical axis...
|
||||||
|
private Vec3d radius = new Vec3d(RADIUS_X, RADIUS_Y, RADIUS_Z);
|
||||||
|
|
||||||
|
private double EFFECT_FACTOR = 3; //This is the radius to which effects such as radiation, vaporization and glassification occur.z
|
||||||
|
private Vec3d effectRadius = new Vec3d(Math.floor(RADIUS_X*EFFECT_FACTOR), Math.floor(RADIUS_Y*EFFECT_FACTOR), Math.floor(RADIUS_Z*EFFECT_FACTOR));
|
||||||
|
|
||||||
|
// public FissionEntity(World world, double x, double y, double z, @Nullable LivingEntity igniter) {
|
||||||
|
|
||||||
|
protected FissionEntity(World world, double x, double y, double z, @Nullable LivingEntity igniter) {
|
||||||
|
this(NukeMod.FISSION_ENTITY, world);
|
||||||
|
this.updatePosition(x, y, z);
|
||||||
|
double d = world.random.nextDouble() * 6.2831854820251465D;
|
||||||
|
this.setVelocity(-Math.sin(d) * 0.02D, 0.20000000298023224D, -Math.cos(d) * 0.02D);
|
||||||
|
this.prevX = x;
|
||||||
|
this.prevY = y+5;
|
||||||
|
this.prevZ = z;
|
||||||
|
this.causingEntity = igniter;
|
||||||
|
// this(NukeMod.FISSION_ENTITY, world);
|
||||||
|
// super(world, x, y, z, igniter); //This calls the super implementation which results in the wrong tick method being used.
|
||||||
|
this.fuseTimer = FUSE_TIMER;
|
||||||
|
this.setFuse(FUSE_TIMER);
|
||||||
|
}
|
||||||
|
|
||||||
|
public FissionEntity(@Nullable EntityType<? extends FissionEntity> entityType, World world) {
|
||||||
|
super(entityType != null ? entityType : NukeMod.FISSION_ENTITY, world);
|
||||||
|
this.fuseTimer = FUSE_TIMER;
|
||||||
|
this.inanimate = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void tick() {
|
||||||
|
if (!this.hasNoGravity()) {
|
||||||
|
this.setVelocity(this.getVelocity().add(0.0D, -0.04D, 0.0D));
|
||||||
|
}
|
||||||
|
|
||||||
|
this.move(MovementType.SELF, this.getVelocity());
|
||||||
|
this.setVelocity(this.getVelocity().multiply(0.98D));
|
||||||
|
if (this.onGround) {
|
||||||
|
this.setVelocity(this.getVelocity().multiply(0.7D, -0.5D, 0.7D));
|
||||||
|
}
|
||||||
|
|
||||||
|
--this.fuseTimer;
|
||||||
|
if (this.fuseTimer <= 0) {
|
||||||
|
this.remove();
|
||||||
|
this.explode();
|
||||||
|
// if (!this.world.isClient) {
|
||||||
|
// this.explode(new Vec3d(this.getX(), this.getY(), this.getZ()), this.RADIUS_X, this.RADIUS_Y, this.RADIUS_Z);
|
||||||
|
// }
|
||||||
|
} else {
|
||||||
|
this.updateWaterState();
|
||||||
|
// System.out.println(this.world.isClient);
|
||||||
|
if (this.world.isClient) {
|
||||||
|
double x = this.getX();
|
||||||
|
double y = this.getY();
|
||||||
|
double z = this.getZ();
|
||||||
|
Vec3d v = this.getVelocity();
|
||||||
|
double vx = v.getX();
|
||||||
|
double vy = v.getY();
|
||||||
|
double vz = v.getZ();
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
spawnAlphaParticles(x, y, z, vx, vy, vz);
|
||||||
|
}
|
||||||
|
// this.world.addParticle(ParticleTypes.SMOKE, this.getX(), this.getY() + 0.5D, this.getZ(), 0.0D, 0.0D, 0.0D);
|
||||||
|
}
|
||||||
|
if (this.fuseTimer % 60 == 0 || this.fuseTimer == FUSE_TIMER - 1) {
|
||||||
|
world.playSound((PlayerEntity)null, this.getX(), this.getY(), this.getZ(), NukeMod.FISSION_ALARM, SoundCategory.BLOCKS, 15.0F, 1.0F);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Why use a custom explosion ?
|
||||||
|
//Because the vanilla method uses raytracing which works well for small explosions but does not scale to large explosions due to a limited number of rays.
|
||||||
|
//Also, raytracing is compartively more expensive/costly, which is evident by the lag generated by large explosions.
|
||||||
|
private void explode() {
|
||||||
|
//Vanilla method - small explosion // this.world.createExplosion(this, this.getX(), this.getBodyY(0.0625D), this.getZ(), 200.0F, Explosion.DestructionType.DESTROY);
|
||||||
|
FastExplosion explosion = new FastExplosion(this, radius, effectRadius, this.getPos(), this.world);
|
||||||
|
explosion.damageBlocksAndEntities();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void spawnAlphaParticles(double x, double y, double z, double vx, double vy, double vz) {
|
||||||
|
this.world.addParticle(
|
||||||
|
NukeModClient.FISSION_PARTICLE,
|
||||||
|
true,
|
||||||
|
x + 0.0D + (random.nextDouble() - 0.5D) * 0.2D,
|
||||||
|
y + 0.7D + (random.nextDouble() - 0.5D) * 0.2D,
|
||||||
|
z + 0.0D + (random.nextDouble() - 0.5D) * 0.2D,
|
||||||
|
vx + (random.nextDouble() - 0.5D) * 0.25F,
|
||||||
|
vy + (random.nextDouble() - 0.0D) * 0.25F,
|
||||||
|
vz + (random.nextDouble() - 0.5D) * 0.25F
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void initDataTracker() {
|
||||||
|
this.dataTracker.startTracking(FUSE, 80);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean canClimb() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean collides() {
|
||||||
|
return !this.removed;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void writeCustomDataToTag(CompoundTag tag) {
|
||||||
|
tag.putShort("Fuse", (short)this.getFuseTimer());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void readCustomDataFromTag(CompoundTag tag) {
|
||||||
|
this.setFuse(tag.getShort("Fuse"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public LivingEntity getCausingEntity() {
|
||||||
|
return this.causingEntity;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected float getEyeHeight(EntityPose pose, EntityDimensions dimensions) {
|
||||||
|
return 0.15F;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFuse(int fuse) {
|
||||||
|
this.dataTracker.set(FUSE, fuse);
|
||||||
|
this.fuseTimer = fuse;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onTrackedDataSet(TrackedData<?> data) {
|
||||||
|
if (FUSE.equals(data)) {
|
||||||
|
this.fuseTimer = this.getFuse();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getFuse() {
|
||||||
|
return (Integer)this.dataTracker.get(FUSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getFuseTimer() {
|
||||||
|
return this.fuseTimer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Packet<?> createSpawnPacket() {
|
||||||
|
return new EntitySpawnS2CPacket(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
static {
|
||||||
|
FUSE = DataTracker.registerData(TntEntity.class, TrackedDataHandlerRegistry.INTEGER);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,91 @@
|
||||||
|
// package io.github.npc_strider.NukeMod.mixin;
|
||||||
|
// import net.minecraft.client.network.ClientPlayNetworkHandler;
|
||||||
|
// import net.minecraft.entity.Entity;
|
||||||
|
// import net.minecraft.network.packet.s2c.play.EntitySpawnS2CPacket;
|
||||||
|
// 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 io.github.npc_strider.NukeMod.NukeMod;
|
||||||
|
// import io.github.npc_strider.NukeMod.fission.FissionEntity;
|
||||||
|
|
||||||
|
|
||||||
|
// @Mixin(ClientPlayNetworkHandler.class)
|
||||||
|
// public class Client {
|
||||||
|
|
||||||
|
// @Inject(at = @At("TAIL"), method="onEntitySpawn")
|
||||||
|
// public void onEntitySpawn(EntitySpawnS2CPacket packet, CallbackInfo cbi) {
|
||||||
|
// System.out.l
|
||||||
|
// ClientPlayNetworkHandler cpnh = (ClientPlayNetworkHandler) (Object) this;
|
||||||
|
|
||||||
|
// if (packet.getEntityTypeId() == NukeMod.FISSION_ENTITY_TYPE) {
|
||||||
|
// Entity e = new FissionEntity(null, cpnh.getWorld());
|
||||||
|
|
||||||
|
// int i = packet.getId();
|
||||||
|
// e.updateTrackedPosition(packet.getX(), packet.getY(), packet.getZ());
|
||||||
|
// e.pitch = (float)(packet.getPitch() * 360) / 256.0F;
|
||||||
|
// e.yaw = (float)(packet.getYaw() * 360) / 256.0F;
|
||||||
|
// e.setEntityId(i);
|
||||||
|
// e.setUuid(packet.getUuid());
|
||||||
|
// cpnh.getWorld().addEntity(i, e);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// }
|
||||||
|
|
||||||
|
package io.github.npc_strider.NukeMod.mixin;
|
||||||
|
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 net.minecraft.util.math.Vec3d;
|
||||||
|
|
||||||
|
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;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
|
||||||
|
|
||||||
|
import io.github.npc_strider.NukeMod.NukeMod;
|
||||||
|
import io.github.npc_strider.NukeMod.fission.FissionEntity;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Absolute bruh moment, wasted hours searching for the solution (why my non-living entity wasn't rendering/appearing on the clientside, including smoke and other effects...)
|
||||||
|
Found this solution here https://www.reddit.com/r/fabricmc/comments/g4xpm9/fabric_modding_custom_entity_rendering_on/.
|
||||||
|
The solution here https://www.reddit.com/r/fabricmc/comments/ft7ds1/entity_not_rendering/ works but it has a small (noticeable) delay until the client renders the entity,
|
||||||
|
so I'm using the first option.
|
||||||
|
*/
|
||||||
|
@Mixin(ClientPlayNetworkHandler.class)
|
||||||
|
public abstract class ClientEntityMixin {
|
||||||
|
@Shadow
|
||||||
|
private ClientWorld world;
|
||||||
|
|
||||||
|
@Inject(
|
||||||
|
method = "onEntitySpawn(Lnet/minecraft/network/packet/s2c/play/EntitySpawnS2CPacket;)V",
|
||||||
|
at = @At(value = "INVOKE_ASSIGN", target = "Lnet/minecraft/network/packet/s2c/play/EntitySpawnS2CPacket;getEntityTypeId()Lnet/minecraft/entity/EntityType;"),
|
||||||
|
cancellable = true,
|
||||||
|
locals = LocalCapture.CAPTURE_FAILHARD
|
||||||
|
)
|
||||||
|
private void onEntitySpawn(EntitySpawnS2CPacket packet, CallbackInfo ci, double x, double y, double z, EntityType<?> type) {
|
||||||
|
Entity entity = null;
|
||||||
|
if (packet.getEntityTypeId() == NukeMod.FISSION_ENTITY_TYPE) {
|
||||||
|
entity = new FissionEntity(null, world);
|
||||||
|
}
|
||||||
|
if (entity != null) {
|
||||||
|
int entityId = packet.getId();
|
||||||
|
entity.setVelocity(Vec3d.ZERO);
|
||||||
|
entity.updatePosition(x, y, z);
|
||||||
|
entity.updateTrackedPosition(x, y, z);
|
||||||
|
entity.pitch = (float) (packet.getPitch() * 360) / 256.0F;
|
||||||
|
entity.yaw = (float) (packet.getYaw() * 360) / 256.0F;
|
||||||
|
entity.setEntityId(entityId);
|
||||||
|
entity.setUuid(packet.getUuid());
|
||||||
|
this.world.addEntity(entityId, entity);
|
||||||
|
ci.cancel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,59 @@
|
||||||
|
package io.github.npc_strider.NukeMod.mixin;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
import io.github.npc_strider.NukeMod.fission.FissionBlock;
|
||||||
|
import net.minecraft.block.Block;
|
||||||
|
import net.minecraft.block.BlockState;
|
||||||
|
import net.minecraft.block.FireBlock;
|
||||||
|
import net.minecraft.block.TntBlock;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
|
@Mixin(FireBlock.class)
|
||||||
|
public class FireMixin {
|
||||||
|
@Shadow
|
||||||
|
private int getSpreadChance(BlockState state) {
|
||||||
|
return 0; //I think this works??
|
||||||
|
};
|
||||||
|
|
||||||
|
//private void trySpreadingFire(World world, BlockPos pos, int spreadFactor, Random rand, int currentAge) {
|
||||||
|
|
||||||
|
@Inject(
|
||||||
|
method = "trySpreadingFire(Lnet/minecraft/world/World;Lnet/minecraft/util/math/BlockPos;ILjava/util/Random;I)V",
|
||||||
|
cancellable = true,
|
||||||
|
// remap = false,
|
||||||
|
at = @At("HEAD")
|
||||||
|
)
|
||||||
|
private void trySpreadingFire(World world, BlockPos pos, int spreadFactor, Random rand, int currentAge, CallbackInfo callbackInfo) {
|
||||||
|
BlockState blockState = world.getBlockState(pos);
|
||||||
|
Block block = blockState.getBlock();
|
||||||
|
if (block instanceof FissionBlock) {
|
||||||
|
int i = this.getSpreadChance(world.getBlockState(pos));
|
||||||
|
if (rand.nextInt(spreadFactor) < i) {
|
||||||
|
TntBlock.primeTnt(world, pos); //Temporary
|
||||||
|
world.removeBlock(pos, false);
|
||||||
|
}
|
||||||
|
callbackInfo.cancel(); //Cannot just return when using inject mixin. Have to cancel first!
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// @Mixin(ItemStack.class) //Why the fuck does this not compile??? It's copypasted from the fucking example documentation. https://fabricmc.net/wiki/tutorial:mixin_redirectors_methods
|
||||||
|
// //y'know what, IIIIIIIIIIII give up goodbye ! -Rick Astley
|
||||||
|
// abstract class ExampleMixin {
|
||||||
|
// @Redirect(method = "readTags",
|
||||||
|
// at = @At(value = "INVOKE_ASSIGN", target = "Lnet/minecraft/item/ItemStack;fromTag(Lnet/minecraft/nbt/ListTag;)Lnet/minecraft/item/ItemStack;"))
|
||||||
|
// private static ItemStack returnNull(ListTag tag) {
|
||||||
|
// return null;
|
||||||
|
// }
|
||||||
|
// }
|
|
@ -0,0 +1,54 @@
|
||||||
|
package io.github.npc_strider.NukeMod.render.entity;
|
||||||
|
|
||||||
|
import io.github.npc_strider.NukeMod.NukeMod;
|
||||||
|
import io.github.npc_strider.NukeMod.fission.FissionEntity;
|
||||||
|
import net.fabricmc.api.EnvType;
|
||||||
|
import net.fabricmc.api.Environment;
|
||||||
|
import net.minecraft.client.render.VertexConsumerProvider;
|
||||||
|
import net.minecraft.client.render.entity.EntityRenderDispatcher;
|
||||||
|
import net.minecraft.client.render.entity.EntityRenderer;
|
||||||
|
import net.minecraft.client.render.entity.TntMinecartEntityRenderer;
|
||||||
|
import net.minecraft.client.texture.SpriteAtlasTexture;
|
||||||
|
import net.minecraft.client.util.math.MatrixStack;
|
||||||
|
import net.minecraft.client.util.math.Vector3f;
|
||||||
|
import net.minecraft.util.Identifier;
|
||||||
|
import net.minecraft.util.math.MathHelper;
|
||||||
|
|
||||||
|
@Environment(EnvType.CLIENT)
|
||||||
|
public class FissionEntityRenderer extends EntityRenderer<FissionEntity> {
|
||||||
|
|
||||||
|
public FissionEntityRenderer(EntityRenderDispatcher entityRenderDispatcher) {
|
||||||
|
super(entityRenderDispatcher);
|
||||||
|
this.shadowRadius = 0.5F;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void render(FissionEntity tntEntity, float f, float g, MatrixStack matrixStack, VertexConsumerProvider vertexConsumerProvider, int i) {
|
||||||
|
matrixStack.push();
|
||||||
|
matrixStack.translate(0.0D, 0.5D, 0.0D);
|
||||||
|
if ((float)tntEntity.getFuseTimer() - g + 1.0F < 10.0F) {
|
||||||
|
float h = 1.0F - ((float)tntEntity.getFuseTimer() - g + 1.0F) / 10.0F * 2.0F;
|
||||||
|
h = MathHelper.clamp(h, 0.0F, 1.0F);
|
||||||
|
h *= h;
|
||||||
|
h *= h;
|
||||||
|
float j = 1.0F + h * 0.3F;
|
||||||
|
matrixStack.scale(j, j, j);
|
||||||
|
}
|
||||||
|
|
||||||
|
matrixStack.multiply(Vector3f.POSITIVE_Y.getDegreesQuaternion(-90.0F));
|
||||||
|
matrixStack.translate(-0.5D, -0.5D, 0.5D);
|
||||||
|
matrixStack.multiply(Vector3f.POSITIVE_Y.getDegreesQuaternion(90.0F));
|
||||||
|
// FissionEntityRenderer.renderFlashingBlock(Blocks.WHITE_WOOL.getDefaultState(), matrixStack, vertexConsumerProvider, i, tntEntity.getFuseTimer() / 5 % 2 == 0);
|
||||||
|
TntMinecartEntityRenderer.renderFlashingBlock(NukeMod.FISSION_BLOCK.getDefaultState(), matrixStack, vertexConsumerProvider, i, tntEntity.getFuseTimer() / 5 % 2 == 0);
|
||||||
|
matrixStack.pop();
|
||||||
|
super.render(tntEntity, f, g, matrixStack, vertexConsumerProvider, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Identifier getTexture(FissionEntity tntEntity) {
|
||||||
|
return SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// MinecraftClient.getInstance().getBlockRenderManager().renderBlockAsEntity(Blocks.TNT.getDefaultState(), matrixStack, vertexConsumerProvider, i, (int)Math.floor(50*Math.sin(tntEntity.getFuseTimer())));
|
||||||
|
// System.out.println((int)Math.floor(50*Math.sin(tntEntity.getFuseTimer())));
|
||||||
|
|
15
src/main/resources/NukeMod.mixins.json
Normal file
15
src/main/resources/NukeMod.mixins.json
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
{
|
||||||
|
"required": true,
|
||||||
|
"minVersion": "0.8",
|
||||||
|
"package": "io.github.npc_strider.NukeMod.mixin",
|
||||||
|
"compatibilityLevel": "JAVA_8",
|
||||||
|
"mixins": [
|
||||||
|
"FireMixin"
|
||||||
|
],
|
||||||
|
"client": [
|
||||||
|
"ClientEntityMixin"
|
||||||
|
],
|
||||||
|
"injectors": {
|
||||||
|
"defaultRequire": 1
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
{
|
||||||
|
"variants": {
|
||||||
|
"": {
|
||||||
|
"model": "minecraft:block/e"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
BIN
src/main/resources/assets/nuke-mod/icon.png
Normal file
BIN
src/main/resources/assets/nuke-mod/icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 453 B |
|
@ -0,0 +1 @@
|
||||||
|
{"textures" : []}
|
|
@ -0,0 +1,20 @@
|
||||||
|
{
|
||||||
|
"textures": [
|
||||||
|
"minecraft:explosion_0",
|
||||||
|
"minecraft:explosion_1",
|
||||||
|
"minecraft:explosion_2",
|
||||||
|
"minecraft:explosion_3",
|
||||||
|
"minecraft:explosion_4",
|
||||||
|
"minecraft:explosion_5",
|
||||||
|
"minecraft:explosion_6",
|
||||||
|
"minecraft:explosion_7",
|
||||||
|
"minecraft:explosion_8",
|
||||||
|
"minecraft:explosion_9",
|
||||||
|
"minecraft:explosion_10",
|
||||||
|
"minecraft:explosion_11",
|
||||||
|
"minecraft:explosion_12",
|
||||||
|
"minecraft:explosion_13",
|
||||||
|
"minecraft:explosion_14",
|
||||||
|
"minecraft:explosion_15"
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
{"textures" : []}
|
12
src/main/resources/assets/nuke-mod/particles/big-smoke.json
Normal file
12
src/main/resources/assets/nuke-mod/particles/big-smoke.json
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
{
|
||||||
|
"textures": [
|
||||||
|
"minecraft:generic_7",
|
||||||
|
"minecraft:generic_6",
|
||||||
|
"minecraft:generic_5",
|
||||||
|
"minecraft:generic_4",
|
||||||
|
"minecraft:generic_3",
|
||||||
|
"minecraft:generic_2",
|
||||||
|
"minecraft:generic_1",
|
||||||
|
"minecraft:generic_0"
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
{
|
||||||
|
"textures": [
|
||||||
|
"minecraft:generic_7",
|
||||||
|
"minecraft:generic_6",
|
||||||
|
"minecraft:generic_5",
|
||||||
|
"minecraft:generic_4",
|
||||||
|
"minecraft:generic_3",
|
||||||
|
"minecraft:generic_2",
|
||||||
|
"minecraft:generic_1",
|
||||||
|
"minecraft:generic_0"
|
||||||
|
]
|
||||||
|
}
|
14
src/main/resources/assets/nuke-mod/sounds.json
Normal file
14
src/main/resources/assets/nuke-mod/sounds.json
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
{
|
||||||
|
"fission-alarm": {
|
||||||
|
"subtitle": "subtitles.nuke-mod.fission-alarm",
|
||||||
|
"sounds": [
|
||||||
|
"nuke-mod:fission-alarm"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"fission-explosion": {
|
||||||
|
"subtitle": "subtitles.nuke-mod.fission-explosion",
|
||||||
|
"sounds": [
|
||||||
|
"nuke-mod:fission-explosion"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
BIN
src/main/resources/assets/nuke-mod/sounds/fission-alarm.ogg
Normal file
BIN
src/main/resources/assets/nuke-mod/sounds/fission-alarm.ogg
Normal file
Binary file not shown.
BIN
src/main/resources/assets/nuke-mod/sounds/fission-explosion.ogg
Normal file
BIN
src/main/resources/assets/nuke-mod/sounds/fission-explosion.ogg
Normal file
Binary file not shown.
40
src/main/resources/fabric.mod.json
Normal file
40
src/main/resources/fabric.mod.json
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
{
|
||||||
|
"schemaVersion": 1,
|
||||||
|
"id": "nuke-mod",
|
||||||
|
"version": "${version}",
|
||||||
|
|
||||||
|
"name": "Yet another nuke mod",
|
||||||
|
"description": "Yet another description",
|
||||||
|
"authors": [
|
||||||
|
"npc_strider"
|
||||||
|
],
|
||||||
|
"contact": {
|
||||||
|
"homepage": "https://npc-strider.github.io/",
|
||||||
|
"sources": "https://github.com/npc-strider/NukeMod"
|
||||||
|
},
|
||||||
|
|
||||||
|
"license": "GPL-3.0",
|
||||||
|
"icon": "assets/nuke-mod/icon.png",
|
||||||
|
|
||||||
|
"environment": "*",
|
||||||
|
"entrypoints": {
|
||||||
|
"main": [
|
||||||
|
"io.github.npc_strider.NukeMod.NukeMod"
|
||||||
|
],
|
||||||
|
"client": [
|
||||||
|
"io.github.npc_strider.NukeMod.NukeModClient"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"mixins": [
|
||||||
|
"NukeMod.mixins.json"
|
||||||
|
],
|
||||||
|
|
||||||
|
"depends": {
|
||||||
|
"fabricloader": ">=0.7.4",
|
||||||
|
"fabric": "*",
|
||||||
|
"minecraft": "1.16.x"
|
||||||
|
},
|
||||||
|
"suggests": {
|
||||||
|
"another-mod": "*"
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user