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