commit 53af69ce43483df8f15957f7cb4b92ad55314ed1 Author: npc-strider Date: Mon Jan 4 00:29:12 2021 +0800 Initial commit - basic functionality diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..31c38ee --- /dev/null +++ b/.github/workflows/build.yml @@ -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/ diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..09cd281 --- /dev/null +++ b/.gitignore @@ -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/ diff --git a/README.md b/README.md new file mode 100644 index 0000000..772af2d --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +# Nuke mod + +## In development. \ No newline at end of file diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..62083f9 --- /dev/null +++ b/build.gradle @@ -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. + } +} diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 0000000..76137f9 --- /dev/null +++ b/gradle.properties @@ -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 diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..e708b1c Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..be52383 --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -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 diff --git a/gradlew b/gradlew new file mode 100644 index 0000000..4f906e0 --- /dev/null +++ b/gradlew @@ -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" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000..107acd3 --- /dev/null +++ b/gradlew.bat @@ -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 diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 0000000..5b60df3 --- /dev/null +++ b/settings.gradle @@ -0,0 +1,10 @@ +pluginManagement { + repositories { + jcenter() + maven { + name = 'Fabric' + url = 'https://maven.fabricmc.net/' + } + gradlePluginPortal() + } +} diff --git a/src/main/java/io/github/npc_strider/NukeMod/NukeMod.java b/src/main/java/io/github/npc_strider/NukeMod/NukeMod.java new file mode 100644 index 0000000..e73be62 --- /dev/null +++ b/src/main/java/io/github/npc_strider/NukeMod/NukeMod.java @@ -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 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 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); + } +} diff --git a/src/main/java/io/github/npc_strider/NukeMod/NukeModClient.java b/src/main/java/io/github/npc_strider/NukeMod/NukeModClient.java new file mode 100644 index 0000000..9f8f61f --- /dev/null +++ b/src/main/java/io/github/npc_strider/NukeMod/NukeModClient.java @@ -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)); + } +} diff --git a/src/main/java/io/github/npc_strider/NukeMod/client/particle/BigFookingExplosionEmitterParticle.java b/src/main/java/io/github/npc_strider/NukeMod/client/particle/BigFookingExplosionEmitterParticle.java new file mode 100644 index 0000000..4aaf09d --- /dev/null +++ b/src/main/java/io/github/npc_strider/NukeMod/client/particle/BigFookingExplosionEmitterParticle.java @@ -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 { + 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); + } + } +} \ No newline at end of file diff --git a/src/main/java/io/github/npc_strider/NukeMod/client/particle/BigFookingExplosionParticle.java b/src/main/java/io/github/npc_strider/NukeMod/client/particle/BigFookingExplosionParticle.java new file mode 100644 index 0000000..451c68a --- /dev/null +++ b/src/main/java/io/github/npc_strider/NukeMod/client/particle/BigFookingExplosionParticle.java @@ -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 { + 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); + } + } +} diff --git a/src/main/java/io/github/npc_strider/NukeMod/client/particle/BigFookingSmokeEmitterParticle.java b/src/main/java/io/github/npc_strider/NukeMod/client/particle/BigFookingSmokeEmitterParticle.java new file mode 100644 index 0000000..53b680d --- /dev/null +++ b/src/main/java/io/github/npc_strider/NukeMod/client/particle/BigFookingSmokeEmitterParticle.java @@ -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 { + 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); + } + } +} \ No newline at end of file diff --git a/src/main/java/io/github/npc_strider/NukeMod/client/particle/BigFookingSmokeParticle.java b/src/main/java/io/github/npc_strider/NukeMod/client/particle/BigFookingSmokeParticle.java new file mode 100644 index 0000000..689afdf --- /dev/null +++ b/src/main/java/io/github/npc_strider/NukeMod/client/particle/BigFookingSmokeParticle.java @@ -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 { + 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); + } + } +} diff --git a/src/main/java/io/github/npc_strider/NukeMod/client/particle/FissioningParticle.java b/src/main/java/io/github/npc_strider/NukeMod/client/particle/FissioningParticle.java new file mode 100644 index 0000000..74f1d71 --- /dev/null +++ b/src/main/java/io/github/npc_strider/NukeMod/client/particle/FissioningParticle.java @@ -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 { + 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); + } + } +} \ No newline at end of file diff --git a/src/main/java/io/github/npc_strider/NukeMod/constant/TransformConstants.java b/src/main/java/io/github/npc_strider/NukeMod/constant/TransformConstants.java new file mode 100644 index 0000000..e6e9a82 --- /dev/null +++ b/src/main/java/io/github/npc_strider/NukeMod/constant/TransformConstants.java @@ -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 transform = ImmutableMap.of( + // Blocks.STONE, Blocks.COBBLESTONE, + // Blocks.DIRT, Blocks.SAND, + // Blocks.GRASS_BLOCK, Blocks.SAND, + // Blocks.SAND, Blocks.GLASS + // ); + + // private static final Map 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 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> 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) ); + } + +} diff --git a/src/main/java/io/github/npc_strider/NukeMod/entity/FastExplosion.java b/src/main/java/io/github/npc_strider/NukeMod/entity/FastExplosion.java new file mode 100644 index 0000000..cf6e3a7 --- /dev/null +++ b/src/main/java/io/github/npc_strider/NukeMod/entity/FastExplosion.java @@ -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 transformMaterial = TransformConstants.transformMaterial; + private static Map> 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 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 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. + } + } +} diff --git a/src/main/java/io/github/npc_strider/NukeMod/fission/FissionBlock.java b/src/main/java/io/github/npc_strider/NukeMod/fission/FissionBlock.java new file mode 100644 index 0000000..44466b2 --- /dev/null +++ b/src/main/java/io/github/npc_strider/NukeMod/fission/FissionBlock.java @@ -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; + } +} diff --git a/src/main/java/io/github/npc_strider/NukeMod/fission/FissionEntity.java b/src/main/java/io/github/npc_strider/NukeMod/fission/FissionEntity.java new file mode 100644 index 0000000..c4274d0 --- /dev/null +++ b/src/main/java/io/github/npc_strider/NukeMod/fission/FissionEntity.java @@ -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 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 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); + } +} diff --git a/src/main/java/io/github/npc_strider/NukeMod/mixin/ClientEntityMixin.java b/src/main/java/io/github/npc_strider/NukeMod/mixin/ClientEntityMixin.java new file mode 100644 index 0000000..48c2fdf --- /dev/null +++ b/src/main/java/io/github/npc_strider/NukeMod/mixin/ClientEntityMixin.java @@ -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(); + } + } + +} \ No newline at end of file diff --git a/src/main/java/io/github/npc_strider/NukeMod/mixin/FireMixin.java b/src/main/java/io/github/npc_strider/NukeMod/mixin/FireMixin.java new file mode 100644 index 0000000..d1b11a1 --- /dev/null +++ b/src/main/java/io/github/npc_strider/NukeMod/mixin/FireMixin.java @@ -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; +// } +// } \ No newline at end of file diff --git a/src/main/java/io/github/npc_strider/NukeMod/render/entity/FissionEntityRenderer.java b/src/main/java/io/github/npc_strider/NukeMod/render/entity/FissionEntityRenderer.java new file mode 100644 index 0000000..c29ac48 --- /dev/null +++ b/src/main/java/io/github/npc_strider/NukeMod/render/entity/FissionEntityRenderer.java @@ -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 { + + 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()))); + \ No newline at end of file diff --git a/src/main/resources/NukeMod.mixins.json b/src/main/resources/NukeMod.mixins.json new file mode 100644 index 0000000..3eb4708 --- /dev/null +++ b/src/main/resources/NukeMod.mixins.json @@ -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 + } +} diff --git a/src/main/resources/assets/nuke-mod/blockstates/fission-device.json b/src/main/resources/assets/nuke-mod/blockstates/fission-device.json new file mode 100644 index 0000000..b281556 --- /dev/null +++ b/src/main/resources/assets/nuke-mod/blockstates/fission-device.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "minecraft:block/e" + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/nuke-mod/icon.png b/src/main/resources/assets/nuke-mod/icon.png new file mode 100644 index 0000000..047b91f Binary files /dev/null and b/src/main/resources/assets/nuke-mod/icon.png differ diff --git a/src/main/resources/assets/nuke-mod/particles/big-explosion-emitter.json b/src/main/resources/assets/nuke-mod/particles/big-explosion-emitter.json new file mode 100644 index 0000000..5a93fec --- /dev/null +++ b/src/main/resources/assets/nuke-mod/particles/big-explosion-emitter.json @@ -0,0 +1 @@ +{"textures" : []} \ No newline at end of file diff --git a/src/main/resources/assets/nuke-mod/particles/big-explosion.json b/src/main/resources/assets/nuke-mod/particles/big-explosion.json new file mode 100644 index 0000000..7b53ead --- /dev/null +++ b/src/main/resources/assets/nuke-mod/particles/big-explosion.json @@ -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" + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/nuke-mod/particles/big-smoke-emitter.json b/src/main/resources/assets/nuke-mod/particles/big-smoke-emitter.json new file mode 100644 index 0000000..5a93fec --- /dev/null +++ b/src/main/resources/assets/nuke-mod/particles/big-smoke-emitter.json @@ -0,0 +1 @@ +{"textures" : []} \ No newline at end of file diff --git a/src/main/resources/assets/nuke-mod/particles/big-smoke.json b/src/main/resources/assets/nuke-mod/particles/big-smoke.json new file mode 100644 index 0000000..f125834 --- /dev/null +++ b/src/main/resources/assets/nuke-mod/particles/big-smoke.json @@ -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" + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/nuke-mod/particles/fission-emission.json b/src/main/resources/assets/nuke-mod/particles/fission-emission.json new file mode 100644 index 0000000..f945bfa --- /dev/null +++ b/src/main/resources/assets/nuke-mod/particles/fission-emission.json @@ -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" + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/nuke-mod/sounds.json b/src/main/resources/assets/nuke-mod/sounds.json new file mode 100644 index 0000000..47e2af8 --- /dev/null +++ b/src/main/resources/assets/nuke-mod/sounds.json @@ -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" + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/nuke-mod/sounds/fission-alarm.ogg b/src/main/resources/assets/nuke-mod/sounds/fission-alarm.ogg new file mode 100644 index 0000000..f828859 Binary files /dev/null and b/src/main/resources/assets/nuke-mod/sounds/fission-alarm.ogg differ diff --git a/src/main/resources/assets/nuke-mod/sounds/fission-explosion.ogg b/src/main/resources/assets/nuke-mod/sounds/fission-explosion.ogg new file mode 100644 index 0000000..616bd50 Binary files /dev/null and b/src/main/resources/assets/nuke-mod/sounds/fission-explosion.ogg differ diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json new file mode 100644 index 0000000..42f6ef0 --- /dev/null +++ b/src/main/resources/fabric.mod.json @@ -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": "*" + } +}