Nauticality 0.1.0 - 1.17

Release for ModFest 1.17!
This commit is contained in:
Motschen
2021-07-03 16:59:15 +02:00
parent 20419d502b
commit 78f524ced0
76 changed files with 2047 additions and 0 deletions

25
.gitignore vendored Executable file
View File

@@ -0,0 +1,25 @@
# gradle
.gradle/
build/
out/
classes/
# idea
.idea/
*.iml
*.ipr
*.iws
# vscode
.settings/
.vscode/
bin/
.classpath
.project
# fabric
run/

21
LICENSE Executable file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2020 MidnightDust
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

0
README.md Normal file → Executable file
View File

94
build.gradle Executable file
View File

@@ -0,0 +1,94 @@
plugins {
id 'fabric-loom' version '0.8-SNAPSHOT'
id 'maven-publish'
}
sourceCompatibility = JavaVersion.VERSION_16
targetCompatibility = JavaVersion.VERSION_16
archivesBaseName = project.archives_base_name
version = project.mod_version
group = project.maven_group
minecraft {
}
repositories {
maven { url "https://maven.blamejared.com" }
maven { url "https://maven.terraformersmc.com/releases" }
flatDir {
dirs 'local_maven'
}
}
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}"
modImplementation ("com.terraformersmc:modmenu:${project.mod_menu_version}"){
exclude module: "fabric-api"
}
modImplementation "eu.midnightdust:midnightlib:${midnightlib_version}"
include "eu.midnightdust:midnightlib:${midnightlib_version}"
}
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"
// Minecraft 1.17 (21w19a) upwards uses Java 16.
it.options.release = 16
}
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
}
}
}
// See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing.
repositories {
// Add repositories to publish to here.
// Notice: This block does NOT have the same function as the block in the top level.
// The repositories here will be used for publishing your artifact, not for
// retrieving dependencies.
}
}

19
gradle.properties Executable file
View File

@@ -0,0 +1,19 @@
# Done to increase the memory available to gradle.
org.gradle.jvmargs=-Xmx2G
# Fabric Properties
# check these on https://fabricmc.net/use
minecraft_version=1.17
yarn_mappings=1.17+build.13
loader_version=0.11.6
# Mod Properties
mod_version = 0.1.0
maven_group = eu.midnightdust
archives_base_name = nauticality
# Dependencies
# currently not on the main fabric site, check on the maven: https://maven.fabricmc.net/net/fabricmc/fabric-api/fabric-api
fabric_version=0.35.2+1.17
mod_menu_version = 2.0.0-beta.7
midnightlib_version=0.2.4

BIN
gradle/wrapper/gradle-wrapper.jar vendored Executable file

Binary file not shown.

5
gradle/wrapper/gradle-wrapper.properties vendored Executable file
View File

@@ -0,0 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.1-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

185
gradlew vendored Executable file
View 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 Executable file
View 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

BIN
local_maven/midnightlib-0.2.4.jar Executable file

Binary file not shown.

10
settings.gradle Executable file
View File

@@ -0,0 +1,10 @@
pluginManagement {
repositories {
jcenter()
maven {
name = 'Fabric'
url = 'https://maven.fabricmc.net/'
}
gradlePluginPortal()
}
}

View File

@@ -0,0 +1,31 @@
package eu.midnightdust.nauticality;
import eu.midnightdust.nauticality.entity.client.model.SubmarineModel;
import eu.midnightdust.nauticality.entity.client.renderer.GlowFishRenderer;
import eu.midnightdust.nauticality.entity.client.renderer.PirateRenderer;
import eu.midnightdust.nauticality.entity.client.renderer.SubmarineRenderer;
import net.fabricmc.api.ClientModInitializer;
import net.fabricmc.fabric.api.client.rendereregistry.v1.EntityModelLayerRegistry;
import net.fabricmc.fabric.api.client.rendereregistry.v1.EntityRendererRegistry;
import net.fabricmc.fabric.api.object.builder.v1.client.model.FabricModelPredicateProviderRegistry;
import net.fabricmc.fabric.impl.blockrenderlayer.BlockRenderLayerMapImpl;
import net.fabricmc.fabric.impl.client.rendering.ColorProviderRegistryImpl;
import net.minecraft.client.color.world.BiomeColors;
import net.minecraft.client.render.RenderLayer;
import net.minecraft.util.Identifier;
@SuppressWarnings({"deprecation","UnstableApiUsage"})
public class NauticalityClient implements ClientModInitializer {
@Override
public void onInitializeClient() {
EntityRendererRegistry.INSTANCE.register(NauticalityMain.GLOW_FISH, GlowFishRenderer::new);
EntityRendererRegistry.INSTANCE.register(NauticalityMain.PIRATE, PirateRenderer::new);
EntityModelLayerRegistry.registerModelLayer(SubmarineRenderer.SUBMARINE_MODEL_LAYER, SubmarineModel::getTexturedModelData);
EntityRendererRegistry.INSTANCE.register(NauticalityMain.SUBMARINE, SubmarineRenderer::new);
BlockRenderLayerMapImpl.INSTANCE.putBlock(NauticalityMain.Algae, RenderLayer.getCutout());
BlockRenderLayerMapImpl.INSTANCE.putBlock(NauticalityMain.Cattail, RenderLayer.getCutout());
ColorProviderRegistryImpl.BLOCK.register((state, world, pos, tintIndex) -> world == null ? 0 : world.getColor(pos, BiomeColors.FOLIAGE_COLOR), NauticalityMain.Algae);
ColorProviderRegistryImpl.ITEM.register((stack, tintIndex) -> 6975545, NauticalityMain.Algae);
FabricModelPredicateProviderRegistry.register(NauticalityMain.Eyepatch.asItem(), new Identifier("right"), (stack, world, entity, seed) -> (stack.getTag() != null && stack.getTag().getBoolean("right")) ? 1 : 0);
}
}

View File

@@ -0,0 +1,81 @@
package eu.midnightdust.nauticality;
import eu.midnightdust.nauticality.block.Algae;
import eu.midnightdust.nauticality.block.Cattail;
import eu.midnightdust.nauticality.config.NauticalityConfig;
import eu.midnightdust.nauticality.entity.GlowFishEntity;
import eu.midnightdust.nauticality.entity.PirateEntity;
import eu.midnightdust.nauticality.entity.SubmarineEntity;
import eu.midnightdust.nauticality.item.SubmarineItem;
import eu.midnightdust.nauticality.world.NauticalityConfiguredFeatures;
import eu.midnightdust.nauticality.world.feature.FeatureInjector;
import eu.midnightdust.nauticality.world.NauticalityStructures;
import eu.midnightdust.nauticality.world.structure.PirateShipStructure;
import net.fabricmc.api.ModInitializer;
import net.fabricmc.fabric.api.biome.v1.BiomeModifications;
import net.fabricmc.fabric.api.biome.v1.BiomeSelectors;
import net.fabricmc.fabric.api.client.itemgroup.FabricItemGroupBuilder;
import net.fabricmc.fabric.api.item.v1.FabricItemSettings;
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
import net.fabricmc.fabric.api.object.builder.v1.entity.FabricDefaultAttributeRegistry;
import net.fabricmc.fabric.api.object.builder.v1.entity.FabricEntityTypeBuilder;
import net.minecraft.block.Block;
import net.minecraft.block.MapColor;
import net.minecraft.block.Material;
import net.minecraft.entity.EntityDimensions;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.SpawnGroup;
import net.minecraft.entity.attribute.EntityAttributes;
import net.minecraft.entity.mob.MobEntity;
import net.minecraft.fluid.Fluids;
import net.minecraft.item.*;
import net.minecraft.sound.BlockSoundGroup;
import net.minecraft.sound.SoundEvents;
import net.minecraft.util.Identifier;
import net.minecraft.util.registry.Registry;
import net.minecraft.world.biome.Biome;
public class NauticalityMain implements ModInitializer {
public static final String MOD_ID = "nauticality";
public static final ItemGroup NauticalityGroup = FabricItemGroupBuilder.build(new Identifier(MOD_ID, "main"), () -> new ItemStack(NauticalityMain.SubmarineItem));
public static final EntityType<GlowFishEntity> GLOW_FISH = Registry.register(Registry.ENTITY_TYPE,
new Identifier(MOD_ID,"glow_fish"), FabricEntityTypeBuilder.create(SpawnGroup.WATER_AMBIENT, GlowFishEntity::new)
.dimensions(EntityDimensions.fixed(0.5F, 0.3F)).trackRangeBlocks(4).build());
public static final EntityType<PirateEntity> PIRATE = Registry.register(Registry.ENTITY_TYPE,
new Identifier(MOD_ID,"pirate"), FabricEntityTypeBuilder.create(SpawnGroup.MONSTER, PirateEntity::new).spawnableFarFromPlayer()
.dimensions(EntityDimensions.fixed(0.6F, 1.95F)).trackRangeBlocks(8).build());
public static final EntityType<SubmarineEntity> SUBMARINE = Registry.register(Registry.ENTITY_TYPE,
new Identifier(MOD_ID,"submarine"), FabricEntityTypeBuilder.create(SpawnGroup.MISC, SubmarineEntity::new)//(a,b) -> new SubmarineEntity(a,b))
.dimensions(EntityDimensions.fixed(1.6F, 1.6F)).trackRangeBlocks(1).build());
public static Item GLOW_FISH_BUCKET;
public static Item Eyepatch;
public static Item SubmarineItem;
public static Block Algae = new Algae(FabricBlockSettings.of(Material.ORGANIC_PRODUCT, MapColor.DARK_GREEN).noCollision().sounds(BlockSoundGroup.AZALEA_LEAVES));
public static Block Cattail = new Cattail(FabricBlockSettings.of(Material.ORGANIC_PRODUCT, MapColor.BROWN).sounds(BlockSoundGroup.WET_GRASS).noCollision());
@Override
public void onInitialize() {
NauticalityConfig.init("nauticality", NauticalityConfig.class);
// Items
Eyepatch = Registry.register(Registry.ITEM, new Identifier(MOD_ID,"eyepatch"), new Item(new FabricItemSettings().group(NauticalityGroup)));
// Entities
GLOW_FISH_BUCKET = Registry.register(Registry.ITEM, new Identifier(MOD_ID,"glow_fish_bucket"), new EntityBucketItem(GLOW_FISH, Fluids.WATER, SoundEvents.ITEM_BUCKET_EMPTY_FISH, (new Item.Settings()).maxCount(1).group(NauticalityGroup)));
Registry.register(Registry.ITEM, new Identifier(MOD_ID,"glow_fish_spawn_egg"), new SpawnEggItem(GLOW_FISH,63246,63425, new FabricItemSettings().group(NauticalityGroup)));
FabricDefaultAttributeRegistry.register(GLOW_FISH, MobEntity.createMobAttributes().add(EntityAttributes.GENERIC_MAX_HEALTH, 8.0D));
Registry.register(Registry.ITEM, new Identifier(MOD_ID,"pirate_spawn_egg"), new SpawnEggItem(PIRATE,78657,24561, new FabricItemSettings().group(NauticalityGroup)));
FabricDefaultAttributeRegistry.register(PIRATE, MobEntity.createMobAttributes().add(EntityAttributes.GENERIC_MOVEMENT_SPEED, 0.25).add(EntityAttributes.GENERIC_ATTACK_DAMAGE,4).add(EntityAttributes.GENERIC_ATTACK_SPEED,1.5).add(EntityAttributes.GENERIC_ATTACK_KNOCKBACK,2));
SubmarineItem = Registry.register(Registry.ITEM, new Identifier(MOD_ID,"submarine"), new SubmarineItem(new FabricItemSettings().group(NauticalityGroup)));
// Blocks
Registry.register(Registry.BLOCK, new Identifier(MOD_ID, "algae"), Algae);
Registry.register(Registry.ITEM, new Identifier(MOD_ID,"algae"), new BlockItem(Algae, new FabricItemSettings().group(NauticalityGroup)));
Registry.register(Registry.BLOCK, new Identifier(MOD_ID, "cattail"), Cattail);
Registry.register(Registry.ITEM, new Identifier(MOD_ID,"cattail"), new BlockItem(Cattail, new FabricItemSettings().group(NauticalityGroup)));
PirateShipStructure.init();
NauticalityStructures.init();
NauticalityConfiguredFeatures.init();
FeatureInjector.init();
BiomeModifications.addSpawn(BiomeSelectors.categories(Biome.Category.OCEAN).and(BiomeSelectors.spawnsOneOf(EntityType.TROPICAL_FISH)),SpawnGroup.WATER_AMBIENT, GLOW_FISH, 6, 3, 10);
}
}

View File

@@ -0,0 +1,53 @@
package eu.midnightdust.nauticality.block;
import net.minecraft.block.*;
import net.minecraft.entity.Entity;
import net.minecraft.entity.vehicle.BoatEntity;
import net.minecraft.fluid.FluidState;
import net.minecraft.fluid.Fluids;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.state.StateManager;
import net.minecraft.state.property.BooleanProperty;
import net.minecraft.state.property.Properties;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.util.shape.VoxelShape;
import net.minecraft.world.BlockView;
import net.minecraft.world.World;
public class Algae extends PlantBlock implements Waterloggable {
protected static final VoxelShape SHAPE = Block.createCuboidShape(0.0D, -0.2D, 0.0D, 16.0D, 0.3D, 16.0D);
public static final BooleanProperty WATERLOGGED = Properties.WATERLOGGED;
public Algae(Settings settings) {
super(settings);
this.setDefaultState(this.getDefaultState().with(WATERLOGGED,false));
}
@Override
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
builder.add(WATERLOGGED);
}
@Override
public void onEntityCollision(BlockState state, World world, BlockPos pos, Entity entity) {
if (entity.isTouchingWater() && !(entity instanceof BoatEntity) && entity.getY() <= pos.getY() + 0.1f) {
entity.slowMovement(state, new Vec3d(2, 2, 2));
}
if (world instanceof ServerWorld && entity instanceof BoatEntity) {
world.breakBlock(new BlockPos(pos), false, entity);
}
}
@Override
public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
return SHAPE;
}
@Override
protected boolean canPlantOnTop(BlockState floor, BlockView world, BlockPos pos) {
FluidState fluidState = world.getFluidState(pos);
FluidState fluidState2 = world.getFluidState(pos.up());
return fluidState.getFluid() == Fluids.WATER || fluidState2.getFluid() == Fluids.WATER;
}
@Override
public FluidState getFluidState(BlockState state) {
return state.get(WATERLOGGED) ? Fluids.WATER.getStill(false) : super.getFluidState(state);
}
}

View File

@@ -0,0 +1,57 @@
package eu.midnightdust.nauticality.block;
import eu.midnightdust.nauticality.NauticalityMain;
import net.minecraft.block.BlockState;
import net.minecraft.block.TallPlantBlock;
import net.minecraft.block.enums.DoubleBlockHalf;
import net.minecraft.fluid.FluidState;
import net.minecraft.fluid.Fluids;
import net.minecraft.item.ItemPlacementContext;
import net.minecraft.item.ItemStack;
import net.minecraft.tag.FluidTags;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.BlockView;
import net.minecraft.world.WorldView;
import org.jetbrains.annotations.Nullable;
public class Cattail extends TallPlantBlock {
public Cattail(Settings settings) {
super(settings);
}
@Override
public ItemStack getPickStack(BlockView world, BlockPos pos, BlockState state) {
return new ItemStack(NauticalityMain.Cattail);
}
@Override
public FluidState getFluidState(BlockState state) {
if (state.get(HALF) == DoubleBlockHalf.LOWER) {
return Fluids.WATER.getStill(false);
}
return Fluids.EMPTY.getDefaultState();
}
@Override
public boolean canPlaceAt(BlockState state, WorldView world, BlockPos pos) {
if (state.get(HALF) == DoubleBlockHalf.UPPER) {
BlockState lowerBlockState = world.getBlockState(pos.down());
return lowerBlockState.isOf(this) && lowerBlockState.get(HALF) == DoubleBlockHalf.LOWER && world.getFluidState(pos).isEmpty();
} else {
FluidState fluidState = world.getFluidState(pos);
FluidState upperFluidState = world.getFluidState(pos.up());
return fluidState.isIn(FluidTags.WATER) && fluidState.getLevel() == 8 && upperFluidState.isEmpty();
}
}
@Override
@Nullable
public BlockState getPlacementState(ItemPlacementContext ctx) {
BlockState blockState = super.getPlacementState(ctx);
if (blockState != null) {
FluidState fluidState = ctx.getWorld().getFluidState(ctx.getBlockPos());
if (fluidState.isIn(FluidTags.WATER) && fluidState.getLevel() == 8) {
return blockState;
}
}
return blockState;
}
}

View File

@@ -0,0 +1,10 @@
package eu.midnightdust.nauticality.config;
import eu.midnightdust.lib.config.MidnightConfig;
public class NauticalityConfig extends MidnightConfig {
@Entry public static int pirateShipRate = 1;
@Entry public static int algaeRate = 4;
@Entry public static int underwaterAlgaeRate = 15;
@Entry public static int cattailRate = 20;
}

View File

@@ -0,0 +1,27 @@
package eu.midnightdust.nauticality.entity;
import eu.midnightdust.nauticality.NauticalityMain;
import net.minecraft.entity.Bucketable;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.passive.FishEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.sound.SoundEvent;
import net.minecraft.sound.SoundEvents;
import net.minecraft.world.World;
public class GlowFishEntity extends FishEntity implements Bucketable {
public GlowFishEntity(EntityType<? extends FishEntity> entityType, World world) {
super(entityType, world);
}
@Override
protected SoundEvent getFlopSound() {
return SoundEvents.ENTITY_TROPICAL_FISH_FLOP;
}
@Override
public ItemStack getBucketItem() {
return new ItemStack(NauticalityMain.GLOW_FISH_BUCKET);
}
}

View File

@@ -0,0 +1,65 @@
package eu.midnightdust.nauticality.entity;
import eu.midnightdust.nauticality.NauticalityMain;
import net.minecraft.entity.*;
import net.minecraft.entity.ai.goal.MeleeAttackGoal;
import net.minecraft.entity.attribute.EntityAttributeModifier;
import net.minecraft.entity.attribute.EntityAttributes;
import net.minecraft.entity.mob.PillagerEntity;
import net.minecraft.entity.mob.RavagerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.world.LocalDifficulty;
import net.minecraft.world.ServerWorldAccess;
import net.minecraft.world.World;
import org.jetbrains.annotations.Nullable;
import java.util.Random;
public class PirateEntity extends PillagerEntity {
public PirateEntity(EntityType<? extends PillagerEntity> entityType, World world) {
super(entityType, world);
}
@Override
protected void initGoals() {
super.initGoals();
this.goalSelector.add(4, new AttackGoal(this));
}
@Override
protected void initEquipment(LocalDifficulty difficulty) {
this.equipStack(EquipmentSlot.MAINHAND, new ItemStack(Items.IRON_SWORD));
this.equipStack(EquipmentSlot.OFFHAND, new ItemStack(Items.SPYGLASS));
ItemStack eyepatch = new ItemStack(NauticalityMain.Eyepatch);
if (new Random().nextBoolean()) {
eyepatch.getOrCreateTag().putBoolean("right", true);
}
this.equipStack(EquipmentSlot.HEAD, eyepatch);
}
@Override
@Nullable
public EntityData initialize(ServerWorldAccess world, LocalDifficulty difficulty, SpawnReason spawnReason, @Nullable EntityData entityData, @Nullable NbtCompound entityNbt) {
this.getAttributeInstance(EntityAttributes.GENERIC_FOLLOW_RANGE).addPersistentModifier(new EntityAttributeModifier("Random spawn bonus", this.random.nextGaussian() * 0.05D, EntityAttributeModifier.Operation.MULTIPLY_BASE));
this.setLeftHanded(this.random.nextFloat() < 0.05F);
this.initEquipment(difficulty);
return entityData;
}
static class AttackGoal extends MeleeAttackGoal {
public AttackGoal(PirateEntity pirate) {
super(pirate, 1.0D, false);
}
protected double getSquaredMaxAttackDistance(LivingEntity entity) {
if (this.mob.getVehicle() instanceof RavagerEntity) {
float f = this.mob.getVehicle().getWidth() - 0.1F;
return f * 2.0F * f * 2.0F + entity.getWidth();
} else {
return super.getSquaredMaxAttackDistance(entity);
}
}
}
}

View File

@@ -0,0 +1,84 @@
package eu.midnightdust.nauticality.entity;
import eu.midnightdust.nauticality.NauticalityMain;
import eu.midnightdust.nauticality.mixin.BoatEntityAccessor;
import net.minecraft.block.BlockState;
import net.minecraft.entity.*;
import net.minecraft.entity.effect.StatusEffectInstance;
import net.minecraft.entity.effect.StatusEffects;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.vehicle.BoatEntity;
import net.minecraft.item.Item;
import net.minecraft.sound.SoundEvents;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Hand;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
public class SubmarineEntity extends BoatEntity {
public boolean pressingForward;
public float prevRoll = 0;
public float rotorAngle;
public SubmarineEntity(EntityType<? extends BoatEntity> entityType, World world) {
super(entityType, world);
this.stepHeight = 1.0F;
}
@Override
public Item asItem() {
return NauticalityMain.SubmarineItem;
}
@Override
protected void playStepSound(BlockPos pos, BlockState state) {
this.playSound(SoundEvents.ENTITY_PIG_STEP, 0.15F, 1.0F);
}
@Override
public void tick() {
super.tick();
((BoatEntityAccessor)this).setTicksUnderwater(0);
updateVelocity();
this.move(MovementType.SELF, this.getVelocity());
if (this.getFirstPassenger() != null && this.pressingForward) {
Entity passenger = this.getFirstPassenger();
this.setPitch(passenger.getPitch() * 0.5F);
}
}
@Override
public boolean hasNoGravity() {
return true;
}
@Override
public ActionResult interact(PlayerEntity player, Hand hand) {
return player.startRiding(this) ? ActionResult.CONSUME : ActionResult.PASS;
}
@Override
protected boolean canAddPassenger(Entity passenger) {
return this.getPassengerList().size() < 2;
}
@Override
public void updatePassengerPosition(Entity passenger) {
super.updatePassengerPosition(passenger);
if (this.hasPassenger(passenger)) {
if (passenger instanceof LivingEntity livingEntity) {
livingEntity.addStatusEffect(new StatusEffectInstance(StatusEffects.NIGHT_VISION,2,1,true,false,false));
}
}
}
public void setInputs(boolean pressingLeft, boolean pressingRight, boolean pressingForward, boolean pressingBack) {
super.setInputs(pressingLeft,pressingRight,pressingForward,pressingBack);
this.pressingForward = pressingForward;
}
private void updateVelocity() {
Vec3d vec3d = this.getVelocity();
if (((BoatEntityAccessor)this).getLocation() == BoatEntity.Location.UNDER_WATER && this.getFirstPassenger() != null && this.pressingForward)
this.setVelocity(vec3d.x * 1.5, vec3d.y - (this.getPitch()) * 0.001, vec3d.z * 1.5);
Vec3d velocity = this.getVelocity();
if (touchingWater) this.setVelocity(velocity.x, velocity.y, velocity.z);
else this.setVelocity(velocity.x * 0.4, -0.75, velocity.z * 0.4);
}
public boolean isSubmergedInWater() {
return false;
}
}

View File

@@ -0,0 +1,93 @@
// Made with Model Converter by Globox_Z
// Generate all required imports
// Made with Blockbench 3.8.4
// Exported for Minecraft version 1.15
// Paste this class into your mod and generate all required imports
package eu.midnightdust.nauticality.entity.client.model;
import eu.midnightdust.nauticality.entity.SubmarineEntity;
import net.minecraft.client.model.*;
import net.minecraft.client.render.VertexConsumer;
import net.minecraft.client.render.entity.model.EntityModel;
import net.minecraft.client.util.math.MatrixStack;
public class SubmarineModel extends EntityModel<SubmarineEntity> {
private final ModelPart base;
private final ModelPart cube_r1;
private final ModelPart cube_r2;
private final ModelPart door;
private final ModelPart front;
private final ModelPart cube_r3;
private final ModelPart cube_r4;
private final ModelPart cube_r5;
private final ModelPart cube_r6;
private final ModelPart cube_r7;
private final ModelPart back;
private final ModelPart rotor;
private final ModelPart interior;
private final ModelPart light;
public SubmarineModel(ModelPart root) {
this.base = root.getChild("base");
this.door = this.base.getChild("door");
this.cube_r2 = this.base.getChild("cube_r2");
this.cube_r1 = this.base.getChild("cube_r1");
this.front = root.getChild("front");
this.cube_r7 = this.front.getChild("cube_r7");
this.cube_r6 = this.front.getChild("cube_r6");
this.cube_r5 = this.front.getChild("cube_r5");
this.cube_r4 = this.front.getChild("cube_r4");
this.cube_r3 = this.front.getChild("cube_r3");
this.back = root.getChild("back");
this.rotor = root.getChild("rotor");
this.interior = root.getChild("interior");
this.light = root.getChild("light");
setRotationAngle(cube_r1, 0.0F, -0.6545F, 0.0F);
setRotationAngle(cube_r2, 0.0F, 0.6545F, 0.0F);
setRotationAngle(cube_r3, 0.3491F, 0.6545F, 0.0F);
setRotationAngle(cube_r4, 0.3491F, -0.6545F, 0.0F);
setRotationAngle(cube_r5, 0.3491F, 0.0F, 0.0F);
setRotationAngle(cube_r6, 0.0F, -0.6545F, 0.0F);
setRotationAngle(cube_r7, 0.0F, 0.6545F, 0.0F);
}
public static TexturedModelData getTexturedModelData() {
ModelData modelData = new ModelData();
ModelPartData modelPartData = modelData.getRoot();
ModelPartData modelPartData1 = modelPartData.addChild("base", ModelPartBuilder.create().uv(0,0).cuboid(-12.0F, -1.0F, -15.0F, 24.0F, 1.0F, 30.0F).uv(78,81).cuboid(-4.0F, -1.0F, -21.0F, 8.0F, 1.0F, 6.0F).uv(0,59).cuboid(-12.0F, -23.0F, -12.0F, 1.0F, 22.0F, 27.0F).uv(56,91).cuboid(-12.0F, -22.0F, -15.0F, 1.0F, 21.0F, 3.0F).uv(18,0).cuboid(11.0F, -22.0F, -15.0F, 1.0F, 21.0F, 3.0F).uv(0,0).cuboid(11.0F, -23.0F, -12.0F, 1.0F, 22.0F, 8.0F).uv(78,7).cuboid(11.0F, -23.0F, -4.0F, 1.0F, 8.0F, 9.0F).uv(56,59).cuboid(11.0F, -23.0F, 5.0F, 1.0F, 22.0F, 10.0F).uv(0,31).cuboid(-12.0F, -24.0F, -12.0F, 24.0F, 1.0F, 27.0F).uv(78,24).cuboid(-6.0F, -24.0F, -15.0F, 12.0F, 1.0F, 3.0F).uv(29,59).cuboid(6.0F, -24.0F, -14.0F, 2.0F, 1.0F, 2.0F).uv(10,4).cuboid(-8.0F, -24.0F, -14.0F, 2.0F, 1.0F, 2.0F), ModelTransform.pivot(0.0F,24.0F,0.0F));
modelPartData1.addChild("cube_r1", ModelPartBuilder.create().uv(78,67).cuboid(-9.5F, -0.995F, -19.0F, 9.0F, 1.0F, 6.0F), ModelTransform.pivot(0.0F,0.0F,0.0F));
modelPartData1.addChild("cube_r2", ModelPartBuilder.create().uv(78,74).cuboid(0.5F, -0.995F, -19.0F, 9.0F, 1.0F, 6.0F), ModelTransform.pivot(0.0F,0.0F,0.0F));
modelPartData1.addChild("door", ModelPartBuilder.create().uv(29,59).cuboid(11.5F, -15.0F, -4.0F, 1.0F, 14.0F, 9.0F).uv(15,0).cuboid(12.0F, -9.0F, -3.0F, 1.0F, 1.0F, 1.0F), ModelTransform.pivot(0.0F,0.0F,0.0F));
ModelPartData modelPartData2 = modelPartData.addChild("front", ModelPartBuilder.create().uv(75,34).cuboid(-4.0F, -21.99F, -21.1F, 8.0F, 22.0F, 1.0F).uv(22,31).cuboid(-4.5F, -22.0F, -21.17F, 1.0F, 22.0F, 1.0F).uv(26,0).cuboid(3.5F, -22.0F, -21.17F, 1.0F, 22.0F, 1.0F), ModelTransform.pivot(0.0F,24.0F,0.0F));
modelPartData2.addChild("cube_r3", ModelPartBuilder.create().uv(18,24).cuboid(3.0F, -1.0F, -3.0F, 1.0F, 1.0F, 1.0F).uv(10,0).cuboid(2.0F, -1.0F, -3.0F, 1.0F, 1.0F, 3.0F).uv(0,0).cuboid(-7.0F, -1.0F, 0.0F, 1.0F, 1.0F, 3.0F).uv(96,99).cuboid(-6.0F, -1.0F, -2.0F, 1.0F, 1.0F, 5.0F).uv(40,59).cuboid(-5.0F, -1.0F, -3.0F, 7.0F, 1.0F, 6.0F), ModelTransform.pivot(-6.0F,-22.0F,-15.0F));
modelPartData2.addChild("cube_r4", ModelPartBuilder.create().uv(0,4).cuboid(-5.0F, -1.0F, -3.0F, 1.0F, 1.0F, 3.0F).uv(18,24).cuboid(4.0F, -1.0F, -2.0F, 1.0F, 1.0F, 5.0F).uv(87,51).cuboid(-4.0F, -1.0F, -3.0F, 8.0F, 1.0F, 6.0F), ModelTransform.pivot(7.0F,-22.0F,-14.0F));
modelPartData2.addChild("cube_r5", ModelPartBuilder.create().uv(78,0).cuboid(-5.0F, -1.0F, -3.0F, 10.0F, 1.0F, 6.0F), ModelTransform.pivot(0.0F,-22.0F,-17.0F));
modelPartData2.addChild("cube_r6", ModelPartBuilder.create().uv(0,31).cuboid(-10.0F, -21.99F, -19.0F, 10.0F, 22.0F, 1.0F), ModelTransform.pivot(0.5F,0.0F,0.0F));
modelPartData2.addChild("cube_r7", ModelPartBuilder.create().uv(0,59).cuboid(0.0F, -21.99F, -19.0F, 10.0F, 22.0F, 1.0F), ModelTransform.pivot(-0.5F,0.0F,0.0F));
modelPartData.addChild("back", ModelPartBuilder.create().uv(70,91).cuboid(9.0F, -23.0F, 15.0F, 2.0F, 22.0F, 1.0F).uv(64,91).cuboid(-11.0F, -23.0F, 15.0F, 2.0F, 22.0F, 1.0F).uv(75,31).cuboid(-9.0F, -3.0F, 15.0F, 18.0F, 2.0F, 1.0F).uv(68,64).cuboid(-9.0F, -23.0F, 15.0F, 18.0F, 2.0F, 1.0F).uv(76,96).cuboid(-9.0F, -21.0F, 16.0F, 2.0F, 18.0F, 1.0F).uv(49,66).cuboid(7.0F, -21.0F, 16.0F, 2.0F, 18.0F, 1.0F).uv(89,7).cuboid(-7.0F, -5.0F, 16.0F, 14.0F, 2.0F, 1.0F).uv(78,88).cuboid(-7.0F, -21.0F, 16.0F, 14.0F, 2.0F, 1.0F).uv(92,99).cuboid(6.0F, -19.0F, 17.0F, 1.0F, 14.0F, 1.0F).uv(22,59).cuboid(-7.0F, -19.0F, 17.0F, 1.0F, 14.0F, 1.0F).uv(0,56).cuboid(-6.0F, -6.0F, 17.0F, 12.0F, 1.0F, 1.0F).uv(0,54).cuboid(-6.0F, -19.0F, 17.0F, 12.0F, 1.0F, 1.0F).uv(100,105).cuboid(-6.0F, -18.0F, 18.0F, 1.0F, 12.0F, 1.0F).uv(96,105).cuboid(5.0F, -18.0F, 18.0F, 1.0F, 12.0F, 1.0F).uv(0,82).cuboid(-5.0F, -7.0F, 18.0F, 10.0F, 1.0F, 1.0F).uv(78,28).cuboid(-5.0F, -18.0F, 18.0F, 10.0F, 1.0F, 1.0F).uv(82,107).cuboid(-5.0F, -17.0F, 19.0F, 1.0F, 10.0F, 1.0F).uv(22,74).cuboid(4.0F, -17.0F, 19.0F, 1.0F, 10.0F, 1.0F).uv(0,84).cuboid(-4.0F, -8.0F, 19.0F, 8.0F, 1.0F, 1.0F).uv(29,82).cuboid(-4.0F, -17.0F, 19.0F, 8.0F, 1.0F, 1.0F).uv(104,105).cuboid(-4.0F, -16.0F, 20.0F, 1.0F, 8.0F, 2.0F).uv(93,48).cuboid(-3.0F, -9.0F, 20.0F, 6.0F, 1.0F, 2.0F).uv(93,45).cuboid(-3.0F, -16.0F, 20.0F, 6.0F, 1.0F, 2.0F).uv(103,34).cuboid(3.0F, -16.0F, 20.0F, 1.0F, 8.0F, 2.0F).uv(98,15).cuboid(-3.0F, -15.0F, 22.0F, 6.0F, 6.0F, 1.0F).uv(92,91).cuboid(-1.0F, -13.0F, 23.0F, 2.0F, 2.0F, 6.0F), ModelTransform.pivot(0.0F,24.0F,0.0F));
modelPartData.addChild("rotor", ModelPartBuilder.create().uv(82,96).cuboid(-1.0F, 1.0F, -2.0F, 1.0F, 7.0F, 4.0F).uv(93,34).cuboid(0.0F, -8.0F, -2.0F, 1.0F, 7.0F, 4.0F).uv(76,91).cuboid(1.0F, 0.0F, -2.0F, 7.0F, 1.0F, 4.0F).uv(89,10).cuboid(-8.0F, -1.0F, -2.0F, 7.0F, 1.0F, 4.0F), ModelTransform.pivot(0.0F,12.0F,26.0F));
modelPartData.addChild("interior", ModelPartBuilder.create().uv(68,59).cuboid(-11.0F, -5.0F, -16.0F, 22.0F, 4.0F, 1.0F), ModelTransform.pivot(0.0F,24.0F,0.0F));
modelPartData.addChild("light", ModelPartBuilder.create().uv(0,119).cuboid(-2.0F, -27.01F, -19.0F, 4.0F, 4.0F, 5.0F), ModelTransform.pivot(0.0F,24.0F,0.0F));
return TexturedModelData.of(modelData,128,128);
}
@Override
public void setAngles(SubmarineEntity entity, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch){
if (entity.isTouchingWater()) entity.rotorAngle = entity.rotorAngle + 0.1f;
rotor.setAngles(0,0,entity.rotorAngle);
}
@Override
public void render(MatrixStack matrixStack, VertexConsumer buffer, int packedLight, int packedOverlay, float red, float green, float blue, float alpha){
base.render(matrixStack, buffer, packedLight, packedOverlay);
front.render(matrixStack, buffer, packedLight, packedOverlay);
back.render(matrixStack, buffer, packedLight, packedOverlay);
interior.render(matrixStack, buffer, packedLight, packedOverlay);
rotor.render(matrixStack, buffer, packedLight, packedOverlay);
light.render(matrixStack, buffer, packedLight, packedOverlay);
}
public static void setRotationAngle(ModelPart bone, float x, float y, float z) {
bone.pitch = x;
bone.yaw = y;
bone.roll = z;
}
}

View File

@@ -0,0 +1,20 @@
package eu.midnightdust.nauticality.entity.client.renderer;
import net.minecraft.client.render.RenderLayer;
import net.minecraft.client.render.entity.feature.EyesFeatureRenderer;
import net.minecraft.client.render.entity.feature.FeatureRendererContext;
import net.minecraft.client.render.entity.model.EntityModel;
import net.minecraft.entity.LivingEntity;
import net.minecraft.util.Identifier;
public class EmissiveOverlayRenderer<T extends LivingEntity> extends EyesFeatureRenderer<T, EntityModel<T>> {
private final RenderLayer SKIN;
public EmissiveOverlayRenderer(FeatureRendererContext<T, EntityModel<T>> featureRendererContext, Identifier texture) {
super(featureRendererContext);
SKIN = RenderLayer.getEyes(texture);
}
public RenderLayer getEyesTexture() {
return SKIN;
}
}

View File

@@ -0,0 +1,26 @@
package eu.midnightdust.nauticality.entity.client.renderer;
import eu.midnightdust.nauticality.entity.GlowFishEntity;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.render.entity.EntityRendererFactory;
import net.minecraft.client.render.entity.MobEntityRenderer;
import net.minecraft.client.render.entity.model.CodEntityModel;
import net.minecraft.client.render.entity.model.EntityModelLayers;
import net.minecraft.util.Identifier;
import static eu.midnightdust.nauticality.NauticalityMain.MOD_ID;
@Environment(EnvType.CLIENT)
public class GlowFishRenderer extends MobEntityRenderer<GlowFishEntity, CodEntityModel<GlowFishEntity>> {
public GlowFishRenderer(EntityRendererFactory.Context context) {
super(context, new CodEntityModel<>(context.getPart(EntityModelLayers.COD)), 0.5F);
this.addFeature(new EmissiveOverlayRenderer(this, new Identifier(MOD_ID,"textures/entity/glow_fish/glow_fish_emissive_layer.png")));
}
@Override
public Identifier getTexture(GlowFishEntity entity) {
return new Identifier("nauticality","textures/entity/glow_fish/glow_fish.png");
}
}

View File

@@ -0,0 +1,27 @@
package eu.midnightdust.nauticality.entity.client.renderer;
import eu.midnightdust.nauticality.entity.PirateEntity;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.render.entity.*;
import net.minecraft.client.render.entity.feature.HeldItemFeatureRenderer;
import net.minecraft.client.render.entity.model.EntityModelLayers;
import net.minecraft.client.render.entity.model.IllagerEntityModel;
import net.minecraft.util.Identifier;
import static eu.midnightdust.nauticality.NauticalityMain.MOD_ID;
@Environment(EnvType.CLIENT)
public class PirateRenderer extends IllagerEntityRenderer<PirateEntity> {
private static final Identifier TEXTURE = new Identifier(MOD_ID,"textures/entity/illager/pirate.png");
public PirateRenderer(EntityRendererFactory.Context context) {
super(context, new IllagerEntityModel<>(context.getPart(EntityModelLayers.PILLAGER)), 0.5F);
this.addFeature(new HeldItemFeatureRenderer<>(this));
}
@Override
public Identifier getTexture(PirateEntity pillagerEntity) {
return TEXTURE;
}
}

View File

@@ -0,0 +1,60 @@
package eu.midnightdust.nauticality.entity.client.renderer;
import eu.midnightdust.nauticality.entity.SubmarineEntity;
import eu.midnightdust.nauticality.entity.client.model.SubmarineModel;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.render.RenderLayer;
import net.minecraft.client.render.VertexConsumerProvider;
import net.minecraft.client.render.entity.EntityRenderer;
import net.minecraft.client.render.entity.EntityRendererFactory;
import net.minecraft.client.render.entity.feature.FeatureRendererContext;
import net.minecraft.client.render.entity.model.EntityModelLayer;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.entity.Entity;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.Vec3f;
import static eu.midnightdust.nauticality.NauticalityMain.MOD_ID;
@Environment(EnvType.CLIENT)
public class SubmarineRenderer extends EntityRenderer<SubmarineEntity> implements FeatureRendererContext<SubmarineEntity, SubmarineModel> {
public static final EntityModelLayer SUBMARINE_MODEL_LAYER = new EntityModelLayer(new Identifier("nauticality","entity"), "submarine");
private static EmissiveOverlayRenderer overlay;
private final SubmarineModel model;
public SubmarineRenderer(EntityRendererFactory.Context ctx) {
super(ctx);
model = new SubmarineModel(ctx.getPart(SUBMARINE_MODEL_LAYER));
overlay = new EmissiveOverlayRenderer(this, new Identifier(MOD_ID,"textures/entity/submarine/submarine_emissive_layer.png"));
}
public void render(SubmarineEntity entity, float yaw, float tickDelta, MatrixStack matrixStack, VertexConsumerProvider vertexConsumers, int light) {
super.render(entity, yaw, tickDelta, matrixStack, vertexConsumers, light);
float pitch = entity.getPitch();
Entity passenger = entity.getFirstPassenger();
if (passenger != null) pitch = passenger.getPitch() * 0.5F;
matrixStack.push();
matrixStack.multiply(Vec3f.POSITIVE_Y.getDegreesQuaternion(180F - yaw));
matrixStack.multiply(Vec3f.POSITIVE_Y.getDegreesQuaternion(180F));
matrixStack.multiply(Vec3f.POSITIVE_Z.getDegreesQuaternion((yaw - entity.prevRoll)*8));
entity.prevRoll = yaw;
matrixStack.multiply(Vec3f.POSITIVE_X.getDegreesQuaternion(180.0F + pitch));
matrixStack.translate(0.0D , -1.75D, -0.5D + (90 + entity.getPitch()) * 0.01f);
matrixStack.scale(1.2f,1.2f,1.2f);
model.setAngles(entity,tickDelta,0,0,yaw,entity.getPitch());
model.render(matrixStack, vertexConsumers.getBuffer(RenderLayer.getEntityCutout(getTexture(entity))), light, 1,1f,1f,1f,1f);
overlay.render(matrixStack,vertexConsumers,light,entity,yaw,0f,tickDelta,0f,yaw,entity.getPitch());
matrixStack.pop();
}
@Override
public SubmarineModel getModel() {
return model;
}
@Override
public Identifier getTexture(SubmarineEntity entity) {
return new Identifier(MOD_ID, "textures/entity/submarine/submarine.png");
}
}

View File

@@ -0,0 +1,112 @@
package eu.midnightdust.nauticality.item;
import eu.midnightdust.nauticality.NauticalityMain;
import eu.midnightdust.nauticality.entity.SubmarineEntity;
import net.minecraft.block.FluidBlock;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.SpawnReason;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.item.SpawnEggItem;
import net.minecraft.predicate.entity.EntityPredicates;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.stat.Stats;
import net.minecraft.util.Hand;
import net.minecraft.util.TypedActionResult;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.hit.HitResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Box;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.RaycastContext;
import net.minecraft.world.World;
import net.minecraft.world.event.GameEvent;
import java.util.List;
import java.util.function.Predicate;
public class SubmarineItem extends Item {
private static final Predicate<Entity> RIDERS;
public SubmarineItem(Settings settings) {
super(settings);
}
public TypedActionResult<ItemStack> use(World world, PlayerEntity user, Hand hand) {
ItemStack itemStack = user.getStackInHand(hand);
HitResult hitResult = raycast(world, user, RaycastContext.FluidHandling.SOURCE_ONLY);
if (hitResult.getType() != HitResult.Type.BLOCK) {
return TypedActionResult.pass(itemStack);
} else if (!(world instanceof ServerWorld)) {
return TypedActionResult.success(itemStack);
} else {
BlockHitResult blockHitResult = (BlockHitResult)hitResult;
BlockPos blockPos = blockHitResult.getBlockPos();
if (!(world.getBlockState(blockPos).getBlock() instanceof FluidBlock)) {
return TypedActionResult.pass(itemStack);
} else if (world.canPlayerModifyAt(user, blockPos) && user.canPlaceOn(blockPos, blockHitResult.getSide(), itemStack)) {
SubmarineEntity boatEntity = new SubmarineEntity(NauticalityMain.SUBMARINE, world);
boatEntity.setPosition(hitResult.getPos().x, hitResult.getPos().y, hitResult.getPos().z);
boatEntity.setYaw(user.getYaw());
world.spawnEntity(boatEntity);
world.emitGameEvent(user, GameEvent.ENTITY_PLACE, new BlockPos(hitResult.getPos()));
if (!user.getAbilities().creativeMode) {
itemStack.decrement(1);
}
user.incrementStat(Stats.USED.getOrCreateStat(this));
world.emitGameEvent(GameEvent.ENTITY_PLACE, user);
return TypedActionResult.consume(itemStack);
} else {
return TypedActionResult.fail(itemStack);
}
}
}
public TypedActionResult<ItemStack> usee(World world, PlayerEntity user, Hand hand) {
ItemStack itemStack = user.getStackInHand(hand);
HitResult hitResult = raycast(world, user, RaycastContext.FluidHandling.SOURCE_ONLY);
if (hitResult.getType() == net.minecraft.util.hit.HitResult.Type.MISS) {
return TypedActionResult.pass(itemStack);
} else {
Vec3d vec3d = user.getRotationVec(1.0F);
List<Entity> list = world.getOtherEntities(user, user.getBoundingBox().stretch(vec3d.multiply(5.0D)).expand(1.0D), RIDERS);
if (!list.isEmpty()) {
Vec3d vec3d2 = user.getEyePos();
for (Entity entity : list) {
Box box = entity.getBoundingBox().expand(entity.getTargetingMargin());
if (box.contains(vec3d2)) {
return TypedActionResult.pass(itemStack);
}
}
}
//if (hitResult.getType() == HitResult.Type.BLOCK) {
SubmarineEntity boatEntity = new SubmarineEntity(NauticalityMain.SUBMARINE, world);
boatEntity.setPosition(hitResult.getPos().x, hitResult.getPos().y, hitResult.getPos().z);
boatEntity.setYaw(user.getYaw());
// if (!world.isSpaceEmpty(boatEntity, boatEntity.getBoundingBox())) {
// return TypedActionResult.fail(itemStack);
// } else
{
if (!world.isClient) {
world.spawnEntity(boatEntity);
world.emitGameEvent(user, GameEvent.ENTITY_PLACE, new BlockPos(hitResult.getPos()));
if (!user.getAbilities().creativeMode) {
itemStack.decrement(1);
}
}
user.incrementStat(Stats.USED.getOrCreateStat(this));
return TypedActionResult.success(itemStack, world.isClient());
}
//} else {
//return TypedActionResult.pass(itemStack);
//}
}
}
static {
RIDERS = EntityPredicates.EXCEPT_SPECTATOR.and(Entity::collides);
}
}

View File

@@ -0,0 +1,13 @@
package eu.midnightdust.nauticality.mixin;
import net.minecraft.entity.vehicle.BoatEntity;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
@Mixin(BoatEntity.class)
public interface BoatEntityAccessor {
@Accessor
void setTicksUnderwater(float ticksUnderwater);
@Accessor
BoatEntity.Location getLocation();
}

View File

@@ -0,0 +1,24 @@
package eu.midnightdust.nauticality.mixin;
import net.minecraft.world.biome.GenerationSettings;
import net.minecraft.world.gen.feature.ConfiguredFeature;
import net.minecraft.world.gen.feature.ConfiguredStructureFeature;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
import java.util.List;
import java.util.function.Supplier;
@Mixin(GenerationSettings.class)
public interface GenerationSettingsAccessorMixin {
@Accessor
List<List<Supplier<ConfiguredFeature<?, ?>>>> getFeatures();
@Accessor
void setFeatures(List<List<Supplier<ConfiguredFeature<?, ?>>>> features);
@Accessor
List<Supplier<ConfiguredStructureFeature<?, ?>>> getStructureFeatures();
@Accessor
void setStructureFeatures(List<Supplier<ConfiguredStructureFeature<?, ?>>> features);
}

View File

@@ -0,0 +1,22 @@
package eu.midnightdust.nauticality.mixin;
import eu.midnightdust.nauticality.NauticalityMain;
import net.minecraft.entity.EquipmentSlot;
import net.minecraft.entity.LivingEntity;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(LivingEntity.class)
public abstract class MixinLivingEntity {
@Inject(method = "getPreferredEquipmentSlot", at = @At(value = "TAIL"), cancellable = true)
private static void getPreferredEquipmentSlot(ItemStack stack, CallbackInfoReturnable<EquipmentSlot> info) {
Item item = stack.getItem();
if(item == NauticalityMain.Eyepatch) {
info.setReturnValue(EquipmentSlot.HEAD);
}
}
}

View File

@@ -0,0 +1,33 @@
package eu.midnightdust.nauticality.world;
import eu.midnightdust.nauticality.NauticalityMain;
import eu.midnightdust.nauticality.config.NauticalityConfig;
import net.minecraft.util.Identifier;
import net.minecraft.util.registry.BuiltinRegistries;
import net.minecraft.util.registry.Registry;
import net.minecraft.world.Heightmap;
import net.minecraft.world.gen.ProbabilityConfig;
import net.minecraft.world.gen.decorator.ConfiguredDecorator;
import net.minecraft.world.gen.decorator.Decorator;
import net.minecraft.world.gen.decorator.HeightmapDecoratorConfig;
import net.minecraft.world.gen.feature.*;
import net.minecraft.world.gen.placer.SimpleBlockPlacer;
import net.minecraft.world.gen.stateprovider.SimpleBlockStateProvider;
import static eu.midnightdust.nauticality.NauticalityMain.MOD_ID;
public class NauticalityConfiguredFeatures {
public static ConfiguredDecorator<?> SQUARE_HEIGHTMAP_SPREAD_DOUBLE = Decorator.HEIGHTMAP_SPREAD_DOUBLE.configure(new HeightmapDecoratorConfig(Heightmap.Type.MOTION_BLOCKING)).spreadHorizontally();
public static ConfiguredFeature<?, ?> ALGAE_SWAMP = Feature.RANDOM_PATCH.configure(
new RandomPatchFeatureConfig.Builder(new SimpleBlockStateProvider(NauticalityMain.Algae.getDefaultState()), SimpleBlockPlacer.INSTANCE).tries(10).build())
.decorate(SQUARE_HEIGHTMAP_SPREAD_DOUBLE).repeat(NauticalityConfig.algaeRate - 1);
public static ConfiguredFeature<?, ?> ALGAE_UNDERWATER = NauticalityFeatures.UNDERWATER_ALGAE_FEATURE.configure(new ProbabilityConfig(1)).repeat(NauticalityConfig.underwaterAlgaeRate - 1);
public static ConfiguredFeature<?, ?> CATTAIL_SWAMP = NauticalityFeatures.UNDERWATER_CATTAIL_FEATURE.configure(new ProbabilityConfig(1)).repeat(NauticalityConfig.cattailRate - 1);
public static void init() {
Registry.register(BuiltinRegistries.CONFIGURED_FEATURE, new Identifier(MOD_ID, "algae_swamp"), ALGAE_SWAMP);
Registry.register(BuiltinRegistries.CONFIGURED_FEATURE, new Identifier(MOD_ID, "algae_underwater"), ALGAE_UNDERWATER);
Registry.register(BuiltinRegistries.CONFIGURED_FEATURE, new Identifier(MOD_ID, "cattail_swamp"), CATTAIL_SWAMP);
}
}

View File

@@ -0,0 +1,16 @@
package eu.midnightdust.nauticality.world;
import eu.midnightdust.nauticality.NauticalityMain;
import eu.midnightdust.nauticality.world.feature.UnderwaterFeature;
import eu.midnightdust.nauticality.world.feature.UnderwaterTallPlantFeature;
import net.minecraft.state.property.Properties;
import net.minecraft.util.registry.Registry;
import net.minecraft.world.gen.ProbabilityConfig;
import net.minecraft.world.gen.stateprovider.SimpleBlockStateProvider;
public class NauticalityFeatures {
public static SimpleBlockStateProvider Algae = new SimpleBlockStateProvider(NauticalityMain.Algae.getDefaultState().with(Properties.WATERLOGGED, true));
public static SimpleBlockStateProvider Cattail = new SimpleBlockStateProvider(NauticalityMain.Cattail.getDefaultState());
public static final UnderwaterFeature UNDERWATER_ALGAE_FEATURE = Registry.register(Registry.FEATURE, "underwater_algae", new UnderwaterFeature(ProbabilityConfig.CODEC, Algae));
public static final UnderwaterTallPlantFeature UNDERWATER_CATTAIL_FEATURE = Registry.register(Registry.FEATURE, "swamp_cattail", new UnderwaterTallPlantFeature(ProbabilityConfig.CODEC, Cattail));
}

View File

@@ -0,0 +1,28 @@
package eu.midnightdust.nauticality.world;
import eu.midnightdust.nauticality.config.NauticalityConfig;
import eu.midnightdust.nauticality.world.structure.PirateShipStructure;
import net.fabricmc.fabric.api.structure.v1.FabricStructureBuilder;
import net.minecraft.util.Identifier;
import net.minecraft.util.registry.BuiltinRegistries;
import net.minecraft.util.registry.Registry;
import net.minecraft.world.gen.GenerationStep;
import net.minecraft.world.gen.feature.*;
import static eu.midnightdust.nauticality.NauticalityMain.MOD_ID;
public class NauticalityStructures {
public static final StructureFeature<StructurePoolFeatureConfig> PIRATE_SHIP = new PirateShipStructure();
public static final ConfiguredStructureFeature<StructurePoolFeatureConfig, ?> CONFIGURED_PIRATE_SHIP = PIRATE_SHIP.configure(new StructurePoolFeatureConfig(() -> PirateShipStructure.PIRATE_SHIP_POOL, 1));
public static void init() {
Registry.register(BuiltinRegistries.CONFIGURED_STRUCTURE_FEATURE, new Identifier(MOD_ID, "pirate_ship"), CONFIGURED_PIRATE_SHIP);
FabricStructureBuilder<StructurePoolFeatureConfig, StructureFeature<StructurePoolFeatureConfig>> pirateShip =
FabricStructureBuilder.create(new Identifier(MOD_ID,"pirate_ship"), PIRATE_SHIP)
.step(GenerationStep.Feature.SURFACE_STRUCTURES)
.defaultConfig(100 - NauticalityConfig.pirateShipRate, 5, 16)
.superflatFeature(CONFIGURED_PIRATE_SHIP);
pirateShip.register();
}
}

View File

@@ -0,0 +1,56 @@
package eu.midnightdust.nauticality.world.feature;
import com.google.common.collect.Lists;
import eu.midnightdust.nauticality.config.NauticalityConfig;
import eu.midnightdust.nauticality.mixin.GenerationSettingsAccessorMixin;
import eu.midnightdust.nauticality.world.NauticalityConfiguredFeatures;
import eu.midnightdust.nauticality.world.NauticalityStructures;
import net.fabricmc.fabric.api.event.registry.RegistryEntryAddedCallback;
import net.minecraft.util.registry.BuiltinRegistries;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.gen.GenerationStep;
import net.minecraft.world.gen.feature.ConfiguredFeature;
import net.minecraft.world.gen.feature.ConfiguredStructureFeature;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Supplier;
public class FeatureInjector {
public static void init() {
BuiltinRegistries.BIOME.forEach(FeatureInjector::addFeatureToBiome);
RegistryEntryAddedCallback.event(BuiltinRegistries.BIOME).register((i, identifier, biome) -> addFeatureToBiome(biome));
}
private static void addFeatureToBiome(Biome biome) {
if (biome.getCategory() == Biome.Category.SWAMP) {
if (NauticalityConfig.algaeRate != 0) addFeature(biome, GenerationStep.Feature.VEGETAL_DECORATION, NauticalityConfiguredFeatures.ALGAE_SWAMP);
if (NauticalityConfig.cattailRate != 0) addFeature(biome, GenerationStep.Feature.VEGETAL_DECORATION, NauticalityConfiguredFeatures.CATTAIL_SWAMP);
}
if (biome.getCategory() == Biome.Category.OCEAN && biome.toString().contains("cold")) {
if (NauticalityConfig.underwaterAlgaeRate != 0) addFeature(biome, GenerationStep.Feature.VEGETAL_DECORATION, NauticalityConfiguredFeatures.ALGAE_UNDERWATER);
}
if (biome.getCategory() == Biome.Category.OCEAN && biome.toString().contains("warm")) {
if (NauticalityConfig.pirateShipRate != 0) addStructureFeature(biome, NauticalityStructures.CONFIGURED_PIRATE_SHIP);
}
}
public static void addFeature(Biome biome, GenerationStep.Feature step, ConfiguredFeature<?, ?> feature) {
GenerationSettingsAccessorMixin generationSettingsAccessor = (GenerationSettingsAccessorMixin) biome.getGenerationSettings();
int stepIndex = step.ordinal();
List<List<Supplier<ConfiguredFeature<?, ?>>>> featuresByStep = new ArrayList<>(generationSettingsAccessor.getFeatures());
while (featuresByStep.size() <= stepIndex) {
featuresByStep.add(Lists.newArrayList());
}
List<Supplier<ConfiguredFeature<?, ?>>> features = new ArrayList<>(featuresByStep.get(stepIndex));
features.add(() -> feature);
featuresByStep.set(stepIndex, features);
generationSettingsAccessor.setFeatures(featuresByStep);
}
public static void addStructureFeature(Biome biome, ConfiguredStructureFeature<?, ?> feature) {
GenerationSettingsAccessorMixin generationSettingsAccessor = (GenerationSettingsAccessorMixin) biome.getGenerationSettings();
List<Supplier<ConfiguredStructureFeature<?, ?>>> features = new ArrayList<>(generationSettingsAccessor.getStructureFeatures());
features.add(() -> feature);
generationSettingsAccessor.setStructureFeatures(features);
}
}

View File

@@ -0,0 +1,45 @@
package eu.midnightdust.nauticality.world.feature;
import com.mojang.serialization.Codec;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.world.Heightmap;
import net.minecraft.world.StructureWorldAccess;
import net.minecraft.world.gen.ProbabilityConfig;
import net.minecraft.world.gen.feature.Feature;
import net.minecraft.world.gen.feature.util.FeatureContext;
import net.minecraft.world.gen.stateprovider.BlockStateProvider;
import java.util.Random;
public class UnderwaterFeature extends Feature<ProbabilityConfig> {
BlockStateProvider blockStateProvider;
public UnderwaterFeature(Codec<ProbabilityConfig> codec, BlockStateProvider blockStateProvider) {
super(codec);
this.blockStateProvider = blockStateProvider;
}
@Override
public boolean generate(FeatureContext<ProbabilityConfig> context) {
Random random = context.getRandom();
StructureWorldAccess structureWorldAccess = context.getWorld();
BlockPos blockPos = context.getOrigin();
int i = random.nextInt(8) - random.nextInt(8);
int j = random.nextInt(8) - random.nextInt(8);
int k = structureWorldAccess.getTopY(Heightmap.Type.OCEAN_FLOOR, blockPos.getX() + i, blockPos.getZ() + j);
BlockPos blockPos2 = new BlockPos(blockPos.getX() + i, k, blockPos.getZ() + j);
if (structureWorldAccess.getBlockState(blockPos2).isOf(Blocks.WATER) && structureWorldAccess.getBlockState(blockPos2.down()).isSideSolidFullSquare(structureWorldAccess,blockPos2, Direction.UP)) {
BlockState blockState = blockStateProvider.getBlockState(random,blockPos);
if (blockState.canPlaceAt(structureWorldAccess, blockPos2)) {
structureWorldAccess.setBlockState(blockPos2, blockState, 2);
return true;
}
}
return false;
}
}

View File

@@ -0,0 +1,49 @@
package eu.midnightdust.nauticality.world.feature;
import com.mojang.serialization.Codec;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.block.TallPlantBlock;
import net.minecraft.block.enums.DoubleBlockHalf;
import net.minecraft.state.property.Properties;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.Heightmap;
import net.minecraft.world.StructureWorldAccess;
import net.minecraft.world.gen.ProbabilityConfig;
import net.minecraft.world.gen.feature.Feature;
import net.minecraft.world.gen.feature.util.FeatureContext;
import net.minecraft.world.gen.stateprovider.BlockStateProvider;
import java.util.Random;
public class UnderwaterTallPlantFeature extends Feature<ProbabilityConfig> {
BlockStateProvider blockStateProvider;
public UnderwaterTallPlantFeature(Codec<ProbabilityConfig> codec, BlockStateProvider blockStateProvider) {
super(codec);
this.blockStateProvider = blockStateProvider;
}
@Override
public boolean generate(FeatureContext<ProbabilityConfig> context) {
Random random = context.getRandom();
StructureWorldAccess structureWorldAccess = context.getWorld();
BlockPos blockPos = context.getOrigin();
int i = random.nextInt(8) - random.nextInt(8);
int j = random.nextInt(8) - random.nextInt(8);
int k = structureWorldAccess.getTopY(Heightmap.Type.OCEAN_FLOOR, blockPos.getX() + i, blockPos.getZ() + j);
BlockPos blockPos2 = new BlockPos(blockPos.getX() + i, k, blockPos.getZ() + j);
if (structureWorldAccess.getBlockState(blockPos2).isOf(Blocks.WATER)) {
BlockState blockState = blockStateProvider.getBlockState(random,blockPos);
BlockState blockState2 = blockStateProvider.getBlockState(random,blockPos).with(Properties.DOUBLE_BLOCK_HALF, DoubleBlockHalf.UPPER);
if (blockState.canPlaceAt(structureWorldAccess, blockPos2)) {
structureWorldAccess.setBlockState(blockPos2, blockState, 2);
structureWorldAccess.setBlockState(blockPos2.up(), blockState2, 2);
return true;
}
}
return false;
}
}

View File

@@ -0,0 +1,76 @@
package eu.midnightdust.nauticality.world.structure;
import com.google.common.collect.ImmutableList;
import com.mojang.datafixers.util.Pair;
import net.minecraft.structure.MarginedStructureStart;
import net.minecraft.structure.PoolStructurePiece;
import net.minecraft.structure.StructureManager;
import net.minecraft.structure.pool.StructurePool;
import net.minecraft.structure.pool.StructurePoolBasedGenerator;
import net.minecraft.structure.pool.StructurePoolElement;
import net.minecraft.structure.pool.StructurePools;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.ChunkPos;
import net.minecraft.util.registry.DynamicRegistryManager;
import net.minecraft.world.HeightLimitView;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.biome.source.BiomeSource;
import net.minecraft.world.gen.ChunkRandom;
import net.minecraft.world.gen.chunk.ChunkGenerator;
import net.minecraft.world.gen.feature.StructureFeature;
import net.minecraft.world.gen.feature.StructurePoolFeatureConfig;
import static eu.midnightdust.nauticality.NauticalityMain.MOD_ID;
public class PirateShipStructure extends StructureFeature<StructurePoolFeatureConfig> {
public static final Identifier PIRATE_SHIPS = new Identifier(MOD_ID,"pirate_ships");
public static final StructurePool PIRATE_SHIP_POOL = StructurePools.register(new StructurePool(PIRATE_SHIPS, new Identifier("empty"), ImmutableList.of(
new Pair<>(StructurePoolElement.ofSingle(MOD_ID + ":pirate_ship"), 1)),
StructurePool.Projection.RIGID
)
);
final boolean field_25836;
final boolean surface;
private final int structureStartY;
public PirateShipStructure() {
this(-2);
}
public PirateShipStructure(int structureStartY) {
this(structureStartY, true, true);
}
public PirateShipStructure(int structureStartY, boolean field_25836, boolean surface) {
super(StructurePoolFeatureConfig.CODEC);
this.structureStartY = structureStartY;
this.field_25836 = field_25836;
this.surface = surface;
}
@Override
public StructureStartFactory<StructurePoolFeatureConfig> getStructureStartFactory() {
return PirateShipStructure.Start::new;
}
@Override
protected boolean shouldStartAt(ChunkGenerator chunkGenerator, BiomeSource biomeSource, long worldSeed, ChunkRandom random, ChunkPos pos, Biome biome, ChunkPos chunkPos, StructurePoolFeatureConfig config, HeightLimitView world) {
return true;
}
public static class Start extends MarginedStructureStart<StructurePoolFeatureConfig> {
public Start(StructureFeature<StructurePoolFeatureConfig> s, ChunkPos c, int i, long l) {
super(s, c, i, l);
}
@Override
public void init(DynamicRegistryManager registryManager, ChunkGenerator chunkGenerator, StructureManager manager, ChunkPos pos, Biome biome, StructurePoolFeatureConfig config, HeightLimitView world) {
PirateShipStructure structure = (PirateShipStructure) this.getFeature();
StructurePoolBasedGenerator.method_30419(registryManager, config, PoolStructurePiece::new, chunkGenerator, manager, new BlockPos(pos.x << 4, structure.structureStartY, pos.z << 4), this, this.random, structure.field_25836, structure.surface, world);
this.setBoundingBoxFromChildren();
}
}
}

View File

@@ -0,0 +1,10 @@
{
"variants": {
"": [
{"model": "nauticality:block/algae"},
{"model": "nauticality:block/algae", "y": 90},
{"model": "nauticality:block/algae", "y": 180},
{"model": "nauticality:block/algae", "y": 270}
]
}
}

View File

@@ -0,0 +1,10 @@
{
"variants": {
"half=lower": {
"model": "nauticality:block/cattail_bottom"
},
"half=upper": {
"model": "nauticality:block/cattail_top"
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

View File

@@ -0,0 +1,17 @@
{
"itemGroup.nauticality.main": "Nauticality",
"item.nauticality.glow_fish_spawn_egg": "Glow Fish Spawn Egg",
"item.nauticality.glow_fish_bucket": "Glow Fish Bucket",
"entity.nauticality.glow_fish": "Glow Fish",
"item.nauticality.pirate_spawn_egg": "Pirate Spawn Egg",
"entity.nauticality.pirate": "Pirate",
"item.nauticality.submarine": "Submarine",
"entity.nauticality.submarine": "Submarine",
"item.nauticality.eyepatch": "Eyepatch",
"item.nauticality.cattail": "Cattail",
"item.nauticality.algae": "Algae",
"block.nauticality.cattail": "Cattail",
"block.nauticality.algae": "Algae",
"nauticality.midnightconfig.title": "Nauticality Config",
"nauticality.midnightconfig.pirateShipRate": "Pirate Ship spawn rate"
}

View File

@@ -0,0 +1,14 @@
{
"defaultMap": {
"spriteMap": [
{
"sprite": "nauticality:block/cattail_bottom",
"material": "canvas:low_foliage"
},
{
"sprite": "nauticality:block/cattail_top",
"material": "canvas:high_foliage"
}
]
}
}

View File

@@ -0,0 +1,12 @@
{
"map": [
{
"predicate": {
"materialPredicate": {
"renderLayerName": "eyes"
}
},
"material": "canvas:emissive_transform"
}
]
}

View File

@@ -0,0 +1,12 @@
{
"map": [
{
"predicate": {
"materialPredicate": {
"renderLayerName": "eyes"
}
},
"material": "canvas:emissive_transform"
}
]
}

View File

@@ -0,0 +1,2 @@
{
}

View File

@@ -0,0 +1,3 @@
{
"defaultMaterial": "nauticality:cold_glow"
}

View File

@@ -0,0 +1,3 @@
{
"defaultMaterial": "nauticality:cold_glow"
}

View File

@@ -0,0 +1,8 @@
{
"layers": [
{
"vertexSource": "canvas:shaders/material/default.vert",
"fragmentSource": "nauticality:shaders/material/cold_glow.frag"
}
]
}

View File

@@ -0,0 +1,18 @@
{
"credit": "Made with Blockbench",
"parent": "block/block",
"textures": {
"0": "nauticality:block/algae",
"particle": "nauticality:block/algae"
},
"elements": [
{
"from": [0, 0, 0],
"to": [16, 0.1, 16],
"faces": {
"up": {"uv": [0, 0, 16, 16], "texture": "#0", "tintindex": 0},
"down": {"uv": [0, 0, 16, 16], "rotation": 90, "texture": "#0", "tintindex": 0}
}
}
]
}

View File

@@ -0,0 +1,6 @@
{
"parent": "minecraft:block/template_seagrass",
"textures": {
"texture": "nauticality:block/cattail_bottom"
}
}

View File

@@ -0,0 +1,6 @@
{
"parent": "minecraft:block/template_seagrass",
"textures": {
"texture": "nauticality:block/cattail_top"
}
}

View File

@@ -0,0 +1,6 @@
{
"parent": "minecraft:item/generated",
"textures": {
"layer0": "nauticality:block/algae"
}
}

View File

@@ -0,0 +1,6 @@
{
"parent": "minecraft:item/generated",
"textures": {
"layer0": "nauticality:block/cattail_top"
}
}

View File

@@ -0,0 +1,80 @@
{
"credit": "Made with Blockbench",
"parent": "block/block",
"textures": {
"0": "block/black_wool",
"particle": "block/black_wool"
},
"elements": [
{
"from": [0, 10, 0],
"to": [16, 11, 1],
"faces": {
"north": {"uv": [0, 0, 16, 1], "texture": "#0"},
"east": {"uv": [0, 0, 1, 1], "texture": "#0"},
"south": {"uv": [0, 0, 16, 1], "texture": "#0"},
"west": {"uv": [0, 0, 1, 1], "texture": "#0"},
"up": {"uv": [0, 0, 16, 1], "texture": "#0"},
"down": {"uv": [0, 0, 16, 1], "texture": "#0"}
}
},
{
"from": [0, 10, 15],
"to": [16, 11, 16],
"faces": {
"north": {"uv": [0, 0, 16, 1], "texture": "#0"},
"east": {"uv": [0, 0, 1, 1], "texture": "#0"},
"south": {"uv": [0, 0, 16, 1], "texture": "#0"},
"west": {"uv": [0, 0, 1, 1], "texture": "#0"},
"up": {"uv": [0, 0, 16, 1], "texture": "#0"},
"down": {"uv": [0, 0, 16, 1], "texture": "#0"}
}
},
{
"from": [15, 10, 1],
"to": [16, 11, 15],
"faces": {
"north": {"uv": [0, 0, 1, 1], "texture": "#0"},
"east": {"uv": [0, 0, 14, 1], "texture": "#0"},
"south": {"uv": [0, 0, 1, 1], "texture": "#0"},
"west": {"uv": [0, 0, 14, 1], "texture": "#0"},
"up": {"uv": [0, 0, 1, 14], "texture": "#0"},
"down": {"uv": [0, 0, 1, 14], "texture": "#0"}
}
},
{
"from": [0, 10, 1],
"to": [1, 11, 15],
"faces": {
"north": {"uv": [0, 0, 1, 1], "texture": "#0"},
"east": {"uv": [0, 0, 14, 1], "texture": "#0"},
"south": {"uv": [0, 0, 1, 1], "texture": "#0"},
"west": {"uv": [0, 0, 14, 1], "texture": "#0"},
"up": {"uv": [0, 0, 1, 14], "texture": "#0"},
"down": {"uv": [0, 0, 1, 14], "texture": "#0"}
}
},
{
"from": [2, 6, 0],
"to": [8, 10, 1],
"faces": {
"north": {"uv": [0, 0, 6, 4], "texture": "#0"},
"east": {"uv": [0, 0, 1, 4], "texture": "#0"},
"south": {"uv": [0, 0, 6, 4], "texture": "#0"},
"west": {"uv": [0, 0, 1, 4], "texture": "#0"},
"up": {"uv": [0, 0, 6, 1], "texture": "#0"},
"down": {"uv": [0, 0, 6, 1], "texture": "#0"}
}
}
],
"display": {
"head": {
"scale": [0.9, 0.9, 0.9]
}
},
"overrides": [
{"predicate": { "right": 1 },
"model": "nauticality:item/eyepatch_right"
}
]
}

View File

@@ -0,0 +1,75 @@
{
"credit": "Made with Blockbench",
"parent": "block/block",
"textures": {
"0": "block/black_wool",
"particle": "block/black_wool"
},
"elements": [
{
"from": [0, 10, 0],
"to": [16, 11, 1],
"faces": {
"north": {"uv": [0, 0, 16, 1], "texture": "#0"},
"east": {"uv": [0, 0, 1, 1], "texture": "#0"},
"south": {"uv": [0, 0, 16, 1], "texture": "#0"},
"west": {"uv": [0, 0, 1, 1], "texture": "#0"},
"up": {"uv": [0, 0, 16, 1], "texture": "#0"},
"down": {"uv": [0, 0, 16, 1], "texture": "#0"}
}
},
{
"from": [0, 10, 15],
"to": [16, 11, 16],
"faces": {
"north": {"uv": [0, 0, 16, 1], "texture": "#0"},
"east": {"uv": [0, 0, 1, 1], "texture": "#0"},
"south": {"uv": [0, 0, 16, 1], "texture": "#0"},
"west": {"uv": [0, 0, 1, 1], "texture": "#0"},
"up": {"uv": [0, 0, 16, 1], "texture": "#0"},
"down": {"uv": [0, 0, 16, 1], "texture": "#0"}
}
},
{
"from": [15, 10, 1],
"to": [16, 11, 15],
"faces": {
"north": {"uv": [0, 0, 1, 1], "texture": "#0"},
"east": {"uv": [0, 0, 14, 1], "texture": "#0"},
"south": {"uv": [0, 0, 1, 1], "texture": "#0"},
"west": {"uv": [0, 0, 14, 1], "texture": "#0"},
"up": {"uv": [0, 0, 1, 14], "texture": "#0"},
"down": {"uv": [0, 0, 1, 14], "texture": "#0"}
}
},
{
"from": [0, 10, 1],
"to": [1, 11, 15],
"faces": {
"north": {"uv": [0, 0, 1, 1], "texture": "#0"},
"east": {"uv": [0, 0, 14, 1], "texture": "#0"},
"south": {"uv": [0, 0, 1, 1], "texture": "#0"},
"west": {"uv": [0, 0, 14, 1], "texture": "#0"},
"up": {"uv": [0, 0, 1, 14], "texture": "#0"},
"down": {"uv": [0, 0, 1, 14], "texture": "#0"}
}
},
{
"from": [8, 6, 0],
"to": [14, 10, 1],
"faces": {
"north": {"uv": [0, 0, 6, 4], "texture": "#0"},
"east": {"uv": [0, 0, 1, 4], "texture": "#0"},
"south": {"uv": [0, 0, 6, 4], "texture": "#0"},
"west": {"uv": [0, 0, 1, 4], "texture": "#0"},
"up": {"uv": [0, 0, 6, 1], "texture": "#0"},
"down": {"uv": [0, 0, 6, 1], "texture": "#0"}
}
}
],
"display": {
"head": {
"scale": [0.9, 0.9, 0.9]
}
}
}

View File

@@ -0,0 +1,6 @@
{
"parent": "minecraft:item/generated",
"textures": {
"layer0": "nauticality:item/glow_fish_bucket"
}
}

View File

@@ -0,0 +1,3 @@
{
"parent": "minecraft:item/template_spawn_egg"
}

View File

@@ -0,0 +1,3 @@
{
"parent": "minecraft:item/template_spawn_egg"
}

View File

@@ -0,0 +1,6 @@
{
"parent": "minecraft:item/generated",
"textures": {
"layer0": "nauticality:item/submarine"
}
}

View File

@@ -0,0 +1,12 @@
#include frex:shaders/api/fragment.glsl
#include frex:shaders/lib/math.glsl
/******************************************************
nauticality:shaders/material/cold_glow.frag
******************************************************/
void frx_startFragment(inout frx_FragmentData fragData) {
float b = frx_smootherstep(0.1, 0.5, dot(fragData.spriteColor.rgb, vec3(-1.0, 0.0, 1.0)));
float l = frx_smootherstep(0.8, 1.0, frx_luminance(fragData.spriteColor.rgb));
fragData.emissivity = max(b, l);
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

View File

@@ -0,0 +1,20 @@
{
"type": "minecraft:block",
"pools": [
{
"rolls": 1.0,
"bonus_rolls": 0.0,
"entries": [
{
"type": "minecraft:item",
"name": "nauticality:algae"
}
],
"conditions": [
{
"condition": "minecraft:survives_explosion"
}
]
}
]
}

View File

@@ -0,0 +1,29 @@
{
"type": "minecraft:block",
"pools": [
{
"rolls": 1.0,
"bonus_rolls": 0.0,
"entries": [
{
"type": "minecraft:item",
"conditions": [
{
"condition": "minecraft:block_state_property",
"block": "nauticality:cattail",
"properties": {
"half": "lower"
}
}
],
"name": "nauticality:cattail"
}
],
"conditions": [
{
"condition": "minecraft:survives_explosion"
}
]
}
]
}

View File

@@ -0,0 +1,39 @@
{
"type": "minecraft:entity",
"pools": [
{
"rolls": 1.0,
"bonus_rolls": 0.0,
"entries": [
{
"type": "minecraft:item",
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 0.0,
"max": 1.0
},
"add": false
},
{
"function": "minecraft:looting_enchant",
"count": {
"type": "minecraft:uniform",
"min": 0.0,
"max": 1.0
}
}
],
"name": "nauticality:eyepatch"
}
],
"conditions": [
{
"condition": "minecraft:killed_by_player"
}
]
}
]
}

View File

@@ -0,0 +1,26 @@
{
"type": "minecraft:crafting_shaped",
"pattern": [
"#Y ",
"G n",
"YY "
],
"key": {
"#": {
"item": "minecraft:redstone_lamp"
},
"Y": {
"item": "minecraft:yellow_concrete"
},
"G": {
"item": "minecraft:glass"
},
"n": {
"item": "minecraft:netherite_ingot"
}
},
"result": {
"item": "nauticality:submarine",
"count": 1
}
}

View File

@@ -0,0 +1,46 @@
{
"schemaVersion": 1,
"id": "nauticality",
"version": "${version}",
"name": "Nauticality",
"description": "Explore the oceans with submarines, fight against pirates and watch the beautiful glow fish!",
"authors": [
"Motschen",
"TeamMidnightDust"
],
"contact": {
"homepage": "https://www.midnightdust.eu/",
"sources": "https://github.com/TeamMidnightDust/Nauticality",
"issues": "https://github.com/TeamMidnightDust/Nauticality/issues"
},
"license": "MIT",
"icon": "assets/nauticality/icon.png",
"environment": "*",
"entrypoints": {
"main": [
"eu.midnightdust.nauticality.NauticalityMain"
],
"client": [
"eu.midnightdust.nauticality.NauticalityClient"
]
},
"mixins": [
"nauticality.mixins.json"
],
"depends": {
"fabric": "*",
"midnightlib": "*"
},
"custom": {
"modmenu": {
"links": {
"modmenu.discord": "https://discord.gg/jAGnWYHm3r"
}
}
}
}

View File

@@ -0,0 +1,13 @@
{
"required": true,
"package": "eu.midnightdust.nauticality.mixin",
"compatibilityLevel": "JAVA_16",
"mixins": [
"GenerationSettingsAccessorMixin",
"MixinLivingEntity",
"BoatEntityAccessor"
],
"injectors": {
"defaultRequire": 1
}
}