commit
ed8c0febea
2364 changed files with 47450 additions and 20161 deletions
11
build.gradle
11
build.gradle
|
@ -1,5 +1,5 @@
|
||||||
plugins {
|
plugins {
|
||||||
id 'fabric-loom' version '0.5-SNAPSHOT'
|
id 'fabric-loom' version '0.7-SNAPSHOT'
|
||||||
id 'maven-publish'
|
id 'maven-publish'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,21 +15,24 @@ repositories {
|
||||||
maven { url "http://server.bbkr.space:8081/artifactory/libs-release/" }
|
maven { url "http://server.bbkr.space:8081/artifactory/libs-release/" }
|
||||||
maven { url "https://maven.fabricmc.net/" }
|
maven { url "https://maven.fabricmc.net/" }
|
||||||
maven { url 'https://maven.blamejared.com' }
|
maven { url 'https://maven.blamejared.com' }
|
||||||
|
maven { url "https://maven.shedaniel.me/" }
|
||||||
maven { url 'https://jitpack.io' }
|
maven { url 'https://jitpack.io' }
|
||||||
jcenter()
|
jcenter()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
apply plugin: 'maven'
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
minecraft "com.mojang:minecraft:${project.minecraft_version}"
|
minecraft "com.mojang:minecraft:${project.minecraft_version}"
|
||||||
mappings "net.fabricmc:yarn:${project.minecraft_version}+build.${project.yarn_mappings}:v2"
|
mappings minecraft.officialMojangMappings()
|
||||||
modImplementation "net.fabricmc:fabric-loader:${project.loader_version}"
|
modImplementation "net.fabricmc:fabric-loader:${project.loader_version}"
|
||||||
modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}"
|
modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}"
|
||||||
|
|
||||||
useApi "vazkii.patchouli:Patchouli:${project.minecraft_version}-${project.patchouli_version}"
|
useApi "vazkii.patchouli:Patchouli:1.16.4-${project.patchouli_version}"
|
||||||
|
|
||||||
useOptional "me.shedaniel:RoughlyEnoughItems:${project.rei_version}"
|
useOptional "me.shedaniel:RoughlyEnoughItems:${project.rei_version}"
|
||||||
useOptional "me.shedaniel:RoughlyEnoughItems-api:${project.rei_version}"
|
useOptional "me.shedaniel:RoughlyEnoughItems-api:${project.rei_version}"
|
||||||
useOptional "grondag:canvas-mc116:${project.canvas_version}"
|
//useOptional "grondag:canvas-mc116:${project.canvas_version}"
|
||||||
}
|
}
|
||||||
|
|
||||||
def useOptional(String dep) {
|
def useOptional(String dep) {
|
||||||
|
|
|
@ -3,18 +3,18 @@
|
||||||
|
|
||||||
# Fabric Properties
|
# Fabric Properties
|
||||||
# check these on https://fabricmc.net/use
|
# check these on https://fabricmc.net/use
|
||||||
minecraft_version=1.16.4
|
minecraft_version=1.16.5
|
||||||
yarn_mappings=7
|
yarn_mappings=6
|
||||||
loader_version=0.10.8
|
loader_version=0.11.3
|
||||||
|
|
||||||
# Mod Properties
|
# Mod Properties
|
||||||
mod_version = 0.8.3-beta
|
mod_version = 0.9.4-pre
|
||||||
maven_group = ru.betterend
|
maven_group = ru.betterend
|
||||||
archives_base_name = better-end
|
archives_base_name = better-end
|
||||||
|
|
||||||
# Dependencies
|
# Dependencies
|
||||||
# currently not on the main fabric site, check on the maven: https://maven.fabricmc.net/net/fabricmc/fabric-api/fabric-api
|
# currently not on the main fabric site, check on the maven: https://maven.fabricmc.net/net/fabricmc/fabric-api/fabric-api
|
||||||
patchouli_version = 48-FABRIC
|
patchouli_version = 50-FABRIC
|
||||||
fabric_version = 0.27.1+1.16
|
fabric_version = 0.32.9+1.16
|
||||||
canvas_version = 1.0.+
|
canvas_version = 1.0.+
|
||||||
rei_version = 5.8.7
|
rei_version = 5.8.10
|
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
|
@ -1,5 +1,5 @@
|
||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-bin.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.3-bin.zip
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -3,14 +3,17 @@ package ru.betterend;
|
||||||
import net.fabricmc.api.EnvType;
|
import net.fabricmc.api.EnvType;
|
||||||
import net.fabricmc.api.ModInitializer;
|
import net.fabricmc.api.ModInitializer;
|
||||||
import net.fabricmc.loader.api.FabricLoader;
|
import net.fabricmc.loader.api.FabricLoader;
|
||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
import net.minecraft.world.item.ItemStack;
|
||||||
import ru.betterend.api.BetterEndPlugin;
|
import ru.betterend.api.BetterEndPlugin;
|
||||||
import ru.betterend.config.Configs;
|
import ru.betterend.config.Configs;
|
||||||
import ru.betterend.effects.EndEnchantments;
|
import ru.betterend.effects.EndEnchantments;
|
||||||
import ru.betterend.effects.EndPotions;
|
import ru.betterend.effects.EndPotions;
|
||||||
|
import ru.betterend.events.PlayerAdvancementsEvents;
|
||||||
import ru.betterend.integration.Integrations;
|
import ru.betterend.integration.Integrations;
|
||||||
import ru.betterend.item.GuideBook;
|
import ru.betterend.item.GuideBookItem;
|
||||||
import ru.betterend.recipe.AlloyingRecipes;
|
import ru.betterend.recipe.AlloyingRecipes;
|
||||||
|
import ru.betterend.recipe.AnvilRecipes;
|
||||||
import ru.betterend.recipe.CraftingRecipes;
|
import ru.betterend.recipe.CraftingRecipes;
|
||||||
import ru.betterend.recipe.FurnaceRecipes;
|
import ru.betterend.recipe.FurnaceRecipes;
|
||||||
import ru.betterend.recipe.InfusionRecipes;
|
import ru.betterend.recipe.InfusionRecipes;
|
||||||
|
@ -21,11 +24,16 @@ import ru.betterend.registry.EndBlocks;
|
||||||
import ru.betterend.registry.EndEntities;
|
import ru.betterend.registry.EndEntities;
|
||||||
import ru.betterend.registry.EndFeatures;
|
import ru.betterend.registry.EndFeatures;
|
||||||
import ru.betterend.registry.EndItems;
|
import ru.betterend.registry.EndItems;
|
||||||
|
import ru.betterend.registry.EndPortals;
|
||||||
import ru.betterend.registry.EndSounds;
|
import ru.betterend.registry.EndSounds;
|
||||||
import ru.betterend.registry.EndStructures;
|
import ru.betterend.registry.EndStructures;
|
||||||
import ru.betterend.registry.EndTags;
|
import ru.betterend.registry.EndTags;
|
||||||
|
import ru.betterend.util.BonemealUtil;
|
||||||
|
import ru.betterend.util.DataFixerUtil;
|
||||||
import ru.betterend.util.Logger;
|
import ru.betterend.util.Logger;
|
||||||
|
import ru.betterend.util.LootTableUtil;
|
||||||
import ru.betterend.world.generator.BetterEndBiomeSource;
|
import ru.betterend.world.generator.BetterEndBiomeSource;
|
||||||
|
import ru.betterend.world.generator.GeneratorOptions;
|
||||||
import ru.betterend.world.surface.SurfaceBuilders;
|
import ru.betterend.world.surface.SurfaceBuilders;
|
||||||
|
|
||||||
public class BetterEnd implements ModInitializer {
|
public class BetterEnd implements ModInitializer {
|
||||||
|
@ -33,6 +41,7 @@ public class BetterEnd implements ModInitializer {
|
||||||
public static final Logger LOGGER = Logger.get();
|
public static final Logger LOGGER = Logger.get();
|
||||||
@Override
|
@Override
|
||||||
public void onInitialize() {
|
public void onInitialize() {
|
||||||
|
EndPortals.loadPortals();
|
||||||
EndSounds.register();
|
EndSounds.register();
|
||||||
EndItems.register();
|
EndItems.register();
|
||||||
EndBlocks.register();
|
EndBlocks.register();
|
||||||
|
@ -48,25 +57,39 @@ public class BetterEnd implements ModInitializer {
|
||||||
CraftingRecipes.register();
|
CraftingRecipes.register();
|
||||||
FurnaceRecipes.register();
|
FurnaceRecipes.register();
|
||||||
AlloyingRecipes.register();
|
AlloyingRecipes.register();
|
||||||
|
AnvilRecipes.register();
|
||||||
SmithingRecipes.register();
|
SmithingRecipes.register();
|
||||||
InfusionRecipes.register();
|
InfusionRecipes.register();
|
||||||
EndStructures.register();
|
EndStructures.register();
|
||||||
Integrations.register();
|
Integrations.register();
|
||||||
|
BonemealUtil.init();
|
||||||
|
GeneratorOptions.init();
|
||||||
|
DataFixerUtil.init();
|
||||||
|
LootTableUtil.init();
|
||||||
|
|
||||||
if (hasGuideBook()) {
|
if (hasGuideBook()) {
|
||||||
GuideBook.register();
|
GuideBookItem.register();
|
||||||
}
|
}
|
||||||
|
|
||||||
FabricLoader.getInstance().getEntrypoints("betterend", BetterEndPlugin.class).forEach(BetterEndPlugin::register);
|
FabricLoader.getInstance().getEntrypoints("betterend", BetterEndPlugin.class).forEach(BetterEndPlugin::register);
|
||||||
Configs.saveConfigs();
|
Configs.saveConfigs();
|
||||||
|
|
||||||
|
if (hasGuideBook()) {
|
||||||
|
PlayerAdvancementsEvents.PLAYER_ADVENCEMENT_COMPLETE.register((player, advancement, criterionName) -> {
|
||||||
|
ResourceLocation advId = new ResourceLocation("minecraft:end/enter_end_gateway");
|
||||||
|
if (advId.equals(advancement.getId())) {
|
||||||
|
player.addItem(new ItemStack(GuideBookItem.GUIDE_BOOK));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean hasGuideBook() {
|
public static boolean hasGuideBook() {
|
||||||
return FabricLoader.getInstance().isModLoaded("patchouli");
|
return FabricLoader.getInstance().isModLoaded("patchouli");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Identifier makeID(String path) {
|
public static ResourceLocation makeID(String path) {
|
||||||
return new Identifier(MOD_ID, path);
|
return new ResourceLocation(MOD_ID, path);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getStringId(String id) {
|
public static String getStringId(String id) {
|
||||||
|
|
35
src/main/java/ru/betterend/blocks/AeterniumAnvil.java
Normal file
35
src/main/java/ru/betterend/blocks/AeterniumAnvil.java
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
package ru.betterend.blocks;
|
||||||
|
|
||||||
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
import net.minecraft.world.level.block.Block;
|
||||||
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
|
import net.minecraft.world.level.block.state.StateDefinition;
|
||||||
|
import net.minecraft.world.level.block.state.properties.IntegerProperty;
|
||||||
|
import ru.betterend.blocks.basis.EndAnvilBlock;
|
||||||
|
import ru.betterend.item.material.EndToolMaterial;
|
||||||
|
import ru.betterend.patterns.Patterns;
|
||||||
|
import ru.betterend.registry.EndBlocks;
|
||||||
|
|
||||||
|
public class AeterniumAnvil extends EndAnvilBlock {
|
||||||
|
private static final IntegerProperty DESTRUCTION = BlockProperties.DESTRUCTION_LONG;
|
||||||
|
|
||||||
|
public AeterniumAnvil() {
|
||||||
|
super(EndBlocks.AETERNIUM_BLOCK.defaultMaterialColor(), EndToolMaterial.AETERNIUM.getLevel());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
|
||||||
|
builder.add(DESTRUCTION);
|
||||||
|
builder.add(FACING);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IntegerProperty getDestructionProperty() {
|
||||||
|
return DESTRUCTION;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResourceLocation statePatternId() {
|
||||||
|
return Patterns.STATE_ANVIL_LONG;
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,26 +3,26 @@ package ru.betterend.blocks;
|
||||||
import net.fabricmc.api.EnvType;
|
import net.fabricmc.api.EnvType;
|
||||||
import net.fabricmc.api.Environment;
|
import net.fabricmc.api.Environment;
|
||||||
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.block.Material;
|
import net.minecraft.world.level.BlockGetter;
|
||||||
import net.minecraft.block.MaterialColor;
|
import net.minecraft.world.level.block.SoundType;
|
||||||
import net.minecraft.sound.BlockSoundGroup;
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.world.level.material.Material;
|
||||||
import net.minecraft.world.BlockView;
|
import net.minecraft.world.level.material.MaterialColor;
|
||||||
import ru.betterend.blocks.basis.BlockBase;
|
import ru.betterend.blocks.basis.BlockBase;
|
||||||
|
|
||||||
public class AeterniumBlock extends BlockBase {
|
public class AeterniumBlock extends BlockBase {
|
||||||
|
|
||||||
public AeterniumBlock() {
|
public AeterniumBlock() {
|
||||||
super(FabricBlockSettings.of(Material.METAL, MaterialColor.GRAY)
|
super(FabricBlockSettings.of(Material.METAL, MaterialColor.COLOR_GRAY)
|
||||||
.hardness(65F)
|
.hardness(65F)
|
||||||
.resistance(1200F)
|
.resistance(1200F)
|
||||||
.requiresTool()
|
.requiresCorrectToolForDrops()
|
||||||
.sounds(BlockSoundGroup.NETHERITE));
|
.sound(SoundType.NETHERITE_BLOCK));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Environment(EnvType.CLIENT)
|
@Environment(EnvType.CLIENT)
|
||||||
public int getColor(BlockState state, BlockView world, BlockPos pos) {
|
public int getColor(BlockState state, BlockGetter world, BlockPos pos) {
|
||||||
return 0xFF657A7A;
|
return 0xFF657A7A;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,12 +2,12 @@ package ru.betterend.blocks;
|
||||||
|
|
||||||
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
||||||
import net.fabricmc.fabric.api.tool.attribute.v1.FabricToolTags;
|
import net.fabricmc.fabric.api.tool.attribute.v1.FabricToolTags;
|
||||||
import net.minecraft.block.Material;
|
import net.minecraft.world.level.block.SoundType;
|
||||||
import net.minecraft.sound.BlockSoundGroup;
|
import net.minecraft.world.level.material.Material;
|
||||||
import ru.betterend.blocks.basis.BlockBase;
|
import ru.betterend.blocks.basis.BlockBase;
|
||||||
|
|
||||||
public class BlockMossyGlowshroomHymenophore extends BlockBase {
|
public class AmaranitaCapBlock extends BlockBase {
|
||||||
public BlockMossyGlowshroomHymenophore() {
|
public AmaranitaCapBlock() {
|
||||||
super(FabricBlockSettings.of(Material.WOOD).breakByTool(FabricToolTags.AXES).sounds(BlockSoundGroup.WART_BLOCK).luminance(15));
|
super(FabricBlockSettings.of(Material.WOOD).breakByTool(FabricToolTags.AXES).sound(SoundType.WOOD));
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
package ru.betterend.blocks;
|
||||||
|
|
||||||
|
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
||||||
|
import net.fabricmc.fabric.api.tool.attribute.v1.FabricToolTags;
|
||||||
|
import net.minecraft.world.level.block.SoundType;
|
||||||
|
import net.minecraft.world.level.material.Material;
|
||||||
|
import ru.betterend.blocks.basis.BlockBase;
|
||||||
|
import ru.betterend.client.render.ERenderLayer;
|
||||||
|
import ru.betterend.interfaces.IRenderTypeable;
|
||||||
|
|
||||||
|
public class AmaranitaHymenophoreBlock extends BlockBase implements IRenderTypeable {
|
||||||
|
public AmaranitaHymenophoreBlock() {
|
||||||
|
super(FabricBlockSettings.of(Material.WOOD).breakByTool(FabricToolTags.AXES).sound(SoundType.WOOD));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ERenderLayer getRenderLayer() {
|
||||||
|
return ERenderLayer.CUTOUT;
|
||||||
|
}
|
||||||
|
}
|
12
src/main/java/ru/betterend/blocks/AmaranitaStemBlock.java
Normal file
12
src/main/java/ru/betterend/blocks/AmaranitaStemBlock.java
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
package ru.betterend.blocks;
|
||||||
|
|
||||||
|
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
||||||
|
import net.minecraft.world.level.block.Blocks;
|
||||||
|
import net.minecraft.world.level.material.MaterialColor;
|
||||||
|
import ru.betterend.blocks.basis.EndPillarBlock;
|
||||||
|
|
||||||
|
public class AmaranitaStemBlock extends EndPillarBlock {
|
||||||
|
public AmaranitaStemBlock() {
|
||||||
|
super(FabricBlockSettings.copyOf(Blocks.OAK_PLANKS).materialColor(MaterialColor.COLOR_LIGHT_GREEN));
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,12 +1,12 @@
|
||||||
package ru.betterend.blocks;
|
package ru.betterend.blocks;
|
||||||
|
|
||||||
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
||||||
import net.minecraft.block.Blocks;
|
import net.minecraft.world.level.block.Blocks;
|
||||||
import net.minecraft.block.MaterialColor;
|
import net.minecraft.world.level.material.MaterialColor;
|
||||||
import ru.betterend.blocks.basis.BlockBase;
|
import ru.betterend.blocks.basis.BlockBase;
|
||||||
|
|
||||||
public class BlockAmber extends BlockBase {
|
public class AmberBlock extends BlockBase {
|
||||||
public BlockAmber() {
|
public AmberBlock() {
|
||||||
super(FabricBlockSettings.copyOf(Blocks.DIAMOND_BLOCK).materialColor(MaterialColor.YELLOW));
|
super(FabricBlockSettings.copyOf(Blocks.DIAMOND_BLOCK).materialColor(MaterialColor.COLOR_YELLOW));
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,70 @@
|
||||||
|
package ru.betterend.blocks;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.core.Direction;
|
||||||
|
import net.minecraft.server.level.ServerLevel;
|
||||||
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
import net.minecraft.world.item.enchantment.EnchantmentHelper;
|
||||||
|
import net.minecraft.world.item.enchantment.Enchantments;
|
||||||
|
import net.minecraft.world.level.block.Blocks;
|
||||||
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
|
import net.minecraft.world.level.storage.loot.LootContext;
|
||||||
|
import net.minecraft.world.level.storage.loot.parameters.LootContextParams;
|
||||||
|
import ru.betterend.blocks.basis.BlockBase;
|
||||||
|
import ru.betterend.registry.EndBlocks;
|
||||||
|
import ru.betterend.registry.EndParticles;
|
||||||
|
import ru.betterend.util.BlocksHelper;
|
||||||
|
import ru.betterend.util.MHelper;
|
||||||
|
|
||||||
|
public class AncientEmeraldIceBlock extends BlockBase {
|
||||||
|
public AncientEmeraldIceBlock() {
|
||||||
|
super(FabricBlockSettings.copyOf(Blocks.BLUE_ICE).randomTicks());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void randomTick(BlockState state, ServerLevel world, BlockPos pos, Random random) {
|
||||||
|
Direction dir = BlocksHelper.randomDirection(random);
|
||||||
|
|
||||||
|
if (random.nextBoolean()) {
|
||||||
|
int x = MHelper.randRange(-2, 2, random);
|
||||||
|
int y = MHelper.randRange(-2, 2, random);
|
||||||
|
int z = MHelper.randRange(-2, 2, random);
|
||||||
|
BlockPos p = pos.offset(x, y, z);
|
||||||
|
if (world.getBlockState(p).is(Blocks.WATER)) {
|
||||||
|
world.setBlockAndUpdate(p, EndBlocks.EMERALD_ICE.defaultBlockState());
|
||||||
|
makeParticles(world, p, random);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pos = pos.relative(dir);
|
||||||
|
state = world.getBlockState(pos);
|
||||||
|
if (state.is(Blocks.WATER)) {
|
||||||
|
world.setBlockAndUpdate(pos, EndBlocks.EMERALD_ICE.defaultBlockState());
|
||||||
|
makeParticles(world, pos, random);
|
||||||
|
}
|
||||||
|
else if (state.is(EndBlocks.EMERALD_ICE)) {
|
||||||
|
world.setBlockAndUpdate(pos, EndBlocks.DENSE_EMERALD_ICE.defaultBlockState());
|
||||||
|
makeParticles(world, pos, random);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void makeParticles(ServerLevel world, BlockPos pos, Random random) {
|
||||||
|
world.sendParticles(EndParticles.SNOWFLAKE, pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5, 20, 0.5, 0.5, 0.5, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<ItemStack> getDrops(BlockState state, LootContext.Builder builder) {
|
||||||
|
ItemStack tool = builder.getOptionalParameter(LootContextParams.TOOL);
|
||||||
|
if (tool != null && EnchantmentHelper.getItemEnchantmentLevel(Enchantments.SILK_TOUCH, tool) != 0) {
|
||||||
|
return Collections.singletonList(new ItemStack(this));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,23 +6,24 @@ import com.google.common.collect.Lists;
|
||||||
|
|
||||||
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
||||||
import net.fabricmc.fabric.api.tool.attribute.v1.FabricToolTags;
|
import net.fabricmc.fabric.api.tool.attribute.v1.FabricToolTags;
|
||||||
import net.minecraft.block.AbstractGlassBlock;
|
import net.minecraft.client.color.block.BlockColor;
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.client.color.item.ItemColor;
|
||||||
import net.minecraft.block.Material;
|
import net.minecraft.core.Vec3i;
|
||||||
import net.minecraft.client.color.block.BlockColorProvider;
|
import net.minecraft.util.Mth;
|
||||||
import net.minecraft.client.color.item.ItemColorProvider;
|
import net.minecraft.world.item.ItemStack;
|
||||||
import net.minecraft.enchantment.EnchantmentHelper;
|
import net.minecraft.world.item.enchantment.EnchantmentHelper;
|
||||||
import net.minecraft.enchantment.Enchantments;
|
import net.minecraft.world.item.enchantment.Enchantments;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.world.level.block.AbstractGlassBlock;
|
||||||
import net.minecraft.loot.context.LootContext;
|
import net.minecraft.world.level.block.SoundType;
|
||||||
import net.minecraft.loot.context.LootContextParameters;
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
import net.minecraft.sound.BlockSoundGroup;
|
import net.minecraft.world.level.material.Material;
|
||||||
import net.minecraft.util.math.MathHelper;
|
import net.minecraft.world.level.storage.loot.LootContext;
|
||||||
import net.minecraft.util.math.Vec3i;
|
import net.minecraft.world.level.storage.loot.parameters.LootContextParams;
|
||||||
import ru.betterend.client.render.ERenderLayer;
|
import ru.betterend.client.render.ERenderLayer;
|
||||||
import ru.betterend.interfaces.IColorProvider;
|
import ru.betterend.interfaces.IColorProvider;
|
||||||
import ru.betterend.interfaces.IRenderTypeable;
|
import ru.betterend.interfaces.IRenderTypeable;
|
||||||
import ru.betterend.registry.EndItems;
|
import ru.betterend.registry.EndItems;
|
||||||
|
import ru.betterend.registry.EndTags;
|
||||||
import ru.betterend.util.MHelper;
|
import ru.betterend.util.MHelper;
|
||||||
|
|
||||||
public class AuroraCrystalBlock extends AbstractGlassBlock implements IRenderTypeable, IColorProvider {
|
public class AuroraCrystalBlock extends AbstractGlassBlock implements IRenderTypeable, IColorProvider {
|
||||||
|
@ -33,16 +34,17 @@ public class AuroraCrystalBlock extends AbstractGlassBlock implements IRenderTyp
|
||||||
public AuroraCrystalBlock() {
|
public AuroraCrystalBlock() {
|
||||||
super(FabricBlockSettings.of(Material.GLASS)
|
super(FabricBlockSettings.of(Material.GLASS)
|
||||||
.breakByTool(FabricToolTags.PICKAXES)
|
.breakByTool(FabricToolTags.PICKAXES)
|
||||||
.suffocates((state, world, pos) -> { return false; })
|
.breakByTool(EndTags.HAMMERS)
|
||||||
.hardness(1F)
|
.hardness(1F)
|
||||||
.resistance(1F)
|
.resistance(1F)
|
||||||
.sounds(BlockSoundGroup.GLASS)
|
|
||||||
.luminance(15)
|
.luminance(15)
|
||||||
.nonOpaque());
|
.noOcclusion()
|
||||||
|
.isSuffocating((state, world, pos) -> false)
|
||||||
|
.sound(SoundType.GLASS));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BlockColorProvider getProvider() {
|
public BlockColor getProvider() {
|
||||||
return (state, world, pos, tintIndex) -> {
|
return (state, world, pos, tintIndex) -> {
|
||||||
long i = (long) pos.getX() + (long) pos.getY() + (long) pos.getZ();
|
long i = (long) pos.getX() + (long) pos.getY() + (long) pos.getZ();
|
||||||
double delta = i * 0.1;
|
double delta = i * 0.1;
|
||||||
|
@ -54,16 +56,16 @@ public class AuroraCrystalBlock extends AbstractGlassBlock implements IRenderTyp
|
||||||
Vec3i color1 = COLORS[index];
|
Vec3i color1 = COLORS[index];
|
||||||
Vec3i color2 = COLORS[index2];
|
Vec3i color2 = COLORS[index2];
|
||||||
|
|
||||||
int r = MHelper.floor(MathHelper.lerp(delta, color1.getX(), color2.getX()));
|
int r = MHelper.floor(Mth.lerp(delta, color1.getX(), color2.getX()));
|
||||||
int g = MHelper.floor(MathHelper.lerp(delta, color1.getY(), color2.getY()));
|
int g = MHelper.floor(Mth.lerp(delta, color1.getY(), color2.getY()));
|
||||||
int b = MHelper.floor(MathHelper.lerp(delta, color1.getZ(), color2.getZ()));
|
int b = MHelper.floor(Mth.lerp(delta, color1.getZ(), color2.getZ()));
|
||||||
|
|
||||||
return MHelper.color(r, g, b);
|
return MHelper.color(r, g, b);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ItemColorProvider getItemProvider() {
|
public ItemColor getItemProvider() {
|
||||||
return (stack, tintIndex) -> {
|
return (stack, tintIndex) -> {
|
||||||
return MHelper.color(COLORS[3].getX(), COLORS[3].getY(), COLORS[3].getZ());
|
return MHelper.color(COLORS[3].getX(), COLORS[3].getY(), COLORS[3].getZ());
|
||||||
};
|
};
|
||||||
|
@ -75,18 +77,18 @@ public class AuroraCrystalBlock extends AbstractGlassBlock implements IRenderTyp
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<ItemStack> getDroppedStacks(BlockState state, LootContext.Builder builder) {
|
public List<ItemStack> getDrops(BlockState state, LootContext.Builder builder) {
|
||||||
ItemStack tool = builder.get(LootContextParameters.TOOL);
|
ItemStack tool = builder.getParameter(LootContextParams.TOOL);
|
||||||
if (tool != null && tool.isEffectiveOn(state)) {
|
if (tool != null && tool.isCorrectToolForDrops(state)) {
|
||||||
int count = 0;
|
int count = 0;
|
||||||
int enchant = EnchantmentHelper.getLevel(Enchantments.SILK_TOUCH, tool);
|
int enchant = EnchantmentHelper.getItemEnchantmentLevel(Enchantments.SILK_TOUCH, tool);
|
||||||
if (enchant > 0) {
|
if (enchant > 0) {
|
||||||
return Lists.newArrayList(new ItemStack(this));
|
return Lists.newArrayList(new ItemStack(this));
|
||||||
}
|
}
|
||||||
enchant = EnchantmentHelper.getLevel(Enchantments.FORTUNE, tool);
|
enchant = EnchantmentHelper.getItemEnchantmentLevel(Enchantments.BLOCK_FORTUNE, tool);
|
||||||
if (enchant > 0) {
|
if (enchant > 0) {
|
||||||
int min = MathHelper.clamp(MIN_DROP + enchant, MIN_DROP, MAX_DROP);
|
int min = Mth.clamp(MIN_DROP + enchant, MIN_DROP, MAX_DROP);
|
||||||
int max = MAX_DROP + (enchant / Enchantments.FORTUNE.getMaxLevel());
|
int max = MAX_DROP + (enchant / Enchantments.BLOCK_FORTUNE.getMaxLevel());
|
||||||
if (min == max) {
|
if (min == max) {
|
||||||
return Lists.newArrayList(new ItemStack(EndItems.CRYSTAL_SHARDS, max));
|
return Lists.newArrayList(new ItemStack(EndItems.CRYSTAL_SHARDS, max));
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,52 +0,0 @@
|
||||||
package ru.betterend.blocks;
|
|
||||||
|
|
||||||
import java.util.Random;
|
|
||||||
|
|
||||||
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
|
||||||
import net.minecraft.block.BlockState;
|
|
||||||
import net.minecraft.block.Blocks;
|
|
||||||
import net.minecraft.server.world.ServerWorld;
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
|
||||||
import net.minecraft.util.math.Direction;
|
|
||||||
import ru.betterend.blocks.basis.BlockBase;
|
|
||||||
import ru.betterend.registry.EndBlocks;
|
|
||||||
import ru.betterend.registry.EndParticles;
|
|
||||||
import ru.betterend.util.BlocksHelper;
|
|
||||||
import ru.betterend.util.MHelper;
|
|
||||||
|
|
||||||
public class BlockAncientEmeraldIce extends BlockBase {
|
|
||||||
public BlockAncientEmeraldIce() {
|
|
||||||
super(FabricBlockSettings.copyOf(Blocks.BLUE_ICE).ticksRandomly());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void randomTick(BlockState state, ServerWorld world, BlockPos pos, Random random) {
|
|
||||||
Direction dir = BlocksHelper.randomDirection(random);
|
|
||||||
|
|
||||||
if (random.nextBoolean()) {
|
|
||||||
int x = MHelper.randRange(-2, 2, random);
|
|
||||||
int y = MHelper.randRange(-2, 2, random);
|
|
||||||
int z = MHelper.randRange(-2, 2, random);
|
|
||||||
BlockPos p = pos.add(x, y, z);
|
|
||||||
if (world.getBlockState(p).isOf(Blocks.WATER)) {
|
|
||||||
world.setBlockState(p, EndBlocks.EMERALD_ICE.getDefaultState());
|
|
||||||
makeParticles(world, p, random);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pos = pos.offset(dir);
|
|
||||||
state = world.getBlockState(pos);
|
|
||||||
if (state.isOf(Blocks.WATER)) {
|
|
||||||
world.setBlockState(pos, EndBlocks.EMERALD_ICE.getDefaultState());
|
|
||||||
makeParticles(world, pos, random);
|
|
||||||
}
|
|
||||||
else if (state.isOf(EndBlocks.EMERALD_ICE)) {
|
|
||||||
world.setBlockState(pos, EndBlocks.DENSE_EMERALD_ICE.getDefaultState());
|
|
||||||
makeParticles(world, pos, random);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void makeParticles(ServerWorld world, BlockPos pos, Random random) {
|
|
||||||
world.spawnParticles(EndParticles.SNOWFLAKE, pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5, 20, 0.5, 0.5, 0.5, 0);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,23 +0,0 @@
|
||||||
package ru.betterend.blocks;
|
|
||||||
|
|
||||||
import net.minecraft.block.Block;
|
|
||||||
import net.minecraft.block.BlockState;
|
|
||||||
import net.minecraft.state.StateManager;
|
|
||||||
import net.minecraft.state.property.EnumProperty;
|
|
||||||
import ru.betterend.blocks.BlockProperties.TripleShape;
|
|
||||||
import ru.betterend.blocks.basis.BlockUpDownPlant;
|
|
||||||
import ru.betterend.registry.EndBlocks;
|
|
||||||
|
|
||||||
public class BlockBlueVine extends BlockUpDownPlant {
|
|
||||||
public static final EnumProperty<TripleShape> SHAPE = BlockProperties.TRIPLE_SHAPE;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void appendProperties(StateManager.Builder<Block, BlockState> stateManager) {
|
|
||||||
stateManager.add(SHAPE);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean isTerrain(BlockState state) {
|
|
||||||
return state.getBlock() == EndBlocks.END_MOSS || state.getBlock() == EndBlocks.END_MYCELIUM;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,46 +0,0 @@
|
||||||
package ru.betterend.blocks;
|
|
||||||
|
|
||||||
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
|
||||||
import net.fabricmc.fabric.api.tool.attribute.v1.FabricToolTags;
|
|
||||||
import net.minecraft.block.Block;
|
|
||||||
import net.minecraft.block.BlockState;
|
|
||||||
import net.minecraft.block.Blocks;
|
|
||||||
import net.minecraft.block.Material;
|
|
||||||
import net.minecraft.sound.BlockSoundGroup;
|
|
||||||
import net.minecraft.state.StateManager;
|
|
||||||
import net.minecraft.state.property.BooleanProperty;
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
|
||||||
import net.minecraft.util.math.Direction;
|
|
||||||
import net.minecraft.world.WorldAccess;
|
|
||||||
import net.minecraft.world.WorldView;
|
|
||||||
import ru.betterend.blocks.basis.BlockBase;
|
|
||||||
import ru.betterend.registry.EndBlocks;
|
|
||||||
|
|
||||||
public class BlockBlueVineLantern extends BlockBase {
|
|
||||||
public static final BooleanProperty NATURAL = BooleanProperty.of("natural");
|
|
||||||
|
|
||||||
public BlockBlueVineLantern() {
|
|
||||||
super(FabricBlockSettings.of(Material.WOOD).breakByTool(FabricToolTags.AXES).sounds(BlockSoundGroup.WART_BLOCK).luminance(15));
|
|
||||||
this.setDefaultState(this.stateManager.getDefaultState().with(NATURAL, false));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean canPlaceAt(BlockState state, WorldView world, BlockPos pos) {
|
|
||||||
return state.get(NATURAL) ? world.getBlockState(pos.down()).getBlock() == EndBlocks.BLUE_VINE : true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BlockState getStateForNeighborUpdate(BlockState state, Direction facing, BlockState neighborState, WorldAccess world, BlockPos pos, BlockPos neighborPos) {
|
|
||||||
if (!canPlaceAt(state, world, pos)) {
|
|
||||||
return Blocks.AIR.getDefaultState();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void appendProperties(StateManager.Builder<Block, BlockState> stateManager) {
|
|
||||||
stateManager.add(NATURAL);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,49 +0,0 @@
|
||||||
package ru.betterend.blocks;
|
|
||||||
|
|
||||||
import java.util.Random;
|
|
||||||
|
|
||||||
import net.minecraft.block.BlockState;
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
|
||||||
import net.minecraft.util.math.Direction;
|
|
||||||
import net.minecraft.world.StructureWorldAccess;
|
|
||||||
import ru.betterend.blocks.BlockProperties.TripleShape;
|
|
||||||
import ru.betterend.blocks.basis.BlockFur;
|
|
||||||
import ru.betterend.blocks.basis.BlockPlantWithAge;
|
|
||||||
import ru.betterend.registry.EndBlocks;
|
|
||||||
import ru.betterend.util.BlocksHelper;
|
|
||||||
import ru.betterend.util.MHelper;
|
|
||||||
|
|
||||||
public class BlockBlueVineSeed extends BlockPlantWithAge {
|
|
||||||
@Override
|
|
||||||
public void growAdult(StructureWorldAccess world, Random random, BlockPos pos) {
|
|
||||||
int height = MHelper.randRange(2, 5, random);
|
|
||||||
int h = BlocksHelper.upRay(world, pos, height + 2);
|
|
||||||
if (h < height + 1) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
BlocksHelper.setWithoutUpdate(world, pos, EndBlocks.BLUE_VINE.getDefaultState().with(BlockProperties.TRIPLE_SHAPE, TripleShape.BOTTOM));
|
|
||||||
for (int i = 1; i < height; i++) {
|
|
||||||
BlocksHelper.setWithoutUpdate(world, pos.up(i), EndBlocks.BLUE_VINE.getDefaultState().with(BlockProperties.TRIPLE_SHAPE, TripleShape.MIDDLE));
|
|
||||||
}
|
|
||||||
BlocksHelper.setWithoutUpdate(world, pos.up(height), EndBlocks.BLUE_VINE.getDefaultState().with(BlockProperties.TRIPLE_SHAPE, TripleShape.TOP));
|
|
||||||
placeLantern(world, pos.up(height + 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void placeLantern(StructureWorldAccess world, BlockPos pos) {
|
|
||||||
BlocksHelper.setWithoutUpdate(world, pos, EndBlocks.BLUE_VINE_LANTERN.getDefaultState().with(BlockBlueVineLantern.NATURAL, true));
|
|
||||||
for (Direction dir: BlocksHelper.HORIZONTAL) {
|
|
||||||
BlockPos p = pos.offset(dir);
|
|
||||||
if (world.isAir(p)) {
|
|
||||||
BlocksHelper.setWithoutUpdate(world, p, EndBlocks.BLUE_VINE_FUR.getDefaultState().with(BlockFur.FACING, dir));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (world.isAir(pos.up())) {
|
|
||||||
BlocksHelper.setWithoutUpdate(world, pos.up(), EndBlocks.BLUE_VINE_FUR.getDefaultState().with(BlockFur.FACING, Direction.UP));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean isTerrain(BlockState state) {
|
|
||||||
return state.isOf(EndBlocks.END_MOSS) || state.isOf(EndBlocks.END_MYCELIUM);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,69 +0,0 @@
|
||||||
package ru.betterend.blocks;
|
|
||||||
|
|
||||||
import java.util.Random;
|
|
||||||
|
|
||||||
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
|
||||||
import net.minecraft.block.Block;
|
|
||||||
import net.minecraft.block.BlockState;
|
|
||||||
import net.minecraft.block.Blocks;
|
|
||||||
import net.minecraft.block.MaterialColor;
|
|
||||||
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.util.math.BlockPos;
|
|
||||||
import net.minecraft.util.math.Direction;
|
|
||||||
import ru.betterend.blocks.basis.BlockBase;
|
|
||||||
import ru.betterend.registry.EndBlocks;
|
|
||||||
import ru.betterend.util.BlocksHelper;
|
|
||||||
|
|
||||||
public class BlockBrimstone extends BlockBase {
|
|
||||||
public static final BooleanProperty ACTIVATED = BlockProperties.ACTIVE;
|
|
||||||
|
|
||||||
public BlockBrimstone() {
|
|
||||||
super(FabricBlockSettings.copyOf(Blocks.END_STONE).materialColor(MaterialColor.BROWN).ticksRandomly());
|
|
||||||
setDefaultState(stateManager.getDefaultState().with(ACTIVATED, false));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void appendProperties(StateManager.Builder<Block, BlockState> stateManager) {
|
|
||||||
stateManager.add(ACTIVATED);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void scheduledTick(BlockState state, ServerWorld world, BlockPos pos, Random random) {
|
|
||||||
boolean deactivate = true;
|
|
||||||
for (Direction dir: BlocksHelper.DIRECTIONS) {
|
|
||||||
if (world.getFluidState(pos.offset(dir)).getFluid().equals(Fluids.WATER)) {
|
|
||||||
deactivate = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (state.get(ACTIVATED)) {
|
|
||||||
if (deactivate) {
|
|
||||||
world.setBlockState(pos, getDefaultState().with(ACTIVATED, false));
|
|
||||||
}
|
|
||||||
else if (state.get(ACTIVATED) && random.nextInt(16) == 0) {
|
|
||||||
Direction dir = BlocksHelper.randomDirection(random);
|
|
||||||
BlockPos side = pos.offset(dir);
|
|
||||||
BlockState sideState = world.getBlockState(side);
|
|
||||||
if (sideState.getBlock() instanceof BlockSulphurCrystal) {
|
|
||||||
if (sideState.get(BlockSulphurCrystal.AGE) < 2 && sideState.get(BlockSulphurCrystal.WATERLOGGED)) {
|
|
||||||
int age = sideState.get(BlockSulphurCrystal.AGE) + 1;
|
|
||||||
world.setBlockState(side, sideState.with(BlockSulphurCrystal.AGE, age));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (sideState.getFluidState().getFluid() == Fluids.WATER) {
|
|
||||||
BlockState crystal = EndBlocks.SULPHUR_CRYSTAL.getDefaultState()
|
|
||||||
.with(BlockSulphurCrystal.FACING, dir)
|
|
||||||
.with(BlockSulphurCrystal.WATERLOGGED, true)
|
|
||||||
.with(BlockSulphurCrystal.AGE, 0);
|
|
||||||
world.setBlockState(side, crystal);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (!deactivate && !state.get(ACTIVATED)) {
|
|
||||||
world.setBlockState(pos, getDefaultState().with(ACTIVATED, true));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,60 +0,0 @@
|
||||||
package ru.betterend.blocks;
|
|
||||||
|
|
||||||
import java.util.Random;
|
|
||||||
|
|
||||||
import net.fabricmc.api.EnvType;
|
|
||||||
import net.fabricmc.api.Environment;
|
|
||||||
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
|
||||||
import net.fabricmc.fabric.api.tool.attribute.v1.FabricToolTags;
|
|
||||||
import net.minecraft.block.AbstractBlock;
|
|
||||||
import net.minecraft.block.Block;
|
|
||||||
import net.minecraft.block.BlockState;
|
|
||||||
import net.minecraft.block.Material;
|
|
||||||
import net.minecraft.block.ShapeContext;
|
|
||||||
import net.minecraft.particle.ParticleTypes;
|
|
||||||
import net.minecraft.sound.BlockSoundGroup;
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
|
||||||
import net.minecraft.util.shape.VoxelShape;
|
|
||||||
import net.minecraft.world.BlockView;
|
|
||||||
import net.minecraft.world.World;
|
|
||||||
import ru.betterend.blocks.basis.BlockUnderwaterPlant;
|
|
||||||
|
|
||||||
public class BlockBubbleCoral extends BlockUnderwaterPlant {
|
|
||||||
private static final VoxelShape SHAPE = Block.createCuboidShape(0, 0, 0, 16, 14, 16);
|
|
||||||
|
|
||||||
public BlockBubbleCoral() {
|
|
||||||
super(FabricBlockSettings.of(Material.UNDERWATER_PLANT)
|
|
||||||
.breakByTool(FabricToolTags.SHEARS)
|
|
||||||
.sounds(BlockSoundGroup.CORAL)
|
|
||||||
.breakByHand(true)
|
|
||||||
.noCollision());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AbstractBlock.OffsetType getOffsetType() {
|
|
||||||
return AbstractBlock.OffsetType.NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Environment(EnvType.CLIENT)
|
|
||||||
public void randomDisplayTick(BlockState state, World world, BlockPos pos, Random random) {
|
|
||||||
double x = pos.getX() + random.nextDouble();
|
|
||||||
double y = pos.getY() + random.nextDouble() * 0.5F + 0.5F;
|
|
||||||
double z = pos.getZ() + random.nextDouble();
|
|
||||||
world.addParticle(ParticleTypes.BUBBLE, x, y, z, 0.0D, 0.0D, 0.0D);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public VoxelShape getOutlineShape(BlockState state, BlockView view, BlockPos pos, ShapeContext ePos) {
|
|
||||||
return SHAPE;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isFertilizable(BlockView world, BlockPos pos, BlockState state, boolean isClient) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean canGrow(World world, Random random, BlockPos pos, BlockState state) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,47 +0,0 @@
|
||||||
package ru.betterend.blocks;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import com.google.common.collect.Lists;
|
|
||||||
|
|
||||||
import net.minecraft.block.BlockState;
|
|
||||||
import net.minecraft.item.ItemStack;
|
|
||||||
import net.minecraft.loot.context.LootContext;
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
|
||||||
import net.minecraft.world.BlockView;
|
|
||||||
import net.minecraft.world.WorldView;
|
|
||||||
import ru.betterend.blocks.BlockProperties.TripleShape;
|
|
||||||
import ru.betterend.blocks.basis.BlockVine;
|
|
||||||
import ru.betterend.registry.EndBlocks;
|
|
||||||
import ru.betterend.registry.EndItems;
|
|
||||||
import ru.betterend.util.MHelper;
|
|
||||||
|
|
||||||
public class BlockBulbVine extends BlockVine {
|
|
||||||
public BlockBulbVine() {
|
|
||||||
super(15, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<ItemStack> getDroppedStacks(BlockState state, LootContext.Builder builder) {
|
|
||||||
if (state.get(SHAPE) == TripleShape.BOTTOM) {
|
|
||||||
return Lists.newArrayList(new ItemStack(EndItems.GLOWING_BULB));
|
|
||||||
}
|
|
||||||
else if (MHelper.RANDOM.nextInt(8) == 0) {
|
|
||||||
return Lists.newArrayList(new ItemStack(EndBlocks.BULB_VINE_SEED));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return Lists.newArrayList();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isFertilizable(BlockView world, BlockPos pos, BlockState state, boolean isClient) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean canPlaceAt(BlockState state, WorldView world, BlockPos pos) {
|
|
||||||
boolean canPlace = super.canPlaceAt(state, world, pos);
|
|
||||||
return (state.isOf(this) && state.get(SHAPE) == TripleShape.BOTTOM) ? canPlace : canPlace && world.getBlockState(pos.down()).isOf(this);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,34 +0,0 @@
|
||||||
package ru.betterend.blocks;
|
|
||||||
|
|
||||||
import java.util.Random;
|
|
||||||
|
|
||||||
import net.minecraft.block.BlockState;
|
|
||||||
import net.minecraft.tag.BlockTags;
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
|
||||||
import net.minecraft.world.StructureWorldAccess;
|
|
||||||
import net.minecraft.world.WorldView;
|
|
||||||
import ru.betterend.blocks.BlockProperties.TripleShape;
|
|
||||||
import ru.betterend.blocks.basis.BlockPlantWithAge;
|
|
||||||
import ru.betterend.registry.EndBlocks;
|
|
||||||
import ru.betterend.registry.EndTags;
|
|
||||||
import ru.betterend.util.BlocksHelper;
|
|
||||||
|
|
||||||
public class BlockBulbVineSeed extends BlockPlantWithAge {
|
|
||||||
@Override
|
|
||||||
public boolean canPlaceAt(BlockState state, WorldView world, BlockPos pos) {
|
|
||||||
BlockState up = world.getBlockState(pos.up());
|
|
||||||
return up.isIn(EndTags.GEN_TERRAIN) || up.isIn(BlockTags.LOGS) || up.isIn(BlockTags.LEAVES);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void growAdult(StructureWorldAccess world, Random random, BlockPos pos) {
|
|
||||||
int h = BlocksHelper.downRay(world, pos, random.nextInt(24)) - 1;
|
|
||||||
if (h > 2) {
|
|
||||||
BlocksHelper.setWithoutUpdate(world, pos, EndBlocks.BULB_VINE.getDefaultState().with(BlockProperties.TRIPLE_SHAPE, TripleShape.TOP));
|
|
||||||
for (int i = 1; i < h; i++) {
|
|
||||||
BlocksHelper.setWithoutUpdate(world, pos.down(i), EndBlocks.BULB_VINE.getDefaultState().with(BlockProperties.TRIPLE_SHAPE, TripleShape.MIDDLE));
|
|
||||||
}
|
|
||||||
BlocksHelper.setWithoutUpdate(world, pos.down(h), EndBlocks.BULB_VINE.getDefaultState().with(BlockProperties.TRIPLE_SHAPE, TripleShape.BOTTOM));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,15 +0,0 @@
|
||||||
package ru.betterend.blocks;
|
|
||||||
|
|
||||||
import net.minecraft.block.BlockState;
|
|
||||||
import net.minecraft.fluid.Fluids;
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
|
||||||
import net.minecraft.util.math.Direction;
|
|
||||||
import net.minecraft.world.WorldView;
|
|
||||||
import ru.betterend.blocks.basis.BlockUnderwaterPlant;
|
|
||||||
|
|
||||||
public class BlockCharnia extends BlockUnderwaterPlant {
|
|
||||||
@Override
|
|
||||||
public boolean canPlaceAt(BlockState state, WorldView world, BlockPos pos) {
|
|
||||||
return sideCoversSmallSquare(world, pos.down(), Direction.UP) && world.getFluidState(pos).getFluid() == Fluids.WATER;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,18 +0,0 @@
|
||||||
package ru.betterend.blocks;
|
|
||||||
|
|
||||||
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
|
||||||
import net.minecraft.block.Blocks;
|
|
||||||
import ru.betterend.blocks.basis.BlockBase;
|
|
||||||
import ru.betterend.client.render.ERenderLayer;
|
|
||||||
import ru.betterend.interfaces.IRenderTypeable;
|
|
||||||
|
|
||||||
public class BlockDenseEmeraldIce extends BlockBase implements IRenderTypeable {
|
|
||||||
public BlockDenseEmeraldIce() {
|
|
||||||
super(FabricBlockSettings.copyOf(Blocks.PACKED_ICE));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ERenderLayer getRenderLayer() {
|
|
||||||
return ERenderLayer.TRANSLUCENT;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
package ru.betterend.blocks;
|
|
||||||
|
|
||||||
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
|
||||||
import net.minecraft.block.Material;
|
|
||||||
import net.minecraft.sound.BlockSoundGroup;
|
|
||||||
import ru.betterend.blocks.basis.BlockBase;
|
|
||||||
|
|
||||||
public class BlockDenseSnow extends BlockBase {
|
|
||||||
public BlockDenseSnow() {
|
|
||||||
super(FabricBlockSettings.of(Material.SNOW_BLOCK).strength(0.2F).sounds(BlockSoundGroup.SNOW));
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,25 +0,0 @@
|
||||||
package ru.betterend.blocks;
|
|
||||||
|
|
||||||
import net.minecraft.block.BlockState;
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
|
||||||
import net.minecraft.world.WorldView;
|
|
||||||
import net.minecraft.world.gen.feature.Feature;
|
|
||||||
import ru.betterend.blocks.basis.BlockFeatureSapling;
|
|
||||||
import ru.betterend.registry.EndBlocks;
|
|
||||||
import ru.betterend.registry.EndFeatures;
|
|
||||||
|
|
||||||
public class BlockDragonTreeSapling extends BlockFeatureSapling {
|
|
||||||
public BlockDragonTreeSapling() {
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Feature<?> getFeature() {
|
|
||||||
return EndFeatures.DRAGON_TREE.getFeature();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean canPlaceAt(BlockState state, WorldView world, BlockPos pos) {
|
|
||||||
return world.getBlockState(pos.down()).isOf(EndBlocks.SHADOW_GRASS);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,98 +0,0 @@
|
||||||
package ru.betterend.blocks;
|
|
||||||
|
|
||||||
import java.io.Reader;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Random;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
|
||||||
import net.minecraft.block.BlockState;
|
|
||||||
import net.minecraft.block.Blocks;
|
|
||||||
import net.minecraft.block.Material;
|
|
||||||
import net.minecraft.block.TransparentBlock;
|
|
||||||
import net.minecraft.block.entity.BlockEntity;
|
|
||||||
import net.minecraft.enchantment.EnchantmentHelper;
|
|
||||||
import net.minecraft.enchantment.Enchantments;
|
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
|
||||||
import net.minecraft.item.ItemStack;
|
|
||||||
import net.minecraft.loot.context.LootContext;
|
|
||||||
import net.minecraft.server.world.ServerWorld;
|
|
||||||
import net.minecraft.util.Identifier;
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
|
||||||
import net.minecraft.util.registry.Registry;
|
|
||||||
import net.minecraft.world.LightType;
|
|
||||||
import net.minecraft.world.World;
|
|
||||||
import ru.betterend.client.render.ERenderLayer;
|
|
||||||
import ru.betterend.interfaces.IRenderTypeable;
|
|
||||||
import ru.betterend.patterns.BlockPatterned;
|
|
||||||
import ru.betterend.patterns.Patterns;
|
|
||||||
|
|
||||||
public class BlockEmeraldIce extends TransparentBlock implements IRenderTypeable, BlockPatterned {
|
|
||||||
public BlockEmeraldIce() {
|
|
||||||
super(FabricBlockSettings.copyOf(Blocks.ICE));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ERenderLayer getRenderLayer() {
|
|
||||||
return ERenderLayer.TRANSLUCENT;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void afterBreak(World world, PlayerEntity player, BlockPos pos, BlockState state, @Nullable BlockEntity blockEntity, ItemStack stack) {
|
|
||||||
super.afterBreak(world, player, pos, state, blockEntity, stack);
|
|
||||||
if (EnchantmentHelper.getLevel(Enchantments.SILK_TOUCH, stack) == 0) {
|
|
||||||
if (world.getDimension().isUltrawarm()) {
|
|
||||||
world.removeBlock(pos, false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Material material = world.getBlockState(pos.down()).getMaterial();
|
|
||||||
if (material.blocksMovement() || material.isLiquid()) {
|
|
||||||
world.setBlockState(pos, Blocks.WATER.getDefaultState());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void randomTick(BlockState state, ServerWorld world, BlockPos pos, Random random) {
|
|
||||||
if (world.getLightLevel(LightType.BLOCK, pos) > 11 - state.getOpacity(world, pos)) {
|
|
||||||
this.melt(state, world, pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void melt(BlockState state, World world, BlockPos pos) {
|
|
||||||
if (world.getDimension().isUltrawarm()) {
|
|
||||||
world.removeBlock(pos, false);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
world.setBlockState(pos, Blocks.WATER.getDefaultState());
|
|
||||||
world.updateNeighbor(pos, Blocks.WATER, pos);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<ItemStack> getDroppedStacks(BlockState state, LootContext.Builder builder) {
|
|
||||||
return Collections.singletonList(new ItemStack(this));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getStatesPattern(Reader data) {
|
|
||||||
String block = Registry.BLOCK.getId(this).getPath();
|
|
||||||
return Patterns.createJson(data, block, block);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getModelPattern(String block) {
|
|
||||||
Identifier blockId = Registry.BLOCK.getId(this);
|
|
||||||
return Patterns.createJson(Patterns.BLOCK_BASE, blockId.getPath(), block);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Identifier statePatternId() {
|
|
||||||
return Patterns.STATE_SIMPLE;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,118 +0,0 @@
|
||||||
package ru.betterend.blocks;
|
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Random;
|
|
||||||
|
|
||||||
import com.google.common.collect.Lists;
|
|
||||||
|
|
||||||
import net.fabricmc.api.EnvType;
|
|
||||||
import net.fabricmc.api.Environment;
|
|
||||||
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
|
||||||
import net.fabricmc.fabric.api.tool.attribute.v1.FabricToolTags;
|
|
||||||
import net.minecraft.block.Block;
|
|
||||||
import net.minecraft.block.BlockState;
|
|
||||||
import net.minecraft.block.Blocks;
|
|
||||||
import net.minecraft.block.Material;
|
|
||||||
import net.minecraft.block.ShapeContext;
|
|
||||||
import net.minecraft.fluid.FluidState;
|
|
||||||
import net.minecraft.fluid.Fluids;
|
|
||||||
import net.minecraft.item.ItemStack;
|
|
||||||
import net.minecraft.loot.context.LootContext;
|
|
||||||
import net.minecraft.sound.BlockSoundGroup;
|
|
||||||
import net.minecraft.state.StateManager;
|
|
||||||
import net.minecraft.state.property.EnumProperty;
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
|
||||||
import net.minecraft.util.math.Direction;
|
|
||||||
import net.minecraft.util.math.Vec3d;
|
|
||||||
import net.minecraft.util.shape.VoxelShape;
|
|
||||||
import net.minecraft.world.BlockView;
|
|
||||||
import net.minecraft.world.World;
|
|
||||||
import net.minecraft.world.WorldAccess;
|
|
||||||
import net.minecraft.world.WorldView;
|
|
||||||
import ru.betterend.blocks.BlockProperties.TripleShape;
|
|
||||||
import ru.betterend.blocks.basis.BlockUnderwaterPlant;
|
|
||||||
import ru.betterend.registry.EndBlocks;
|
|
||||||
import ru.betterend.registry.EndItems;
|
|
||||||
import ru.betterend.util.MHelper;
|
|
||||||
|
|
||||||
public class BlockEndLily extends BlockUnderwaterPlant {
|
|
||||||
public static final EnumProperty<TripleShape> SHAPE = BlockProperties.TRIPLE_SHAPE;
|
|
||||||
private static final VoxelShape SHAPE_BOTTOM = Block.createCuboidShape(4, 0, 4, 12, 16, 12);
|
|
||||||
private static final VoxelShape SHAPE_TOP = Block.createCuboidShape(2, 0, 2, 14, 6, 14);
|
|
||||||
|
|
||||||
public BlockEndLily() {
|
|
||||||
super(FabricBlockSettings.of(Material.UNDERWATER_PLANT)
|
|
||||||
.breakByTool(FabricToolTags.SHEARS)
|
|
||||||
.sounds(BlockSoundGroup.WET_GRASS)
|
|
||||||
.breakByHand(true)
|
|
||||||
.luminance((state) -> { return state.get(SHAPE) == TripleShape.TOP ? 13 : 0; })
|
|
||||||
.noCollision());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BlockState getStateForNeighborUpdate(BlockState state, Direction facing, BlockState neighborState, WorldAccess world, BlockPos pos, BlockPos neighborPos) {
|
|
||||||
if (!canPlaceAt(state, world, pos)) {
|
|
||||||
return state.get(SHAPE) == TripleShape.TOP ? Blocks.AIR.getDefaultState() : Blocks.WATER.getDefaultState();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public VoxelShape getOutlineShape(BlockState state, BlockView view, BlockPos pos, ShapeContext ePos) {
|
|
||||||
Vec3d vec3d = state.getModelOffset(view, pos);
|
|
||||||
VoxelShape shape = state.get(SHAPE) == TripleShape.TOP ? SHAPE_TOP : SHAPE_BOTTOM;
|
|
||||||
return shape.offset(vec3d.x, vec3d.y, vec3d.z);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void appendProperties(StateManager.Builder<Block, BlockState> stateManager) {
|
|
||||||
stateManager.add(SHAPE);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public FluidState getFluidState(BlockState state) {
|
|
||||||
return state.get(SHAPE) == TripleShape.TOP ? Fluids.EMPTY.getDefaultState() : Fluids.WATER.getStill(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean canPlaceAt(BlockState state, WorldView world, BlockPos pos) {
|
|
||||||
if (state.get(SHAPE) == TripleShape.TOP) {
|
|
||||||
return world.getBlockState(pos.down()).getBlock() == this;
|
|
||||||
}
|
|
||||||
else if (state.get(SHAPE) == TripleShape.BOTTOM) {
|
|
||||||
return isTerrain(world.getBlockState(pos.down()));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
BlockState up = world.getBlockState(pos.up());
|
|
||||||
BlockState down = world.getBlockState(pos.down());
|
|
||||||
return up.getBlock() == this && down.getBlock() == this;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<ItemStack> getDroppedStacks(BlockState state, LootContext.Builder builder) {
|
|
||||||
if (state.get(SHAPE) == TripleShape.TOP) {
|
|
||||||
return Lists.newArrayList(new ItemStack(EndItems.END_LILY_LEAF, MHelper.randRange(1, 2, MHelper.RANDOM)), new ItemStack(EndBlocks.END_LILY_SEED, MHelper.randRange(1, 2, MHelper.RANDOM)));
|
|
||||||
}
|
|
||||||
return Collections.emptyList();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Environment(EnvType.CLIENT)
|
|
||||||
public ItemStack getPickStack(BlockView world, BlockPos pos, BlockState state) {
|
|
||||||
return new ItemStack(EndBlocks.END_LILY_SEED);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isFertilizable(BlockView world, BlockPos pos, BlockState state, boolean isClient) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean canGrow(World world, Random random, BlockPos pos, BlockState state) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,34 +0,0 @@
|
||||||
package ru.betterend.blocks;
|
|
||||||
|
|
||||||
import java.util.Random;
|
|
||||||
|
|
||||||
import net.minecraft.fluid.Fluids;
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
|
||||||
import net.minecraft.world.StructureWorldAccess;
|
|
||||||
import ru.betterend.blocks.BlockProperties.TripleShape;
|
|
||||||
import ru.betterend.blocks.basis.BlockUnderwaterPlantWithAge;
|
|
||||||
import ru.betterend.registry.EndBlocks;
|
|
||||||
import ru.betterend.util.BlocksHelper;
|
|
||||||
|
|
||||||
public class BlockEndLilySeed extends BlockUnderwaterPlantWithAge {
|
|
||||||
@Override
|
|
||||||
public void grow(StructureWorldAccess world, Random random, BlockPos pos) {
|
|
||||||
if (canGrow(world, pos)) {
|
|
||||||
BlocksHelper.setWithoutUpdate(world, pos, EndBlocks.END_LILY.getDefaultState().with(BlockEndLily.SHAPE, TripleShape.BOTTOM));
|
|
||||||
BlockPos up = pos.up();
|
|
||||||
while (world.getFluidState(up).isStill()) {
|
|
||||||
BlocksHelper.setWithoutUpdate(world, up, EndBlocks.END_LILY.getDefaultState().with(BlockEndLily.SHAPE, TripleShape.MIDDLE));
|
|
||||||
up = up.up();
|
|
||||||
}
|
|
||||||
BlocksHelper.setWithoutUpdate(world, up, EndBlocks.END_LILY.getDefaultState().with(BlockEndLily.SHAPE, TripleShape.TOP));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean canGrow(StructureWorldAccess world, BlockPos pos) {
|
|
||||||
BlockPos up = pos.up();
|
|
||||||
while (world.getBlockState(up).getFluidState().getFluid().equals(Fluids.WATER.getStill())) {
|
|
||||||
up = up.up();
|
|
||||||
}
|
|
||||||
return world.isAir(up);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,63 +0,0 @@
|
||||||
package ru.betterend.blocks;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import com.google.common.collect.Lists;
|
|
||||||
|
|
||||||
import net.fabricmc.api.EnvType;
|
|
||||||
import net.fabricmc.api.Environment;
|
|
||||||
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
|
||||||
import net.minecraft.block.AbstractBlock;
|
|
||||||
import net.minecraft.block.Block;
|
|
||||||
import net.minecraft.block.BlockState;
|
|
||||||
import net.minecraft.block.Material;
|
|
||||||
import net.minecraft.block.ShapeContext;
|
|
||||||
import net.minecraft.item.ItemStack;
|
|
||||||
import net.minecraft.loot.context.LootContext;
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
|
||||||
import net.minecraft.util.shape.VoxelShape;
|
|
||||||
import net.minecraft.world.BlockView;
|
|
||||||
import ru.betterend.blocks.basis.BlockPlant;
|
|
||||||
import ru.betterend.registry.EndBlocks;
|
|
||||||
import ru.betterend.util.MHelper;
|
|
||||||
|
|
||||||
public class BlockEndLotusFlower extends BlockPlant {
|
|
||||||
private static final VoxelShape SHAPE_OUTLINE = Block.createCuboidShape(2, 0, 2, 14, 14, 14);
|
|
||||||
private static final VoxelShape SHAPE_COLLISION = Block.createCuboidShape(0, 0, 0, 16, 2, 16);
|
|
||||||
|
|
||||||
public BlockEndLotusFlower() {
|
|
||||||
super(FabricBlockSettings.of(Material.PLANT).nonOpaque().luminance(15));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean isTerrain(BlockState state) {
|
|
||||||
return state.isOf(EndBlocks.END_LOTUS_STEM);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AbstractBlock.OffsetType getOffsetType() {
|
|
||||||
return AbstractBlock.OffsetType.NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public VoxelShape getOutlineShape(BlockState state, BlockView view, BlockPos pos, ShapeContext ePos) {
|
|
||||||
return SHAPE_OUTLINE;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public VoxelShape getCollisionShape(BlockState state, BlockView view, BlockPos pos, ShapeContext ePos) {
|
|
||||||
return SHAPE_COLLISION;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<ItemStack> getDroppedStacks(BlockState state, LootContext.Builder builder) {
|
|
||||||
int count = MHelper.randRange(1, 2, MHelper.RANDOM);
|
|
||||||
return Lists.newArrayList(new ItemStack(EndBlocks.END_LOTUS_SEED, count));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Environment(EnvType.CLIENT)
|
|
||||||
public ItemStack getPickStack(BlockView world, BlockPos pos, BlockState state) {
|
|
||||||
return new ItemStack(EndBlocks.END_LOTUS_SEED);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,75 +0,0 @@
|
||||||
package ru.betterend.blocks;
|
|
||||||
|
|
||||||
import net.fabricmc.api.EnvType;
|
|
||||||
import net.fabricmc.api.Environment;
|
|
||||||
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
|
||||||
import net.minecraft.block.Block;
|
|
||||||
import net.minecraft.block.BlockState;
|
|
||||||
import net.minecraft.block.Material;
|
|
||||||
import net.minecraft.block.ShapeContext;
|
|
||||||
import net.minecraft.fluid.WaterFluid;
|
|
||||||
import net.minecraft.item.ItemStack;
|
|
||||||
import net.minecraft.sound.BlockSoundGroup;
|
|
||||||
import net.minecraft.state.StateManager;
|
|
||||||
import net.minecraft.state.property.EnumProperty;
|
|
||||||
import net.minecraft.state.property.Properties;
|
|
||||||
import net.minecraft.util.BlockMirror;
|
|
||||||
import net.minecraft.util.BlockRotation;
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
|
||||||
import net.minecraft.util.math.Direction;
|
|
||||||
import net.minecraft.util.shape.VoxelShape;
|
|
||||||
import net.minecraft.world.BlockView;
|
|
||||||
import net.minecraft.world.WorldView;
|
|
||||||
import ru.betterend.blocks.BlockProperties.TripleShape;
|
|
||||||
import ru.betterend.blocks.basis.BlockBaseNotFull;
|
|
||||||
import ru.betterend.client.render.ERenderLayer;
|
|
||||||
import ru.betterend.interfaces.IRenderTypeable;
|
|
||||||
import ru.betterend.registry.EndBlocks;
|
|
||||||
import ru.betterend.util.BlocksHelper;
|
|
||||||
|
|
||||||
public class BlockEndLotusLeaf extends BlockBaseNotFull implements IRenderTypeable {
|
|
||||||
public static final EnumProperty<Direction> HORIZONTAL_FACING = Properties.HORIZONTAL_FACING;
|
|
||||||
public static final EnumProperty<TripleShape> SHAPE = BlockProperties.TRIPLE_SHAPE;
|
|
||||||
private static final VoxelShape VSHAPE = Block.createCuboidShape(0, 0, 0, 16, 1, 16);
|
|
||||||
|
|
||||||
public BlockEndLotusLeaf() {
|
|
||||||
super(FabricBlockSettings.of(Material.PLANT).nonOpaque().sounds(BlockSoundGroup.WET_GRASS));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean canPlaceAt(BlockState state, WorldView world, BlockPos pos) {
|
|
||||||
BlockState down = world.getBlockState(pos.down());
|
|
||||||
return !down.getFluidState().isEmpty() && down.getFluidState().getFluid() instanceof WaterFluid;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
|
|
||||||
builder.add(SHAPE, HORIZONTAL_FACING);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public VoxelShape getOutlineShape(BlockState state, BlockView view, BlockPos pos, ShapeContext ePos) {
|
|
||||||
return VSHAPE;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BlockState rotate(BlockState state, BlockRotation rotation) {
|
|
||||||
return BlocksHelper.rotateHorizontal(state, rotation, HORIZONTAL_FACING);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BlockState mirror(BlockState state, BlockMirror mirror) {
|
|
||||||
return BlocksHelper.mirrorHorizontal(state, mirror, HORIZONTAL_FACING);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ERenderLayer getRenderLayer() {
|
|
||||||
return ERenderLayer.CUTOUT;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Environment(EnvType.CLIENT)
|
|
||||||
public ItemStack getPickStack(BlockView world, BlockPos pos, BlockState state) {
|
|
||||||
return new ItemStack(EndBlocks.END_LOTUS_SEED);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,118 +0,0 @@
|
||||||
package ru.betterend.blocks;
|
|
||||||
|
|
||||||
import java.util.Random;
|
|
||||||
|
|
||||||
import net.minecraft.block.BlockState;
|
|
||||||
import net.minecraft.fluid.Fluids;
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
|
||||||
import net.minecraft.util.math.BlockPos.Mutable;
|
|
||||||
import net.minecraft.util.math.Direction;
|
|
||||||
import net.minecraft.world.StructureWorldAccess;
|
|
||||||
import ru.betterend.blocks.BlockProperties.TripleShape;
|
|
||||||
import ru.betterend.blocks.basis.BlockUnderwaterPlantWithAge;
|
|
||||||
import ru.betterend.registry.EndBlocks;
|
|
||||||
import ru.betterend.util.BlocksHelper;
|
|
||||||
|
|
||||||
public class BlockEndLotusSeed extends BlockUnderwaterPlantWithAge {
|
|
||||||
@Override
|
|
||||||
public void grow(StructureWorldAccess world, Random random, BlockPos pos) {
|
|
||||||
if (canGrow(world, pos)) {
|
|
||||||
BlockState startLeaf = EndBlocks.END_LOTUS_STEM.getDefaultState().with(BlockEndLotusStem.LEAF, true);
|
|
||||||
BlockState roots = EndBlocks.END_LOTUS_STEM.getDefaultState().with(BlockEndLotusStem.SHAPE, TripleShape.BOTTOM).with(BlockEndLotusStem.WATERLOGGED, true);
|
|
||||||
BlockState stem = EndBlocks.END_LOTUS_STEM.getDefaultState();
|
|
||||||
BlockState flower = EndBlocks.END_LOTUS_FLOWER.getDefaultState();
|
|
||||||
|
|
||||||
BlocksHelper.setWithoutUpdate(world, pos, roots);
|
|
||||||
Mutable bpos = new Mutable().set(pos);
|
|
||||||
bpos.setY(bpos.getY() + 1);
|
|
||||||
while (world.getFluidState(bpos).isStill()) {
|
|
||||||
BlocksHelper.setWithoutUpdate(world, bpos, stem.with(BlockEndLotusStem.WATERLOGGED, true));
|
|
||||||
bpos.setY(bpos.getY() + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
int height = random.nextBoolean() ? 0 : random.nextBoolean() ? 1 : random.nextBoolean() ? 1 : -1;
|
|
||||||
TripleShape shape = (height == 0) ? TripleShape.TOP : TripleShape.MIDDLE;
|
|
||||||
Direction dir = BlocksHelper.randomHorizontal(random);
|
|
||||||
BlockPos leafCenter = bpos.toImmutable().offset(dir);
|
|
||||||
if (hasLeaf(world, leafCenter)) {
|
|
||||||
generateLeaf(world, leafCenter);
|
|
||||||
BlocksHelper.setWithoutUpdate(world, bpos, startLeaf.with(BlockEndLotusStem.SHAPE, shape).with(BlockEndLotusStem.FACING, dir));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
BlocksHelper.setWithoutUpdate(world, bpos, stem.with(BlockEndLotusStem.SHAPE, shape));
|
|
||||||
}
|
|
||||||
|
|
||||||
bpos.setY(bpos.getY() + 1);
|
|
||||||
for (int i = 1; i <= height; i++) {
|
|
||||||
if (!world.isAir(bpos)) {
|
|
||||||
bpos.setY(bpos.getY() - 1);
|
|
||||||
BlocksHelper.setWithoutUpdate(world, bpos, flower);
|
|
||||||
bpos.setY(bpos.getY() - 1);
|
|
||||||
stem = world.getBlockState(bpos);
|
|
||||||
BlocksHelper.setWithoutUpdate(world, bpos, stem.with(BlockEndLotusStem.SHAPE, TripleShape.TOP));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
BlocksHelper.setWithoutUpdate(world, bpos, stem);
|
|
||||||
bpos.setY(bpos.getY() + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!world.isAir(bpos) || height < 0) {
|
|
||||||
bpos.setY(bpos.getY() - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
BlocksHelper.setWithoutUpdate(world, bpos, flower);
|
|
||||||
bpos.setY(bpos.getY() - 1);
|
|
||||||
stem = world.getBlockState(bpos);
|
|
||||||
if (!stem.isOf(EndBlocks.END_LOTUS_STEM)) {
|
|
||||||
stem = EndBlocks.END_LOTUS_STEM.getDefaultState();
|
|
||||||
if (!world.getBlockState(bpos.north()).getFluidState().isEmpty()) {
|
|
||||||
stem = stem.with(BlockEndLotusStem.WATERLOGGED, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (world.getBlockState(bpos.offset(dir)).isOf(EndBlocks.END_LOTUS_LEAF)) {
|
|
||||||
stem = stem.with(BlockEndLotusStem.LEAF, true).with(BlockEndLotusStem.FACING, dir);
|
|
||||||
}
|
|
||||||
|
|
||||||
BlocksHelper.setWithoutUpdate(world, bpos, stem.with(BlockEndLotusStem.SHAPE, TripleShape.TOP));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean canGrow(StructureWorldAccess world, BlockPos pos) {
|
|
||||||
Mutable bpos = new Mutable();
|
|
||||||
bpos.set(pos);
|
|
||||||
while (world.getBlockState(bpos).getFluidState().getFluid().equals(Fluids.WATER.getStill())) {
|
|
||||||
bpos.setY(bpos.getY() + 1);
|
|
||||||
}
|
|
||||||
return world.isAir(bpos) && world.isAir(bpos.up());
|
|
||||||
}
|
|
||||||
|
|
||||||
private void generateLeaf(StructureWorldAccess world, BlockPos pos) {
|
|
||||||
Mutable p = new Mutable();
|
|
||||||
BlockState leaf = EndBlocks.END_LOTUS_LEAF.getDefaultState();
|
|
||||||
BlocksHelper.setWithoutUpdate(world, pos, leaf.with(BlockEndLotusLeaf.SHAPE, TripleShape.BOTTOM));
|
|
||||||
for (Direction move: BlocksHelper.HORIZONTAL) {
|
|
||||||
BlocksHelper.setWithoutUpdate(world, p.set(pos).move(move), leaf.with(BlockEndLotusLeaf.HORIZONTAL_FACING, move).with(BlockEndLotusLeaf.SHAPE, TripleShape.MIDDLE));
|
|
||||||
}
|
|
||||||
for (int i = 0; i < 4; i ++) {
|
|
||||||
Direction d1 = BlocksHelper.HORIZONTAL[i];
|
|
||||||
Direction d2 = BlocksHelper.HORIZONTAL[(i + 1) & 3];
|
|
||||||
BlocksHelper.setWithoutUpdate(world, p.set(pos).move(d1).move(d2), leaf.with(BlockEndLotusLeaf.HORIZONTAL_FACING, d1).with(BlockEndLotusLeaf.SHAPE, TripleShape.TOP));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean hasLeaf(StructureWorldAccess world, BlockPos pos) {
|
|
||||||
Mutable p = new Mutable();
|
|
||||||
p.setY(pos.getY());
|
|
||||||
int count = 0;
|
|
||||||
for (int x = -1; x < 2; x ++) {
|
|
||||||
p.setX(pos.getX() + x);
|
|
||||||
for (int z = -1; z < 2; z ++) {
|
|
||||||
p.setZ(pos.getZ() + z);
|
|
||||||
if (world.isAir(p) && !world.getFluidState(p.down()).isEmpty())
|
|
||||||
count ++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return count == 9;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,96 +0,0 @@
|
||||||
package ru.betterend.blocks;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import com.google.common.collect.Maps;
|
|
||||||
|
|
||||||
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
|
||||||
import net.minecraft.block.Block;
|
|
||||||
import net.minecraft.block.BlockState;
|
|
||||||
import net.minecraft.block.Blocks;
|
|
||||||
import net.minecraft.block.ShapeContext;
|
|
||||||
import net.minecraft.block.Waterloggable;
|
|
||||||
import net.minecraft.fluid.FluidState;
|
|
||||||
import net.minecraft.fluid.Fluids;
|
|
||||||
import net.minecraft.item.ItemPlacementContext;
|
|
||||||
import net.minecraft.state.StateManager;
|
|
||||||
import net.minecraft.state.property.BooleanProperty;
|
|
||||||
import net.minecraft.state.property.EnumProperty;
|
|
||||||
import net.minecraft.state.property.Properties;
|
|
||||||
import net.minecraft.util.BlockMirror;
|
|
||||||
import net.minecraft.util.BlockRotation;
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
|
||||||
import net.minecraft.util.math.Direction;
|
|
||||||
import net.minecraft.util.math.Direction.Axis;
|
|
||||||
import net.minecraft.util.shape.VoxelShape;
|
|
||||||
import net.minecraft.world.BlockView;
|
|
||||||
import net.minecraft.world.WorldAccess;
|
|
||||||
import ru.betterend.blocks.BlockProperties.TripleShape;
|
|
||||||
import ru.betterend.blocks.basis.BlockBase;
|
|
||||||
import ru.betterend.client.render.ERenderLayer;
|
|
||||||
import ru.betterend.interfaces.IRenderTypeable;
|
|
||||||
import ru.betterend.util.BlocksHelper;
|
|
||||||
|
|
||||||
public class BlockEndLotusStem extends BlockBase implements Waterloggable, IRenderTypeable {
|
|
||||||
public static final EnumProperty<Direction> FACING = Properties.FACING;
|
|
||||||
public static final BooleanProperty WATERLOGGED = Properties.WATERLOGGED;
|
|
||||||
public static final BooleanProperty LEAF = BooleanProperty.of("leaf");
|
|
||||||
public static final EnumProperty<TripleShape> SHAPE = BlockProperties.TRIPLE_SHAPE;
|
|
||||||
private static final Map<Axis, VoxelShape> SHAPES = Maps.newEnumMap(Axis.class);
|
|
||||||
|
|
||||||
public BlockEndLotusStem() {
|
|
||||||
super(FabricBlockSettings.copyOf(Blocks.OAK_PLANKS));
|
|
||||||
this.setDefaultState(getDefaultState().with(WATERLOGGED, false).with(SHAPE, TripleShape.MIDDLE).with(LEAF, false).with(FACING, Direction.UP));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public VoxelShape getOutlineShape(BlockState state, BlockView view, BlockPos pos, ShapeContext ePos) {
|
|
||||||
return state.get(LEAF) ? SHAPES.get(Axis.Y) : SHAPES.get(state.get(FACING).getAxis());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
|
|
||||||
builder.add(FACING, WATERLOGGED, SHAPE, LEAF);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public FluidState getFluidState(BlockState state) {
|
|
||||||
return (Boolean) state.get(WATERLOGGED) ? Fluids.WATER.getStill(false) : super.getFluidState(state);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BlockState getPlacementState(ItemPlacementContext ctx) {
|
|
||||||
WorldAccess worldAccess = ctx.getWorld();
|
|
||||||
BlockPos blockPos = ctx.getBlockPos();
|
|
||||||
return this.getDefaultState().with(WATERLOGGED, worldAccess.getFluidState(blockPos).getFluid() == Fluids.WATER).with(FACING, ctx.getSide());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BlockState rotate(BlockState state, BlockRotation rotation) {
|
|
||||||
return BlocksHelper.rotateHorizontal(state, rotation, FACING);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BlockState mirror(BlockState state, BlockMirror mirror) {
|
|
||||||
return BlocksHelper.mirrorHorizontal(state, mirror, FACING);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BlockState getStateForNeighborUpdate(BlockState state, Direction direction, BlockState newState, WorldAccess world, BlockPos pos, BlockPos posFrom) {
|
|
||||||
if ((Boolean) state.get(WATERLOGGED)) {
|
|
||||||
world.getFluidTickScheduler().schedule(pos, Fluids.WATER, Fluids.WATER.getTickRate(world));
|
|
||||||
}
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ERenderLayer getRenderLayer() {
|
|
||||||
return ERenderLayer.CUTOUT;
|
|
||||||
}
|
|
||||||
|
|
||||||
static {
|
|
||||||
SHAPES.put(Axis.X, Block.createCuboidShape(0, 6, 6, 16, 10, 10));
|
|
||||||
SHAPES.put(Axis.Y, Block.createCuboidShape(6, 0, 6, 10, 16, 10));
|
|
||||||
SHAPES.put(Axis.Z, Block.createCuboidShape(6, 6, 0, 10, 10, 16));
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,35 +0,0 @@
|
||||||
package ru.betterend.blocks;
|
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import net.fabricmc.api.EnvType;
|
|
||||||
import net.fabricmc.api.Environment;
|
|
||||||
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
|
||||||
import net.minecraft.block.BlockState;
|
|
||||||
import net.minecraft.block.Blocks;
|
|
||||||
import net.minecraft.block.FallingBlock;
|
|
||||||
import net.minecraft.item.ItemStack;
|
|
||||||
import net.minecraft.loot.context.LootContext;
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
|
||||||
import net.minecraft.world.BlockView;
|
|
||||||
import ru.betterend.util.MHelper;
|
|
||||||
|
|
||||||
public class BlockEndstoneDust extends FallingBlock {
|
|
||||||
@Environment(EnvType.CLIENT)
|
|
||||||
private static final int COLOR = MHelper.color(226, 239, 168);
|
|
||||||
|
|
||||||
public BlockEndstoneDust() {
|
|
||||||
super(FabricBlockSettings.copyOf(Blocks.SAND).materialColor(Blocks.END_STONE.getDefaultMaterialColor()));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<ItemStack> getDroppedStacks(BlockState state, LootContext.Builder builder) {
|
|
||||||
return Collections.singletonList(new ItemStack(this));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Environment(EnvType.CLIENT)
|
|
||||||
public int getColor(BlockState state, BlockView world, BlockPos pos) {
|
|
||||||
return COLOR;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,30 +0,0 @@
|
||||||
package ru.betterend.blocks;
|
|
||||||
|
|
||||||
import net.fabricmc.api.EnvType;
|
|
||||||
import net.fabricmc.api.Environment;
|
|
||||||
import net.minecraft.block.BlockState;
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
|
||||||
import net.minecraft.world.BlockView;
|
|
||||||
import ru.betterend.blocks.basis.BlockPlant;
|
|
||||||
import ru.betterend.registry.EndBlocks;
|
|
||||||
|
|
||||||
public class BlockGlowingMoss extends BlockPlant {
|
|
||||||
public BlockGlowingMoss(int light) {
|
|
||||||
super(light);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean isTerrain(BlockState state) {
|
|
||||||
return state.getBlock() == EndBlocks.END_MOSS || state.getBlock() == EndBlocks.END_MYCELIUM;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Environment(EnvType.CLIENT)
|
|
||||||
public boolean hasEmissiveLighting(BlockView world, BlockPos pos) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Environment(EnvType.CLIENT)
|
|
||||||
public float getAmbientOcclusionLightLevel(BlockView world, BlockPos pos) {
|
|
||||||
return 1F;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,52 +0,0 @@
|
||||||
package ru.betterend.blocks;
|
|
||||||
|
|
||||||
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
|
||||||
import net.fabricmc.fabric.api.tool.attribute.v1.FabricToolTags;
|
|
||||||
import net.minecraft.block.Block;
|
|
||||||
import net.minecraft.block.BlockState;
|
|
||||||
import net.minecraft.block.Blocks;
|
|
||||||
import net.minecraft.block.Material;
|
|
||||||
import net.minecraft.block.MaterialColor;
|
|
||||||
import net.minecraft.sound.BlockSoundGroup;
|
|
||||||
import net.minecraft.state.StateManager;
|
|
||||||
import net.minecraft.state.property.BooleanProperty;
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
|
||||||
import net.minecraft.util.math.Direction;
|
|
||||||
import net.minecraft.world.WorldAccess;
|
|
||||||
import net.minecraft.world.WorldView;
|
|
||||||
import ru.betterend.blocks.basis.BlockBase;
|
|
||||||
import ru.betterend.registry.EndBlocks;
|
|
||||||
|
|
||||||
public class BlockGlowingPillarLuminophor extends BlockBase {
|
|
||||||
public static final BooleanProperty NATURAL = BooleanProperty.of("natural");
|
|
||||||
|
|
||||||
public BlockGlowingPillarLuminophor() {
|
|
||||||
super(FabricBlockSettings.of(Material.LEAVES)
|
|
||||||
.materialColor(MaterialColor.ORANGE)
|
|
||||||
.breakByTool(FabricToolTags.SHEARS)
|
|
||||||
.sounds(BlockSoundGroup.GRASS)
|
|
||||||
.strength(0.2F)
|
|
||||||
.luminance(15));
|
|
||||||
this.setDefaultState(this.stateManager.getDefaultState().with(NATURAL, false));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean canPlaceAt(BlockState state, WorldView world, BlockPos pos) {
|
|
||||||
return state.get(NATURAL) ? world.getBlockState(pos.down()).isOf(EndBlocks.GLOWING_PILLAR_ROOTS) : true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BlockState getStateForNeighborUpdate(BlockState state, Direction facing, BlockState neighborState, WorldAccess world, BlockPos pos, BlockPos neighborPos) {
|
|
||||||
if (!canPlaceAt(state, world, pos)) {
|
|
||||||
return Blocks.AIR.getDefaultState();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void appendProperties(StateManager.Builder<Block, BlockState> stateManager) {
|
|
||||||
stateManager.add(NATURAL);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,23 +0,0 @@
|
||||||
package ru.betterend.blocks;
|
|
||||||
|
|
||||||
import net.minecraft.block.Block;
|
|
||||||
import net.minecraft.block.BlockState;
|
|
||||||
import net.minecraft.state.StateManager;
|
|
||||||
import net.minecraft.state.property.EnumProperty;
|
|
||||||
import ru.betterend.blocks.BlockProperties.TripleShape;
|
|
||||||
import ru.betterend.blocks.basis.BlockUpDownPlant;
|
|
||||||
import ru.betterend.registry.EndBlocks;
|
|
||||||
|
|
||||||
public class BlockGlowingPillarRoots extends BlockUpDownPlant {
|
|
||||||
public static final EnumProperty<TripleShape> SHAPE = BlockProperties.TRIPLE_SHAPE;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void appendProperties(StateManager.Builder<Block, BlockState> stateManager) {
|
|
||||||
stateManager.add(SHAPE);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean isTerrain(BlockState state) {
|
|
||||||
return state.isOf(EndBlocks.AMBER_MOSS);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,69 +0,0 @@
|
||||||
package ru.betterend.blocks;
|
|
||||||
|
|
||||||
import java.util.Random;
|
|
||||||
|
|
||||||
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
|
||||||
import net.fabricmc.fabric.api.tool.attribute.v1.FabricToolTags;
|
|
||||||
import net.minecraft.block.BlockState;
|
|
||||||
import net.minecraft.block.Material;
|
|
||||||
import net.minecraft.sound.BlockSoundGroup;
|
|
||||||
import net.minecraft.state.property.Properties;
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
|
||||||
import net.minecraft.util.math.BlockPos.Mutable;
|
|
||||||
import net.minecraft.util.math.Direction;
|
|
||||||
import net.minecraft.world.StructureWorldAccess;
|
|
||||||
import ru.betterend.blocks.BlockProperties.TripleShape;
|
|
||||||
import ru.betterend.blocks.basis.BlockPlantWithAge;
|
|
||||||
import ru.betterend.registry.EndBlocks;
|
|
||||||
import ru.betterend.util.BlocksHelper;
|
|
||||||
import ru.betterend.util.MHelper;
|
|
||||||
|
|
||||||
public class BlockGlowingPillarSeed extends BlockPlantWithAge {
|
|
||||||
public BlockGlowingPillarSeed() {
|
|
||||||
super(FabricBlockSettings.of(Material.PLANT)
|
|
||||||
.luminance((state) -> { return state.get(AGE) * 3 + 3; })
|
|
||||||
.breakByTool(FabricToolTags.SHEARS)
|
|
||||||
.sounds(BlockSoundGroup.GRASS)
|
|
||||||
.breakByHand(true)
|
|
||||||
.ticksRandomly()
|
|
||||||
.noCollision());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void growAdult(StructureWorldAccess world, Random random, BlockPos pos) {
|
|
||||||
int height = MHelper.randRange(1, 2, random);
|
|
||||||
int h = BlocksHelper.upRay(world, pos, height + 2);
|
|
||||||
if (h < height) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Mutable mut = new Mutable().set(pos);
|
|
||||||
BlockState roots = EndBlocks.GLOWING_PILLAR_ROOTS.getDefaultState();
|
|
||||||
if (height < 2) {
|
|
||||||
BlocksHelper.setWithUpdate(world, mut, roots.with(BlockProperties.TRIPLE_SHAPE, TripleShape.MIDDLE));
|
|
||||||
mut.move(Direction.UP);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
BlocksHelper.setWithUpdate(world, mut, roots.with(BlockProperties.TRIPLE_SHAPE, TripleShape.BOTTOM));
|
|
||||||
mut.move(Direction.UP);
|
|
||||||
BlocksHelper.setWithUpdate(world, mut, roots.with(BlockProperties.TRIPLE_SHAPE, TripleShape.TOP));
|
|
||||||
mut.move(Direction.UP);
|
|
||||||
}
|
|
||||||
BlocksHelper.setWithUpdate(world, mut, EndBlocks.GLOWING_PILLAR_LUMINOPHOR.getDefaultState().with(BlockBlueVineLantern.NATURAL, true));
|
|
||||||
for (Direction dir: BlocksHelper.DIRECTIONS) {
|
|
||||||
pos = mut.offset(dir);
|
|
||||||
if (world.isAir(pos)) {
|
|
||||||
BlocksHelper.setWithUpdate(world, pos, EndBlocks.GLOWING_PILLAR_LEAVES.getDefaultState().with(Properties.FACING, dir));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mut.move(Direction.UP);
|
|
||||||
if (world.isAir(mut)) {
|
|
||||||
BlocksHelper.setWithUpdate(world, mut, EndBlocks.GLOWING_PILLAR_LEAVES.getDefaultState().with(Properties.FACING, Direction.UP));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean isTerrain(BlockState state) {
|
|
||||||
return state.isOf(EndBlocks.AMBER_MOSS);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,87 +0,0 @@
|
||||||
package ru.betterend.blocks;
|
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import com.google.common.collect.Lists;
|
|
||||||
|
|
||||||
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
|
||||||
import net.fabricmc.fabric.api.tool.attribute.v1.FabricToolTags;
|
|
||||||
import net.minecraft.block.Block;
|
|
||||||
import net.minecraft.block.BlockState;
|
|
||||||
import net.minecraft.block.Material;
|
|
||||||
import net.minecraft.block.MaterialColor;
|
|
||||||
import net.minecraft.client.color.block.BlockColorProvider;
|
|
||||||
import net.minecraft.client.color.item.ItemColorProvider;
|
|
||||||
import net.minecraft.enchantment.EnchantmentHelper;
|
|
||||||
import net.minecraft.enchantment.Enchantments;
|
|
||||||
import net.minecraft.item.ItemPlacementContext;
|
|
||||||
import net.minecraft.item.ItemStack;
|
|
||||||
import net.minecraft.loot.context.LootContext;
|
|
||||||
import net.minecraft.loot.context.LootContextParameters;
|
|
||||||
import net.minecraft.sound.BlockSoundGroup;
|
|
||||||
import net.minecraft.state.StateManager;
|
|
||||||
import net.minecraft.state.property.IntProperty;
|
|
||||||
import net.minecraft.util.math.MathHelper;
|
|
||||||
import ru.betterend.blocks.basis.BlockBase;
|
|
||||||
import ru.betterend.interfaces.IColorProvider;
|
|
||||||
import ru.betterend.registry.EndBlocks;
|
|
||||||
import ru.betterend.util.MHelper;
|
|
||||||
|
|
||||||
public class BlockHelixTreeLeaves extends BlockBase implements IColorProvider {
|
|
||||||
public static final IntProperty COLOR = IntProperty.of("color", 0, 7);
|
|
||||||
|
|
||||||
public BlockHelixTreeLeaves() {
|
|
||||||
super(FabricBlockSettings.of(Material.LEAVES)
|
|
||||||
.materialColor(MaterialColor.ORANGE)
|
|
||||||
.breakByTool(FabricToolTags.SHEARS)
|
|
||||||
.sounds(BlockSoundGroup.WART_BLOCK)
|
|
||||||
.sounds(BlockSoundGroup.GRASS)
|
|
||||||
.strength(0.2F));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void appendProperties(StateManager.Builder<Block, BlockState> stateManager) {
|
|
||||||
stateManager.add(COLOR);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BlockColorProvider getProvider() {
|
|
||||||
return (state, world, pos, tintIndex) -> {
|
|
||||||
return MHelper.color(237, getGreen(state.get(COLOR)), 20);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ItemColorProvider getItemProvider() {
|
|
||||||
return (stack, tintIndex) -> {
|
|
||||||
return MHelper.color(237, getGreen(4), 20);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BlockState getPlacementState(ItemPlacementContext ctx) {
|
|
||||||
return this.getDefaultState().with(COLOR, MHelper.randRange(3, 5, ctx.getWorld().getRandom()));
|
|
||||||
}
|
|
||||||
|
|
||||||
private int getGreen(int color) {
|
|
||||||
float delta = color / 7F;
|
|
||||||
return (int) MathHelper.lerp(delta, 80, 158);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<ItemStack> getDroppedStacks(BlockState state, LootContext.Builder builder) {
|
|
||||||
ItemStack tool = builder.get(LootContextParameters.TOOL);
|
|
||||||
if (tool != null) {
|
|
||||||
if (tool.getItem().isIn(FabricToolTags.SHEARS) || tool.isEffectiveOn(state) || EnchantmentHelper.getLevel(Enchantments.SILK_TOUCH, tool) > 0) {
|
|
||||||
return Collections.singletonList(new ItemStack(this));
|
|
||||||
}
|
|
||||||
int fortune = EnchantmentHelper.getLevel(Enchantments.FORTUNE, tool);
|
|
||||||
if (MHelper.RANDOM.nextInt(16) <= fortune) {
|
|
||||||
return Lists.newArrayList(new ItemStack(EndBlocks.HELIX_TREE_SAPLING));
|
|
||||||
}
|
|
||||||
return Lists.newArrayList();
|
|
||||||
}
|
|
||||||
return MHelper.RANDOM.nextInt(32) == 0 ? Lists.newArrayList(new ItemStack(EndBlocks.HELIX_TREE_SAPLING)) : Lists.newArrayList();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
package ru.betterend.blocks;
|
|
||||||
|
|
||||||
import net.minecraft.world.gen.feature.Feature;
|
|
||||||
import ru.betterend.blocks.basis.BlockFeatureSapling;
|
|
||||||
import ru.betterend.registry.EndFeatures;
|
|
||||||
|
|
||||||
public class BlockHelixTreeSapling extends BlockFeatureSapling {
|
|
||||||
@Override
|
|
||||||
protected Feature<?> getFeature() {
|
|
||||||
return EndFeatures.HELIX_TREE.getFeature();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,90 +0,0 @@
|
||||||
package ru.betterend.blocks;
|
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Random;
|
|
||||||
|
|
||||||
import com.google.common.collect.Lists;
|
|
||||||
|
|
||||||
import net.fabricmc.api.EnvType;
|
|
||||||
import net.fabricmc.api.Environment;
|
|
||||||
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
|
||||||
import net.fabricmc.fabric.api.tool.attribute.v1.FabricToolTags;
|
|
||||||
import net.minecraft.block.Block;
|
|
||||||
import net.minecraft.block.BlockState;
|
|
||||||
import net.minecraft.block.Material;
|
|
||||||
import net.minecraft.item.ItemStack;
|
|
||||||
import net.minecraft.loot.context.LootContext;
|
|
||||||
import net.minecraft.sound.BlockSoundGroup;
|
|
||||||
import net.minecraft.state.StateManager;
|
|
||||||
import net.minecraft.state.property.EnumProperty;
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
|
||||||
import net.minecraft.world.BlockView;
|
|
||||||
import net.minecraft.world.World;
|
|
||||||
import net.minecraft.world.WorldView;
|
|
||||||
import ru.betterend.blocks.BlockProperties.HydraluxShape;
|
|
||||||
import ru.betterend.blocks.basis.BlockUnderwaterPlant;
|
|
||||||
import ru.betterend.registry.EndBlocks;
|
|
||||||
import ru.betterend.registry.EndItems;
|
|
||||||
import ru.betterend.util.MHelper;
|
|
||||||
|
|
||||||
public class BlockHydralux extends BlockUnderwaterPlant {
|
|
||||||
public static final EnumProperty<HydraluxShape> SHAPE = BlockProperties.HYDRALUX_SHAPE;
|
|
||||||
|
|
||||||
public BlockHydralux() {
|
|
||||||
super(FabricBlockSettings.of(Material.UNDERWATER_PLANT)
|
|
||||||
.breakByTool(FabricToolTags.SHEARS)
|
|
||||||
.sounds(BlockSoundGroup.WET_GRASS)
|
|
||||||
.breakByHand(true)
|
|
||||||
.luminance((state) -> { return state.get(SHAPE).hasGlow() ? 15 : 0; })
|
|
||||||
.noCollision());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void appendProperties(StateManager.Builder<Block, BlockState> stateManager) {
|
|
||||||
stateManager.add(SHAPE);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean canPlaceAt(BlockState state, WorldView world, BlockPos pos) {
|
|
||||||
BlockState down = world.getBlockState(pos.down());
|
|
||||||
HydraluxShape shape = state.get(SHAPE);
|
|
||||||
if (shape == HydraluxShape.FLOWER_BIG_TOP || shape == HydraluxShape.FLOWER_SMALL_TOP) {
|
|
||||||
return down.isOf(this);
|
|
||||||
}
|
|
||||||
else if (shape == HydraluxShape.ROOTS) {
|
|
||||||
return down.isOf(EndBlocks.SULPHURIC_ROCK.stone) && world.getBlockState(pos.up()).isOf(this);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return down.isOf(this) && world.getBlockState(pos.up()).isOf(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isFertilizable(BlockView world, BlockPos pos, BlockState state, boolean isClient) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean canGrow(World world, Random random, BlockPos pos, BlockState state) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Environment(EnvType.CLIENT)
|
|
||||||
public ItemStack getPickStack(BlockView world, BlockPos pos, BlockState state) {
|
|
||||||
return new ItemStack(EndBlocks.HYDRALUX_SAPLING);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<ItemStack> getDroppedStacks(BlockState state, LootContext.Builder builder) {
|
|
||||||
HydraluxShape shape = state.get(SHAPE);
|
|
||||||
if (shape == HydraluxShape.FLOWER_BIG_BOTTOM || shape == HydraluxShape.FLOWER_SMALL_BOTTOM) {
|
|
||||||
return Lists.newArrayList(new ItemStack(EndItems.HYDRALUX_PETAL, MHelper.randRange(1, 4, MHelper.RANDOM)));
|
|
||||||
}
|
|
||||||
else if (shape == HydraluxShape.ROOTS) {
|
|
||||||
return Lists.newArrayList(new ItemStack(EndBlocks.HYDRALUX_SAPLING, MHelper.randRange(1, 2, MHelper.RANDOM)));
|
|
||||||
}
|
|
||||||
return Collections.emptyList();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,30 +0,0 @@
|
||||||
package ru.betterend.blocks;
|
|
||||||
|
|
||||||
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
|
||||||
import net.fabricmc.fabric.api.tool.attribute.v1.FabricToolTags;
|
|
||||||
import net.minecraft.block.Material;
|
|
||||||
import net.minecraft.block.MaterialColor;
|
|
||||||
import net.minecraft.entity.Entity;
|
|
||||||
import net.minecraft.sound.BlockSoundGroup;
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
|
||||||
import net.minecraft.world.World;
|
|
||||||
import ru.betterend.blocks.basis.BlockBase;
|
|
||||||
|
|
||||||
public class BlockHydraluxPetal extends BlockBase {
|
|
||||||
public BlockHydraluxPetal() {
|
|
||||||
this(FabricBlockSettings.of(Material.PLANT)
|
|
||||||
.materialColor(MaterialColor.SPRUCE)
|
|
||||||
.sounds(BlockSoundGroup.WART_BLOCK)
|
|
||||||
.breakByTool(FabricToolTags.AXES)
|
|
||||||
.hardness(1)
|
|
||||||
.resistance(1)
|
|
||||||
.breakByHand(true));
|
|
||||||
}
|
|
||||||
|
|
||||||
public BlockHydraluxPetal(FabricBlockSettings settings) {
|
|
||||||
super(settings);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onLandedUpon(World world, BlockPos pos, Entity entity, float distance) {}
|
|
||||||
}
|
|
|
@ -1,49 +0,0 @@
|
||||||
package ru.betterend.blocks;
|
|
||||||
|
|
||||||
import java.util.Random;
|
|
||||||
|
|
||||||
import net.minecraft.block.BlockState;
|
|
||||||
import net.minecraft.block.Blocks;
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
|
||||||
import net.minecraft.util.math.BlockPos.Mutable;
|
|
||||||
import net.minecraft.world.StructureWorldAccess;
|
|
||||||
import ru.betterend.blocks.BlockProperties.HydraluxShape;
|
|
||||||
import ru.betterend.blocks.basis.BlockUnderwaterPlantWithAge;
|
|
||||||
import ru.betterend.registry.EndBlocks;
|
|
||||||
import ru.betterend.util.BlocksHelper;
|
|
||||||
import ru.betterend.util.MHelper;
|
|
||||||
|
|
||||||
public class BlockHydraluxSapling extends BlockUnderwaterPlantWithAge {
|
|
||||||
@Override
|
|
||||||
public void grow(StructureWorldAccess world, Random random, BlockPos pos) {
|
|
||||||
int h = MHelper.randRange(4, 8, random);
|
|
||||||
Mutable mut = new Mutable().set(pos);
|
|
||||||
|
|
||||||
for (int i = 1; i < h; i++) {
|
|
||||||
mut.setY(pos.getY() + i);
|
|
||||||
if (!world.getBlockState(mut).isOf(Blocks.WATER)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mut.setY(pos.getY());
|
|
||||||
BlockState state = EndBlocks.HYDRALUX.getDefaultState();
|
|
||||||
BlocksHelper.setWithoutUpdate(world, pos, state.with(BlockProperties.HYDRALUX_SHAPE, HydraluxShape.ROOTS));
|
|
||||||
for (int i = 1; i < h - 2; i++) {
|
|
||||||
mut.setY(pos.getY() + i);
|
|
||||||
BlocksHelper.setWithoutUpdate(world, mut, state.with(BlockProperties.HYDRALUX_SHAPE, HydraluxShape.VINE));
|
|
||||||
}
|
|
||||||
|
|
||||||
mut.setY(mut.getY() + 1);
|
|
||||||
boolean big = random.nextBoolean();
|
|
||||||
BlocksHelper.setWithoutUpdate(world, mut, state.with(BlockProperties.HYDRALUX_SHAPE, big ? HydraluxShape.FLOWER_BIG_BOTTOM : HydraluxShape.FLOWER_SMALL_BOTTOM));
|
|
||||||
|
|
||||||
mut.setY(mut.getY() + 1);
|
|
||||||
BlocksHelper.setWithoutUpdate(world, mut, state.with(BlockProperties.HYDRALUX_SHAPE, big ? HydraluxShape.FLOWER_BIG_TOP : HydraluxShape.FLOWER_SMALL_TOP));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean isTerrain(BlockState state) {
|
|
||||||
return state.isOf(EndBlocks.SULPHURIC_ROCK.stone);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,144 +0,0 @@
|
||||||
package ru.betterend.blocks;
|
|
||||||
|
|
||||||
import java.util.Random;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import net.fabricmc.api.EnvType;
|
|
||||||
import net.fabricmc.api.Environment;
|
|
||||||
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
|
||||||
import net.fabricmc.fabric.api.tool.attribute.v1.FabricToolTags;
|
|
||||||
import net.minecraft.block.Block;
|
|
||||||
import net.minecraft.block.BlockEntityProvider;
|
|
||||||
import net.minecraft.block.BlockState;
|
|
||||||
import net.minecraft.block.Blocks;
|
|
||||||
import net.minecraft.block.FluidFillable;
|
|
||||||
import net.minecraft.block.Material;
|
|
||||||
import net.minecraft.block.ShapeContext;
|
|
||||||
import net.minecraft.block.Waterloggable;
|
|
||||||
import net.minecraft.block.entity.BlockEntity;
|
|
||||||
import net.minecraft.entity.LivingEntity;
|
|
||||||
import net.minecraft.fluid.Fluid;
|
|
||||||
import net.minecraft.fluid.FluidState;
|
|
||||||
import net.minecraft.fluid.Fluids;
|
|
||||||
import net.minecraft.item.ItemPlacementContext;
|
|
||||||
import net.minecraft.item.ItemStack;
|
|
||||||
import net.minecraft.particle.ParticleTypes;
|
|
||||||
import net.minecraft.server.world.ServerWorld;
|
|
||||||
import net.minecraft.sound.BlockSoundGroup;
|
|
||||||
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.Direction;
|
|
||||||
import net.minecraft.util.shape.VoxelShape;
|
|
||||||
import net.minecraft.world.BlockView;
|
|
||||||
import net.minecraft.world.World;
|
|
||||||
import net.minecraft.world.WorldAccess;
|
|
||||||
import net.minecraft.world.WorldView;
|
|
||||||
import ru.betterend.blocks.basis.BlockBaseNotFull;
|
|
||||||
import ru.betterend.blocks.entities.BlockEntityHydrothermalVent;
|
|
||||||
import ru.betterend.registry.EndBlocks;
|
|
||||||
import ru.betterend.registry.EndParticles;
|
|
||||||
import ru.betterend.util.BlocksHelper;
|
|
||||||
|
|
||||||
public class BlockHydrothermalVent extends BlockBaseNotFull implements BlockEntityProvider, FluidFillable, Waterloggable {
|
|
||||||
public static final BooleanProperty WATERLOGGED = Properties.WATERLOGGED;
|
|
||||||
public static final BooleanProperty ACTIVATED = BlockProperties.ACTIVE;
|
|
||||||
private static final VoxelShape SHAPE = Block.createCuboidShape(1, 1, 1, 15, 16, 15);
|
|
||||||
|
|
||||||
public BlockHydrothermalVent() {
|
|
||||||
super(FabricBlockSettings.of(Material.STONE)
|
|
||||||
.breakByTool(FabricToolTags.PICKAXES)
|
|
||||||
.sounds(BlockSoundGroup.STONE)
|
|
||||||
.noCollision()
|
|
||||||
.requiresTool());
|
|
||||||
this.setDefaultState(getDefaultState().with(WATERLOGGED, true).with(ACTIVATED, false));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
|
|
||||||
builder.add(WATERLOGGED, ACTIVATED);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public VoxelShape getOutlineShape(BlockState state, BlockView view, BlockPos pos, ShapeContext ePos) {
|
|
||||||
return SHAPE;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean canFillWithFluid(BlockView world, BlockPos pos, BlockState state, Fluid fluid) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean tryFillWithFluid(WorldAccess world, BlockPos pos, BlockState state, FluidState fluidState) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean canPlaceAt(BlockState state, WorldView world, BlockPos pos) {
|
|
||||||
state = world.getBlockState(pos.down());
|
|
||||||
return state.isOf(EndBlocks.SULPHURIC_ROCK.stone);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BlockState getStateForNeighborUpdate(BlockState state, Direction facing, BlockState neighborState, WorldAccess world, BlockPos pos, BlockPos neighborPos) {
|
|
||||||
if (!canPlaceAt(state, world, pos)) {
|
|
||||||
return Blocks.WATER.getDefaultState();
|
|
||||||
}
|
|
||||||
else if (state.get(WATERLOGGED) && facing == Direction.UP && neighborState.isOf(Blocks.WATER)) {
|
|
||||||
world.getBlockTickScheduler().schedule(pos, this, 20);
|
|
||||||
}
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BlockState getPlacementState(ItemPlacementContext ctx) {
|
|
||||||
WorldAccess worldAccess = ctx.getWorld();
|
|
||||||
BlockPos blockPos = ctx.getBlockPos();
|
|
||||||
return this.getDefaultState().with(WATERLOGGED, worldAccess.getFluidState(blockPos).getFluid() == Fluids.WATER);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public FluidState getFluidState(BlockState state) {
|
|
||||||
return (Boolean) state.get(WATERLOGGED) ? Fluids.WATER.getStill(false) : super.getFluidState(state);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BlockEntity createBlockEntity(BlockView world) {
|
|
||||||
return new BlockEntityHydrothermalVent();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void scheduledTick(BlockState state, ServerWorld world, BlockPos pos, Random random) {
|
|
||||||
BlockPos up = pos.up();
|
|
||||||
if (world.getBlockState(up).isOf(Blocks.WATER)) {
|
|
||||||
BlocksHelper.setWithoutUpdate(world, up, EndBlocks.VENT_BUBBLE_COLUMN);
|
|
||||||
world.getBlockTickScheduler().schedule(up, EndBlocks.VENT_BUBBLE_COLUMN, 5);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onPlaced(World world, BlockPos pos, BlockState state, @Nullable LivingEntity placer, ItemStack itemStack) {
|
|
||||||
if (world instanceof ServerWorld && state.get(WATERLOGGED) && world.getBlockState(pos.up()).isOf(Blocks.WATER)) {
|
|
||||||
scheduledTick(state,(ServerWorld) world, pos, world.random);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Environment(EnvType.CLIENT)
|
|
||||||
public void randomDisplayTick(BlockState state, World world, BlockPos pos, Random random) {
|
|
||||||
if (!state.get(ACTIVATED) && random.nextBoolean()) {
|
|
||||||
super.randomDisplayTick(state, world, pos, random);
|
|
||||||
double x = pos.getX() + random.nextDouble();
|
|
||||||
double y = pos.getY() + 0.9 + random.nextDouble() * 0.3;
|
|
||||||
double z = pos.getZ() + random.nextDouble();
|
|
||||||
if (state.get(WATERLOGGED)) {
|
|
||||||
world.addParticle(EndParticles.GEYSER_PARTICLE, x, y, z, 0, 0, 0);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
world.addParticle(ParticleTypes.SMOKE, x, y, z, 0, 0, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,25 +0,0 @@
|
||||||
package ru.betterend.blocks;
|
|
||||||
|
|
||||||
import net.minecraft.block.BlockState;
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
|
||||||
import net.minecraft.world.WorldView;
|
|
||||||
import net.minecraft.world.gen.feature.Feature;
|
|
||||||
import ru.betterend.blocks.basis.BlockFeatureSapling;
|
|
||||||
import ru.betterend.registry.EndBlocks;
|
|
||||||
import ru.betterend.registry.EndFeatures;
|
|
||||||
|
|
||||||
public class BlockLacugroveSapling extends BlockFeatureSapling {
|
|
||||||
public BlockLacugroveSapling() {
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Feature<?> getFeature() {
|
|
||||||
return EndFeatures.LACUGROVE.getFeature();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean canPlaceAt(BlockState state, WorldView world, BlockPos pos) {
|
|
||||||
return world.getBlockState(pos.down()).isOf(EndBlocks.END_MOSS) || world.getBlockState(pos.down()).isOf(EndBlocks.ENDSTONE_DUST);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,53 +0,0 @@
|
||||||
package ru.betterend.blocks;
|
|
||||||
|
|
||||||
import net.minecraft.block.Block;
|
|
||||||
import net.minecraft.block.BlockState;
|
|
||||||
import net.minecraft.block.Blocks;
|
|
||||||
import net.minecraft.state.StateManager;
|
|
||||||
import net.minecraft.state.property.EnumProperty;
|
|
||||||
import net.minecraft.state.property.IntProperty;
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
|
||||||
import net.minecraft.util.math.Direction;
|
|
||||||
import net.minecraft.world.WorldAccess;
|
|
||||||
import net.minecraft.world.WorldView;
|
|
||||||
import ru.betterend.blocks.BlockProperties.PentaShape;
|
|
||||||
import ru.betterend.blocks.basis.BlockPlant;
|
|
||||||
import ru.betterend.registry.EndBlocks;
|
|
||||||
|
|
||||||
public class BlockLanceleaf extends BlockPlant {
|
|
||||||
public static final EnumProperty<PentaShape> SHAPE = BlockProperties.PENTA_SHAPE;
|
|
||||||
public static final IntProperty ROTATION = BlockProperties.ROTATION;
|
|
||||||
|
|
||||||
public BlockLanceleaf() {
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void appendProperties(StateManager.Builder<Block, BlockState> stateManager) {
|
|
||||||
stateManager.add(SHAPE, ROTATION);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean canPlaceAt(BlockState state, WorldView world, BlockPos pos) {
|
|
||||||
PentaShape shape = state.get(SHAPE);
|
|
||||||
if (shape == PentaShape.TOP) {
|
|
||||||
return world.getBlockState(pos.down()).isOf(this);
|
|
||||||
}
|
|
||||||
else if (shape == PentaShape.BOTTOM) {
|
|
||||||
return world.getBlockState(pos.down()).isOf(EndBlocks.AMBER_MOSS) && world.getBlockState(pos.up()).isOf(this);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return world.getBlockState(pos.down()).isOf(this) && world.getBlockState(pos.up()).isOf(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BlockState getStateForNeighborUpdate(BlockState state, Direction facing, BlockState neighborState, WorldAccess world, BlockPos pos, BlockPos neighborPos) {
|
|
||||||
if (!canPlaceAt(state, world, pos)) {
|
|
||||||
return Blocks.AIR.getDefaultState();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,40 +0,0 @@
|
||||||
package ru.betterend.blocks;
|
|
||||||
|
|
||||||
import java.util.Random;
|
|
||||||
|
|
||||||
import net.minecraft.block.BlockState;
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
|
||||||
import net.minecraft.util.math.BlockPos.Mutable;
|
|
||||||
import net.minecraft.util.math.Direction;
|
|
||||||
import net.minecraft.world.StructureWorldAccess;
|
|
||||||
import ru.betterend.blocks.BlockProperties.PentaShape;
|
|
||||||
import ru.betterend.blocks.basis.BlockPlantWithAge;
|
|
||||||
import ru.betterend.registry.EndBlocks;
|
|
||||||
import ru.betterend.util.BlocksHelper;
|
|
||||||
import ru.betterend.util.MHelper;
|
|
||||||
|
|
||||||
public class BlockLanceleafSeed extends BlockPlantWithAge {
|
|
||||||
@Override
|
|
||||||
public void growAdult(StructureWorldAccess world, Random random, BlockPos pos) {
|
|
||||||
int height = MHelper.randRange(4, 6, random);
|
|
||||||
int h = BlocksHelper.upRay(world, pos, height + 2);
|
|
||||||
if (h < height + 1) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
int rotation = random.nextInt(4);
|
|
||||||
Mutable mut = new Mutable().set(pos);
|
|
||||||
BlockState plant = EndBlocks.LANCELEAF.getDefaultState().with(BlockProperties.ROTATION, rotation);
|
|
||||||
BlocksHelper.setWithoutUpdate(world, mut, plant.with(BlockProperties.PENTA_SHAPE, PentaShape.BOTTOM));
|
|
||||||
BlocksHelper.setWithoutUpdate(world, mut.move(Direction.UP), plant.with(BlockProperties.PENTA_SHAPE, PentaShape.PRE_BOTTOM));
|
|
||||||
for (int i = 2; i < height - 2; i++) {
|
|
||||||
BlocksHelper.setWithoutUpdate(world, mut.move(Direction.UP), plant.with(BlockProperties.PENTA_SHAPE, PentaShape.MIDDLE));
|
|
||||||
}
|
|
||||||
BlocksHelper.setWithoutUpdate(world, mut.move(Direction.UP), plant.with(BlockProperties.PENTA_SHAPE, PentaShape.PRE_TOP));
|
|
||||||
BlocksHelper.setWithoutUpdate(world, mut.move(Direction.UP), plant.with(BlockProperties.PENTA_SHAPE, PentaShape.TOP));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean isTerrain(BlockState state) {
|
|
||||||
return state.isOf(EndBlocks.AMBER_MOSS);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,103 +0,0 @@
|
||||||
package ru.betterend.blocks;
|
|
||||||
|
|
||||||
import java.util.Queue;
|
|
||||||
|
|
||||||
import com.google.common.collect.Lists;
|
|
||||||
|
|
||||||
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
|
||||||
import net.minecraft.block.BlockState;
|
|
||||||
import net.minecraft.block.Blocks;
|
|
||||||
import net.minecraft.block.FluidBlock;
|
|
||||||
import net.minecraft.block.FluidDrainable;
|
|
||||||
import net.minecraft.block.Material;
|
|
||||||
import net.minecraft.block.entity.BlockEntity;
|
|
||||||
import net.minecraft.fluid.FluidState;
|
|
||||||
import net.minecraft.fluid.Fluids;
|
|
||||||
import net.minecraft.tag.FluidTags;
|
|
||||||
import net.minecraft.util.Pair;
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
|
||||||
import net.minecraft.util.math.Direction;
|
|
||||||
import net.minecraft.world.World;
|
|
||||||
import net.minecraft.world.WorldAccess;
|
|
||||||
import ru.betterend.blocks.basis.BlockBaseNotFull;
|
|
||||||
import ru.betterend.client.render.ERenderLayer;
|
|
||||||
import ru.betterend.interfaces.IRenderTypeable;
|
|
||||||
import ru.betterend.registry.EndBlocks;
|
|
||||||
|
|
||||||
public class BlockMengerSponge extends BlockBaseNotFull implements IRenderTypeable {
|
|
||||||
public BlockMengerSponge() {
|
|
||||||
super(FabricBlockSettings.copyOf(Blocks.SPONGE).nonOpaque());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onBlockAdded(BlockState state, World world, BlockPos pos, BlockState oldState, boolean notify) {
|
|
||||||
if (absorbWater(world, pos)) {
|
|
||||||
world.setBlockState(pos, EndBlocks.MENGER_SPONGE_WET.getDefaultState());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BlockState getStateForNeighborUpdate(BlockState state, Direction facing, BlockState neighborState, WorldAccess world, BlockPos pos, BlockPos neighborPos) {
|
|
||||||
if (absorbWater(world, pos)) {
|
|
||||||
return EndBlocks.MENGER_SPONGE_WET.getDefaultState();
|
|
||||||
}
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean absorbWater(WorldAccess world, BlockPos pos) {
|
|
||||||
Queue<Pair<BlockPos, Integer>> queue = Lists.newLinkedList();
|
|
||||||
queue.add(new Pair<BlockPos, Integer>(pos, 0));
|
|
||||||
int i = 0;
|
|
||||||
|
|
||||||
while (!queue.isEmpty()) {
|
|
||||||
Pair<BlockPos, Integer> pair = queue.poll();
|
|
||||||
BlockPos blockPos = (BlockPos) pair.getLeft();
|
|
||||||
int j = (Integer) pair.getRight();
|
|
||||||
Direction[] var8 = Direction.values();
|
|
||||||
int var9 = var8.length;
|
|
||||||
|
|
||||||
for (int var10 = 0; var10 < var9; ++var10) {
|
|
||||||
Direction direction = var8[var10];
|
|
||||||
BlockPos blockPos2 = blockPos.offset(direction);
|
|
||||||
BlockState blockState = world.getBlockState(blockPos2);
|
|
||||||
FluidState fluidState = world.getFluidState(blockPos2);
|
|
||||||
Material material = blockState.getMaterial();
|
|
||||||
if (fluidState.isIn(FluidTags.WATER)) {
|
|
||||||
if (blockState.getBlock() instanceof FluidDrainable && ((FluidDrainable) blockState.getBlock()).tryDrainFluid(world, blockPos2, blockState) != Fluids.EMPTY) {
|
|
||||||
++i;
|
|
||||||
if (j < 6) {
|
|
||||||
queue.add(new Pair<BlockPos, Integer>(blockPos2, j + 1));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (blockState.getBlock() instanceof FluidBlock) {
|
|
||||||
world.setBlockState(blockPos2, Blocks.AIR.getDefaultState(), 3);
|
|
||||||
++i;
|
|
||||||
if (j < 6) {
|
|
||||||
queue.add(new Pair<BlockPos, Integer>(blockPos2, j + 1));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (material == Material.UNDERWATER_PLANT || material == Material.REPLACEABLE_UNDERWATER_PLANT) {
|
|
||||||
BlockEntity blockEntity = blockState.getBlock().hasBlockEntity() ? world.getBlockEntity(blockPos2) : null;
|
|
||||||
dropStacks(blockState, world, blockPos2, blockEntity);
|
|
||||||
world.setBlockState(blockPos2, Blocks.AIR.getDefaultState(), 3);
|
|
||||||
++i;
|
|
||||||
if (j < 6) {
|
|
||||||
queue.add(new Pair<BlockPos, Integer>(blockPos2, j + 1));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (i > 64) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return i > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ERenderLayer getRenderLayer() {
|
|
||||||
return ERenderLayer.CUTOUT;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,97 +0,0 @@
|
||||||
package ru.betterend.blocks;
|
|
||||||
|
|
||||||
import java.util.Random;
|
|
||||||
|
|
||||||
import net.fabricmc.api.EnvType;
|
|
||||||
import net.fabricmc.api.Environment;
|
|
||||||
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
|
||||||
import net.minecraft.block.BlockState;
|
|
||||||
import net.minecraft.block.Blocks;
|
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
|
||||||
import net.minecraft.fluid.FluidState;
|
|
||||||
import net.minecraft.fluid.Fluids;
|
|
||||||
import net.minecraft.particle.ParticleTypes;
|
|
||||||
import net.minecraft.sound.SoundCategory;
|
|
||||||
import net.minecraft.sound.SoundEvents;
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
|
||||||
import net.minecraft.util.math.Direction;
|
|
||||||
import net.minecraft.world.World;
|
|
||||||
import ru.betterend.blocks.basis.BlockBaseNotFull;
|
|
||||||
import ru.betterend.client.render.ERenderLayer;
|
|
||||||
import ru.betterend.interfaces.IRenderTypeable;
|
|
||||||
import ru.betterend.registry.EndBlocks;
|
|
||||||
import ru.betterend.util.BlocksHelper;
|
|
||||||
|
|
||||||
public class BlockMengerSpongeWet extends BlockBaseNotFull implements IRenderTypeable {
|
|
||||||
public BlockMengerSpongeWet() {
|
|
||||||
super(FabricBlockSettings.copyOf(Blocks.WET_SPONGE).nonOpaque());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onBlockAdded(BlockState state, World world, BlockPos pos, BlockState oldState, boolean notify) {
|
|
||||||
if (world.getDimension().isUltrawarm()) {
|
|
||||||
world.setBlockState(pos, EndBlocks.MENGER_SPONGE.getDefaultState(), 3);
|
|
||||||
world.syncWorldEvent(2009, pos, 0);
|
|
||||||
world.playSound((PlayerEntity) null, pos, SoundEvents.BLOCK_FIRE_EXTINGUISH, SoundCategory.BLOCKS, 1.0F, (1.0F + world.getRandom().nextFloat() * 0.2F) * 0.7F);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Environment(EnvType.CLIENT)
|
|
||||||
public void randomDisplayTick(BlockState state, World world, BlockPos pos, Random random) {
|
|
||||||
Direction direction = Direction.random(random);
|
|
||||||
if (direction != Direction.UP) {
|
|
||||||
BlockPos blockPos = pos.offset(direction);
|
|
||||||
BlockState blockState = world.getBlockState(blockPos);
|
|
||||||
if (!state.isOpaque() || !blockState.isSideSolidFullSquare(world, blockPos, direction.getOpposite())) {
|
|
||||||
double x = (double) pos.getX();
|
|
||||||
double y = (double) pos.getY();
|
|
||||||
double z = (double) pos.getZ();
|
|
||||||
if (direction == Direction.DOWN) {
|
|
||||||
y -= 0.05;
|
|
||||||
x += random.nextDouble();
|
|
||||||
z += random.nextDouble();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
y += random.nextDouble() * 0.8;
|
|
||||||
if (direction.getAxis() == Direction.Axis.X) {
|
|
||||||
z += random.nextDouble();
|
|
||||||
if (direction == Direction.EAST) {
|
|
||||||
++x;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
x += 0.05;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
x += random.nextDouble();
|
|
||||||
if (direction == Direction.SOUTH) {
|
|
||||||
++z;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
z += 0.05;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
world.addParticle(ParticleTypes.DRIPPING_WATER, x, y, z, 0, 0, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onBreak(World world, BlockPos pos, BlockState state, PlayerEntity player) {
|
|
||||||
super.onBreak(world, pos, state, player);
|
|
||||||
BlocksHelper.setWithUpdate(world, pos, Blocks.AIR);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ERenderLayer getRenderLayer() {
|
|
||||||
return ERenderLayer.CUTOUT;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public FluidState getFluidState(BlockState state) {
|
|
||||||
return Fluids.WATER.getStill(false);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,30 +0,0 @@
|
||||||
package ru.betterend.blocks;
|
|
||||||
|
|
||||||
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
|
||||||
import net.fabricmc.fabric.api.tool.attribute.v1.FabricToolTags;
|
|
||||||
import net.minecraft.block.Block;
|
|
||||||
import net.minecraft.block.BlockState;
|
|
||||||
import net.minecraft.block.Material;
|
|
||||||
import net.minecraft.item.ItemPlacementContext;
|
|
||||||
import net.minecraft.sound.BlockSoundGroup;
|
|
||||||
import net.minecraft.state.StateManager;
|
|
||||||
import net.minecraft.state.property.BooleanProperty;
|
|
||||||
import ru.betterend.blocks.basis.BlockBase;
|
|
||||||
import ru.betterend.registry.EndBlocks;
|
|
||||||
|
|
||||||
public class BlockMossyGlowshroomCap extends BlockBase {
|
|
||||||
public static final BooleanProperty TRANSITION = BooleanProperty.of("transition");
|
|
||||||
|
|
||||||
public BlockMossyGlowshroomCap() {
|
|
||||||
super(FabricBlockSettings.of(Material.WOOD).breakByTool(FabricToolTags.AXES).sounds(BlockSoundGroup.WOOD));
|
|
||||||
this.setDefaultState(this.stateManager.getDefaultState().with(TRANSITION, false));
|
|
||||||
}
|
|
||||||
|
|
||||||
public BlockState getPlacementState(ItemPlacementContext ctx) {
|
|
||||||
return this.getDefaultState().with(TRANSITION, EndBlocks.MOSSY_GLOWSHROOM.isTreeLog(ctx.getWorld().getBlockState(ctx.getBlockPos().down())));
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
|
|
||||||
builder.add(TRANSITION);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,25 +0,0 @@
|
||||||
package ru.betterend.blocks;
|
|
||||||
|
|
||||||
import net.minecraft.block.BlockState;
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
|
||||||
import net.minecraft.world.WorldView;
|
|
||||||
import net.minecraft.world.gen.feature.Feature;
|
|
||||||
import ru.betterend.blocks.basis.BlockFeatureSapling;
|
|
||||||
import ru.betterend.registry.EndBlocks;
|
|
||||||
import ru.betterend.registry.EndFeatures;
|
|
||||||
|
|
||||||
public class BlockMossyGlowshroomSapling extends BlockFeatureSapling {
|
|
||||||
public BlockMossyGlowshroomSapling() {
|
|
||||||
super(7);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Feature<?> getFeature() {
|
|
||||||
return EndFeatures.MOSSY_GLOWSHROOM.getFeature();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean canPlaceAt(BlockState state, WorldView world, BlockPos pos) {
|
|
||||||
return world.getBlockState(pos.down()).isOf(EndBlocks.END_MOSS) || world.getBlockState(pos.down()).isOf(EndBlocks.END_MYCELIUM);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,40 +0,0 @@
|
||||||
package ru.betterend.blocks;
|
|
||||||
|
|
||||||
import java.util.Random;
|
|
||||||
|
|
||||||
import net.fabricmc.api.EnvType;
|
|
||||||
import net.fabricmc.api.Environment;
|
|
||||||
import net.minecraft.block.BlockState;
|
|
||||||
import net.minecraft.entity.Entity;
|
|
||||||
import net.minecraft.entity.LivingEntity;
|
|
||||||
import net.minecraft.entity.effect.StatusEffectInstance;
|
|
||||||
import net.minecraft.entity.effect.StatusEffects;
|
|
||||||
import net.minecraft.particle.ParticleTypes;
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
|
||||||
import net.minecraft.world.World;
|
|
||||||
import ru.betterend.blocks.basis.BlockPlant;
|
|
||||||
import ru.betterend.registry.EndBlocks;
|
|
||||||
|
|
||||||
public class BlockMurkweed extends BlockPlant {
|
|
||||||
@Override
|
|
||||||
@Environment(EnvType.CLIENT)
|
|
||||||
public void randomDisplayTick(BlockState state, World world, BlockPos pos, Random random) {
|
|
||||||
double x = pos.getX() + random.nextDouble();
|
|
||||||
double y = pos.getY() + random.nextDouble() * 0.5 + 0.5;
|
|
||||||
double z = pos.getZ() + random.nextDouble();
|
|
||||||
double v = random.nextDouble() * 0.1;
|
|
||||||
world.addParticle(ParticleTypes.ENTITY_EFFECT, x, y, z, v, v, v);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onEntityCollision(BlockState state, World world, BlockPos pos, Entity entity) {
|
|
||||||
if (entity instanceof LivingEntity && !((LivingEntity) entity).hasStatusEffect(StatusEffects.BLINDNESS)) {
|
|
||||||
((LivingEntity) entity).addStatusEffect(new StatusEffectInstance(StatusEffects.BLINDNESS, 50));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean isTerrain(BlockState state) {
|
|
||||||
return state.isOf(EndBlocks.SHADOW_GRASS);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,47 +0,0 @@
|
||||||
package ru.betterend.blocks;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import com.google.common.collect.Lists;
|
|
||||||
|
|
||||||
import net.fabricmc.fabric.api.tool.attribute.v1.FabricToolTags;
|
|
||||||
import net.minecraft.block.BlockState;
|
|
||||||
import net.minecraft.enchantment.EnchantmentHelper;
|
|
||||||
import net.minecraft.enchantment.Enchantments;
|
|
||||||
import net.minecraft.entity.Entity;
|
|
||||||
import net.minecraft.entity.LivingEntity;
|
|
||||||
import net.minecraft.entity.damage.DamageSource;
|
|
||||||
import net.minecraft.item.ItemStack;
|
|
||||||
import net.minecraft.item.Items;
|
|
||||||
import net.minecraft.loot.context.LootContext;
|
|
||||||
import net.minecraft.loot.context.LootContextParameters;
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
|
||||||
import net.minecraft.world.World;
|
|
||||||
import ru.betterend.blocks.basis.BlockPlant;
|
|
||||||
import ru.betterend.registry.EndBlocks;
|
|
||||||
import ru.betterend.util.MHelper;
|
|
||||||
|
|
||||||
public class BlockNeedlegrass extends BlockPlant {
|
|
||||||
@Override
|
|
||||||
public void onEntityCollision(BlockState state, World world, BlockPos pos, Entity entity) {
|
|
||||||
if (entity instanceof LivingEntity) {
|
|
||||||
entity.damage(DamageSource.CACTUS, 0.1F);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<ItemStack> getDroppedStacks(BlockState state, LootContext.Builder builder) {
|
|
||||||
ItemStack tool = builder.get(LootContextParameters.TOOL);
|
|
||||||
if (tool != null && tool.getItem().isIn(FabricToolTags.SHEARS) || EnchantmentHelper.getLevel(Enchantments.SILK_TOUCH, tool) > 0) {
|
|
||||||
return Lists.newArrayList(new ItemStack(this));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return Lists.newArrayList(new ItemStack(Items.STICK, MHelper.randRange(0, 2, MHelper.RANDOM)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean isTerrain(BlockState state) {
|
|
||||||
return state.isOf(EndBlocks.SHADOW_GRASS);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,50 +0,0 @@
|
||||||
package ru.betterend.blocks;
|
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
|
||||||
import net.minecraft.block.Block;
|
|
||||||
import net.minecraft.block.BlockState;
|
|
||||||
import net.minecraft.block.Blocks;
|
|
||||||
import net.minecraft.block.ShapeContext;
|
|
||||||
import net.minecraft.enchantment.EnchantmentHelper;
|
|
||||||
import net.minecraft.enchantment.Enchantments;
|
|
||||||
import net.minecraft.item.ItemStack;
|
|
||||||
import net.minecraft.loot.context.LootContext;
|
|
||||||
import net.minecraft.loot.context.LootContextParameters;
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
|
||||||
import net.minecraft.util.shape.VoxelShape;
|
|
||||||
import net.minecraft.world.BlockView;
|
|
||||||
import ru.betterend.blocks.basis.BlockBaseNotFull;
|
|
||||||
|
|
||||||
public class BlockPath extends BlockBaseNotFull {
|
|
||||||
private static final VoxelShape SHAPE = Block.createCuboidShape(0, 0, 0, 16, 15, 16);
|
|
||||||
|
|
||||||
public BlockPath(Block source) {
|
|
||||||
super(FabricBlockSettings.copyOf(source).allowsSpawning((state, world, pos, type) -> { return false; }));
|
|
||||||
if (source instanceof BlockTerrain) {
|
|
||||||
BlockTerrain terrain = (BlockTerrain) source;
|
|
||||||
terrain.setPathBlock(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<ItemStack> getDroppedStacks(BlockState state, LootContext.Builder builder) {
|
|
||||||
ItemStack tool = builder.get(LootContextParameters.TOOL);
|
|
||||||
if (tool != null && EnchantmentHelper.getLevel(Enchantments.SILK_TOUCH, tool) > 0) {
|
|
||||||
return Collections.singletonList(new ItemStack(this));
|
|
||||||
}
|
|
||||||
return Collections.singletonList(new ItemStack(Blocks.END_STONE));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public VoxelShape getOutlineShape(BlockState state, BlockView view, BlockPos pos, ShapeContext ePos) {
|
|
||||||
return SHAPE;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public VoxelShape getCollisionShape(BlockState state, BlockView view, BlockPos pos, ShapeContext ePos) {
|
|
||||||
return SHAPE;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,33 +1,50 @@
|
||||||
package ru.betterend.blocks;
|
package ru.betterend.blocks;
|
||||||
|
|
||||||
import net.minecraft.state.property.BooleanProperty;
|
import net.minecraft.util.StringRepresentable;
|
||||||
import net.minecraft.state.property.EnumProperty;
|
import net.minecraft.world.level.block.state.properties.BooleanProperty;
|
||||||
import net.minecraft.state.property.IntProperty;
|
import net.minecraft.world.level.block.state.properties.EnumProperty;
|
||||||
import net.minecraft.util.StringIdentifiable;
|
import net.minecraft.world.level.block.state.properties.IntegerProperty;
|
||||||
|
import ru.betterend.registry.EndPortals;
|
||||||
|
|
||||||
public class BlockProperties {
|
public class BlockProperties {
|
||||||
public static final EnumProperty<TripleShape> TRIPLE_SHAPE = EnumProperty.of("shape", TripleShape.class);
|
public static final EnumProperty<HydraluxShape> HYDRALUX_SHAPE = EnumProperty.create("shape", HydraluxShape.class);
|
||||||
public final static EnumProperty<PedestalState> PEDESTAL_STATE = EnumProperty.of("state", PedestalState.class);
|
public static final EnumProperty<PedestalState> PEDESTAL_STATE = EnumProperty.create("state", PedestalState.class);
|
||||||
public static final EnumProperty<HydraluxShape> HYDRALUX_SHAPE = EnumProperty.of("shape", HydraluxShape.class);
|
public static final EnumProperty<CactusBottom> CACTUS_BOTTOM = EnumProperty.create("bottom", CactusBottom.class);
|
||||||
public static final EnumProperty<PentaShape> PENTA_SHAPE = EnumProperty.of("shape", PentaShape.class);
|
public static final EnumProperty<TripleShape> TRIPLE_SHAPE = EnumProperty.create("shape", TripleShape.class);
|
||||||
public static final BooleanProperty HAS_ITEM = BooleanProperty.of("has_item");
|
public static final EnumProperty<PentaShape> PENTA_SHAPE = EnumProperty.create("shape", PentaShape.class);
|
||||||
public static final BooleanProperty HAS_LIGHT = BooleanProperty.of("has_light");
|
|
||||||
public static final BooleanProperty ACTIVE = BooleanProperty.of("active");
|
|
||||||
public static final IntProperty ROTATION = IntProperty.of("rotation", 0, 3);
|
|
||||||
|
|
||||||
public static enum TripleShape implements StringIdentifiable {
|
public static final BooleanProperty TRANSITION = BooleanProperty.create("transition");
|
||||||
TOP("top"),
|
public static final BooleanProperty HAS_LIGHT = BooleanProperty.create("has_light");
|
||||||
MIDDLE("middle"),
|
public static final BooleanProperty HAS_ITEM = BooleanProperty.create("has_item");
|
||||||
BOTTOM("bottom");
|
public static final BooleanProperty IS_FLOOR = BooleanProperty.create("is_floor");
|
||||||
|
public static final BooleanProperty NATURAL = BooleanProperty.create("natural");
|
||||||
|
public static final BooleanProperty ACTIVE = BooleanProperty.create("active");
|
||||||
|
public static final BooleanProperty SMALL = BooleanProperty.create("small");
|
||||||
|
|
||||||
|
public static final IntegerProperty DESTRUCTION_LONG = IntegerProperty.create("destruction", 0, 8);
|
||||||
|
public static final IntegerProperty DESTRUCTION = IntegerProperty.create("destruction", 0, 2);
|
||||||
|
public static final IntegerProperty ROTATION = IntegerProperty.create("rotation", 0, 3);
|
||||||
|
public static final IntegerProperty FULLNESS = IntegerProperty.create("fullness", 0, 3);
|
||||||
|
public static final IntegerProperty COLOR = IntegerProperty.create("color", 0, 7);
|
||||||
|
public static final IntegerProperty PORTAL = IntegerProperty.create("portal", 0, EndPortals.getCount());
|
||||||
|
public static final IntegerProperty SIZE = IntegerProperty.create("size", 0, 7);
|
||||||
|
public static final IntegerProperty AGE = IntegerProperty.create("age", 0, 3);
|
||||||
|
|
||||||
|
public static enum TripleShape implements StringRepresentable {
|
||||||
|
TOP("top", 0),
|
||||||
|
MIDDLE("middle", 1),
|
||||||
|
BOTTOM("bottom", 2);
|
||||||
|
|
||||||
private final String name;
|
private final String name;
|
||||||
|
private final int index;
|
||||||
|
|
||||||
TripleShape(String name) {
|
TripleShape(String name, int index) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
|
this.index = index;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String asString() {
|
public String getSerializedName() {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,9 +52,17 @@ public class BlockProperties {
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getIndex() {
|
||||||
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static enum PedestalState implements StringIdentifiable {
|
public static TripleShape fromIndex(int index) {
|
||||||
|
return index > 1 ? BOTTOM : index == 1 ? MIDDLE : TOP;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static enum PedestalState implements StringRepresentable {
|
||||||
PEDESTAL_TOP("pedestal_top"),
|
PEDESTAL_TOP("pedestal_top"),
|
||||||
COLUMN_TOP("column_top"),
|
COLUMN_TOP("column_top"),
|
||||||
BOTTOM("bottom"),
|
BOTTOM("bottom"),
|
||||||
|
@ -52,7 +77,7 @@ public class BlockProperties {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String asString() {
|
public String getSerializedName() {
|
||||||
return this.name;
|
return this.name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,7 +87,7 @@ public class BlockProperties {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static enum HydraluxShape implements StringIdentifiable {
|
public static enum HydraluxShape implements StringRepresentable {
|
||||||
FLOWER_BIG_BOTTOM("flower_big_bottom", true),
|
FLOWER_BIG_BOTTOM("flower_big_bottom", true),
|
||||||
FLOWER_BIG_TOP("flower_big_top", true),
|
FLOWER_BIG_TOP("flower_big_top", true),
|
||||||
FLOWER_SMALL_BOTTOM("flower_small_bottom", true),
|
FLOWER_SMALL_BOTTOM("flower_small_bottom", true),
|
||||||
|
@ -79,7 +104,7 @@ public class BlockProperties {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String asString() {
|
public String getSerializedName() {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,7 +118,7 @@ public class BlockProperties {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static enum PentaShape implements StringIdentifiable {
|
public static enum PentaShape implements StringRepresentable {
|
||||||
BOTTOM("bottom"),
|
BOTTOM("bottom"),
|
||||||
PRE_BOTTOM("pre_bottom"),
|
PRE_BOTTOM("pre_bottom"),
|
||||||
MIDDLE("middle"),
|
MIDDLE("middle"),
|
||||||
|
@ -107,7 +132,61 @@ public class BlockProperties {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String asString() {
|
public String getSerializedName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static enum LumecornShape implements StringRepresentable {
|
||||||
|
LIGHT_TOP("light_top", 15),
|
||||||
|
LIGHT_TOP_MIDDLE("light_top_middle", 15),
|
||||||
|
LIGHT_MIDDLE("light_middle", 15),
|
||||||
|
LIGHT_BOTTOM("light_bottom", 15),
|
||||||
|
MIDDLE("middle", 0),
|
||||||
|
BOTTOM_BIG("bottom_big", 0),
|
||||||
|
BOTTOM_SMALL("bottom_small", 0);
|
||||||
|
|
||||||
|
private final String name;
|
||||||
|
private final int light;
|
||||||
|
|
||||||
|
LumecornShape(String name, int light) {
|
||||||
|
this.name = name;
|
||||||
|
this.light = light;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getSerializedName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getLight() {
|
||||||
|
return light;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static enum CactusBottom implements StringRepresentable {
|
||||||
|
EMPTY("empty"),
|
||||||
|
SAND("sand"),
|
||||||
|
MOSS("moss");
|
||||||
|
|
||||||
|
private final String name;
|
||||||
|
|
||||||
|
CactusBottom(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getSerializedName() {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,25 +0,0 @@
|
||||||
package ru.betterend.blocks;
|
|
||||||
|
|
||||||
import net.minecraft.block.BlockState;
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
|
||||||
import net.minecraft.world.WorldView;
|
|
||||||
import net.minecraft.world.gen.feature.Feature;
|
|
||||||
import ru.betterend.blocks.basis.BlockFeatureSapling;
|
|
||||||
import ru.betterend.registry.EndBlocks;
|
|
||||||
import ru.betterend.registry.EndFeatures;
|
|
||||||
|
|
||||||
public class BlockPythadendronSapling extends BlockFeatureSapling {
|
|
||||||
public BlockPythadendronSapling() {
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Feature<?> getFeature() {
|
|
||||||
return EndFeatures.PYTHADENDRON_TREE.getFeature();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean canPlaceAt(BlockState state, WorldView world, BlockPos pos) {
|
|
||||||
return world.getBlockState(pos.down()).isOf(EndBlocks.CHORUS_NYLIUM);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,202 +0,0 @@
|
||||||
package ru.betterend.blocks;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import com.google.common.collect.Lists;
|
|
||||||
|
|
||||||
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
|
||||||
import net.minecraft.block.Block;
|
|
||||||
import net.minecraft.block.BlockState;
|
|
||||||
import net.minecraft.block.Blocks;
|
|
||||||
import net.minecraft.block.ShapeContext;
|
|
||||||
import net.minecraft.client.color.block.BlockColorProvider;
|
|
||||||
import net.minecraft.client.color.item.ItemColorProvider;
|
|
||||||
import net.minecraft.entity.LivingEntity;
|
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
|
||||||
import net.minecraft.item.BlockItem;
|
|
||||||
import net.minecraft.item.ItemStack;
|
|
||||||
import net.minecraft.loot.context.LootContext;
|
|
||||||
import net.minecraft.server.network.ServerPlayerEntity;
|
|
||||||
import net.minecraft.server.world.ServerWorld;
|
|
||||||
import net.minecraft.sound.SoundCategory;
|
|
||||||
import net.minecraft.sound.SoundEvents;
|
|
||||||
import net.minecraft.state.StateManager;
|
|
||||||
import net.minecraft.state.property.EnumProperty;
|
|
||||||
import net.minecraft.text.TranslatableText;
|
|
||||||
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.util.math.Direction;
|
|
||||||
import net.minecraft.util.shape.VoxelShape;
|
|
||||||
import net.minecraft.world.BlockView;
|
|
||||||
import net.minecraft.world.World;
|
|
||||||
import net.minecraft.world.WorldAccess;
|
|
||||||
import net.minecraft.world.WorldView;
|
|
||||||
import ru.betterend.blocks.BlockProperties.TripleShape;
|
|
||||||
import ru.betterend.blocks.basis.BlockBase;
|
|
||||||
import ru.betterend.client.render.ERenderLayer;
|
|
||||||
import ru.betterend.interfaces.IColorProvider;
|
|
||||||
import ru.betterend.interfaces.IRenderTypeable;
|
|
||||||
import ru.betterend.particle.InfusionParticleType;
|
|
||||||
import ru.betterend.registry.EndBlocks;
|
|
||||||
import ru.betterend.registry.EndItems;
|
|
||||||
import ru.betterend.util.BlocksHelper;
|
|
||||||
import ru.betterend.util.MHelper;
|
|
||||||
|
|
||||||
public class BlockRespawnObelisk extends BlockBase implements IColorProvider, IRenderTypeable {
|
|
||||||
private static final VoxelShape VOXEL_SHAPE_BOTTOM = Block.createCuboidShape(1, 0, 1, 15, 16, 15);
|
|
||||||
private static final VoxelShape VOXEL_SHAPE_MIDDLE_TOP = Block.createCuboidShape(2, 0, 2, 14, 16, 14);
|
|
||||||
|
|
||||||
public static final EnumProperty<TripleShape> SHAPE = BlockProperties.TRIPLE_SHAPE;
|
|
||||||
|
|
||||||
public BlockRespawnObelisk() {
|
|
||||||
super(FabricBlockSettings.copyOf(Blocks.END_STONE).luminance((state) -> {
|
|
||||||
return (state.get(SHAPE) == TripleShape.BOTTOM) ? 0 : 15;
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public VoxelShape getOutlineShape(BlockState state, BlockView view, BlockPos pos, ShapeContext ePos) {
|
|
||||||
return (state.get(SHAPE) == TripleShape.BOTTOM) ? VOXEL_SHAPE_BOTTOM : VOXEL_SHAPE_MIDDLE_TOP;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void appendProperties(StateManager.Builder<Block, BlockState> stateManager) {
|
|
||||||
stateManager.add(SHAPE);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean canPlaceAt(BlockState state, WorldView world, BlockPos pos) {
|
|
||||||
for (int i = 0; i < 3; i++) {
|
|
||||||
if (!world.getBlockState(pos.up(i)).getMaterial().isReplaceable()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onPlaced(World world, BlockPos pos, BlockState state, @Nullable LivingEntity placer, ItemStack itemStack) {
|
|
||||||
state = this.getDefaultState();
|
|
||||||
BlocksHelper.setWithUpdate(world, pos, state.with(SHAPE, TripleShape.BOTTOM));
|
|
||||||
BlocksHelper.setWithUpdate(world, pos.up(), state.with(SHAPE, TripleShape.MIDDLE));
|
|
||||||
BlocksHelper.setWithUpdate(world, pos.up(2), state.with(SHAPE, TripleShape.TOP));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BlockState getStateForNeighborUpdate(BlockState state, Direction facing, BlockState neighborState, WorldAccess world, BlockPos pos, BlockPos neighborPos) {
|
|
||||||
TripleShape shape = state.get(SHAPE);
|
|
||||||
if (shape == TripleShape.BOTTOM) {
|
|
||||||
if (world.getBlockState(pos.up()).isOf(this)) {
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return Blocks.AIR.getDefaultState();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (shape == TripleShape.MIDDLE) {
|
|
||||||
if (world.getBlockState(pos.up()).isOf(this) && world.getBlockState(pos.down()).isOf(this)) {
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return Blocks.AIR.getDefaultState();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (world.getBlockState(pos.down()).isOf(this)) {
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return Blocks.AIR.getDefaultState();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onBreak(World world, BlockPos pos, BlockState state, PlayerEntity player) {
|
|
||||||
if (player.isCreative()) {
|
|
||||||
TripleShape shape = state.get(SHAPE);
|
|
||||||
if (shape == TripleShape.MIDDLE) {
|
|
||||||
BlocksHelper.setWithUpdate(world, pos.down(), Blocks.AIR);
|
|
||||||
}
|
|
||||||
else if (shape == TripleShape.TOP) {
|
|
||||||
BlocksHelper.setWithUpdate(world, pos.down(2), Blocks.AIR);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
super.onBreak(world, pos, state, player);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<ItemStack> getDroppedStacks(BlockState state, LootContext.Builder builder) {
|
|
||||||
if (state.get(SHAPE) == TripleShape.BOTTOM) {
|
|
||||||
return Lists.newArrayList(new ItemStack(this));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return Lists.newArrayList();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ERenderLayer getRenderLayer() {
|
|
||||||
return ERenderLayer.TRANSLUCENT;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BlockColorProvider getProvider() {
|
|
||||||
return ((IColorProvider) EndBlocks.AURORA_CRYSTAL).getProvider();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ItemColorProvider getItemProvider() {
|
|
||||||
return (stack, tintIndex) -> {
|
|
||||||
return MHelper.color(255, 255, 255);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) {
|
|
||||||
ItemStack itemStack = player.getStackInHand(hand);
|
|
||||||
boolean canActivate = itemStack.getItem() == EndItems.AMBER_GEM && itemStack.getCount() > 5;
|
|
||||||
if (hand != Hand.MAIN_HAND || !canActivate) {
|
|
||||||
if (!world.isClient && !(itemStack.getItem() instanceof BlockItem) && !player.isCreative()) {
|
|
||||||
ServerPlayerEntity serverPlayerEntity = (ServerPlayerEntity) player;
|
|
||||||
serverPlayerEntity.sendMessage(new TranslatableText("message.betterend.fail_spawn"), true);
|
|
||||||
}
|
|
||||||
return ActionResult.FAIL;
|
|
||||||
}
|
|
||||||
else if (!world.isClient) {
|
|
||||||
ServerPlayerEntity serverPlayerEntity = (ServerPlayerEntity) player;
|
|
||||||
serverPlayerEntity.setSpawnPoint(world.getRegistryKey(), pos, 0.0F, false, false);
|
|
||||||
serverPlayerEntity.sendMessage(new TranslatableText("message.betterend.set_spawn"), true);
|
|
||||||
double px = pos.getX() + 0.5;
|
|
||||||
double py = pos.getY() + 0.5;
|
|
||||||
double pz = pos.getZ() + 0.5;
|
|
||||||
InfusionParticleType particle = new InfusionParticleType(new ItemStack(EndItems.AMBER_GEM));
|
|
||||||
if (world instanceof ServerWorld) {
|
|
||||||
double py1 = py;
|
|
||||||
double py2 = py - 0.2;
|
|
||||||
if (state.get(SHAPE) == TripleShape.BOTTOM) {
|
|
||||||
py1 += 1;
|
|
||||||
py2 += 2;
|
|
||||||
}
|
|
||||||
else if (state.get(SHAPE) == TripleShape.MIDDLE) {
|
|
||||||
py1 += 0;
|
|
||||||
py2 += 1;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
py1 -= 2;
|
|
||||||
}
|
|
||||||
((ServerWorld) world).spawnParticles(particle, px, py1, pz, 20, 0.14, 0.5, 0.14, 0.1);
|
|
||||||
((ServerWorld) world).spawnParticles(particle, px, py2, pz, 20, 0.14, 0.3, 0.14, 0.1);
|
|
||||||
}
|
|
||||||
world.playSound(null, px, py, py, SoundEvents.BLOCK_RESPAWN_ANCHOR_SET_SPAWN, SoundCategory.BLOCKS, 1F, 1F);
|
|
||||||
if (!player.isCreative()) {
|
|
||||||
itemStack.decrement(6);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return player.isCreative() ? ActionResult.PASS : ActionResult.success(world.isClient);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,64 +0,0 @@
|
||||||
package ru.betterend.blocks;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Random;
|
|
||||||
|
|
||||||
import com.google.common.collect.Lists;
|
|
||||||
|
|
||||||
import net.minecraft.block.AbstractBlock;
|
|
||||||
import net.minecraft.block.Block;
|
|
||||||
import net.minecraft.block.BlockState;
|
|
||||||
import net.minecraft.block.ShapeContext;
|
|
||||||
import net.minecraft.item.ItemStack;
|
|
||||||
import net.minecraft.loot.context.LootContext;
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
|
||||||
import net.minecraft.util.shape.VoxelShape;
|
|
||||||
import net.minecraft.world.BlockView;
|
|
||||||
import net.minecraft.world.StructureWorldAccess;
|
|
||||||
import net.minecraft.world.World;
|
|
||||||
import ru.betterend.blocks.basis.BlockPlantWithAge;
|
|
||||||
import ru.betterend.registry.EndBlocks;
|
|
||||||
import ru.betterend.registry.EndItems;
|
|
||||||
import ru.betterend.util.MHelper;
|
|
||||||
|
|
||||||
public class BlockShadowBerry extends BlockPlantWithAge {
|
|
||||||
private static final VoxelShape SHAPE = Block.createCuboidShape(1, 0, 1, 15, 8, 15);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void growAdult(StructureWorldAccess world, Random random, BlockPos pos) {}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<ItemStack> getDroppedStacks(BlockState state, LootContext.Builder builder) {
|
|
||||||
if (state.get(AGE) < 3) {
|
|
||||||
return Lists.newArrayList(new ItemStack(this));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return Lists.newArrayList(new ItemStack(this), new ItemStack(EndItems.SHADOW_BERRY_RAW, MHelper.randRange(1, 3, MHelper.RANDOM)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isFertilizable(BlockView world, BlockPos pos, BlockState state, boolean isClient) {
|
|
||||||
return state.get(AGE) < 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean canGrow(World world, Random random, BlockPos pos, BlockState state) {
|
|
||||||
return state.get(AGE) < 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public VoxelShape getOutlineShape(BlockState state, BlockView view, BlockPos pos, ShapeContext ePos) {
|
|
||||||
return SHAPE;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AbstractBlock.OffsetType getOffsetType() {
|
|
||||||
return AbstractBlock.OffsetType.NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean isTerrain(BlockState state) {
|
|
||||||
return state.isOf(EndBlocks.SHADOW_GRASS);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,25 +0,0 @@
|
||||||
package ru.betterend.blocks;
|
|
||||||
|
|
||||||
import java.util.Random;
|
|
||||||
|
|
||||||
import net.fabricmc.api.EnvType;
|
|
||||||
import net.fabricmc.api.Environment;
|
|
||||||
import net.minecraft.block.BlockState;
|
|
||||||
import net.minecraft.block.MaterialColor;
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
|
||||||
import net.minecraft.world.World;
|
|
||||||
import ru.betterend.registry.EndParticles;
|
|
||||||
|
|
||||||
public class BlockShadowGrass extends BlockTerrain {
|
|
||||||
public BlockShadowGrass() {
|
|
||||||
super(MaterialColor.BLACK);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Environment(EnvType.CLIENT)
|
|
||||||
public void randomDisplayTick(BlockState state, World world, BlockPos pos, Random random) {
|
|
||||||
super.randomDisplayTick(state, world, pos, random);
|
|
||||||
if (random.nextInt(32) == 0) {
|
|
||||||
world.addParticle(EndParticles.BLACK_SPORE, (double) pos.getX() + random.nextDouble(), (double) pos.getY() + 1.1D, (double) pos.getZ() + random.nextDouble(), 0.0D, 0.0D, 0.0D);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,106 +0,0 @@
|
||||||
package ru.betterend.blocks;
|
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
|
||||||
import net.minecraft.block.Block;
|
|
||||||
import net.minecraft.block.BlockState;
|
|
||||||
import net.minecraft.block.Blocks;
|
|
||||||
import net.minecraft.block.Material;
|
|
||||||
import net.minecraft.block.ShapeContext;
|
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
|
||||||
import net.minecraft.item.ItemPlacementContext;
|
|
||||||
import net.minecraft.item.ItemStack;
|
|
||||||
import net.minecraft.loot.context.LootContext;
|
|
||||||
import net.minecraft.sound.BlockSoundGroup;
|
|
||||||
import net.minecraft.state.StateManager;
|
|
||||||
import net.minecraft.state.property.BooleanProperty;
|
|
||||||
import net.minecraft.state.property.DirectionProperty;
|
|
||||||
import net.minecraft.state.property.Properties;
|
|
||||||
import net.minecraft.tag.BlockTags;
|
|
||||||
import net.minecraft.util.BlockMirror;
|
|
||||||
import net.minecraft.util.BlockRotation;
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
|
||||||
import net.minecraft.util.math.Direction;
|
|
||||||
import net.minecraft.util.shape.VoxelShape;
|
|
||||||
import net.minecraft.world.BlockView;
|
|
||||||
import net.minecraft.world.World;
|
|
||||||
import net.minecraft.world.WorldAccess;
|
|
||||||
import ru.betterend.blocks.basis.BlockBase;
|
|
||||||
import ru.betterend.client.render.ERenderLayer;
|
|
||||||
import ru.betterend.interfaces.IRenderTypeable;
|
|
||||||
import ru.betterend.util.BlocksHelper;
|
|
||||||
|
|
||||||
public class BlockSilkMothNest extends BlockBase implements IRenderTypeable {
|
|
||||||
public static final BooleanProperty ACTIVE = BlockProperties.ACTIVE;
|
|
||||||
public static final DirectionProperty FACING = Properties.HORIZONTAL_FACING;
|
|
||||||
private static final VoxelShape TOP = createCuboidShape(6, 0, 6, 10, 16, 10);
|
|
||||||
private static final VoxelShape BOTTOM = createCuboidShape(0, 0, 0, 16, 16, 16);
|
|
||||||
|
|
||||||
public BlockSilkMothNest() {
|
|
||||||
super(FabricBlockSettings.of(Material.WOOL).hardness(0.5F).resistance(0.1F).sounds(BlockSoundGroup.WOOL).nonOpaque());
|
|
||||||
this.setDefaultState(getDefaultState().with(ACTIVE, true));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void appendProperties(StateManager.Builder<Block, BlockState> stateManager) {
|
|
||||||
stateManager.add(ACTIVE, FACING);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public VoxelShape getOutlineShape(BlockState state, BlockView view, BlockPos pos, ShapeContext ePos) {
|
|
||||||
return state.get(ACTIVE) ? BOTTOM : TOP;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ERenderLayer getRenderLayer() {
|
|
||||||
return ERenderLayer.CUTOUT;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BlockState getPlacementState(ItemPlacementContext ctx) {
|
|
||||||
Direction dir = ctx.getPlayerFacing().getOpposite();
|
|
||||||
return this.getDefaultState().with(FACING, dir);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BlockState getStateForNeighborUpdate(BlockState state, Direction facing, BlockState neighborState, WorldAccess world, BlockPos pos, BlockPos neighborPos) {
|
|
||||||
if (!state.get(ACTIVE)) {
|
|
||||||
if (sideCoversSmallSquare(world, pos.up(), Direction.DOWN) || world.getBlockState(pos.up()).isIn(BlockTags.LEAVES)) {
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return Blocks.AIR.getDefaultState();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BlockState rotate(BlockState state, BlockRotation rotation) {
|
|
||||||
return BlocksHelper.rotateHorizontal(state, rotation, FACING);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BlockState mirror(BlockState state, BlockMirror mirror) {
|
|
||||||
return BlocksHelper.mirrorHorizontal(state, mirror, FACING);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<ItemStack> getDroppedStacks(BlockState state, LootContext.Builder builder) {
|
|
||||||
return state.get(ACTIVE) ? Collections.singletonList(new ItemStack(this)) : Collections.emptyList();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onBreak(World world, BlockPos pos, BlockState state, PlayerEntity player) {
|
|
||||||
if (!state.get(ACTIVE) && player.isCreative()) {
|
|
||||||
BlocksHelper.setWithUpdate(world, pos.down(), Blocks.AIR);
|
|
||||||
}
|
|
||||||
BlockState up = world.getBlockState(pos.up());
|
|
||||||
if (up.isOf(this) && !up.get(ACTIVE)) {
|
|
||||||
BlocksHelper.setWithUpdate(world, pos.up(), Blocks.AIR);
|
|
||||||
}
|
|
||||||
super.onBreak(world, pos, state, player);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,13 +1,13 @@
|
||||||
package ru.betterend.blocks;
|
package ru.betterend.blocks;
|
||||||
|
|
||||||
import net.minecraft.sound.BlockSoundGroup;
|
import net.minecraft.sounds.SoundEvents;
|
||||||
import net.minecraft.sound.SoundEvents;
|
import net.minecraft.world.level.block.SoundType;
|
||||||
|
|
||||||
public class BlockSounds {
|
public class BlockSounds {
|
||||||
public static final BlockSoundGroup TERRAIN_SOUND = new BlockSoundGroup(1.0F, 1.0F,
|
public static final SoundType TERRAIN_SOUND = new SoundType(1.0F, 1.0F,
|
||||||
SoundEvents.BLOCK_STONE_BREAK,
|
SoundEvents.STONE_BREAK,
|
||||||
SoundEvents.BLOCK_WART_BLOCK_STEP,
|
SoundEvents.WART_BLOCK_STEP,
|
||||||
SoundEvents.BLOCK_STONE_PLACE,
|
SoundEvents.STONE_PLACE,
|
||||||
SoundEvents.BLOCK_STONE_HIT,
|
SoundEvents.STONE_HIT,
|
||||||
SoundEvents.BLOCK_STONE_FALL);
|
SoundEvents.STONE_FALL);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +0,0 @@
|
||||||
package ru.betterend.blocks;
|
|
||||||
|
|
||||||
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
|
||||||
import net.minecraft.block.Blocks;
|
|
||||||
import net.minecraft.block.MaterialColor;
|
|
||||||
import net.minecraft.sound.BlockSoundGroup;
|
|
||||||
import ru.betterend.blocks.basis.BlockBase;
|
|
||||||
|
|
||||||
public class BlockStone extends BlockBase {
|
|
||||||
|
|
||||||
public BlockStone(MaterialColor color) {
|
|
||||||
super(FabricBlockSettings.copyOf(Blocks.END_STONE).materialColor(color).sounds(BlockSoundGroup.STONE));
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,121 +0,0 @@
|
||||||
package ru.betterend.blocks;
|
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.EnumMap;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import com.google.common.collect.Lists;
|
|
||||||
import com.google.common.collect.Maps;
|
|
||||||
|
|
||||||
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
|
||||||
import net.fabricmc.fabric.api.tool.attribute.v1.FabricToolTags;
|
|
||||||
import net.minecraft.block.Block;
|
|
||||||
import net.minecraft.block.BlockState;
|
|
||||||
import net.minecraft.block.FluidFillable;
|
|
||||||
import net.minecraft.block.Material;
|
|
||||||
import net.minecraft.block.MaterialColor;
|
|
||||||
import net.minecraft.block.ShapeContext;
|
|
||||||
import net.minecraft.block.Waterloggable;
|
|
||||||
import net.minecraft.fluid.Fluid;
|
|
||||||
import net.minecraft.fluid.FluidState;
|
|
||||||
import net.minecraft.fluid.Fluids;
|
|
||||||
import net.minecraft.item.ItemPlacementContext;
|
|
||||||
import net.minecraft.item.ItemStack;
|
|
||||||
import net.minecraft.loot.context.LootContext;
|
|
||||||
import net.minecraft.sound.BlockSoundGroup;
|
|
||||||
import net.minecraft.state.StateManager;
|
|
||||||
import net.minecraft.state.property.BooleanProperty;
|
|
||||||
import net.minecraft.state.property.IntProperty;
|
|
||||||
import net.minecraft.state.property.Properties;
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
|
||||||
import net.minecraft.util.math.Direction;
|
|
||||||
import net.minecraft.util.shape.VoxelShape;
|
|
||||||
import net.minecraft.util.shape.VoxelShapes;
|
|
||||||
import net.minecraft.world.BlockView;
|
|
||||||
import net.minecraft.world.WorldAccess;
|
|
||||||
import net.minecraft.world.WorldView;
|
|
||||||
import ru.betterend.blocks.basis.BlockAttached;
|
|
||||||
import ru.betterend.client.render.ERenderLayer;
|
|
||||||
import ru.betterend.interfaces.IRenderTypeable;
|
|
||||||
import ru.betterend.registry.EndBlocks;
|
|
||||||
import ru.betterend.registry.EndItems;
|
|
||||||
import ru.betterend.util.MHelper;
|
|
||||||
|
|
||||||
public class BlockSulphurCrystal extends BlockAttached implements IRenderTypeable, Waterloggable, FluidFillable {
|
|
||||||
private static final EnumMap<Direction, VoxelShape> BOUNDING_SHAPES = Maps.newEnumMap(Direction.class);
|
|
||||||
public static final IntProperty AGE = IntProperty.of("age", 0, 2);
|
|
||||||
public static final BooleanProperty WATERLOGGED = Properties.WATERLOGGED;
|
|
||||||
|
|
||||||
public BlockSulphurCrystal() {
|
|
||||||
super(FabricBlockSettings.of(Material.STONE)
|
|
||||||
.materialColor(MaterialColor.YELLOW)
|
|
||||||
.breakByTool(FabricToolTags.PICKAXES)
|
|
||||||
.sounds(BlockSoundGroup.GLASS)
|
|
||||||
.requiresTool()
|
|
||||||
.noCollision());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void appendProperties(StateManager.Builder<Block, BlockState> stateManager) {
|
|
||||||
super.appendProperties(stateManager);
|
|
||||||
stateManager.add(AGE, WATERLOGGED);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ERenderLayer getRenderLayer() {
|
|
||||||
return ERenderLayer.CUTOUT;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<ItemStack> getDroppedStacks(BlockState state, LootContext.Builder builder) {
|
|
||||||
return state.get(AGE) < 2 ? Collections.emptyList() : Lists.newArrayList(new ItemStack(EndItems.CRYSTALLINE_SULPHUR, MHelper.randRange(1, 3, MHelper.RANDOM)));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean canFillWithFluid(BlockView world, BlockPos pos, BlockState state, Fluid fluid) {
|
|
||||||
return !state.get(WATERLOGGED);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean tryFillWithFluid(WorldAccess world, BlockPos pos, BlockState state, FluidState fluidState) {
|
|
||||||
return !state.get(WATERLOGGED);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BlockState getPlacementState(ItemPlacementContext ctx) {
|
|
||||||
BlockState state = super.getPlacementState(ctx);
|
|
||||||
if (state != null) {
|
|
||||||
WorldView worldView = ctx.getWorld();
|
|
||||||
BlockPos blockPos = ctx.getBlockPos();
|
|
||||||
boolean water = worldView.getFluidState(blockPos).getFluid() == Fluids.WATER;
|
|
||||||
return state.with(WATERLOGGED, water);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public FluidState getFluidState(BlockState state) {
|
|
||||||
return state.get(WATERLOGGED) ? Fluids.WATER.getStill(false) : Fluids.EMPTY.getDefaultState();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public VoxelShape getOutlineShape(BlockState state, BlockView view, BlockPos pos, ShapeContext ePos) {
|
|
||||||
return BOUNDING_SHAPES.get(state.get(FACING));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean canPlaceAt(BlockState state, WorldView world, BlockPos pos) {
|
|
||||||
Direction direction = (Direction) state.get(FACING);
|
|
||||||
BlockPos blockPos = pos.offset(direction.getOpposite());
|
|
||||||
return world.getBlockState(blockPos).isOf(EndBlocks.BRIMSTONE);
|
|
||||||
}
|
|
||||||
|
|
||||||
static {
|
|
||||||
BOUNDING_SHAPES.put(Direction.UP, VoxelShapes.cuboid(0.125, 0.0, 0.125, 0.875F, 0.5, 0.875F));
|
|
||||||
BOUNDING_SHAPES.put(Direction.DOWN, VoxelShapes.cuboid(0.125, 0.5, 0.125, 0.875F, 1.0, 0.875F));
|
|
||||||
BOUNDING_SHAPES.put(Direction.NORTH, VoxelShapes.cuboid(0.125, 0.125, 0.5, 0.875F, 0.875F, 1.0));
|
|
||||||
BOUNDING_SHAPES.put(Direction.SOUTH, VoxelShapes.cuboid(0.125, 0.125, 0.0, 0.875F, 0.875F, 0.5));
|
|
||||||
BOUNDING_SHAPES.put(Direction.WEST, VoxelShapes.cuboid(0.5, 0.125, 0.125, 1.0, 0.875F, 0.875F));
|
|
||||||
BOUNDING_SHAPES.put(Direction.EAST, VoxelShapes.cuboid(0.0, 0.125, 0.125, 0.5, 0.875F, 0.875F));
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,25 +0,0 @@
|
||||||
package ru.betterend.blocks;
|
|
||||||
|
|
||||||
import net.minecraft.block.BlockState;
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
|
||||||
import net.minecraft.world.WorldView;
|
|
||||||
import net.minecraft.world.gen.feature.Feature;
|
|
||||||
import ru.betterend.blocks.basis.BlockFeatureSapling;
|
|
||||||
import ru.betterend.registry.EndBlocks;
|
|
||||||
import ru.betterend.registry.EndFeatures;
|
|
||||||
|
|
||||||
public class BlockTenaneaSapling extends BlockFeatureSapling {
|
|
||||||
public BlockTenaneaSapling() {
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Feature<?> getFeature() {
|
|
||||||
return EndFeatures.TENANEA.getFeature();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean canPlaceAt(BlockState state, WorldView world, BlockPos pos) {
|
|
||||||
return world.getBlockState(pos.down()).isOf(EndBlocks.PINK_MOSS);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,88 +0,0 @@
|
||||||
package ru.betterend.blocks;
|
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Random;
|
|
||||||
|
|
||||||
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
|
||||||
import net.fabricmc.fabric.api.tool.attribute.v1.FabricToolTags;
|
|
||||||
import net.minecraft.block.Block;
|
|
||||||
import net.minecraft.block.BlockState;
|
|
||||||
import net.minecraft.block.Blocks;
|
|
||||||
import net.minecraft.block.MaterialColor;
|
|
||||||
import net.minecraft.block.SnowBlock;
|
|
||||||
import net.minecraft.enchantment.EnchantmentHelper;
|
|
||||||
import net.minecraft.enchantment.Enchantments;
|
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
|
||||||
import net.minecraft.item.ItemStack;
|
|
||||||
import net.minecraft.loot.context.LootContext;
|
|
||||||
import net.minecraft.loot.context.LootContextParameters;
|
|
||||||
import net.minecraft.server.network.ServerPlayerEntity;
|
|
||||||
import net.minecraft.server.world.ServerWorld;
|
|
||||||
import net.minecraft.sound.SoundCategory;
|
|
||||||
import net.minecraft.sound.SoundEvents;
|
|
||||||
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.util.math.Direction;
|
|
||||||
import net.minecraft.world.World;
|
|
||||||
import net.minecraft.world.WorldView;
|
|
||||||
import net.minecraft.world.chunk.light.ChunkLightProvider;
|
|
||||||
import ru.betterend.blocks.basis.BlockBase;
|
|
||||||
|
|
||||||
public class BlockTerrain extends BlockBase {
|
|
||||||
private Block pathBlock;
|
|
||||||
|
|
||||||
public BlockTerrain(MaterialColor color) {
|
|
||||||
super(FabricBlockSettings.copyOf(Blocks.END_STONE).materialColor(color).sounds(BlockSounds.TERRAIN_SOUND).ticksRandomly());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPathBlock(Block roadBlock) {
|
|
||||||
this.pathBlock = roadBlock;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) {
|
|
||||||
if (pathBlock != null && player.getMainHandStack().getItem().isIn(FabricToolTags.SHOVELS)) {
|
|
||||||
world.playSound(player, pos, SoundEvents.ITEM_SHOVEL_FLATTEN, SoundCategory.BLOCKS, 1.0F, 1.0F);
|
|
||||||
if (!world.isClient) {
|
|
||||||
world.setBlockState(pos, pathBlock.getDefaultState());
|
|
||||||
if (player != null && !player.isCreative()) {
|
|
||||||
player.getMainHandStack().damage(1, world.random, (ServerPlayerEntity) player);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ActionResult.SUCCESS;
|
|
||||||
}
|
|
||||||
return ActionResult.FAIL;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<ItemStack> getDroppedStacks(BlockState state, LootContext.Builder builder) {
|
|
||||||
ItemStack tool = builder.get(LootContextParameters.TOOL);
|
|
||||||
if (tool != null && EnchantmentHelper.getLevel(Enchantments.SILK_TOUCH, tool) > 0) {
|
|
||||||
return Collections.singletonList(new ItemStack(this));
|
|
||||||
}
|
|
||||||
return Collections.singletonList(new ItemStack(Blocks.END_STONE));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void randomTick(BlockState state, ServerWorld world, BlockPos pos, Random random) {
|
|
||||||
if (random.nextInt(16) == 0 && !canSurvive(state, world, pos)) {
|
|
||||||
world.setBlockState(pos, Blocks.END_STONE.getDefaultState());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean canSurvive(BlockState state, WorldView worldView, BlockPos pos) {
|
|
||||||
BlockPos blockPos = pos.up();
|
|
||||||
BlockState blockState = worldView.getBlockState(blockPos);
|
|
||||||
if (blockState.isOf(Blocks.SNOW) && (Integer)blockState.get(SnowBlock.LAYERS) == 1) {
|
|
||||||
return true;
|
|
||||||
} else if (blockState.getFluidState().getLevel() == 8) {
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
int i = ChunkLightProvider.getRealisticOpacity(worldView, state, pos, blockState, blockPos, Direction.UP, blockState.getOpacity(worldView, blockPos));
|
|
||||||
return i < 5;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,19 +0,0 @@
|
||||||
package ru.betterend.blocks;
|
|
||||||
|
|
||||||
import net.minecraft.block.Block;
|
|
||||||
import net.minecraft.block.BlockState;
|
|
||||||
import ru.betterend.blocks.basis.BlockPlant;
|
|
||||||
|
|
||||||
public class BlockTerrainPlant extends BlockPlant {
|
|
||||||
private final Block ground;
|
|
||||||
|
|
||||||
public BlockTerrainPlant(Block ground) {
|
|
||||||
super(true);
|
|
||||||
this.ground = ground;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean isTerrain(BlockState state) {
|
|
||||||
return state.isOf(ground);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,49 +0,0 @@
|
||||||
package ru.betterend.blocks;
|
|
||||||
|
|
||||||
import java.util.Random;
|
|
||||||
|
|
||||||
import net.fabricmc.api.EnvType;
|
|
||||||
import net.fabricmc.api.Environment;
|
|
||||||
import net.minecraft.block.BlockState;
|
|
||||||
import net.minecraft.server.world.ServerWorld;
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
|
||||||
import net.minecraft.world.BlockView;
|
|
||||||
import net.minecraft.world.World;
|
|
||||||
import ru.betterend.blocks.basis.BlockDoublePlant;
|
|
||||||
import ru.betterend.blocks.basis.BlockPlant;
|
|
||||||
import ru.betterend.registry.EndBlocks;
|
|
||||||
import ru.betterend.util.BlocksHelper;
|
|
||||||
|
|
||||||
public class BlockUmbrellaMoss extends BlockPlant {
|
|
||||||
public BlockUmbrellaMoss() {
|
|
||||||
super(11);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean isTerrain(BlockState state) {
|
|
||||||
return state.getBlock() == EndBlocks.END_MOSS || state.getBlock() == EndBlocks.END_MYCELIUM;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Environment(EnvType.CLIENT)
|
|
||||||
public boolean hasEmissiveLighting(BlockView world, BlockPos pos) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Environment(EnvType.CLIENT)
|
|
||||||
public float getAmbientOcclusionLightLevel(BlockView world, BlockPos pos) {
|
|
||||||
return 1F;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean canGrow(World world, Random random, BlockPos pos, BlockState state) {
|
|
||||||
return world.isAir(pos.up());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void grow(ServerWorld world, Random random, BlockPos pos, BlockState state) {
|
|
||||||
int rot = world.random.nextInt(4);
|
|
||||||
BlockState bs = EndBlocks.UMBRELLA_MOSS_TALL.getDefaultState().with(BlockDoublePlant.ROTATION, rot);
|
|
||||||
BlocksHelper.setWithoutUpdate(world, pos, bs);
|
|
||||||
BlocksHelper.setWithoutUpdate(world, pos.up(), bs.with(BlockDoublePlant.TOP, true));
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,28 +0,0 @@
|
||||||
package ru.betterend.blocks;
|
|
||||||
|
|
||||||
import java.util.Random;
|
|
||||||
|
|
||||||
import net.minecraft.block.BlockState;
|
|
||||||
import net.minecraft.entity.ItemEntity;
|
|
||||||
import net.minecraft.item.ItemStack;
|
|
||||||
import net.minecraft.server.world.ServerWorld;
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
|
||||||
import ru.betterend.blocks.basis.BlockDoublePlant;
|
|
||||||
import ru.betterend.registry.EndBlocks;
|
|
||||||
|
|
||||||
public class BlockUmbrellaMossTall extends BlockDoublePlant {
|
|
||||||
public BlockUmbrellaMossTall() {
|
|
||||||
super(12);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void grow(ServerWorld world, Random random, BlockPos pos, BlockState state) {
|
|
||||||
ItemEntity item = new ItemEntity(world, pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5, new ItemStack(EndBlocks.UMBRELLA_MOSS));
|
|
||||||
world.spawnEntity(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean isTerrain(BlockState state) {
|
|
||||||
return state.getBlock() == EndBlocks.END_MOSS || state.getBlock() == EndBlocks.END_MYCELIUM;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,53 +0,0 @@
|
||||||
package ru.betterend.blocks;
|
|
||||||
|
|
||||||
import java.io.Reader;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import com.google.common.collect.Lists;
|
|
||||||
|
|
||||||
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
|
||||||
import net.minecraft.block.AbstractGlassBlock;
|
|
||||||
import net.minecraft.block.BlockState;
|
|
||||||
import net.minecraft.block.Blocks;
|
|
||||||
import net.minecraft.item.ItemStack;
|
|
||||||
import net.minecraft.loot.context.LootContext;
|
|
||||||
import net.minecraft.util.Identifier;
|
|
||||||
import net.minecraft.util.registry.Registry;
|
|
||||||
import ru.betterend.client.render.ERenderLayer;
|
|
||||||
import ru.betterend.interfaces.IRenderTypeable;
|
|
||||||
import ru.betterend.patterns.BlockPatterned;
|
|
||||||
import ru.betterend.patterns.Patterns;
|
|
||||||
import ru.betterend.registry.EndItems;
|
|
||||||
|
|
||||||
public class BlockUmbrellaTreeMembrane extends AbstractGlassBlock implements IRenderTypeable, BlockPatterned {
|
|
||||||
public BlockUmbrellaTreeMembrane() {
|
|
||||||
super(FabricBlockSettings.copyOf(Blocks.SLIME_BLOCK));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ERenderLayer getRenderLayer() {
|
|
||||||
return ERenderLayer.TRANSLUCENT;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<ItemStack> getDroppedStacks(BlockState state, LootContext.Builder builder) {
|
|
||||||
return Lists.newArrayList(new ItemStack(EndItems.CRYSTAL_SHARDS));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getStatesPattern(Reader data) {
|
|
||||||
String block = Registry.BLOCK.getId(this).getPath();
|
|
||||||
return Patterns.createJson(data, block, block);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getModelPattern(String block) {
|
|
||||||
Identifier blockId = Registry.BLOCK.getId(this);
|
|
||||||
return Patterns.createJson(Patterns.BLOCK_BASE, blockId.getPath(), block);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Identifier statePatternId() {
|
|
||||||
return Patterns.STATE_SIMPLE;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,123 +0,0 @@
|
||||||
package ru.betterend.blocks;
|
|
||||||
|
|
||||||
import java.util.Random;
|
|
||||||
|
|
||||||
import net.fabricmc.api.EnvType;
|
|
||||||
import net.fabricmc.api.Environment;
|
|
||||||
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
|
||||||
import net.minecraft.block.Block;
|
|
||||||
import net.minecraft.block.BlockRenderType;
|
|
||||||
import net.minecraft.block.BlockState;
|
|
||||||
import net.minecraft.block.Blocks;
|
|
||||||
import net.minecraft.block.FluidDrainable;
|
|
||||||
import net.minecraft.block.FluidFillable;
|
|
||||||
import net.minecraft.block.Material;
|
|
||||||
import net.minecraft.block.ShapeContext;
|
|
||||||
import net.minecraft.entity.Entity;
|
|
||||||
import net.minecraft.fluid.Fluid;
|
|
||||||
import net.minecraft.fluid.FluidState;
|
|
||||||
import net.minecraft.fluid.Fluids;
|
|
||||||
import net.minecraft.particle.ParticleTypes;
|
|
||||||
import net.minecraft.server.world.ServerWorld;
|
|
||||||
import net.minecraft.sound.SoundCategory;
|
|
||||||
import net.minecraft.sound.SoundEvents;
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
|
||||||
import net.minecraft.util.math.Direction;
|
|
||||||
import net.minecraft.util.shape.VoxelShape;
|
|
||||||
import net.minecraft.util.shape.VoxelShapes;
|
|
||||||
import net.minecraft.world.BlockView;
|
|
||||||
import net.minecraft.world.World;
|
|
||||||
import net.minecraft.world.WorldAccess;
|
|
||||||
import net.minecraft.world.WorldView;
|
|
||||||
import ru.betterend.registry.EndBlocks;
|
|
||||||
import ru.betterend.util.BlocksHelper;
|
|
||||||
|
|
||||||
public class BlockVentBubbleColumn extends Block implements FluidDrainable, FluidFillable {
|
|
||||||
public BlockVentBubbleColumn() {
|
|
||||||
super(FabricBlockSettings.of(Material.BUBBLE_COLUMN).nonOpaque().noCollision().dropsNothing());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Fluid tryDrainFluid(WorldAccess world, BlockPos pos, BlockState state) {
|
|
||||||
world.setBlockState(pos, Blocks.AIR.getDefaultState(), 11);
|
|
||||||
return Fluids.WATER;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BlockRenderType getRenderType(BlockState state) {
|
|
||||||
return BlockRenderType.INVISIBLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean canPlaceAt(BlockState state, WorldView world, BlockPos pos) {
|
|
||||||
BlockState blockState = world.getBlockState(pos.down());
|
|
||||||
return blockState.isOf(this) || blockState.isOf(EndBlocks.HYDROTHERMAL_VENT);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
|
|
||||||
return VoxelShapes.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BlockState getStateForNeighborUpdate(BlockState state, Direction direction, BlockState newState, WorldAccess world, BlockPos pos, BlockPos posFrom) {
|
|
||||||
if (!state.canPlaceAt(world, pos)) {
|
|
||||||
return Blocks.WATER.getDefaultState();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
BlockPos up = pos.up();
|
|
||||||
if (world.getBlockState(up).isOf(Blocks.WATER)) {
|
|
||||||
BlocksHelper.setWithoutUpdate(world, up, this);
|
|
||||||
world.getBlockTickScheduler().schedule(up, this, 5);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Environment(EnvType.CLIENT)
|
|
||||||
public void randomDisplayTick(BlockState state, World world, BlockPos pos, Random random) {
|
|
||||||
if (random.nextInt(4) == 0) {
|
|
||||||
double px = pos.getX() + random.nextDouble();
|
|
||||||
double py = pos.getY() + random.nextDouble();
|
|
||||||
double pz = pos.getZ() + random.nextDouble();
|
|
||||||
world.addImportantParticle(ParticleTypes.BUBBLE_COLUMN_UP, px, py, pz, 0, 0.04, 0);
|
|
||||||
}
|
|
||||||
if (random.nextInt(200) == 0) {
|
|
||||||
world.playSound(pos.getX(), pos.getY(), pos.getZ(), SoundEvents.BLOCK_BUBBLE_COLUMN_UPWARDS_AMBIENT, SoundCategory.BLOCKS, 0.2F + random.nextFloat() * 0.2F, 0.9F + random.nextFloat() * 0.15F, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Environment(EnvType.CLIENT)
|
|
||||||
public void onEntityCollision(BlockState state, World world, BlockPos pos, Entity entity) {
|
|
||||||
BlockState blockState = world.getBlockState(pos.up());
|
|
||||||
if (blockState.isAir()) {
|
|
||||||
entity.onBubbleColumnSurfaceCollision(false);
|
|
||||||
if (!world.isClient) {
|
|
||||||
ServerWorld serverWorld = (ServerWorld) world;
|
|
||||||
|
|
||||||
for (int i = 0; i < 2; ++i) {
|
|
||||||
serverWorld.spawnParticles(ParticleTypes.SPLASH, (double) pos.getX() + world.random.nextDouble(), (double) (pos.getY() + 1), (double) pos.getZ() + world.random.nextDouble(), 1, 0.0D, 0.0D, 0.0D, 1.0D);
|
|
||||||
serverWorld.spawnParticles(ParticleTypes.BUBBLE, (double) pos.getX() + world.random.nextDouble(), (double) (pos.getY() + 1), (double) pos.getZ() + world.random.nextDouble(), 1, 0.0D, 0.01D, 0.0D, 0.2D);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
entity.onBubbleColumnCollision(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean canFillWithFluid(BlockView world, BlockPos pos, BlockState state, Fluid fluid) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean tryFillWithFluid(WorldAccess world, BlockPos pos, BlockState state, FluidState fluidState) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public FluidState getFluidState(BlockState state) {
|
|
||||||
return Fluids.WATER.getStill(false);
|
|
||||||
}
|
|
||||||
}
|
|
23
src/main/java/ru/betterend/blocks/BlueVineBlock.java
Normal file
23
src/main/java/ru/betterend/blocks/BlueVineBlock.java
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
package ru.betterend.blocks;
|
||||||
|
|
||||||
|
import net.minecraft.world.level.block.Block;
|
||||||
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
|
import net.minecraft.world.level.block.state.StateDefinition;
|
||||||
|
import net.minecraft.world.level.block.state.properties.EnumProperty;
|
||||||
|
import ru.betterend.blocks.BlockProperties.TripleShape;
|
||||||
|
import ru.betterend.blocks.basis.UpDownPlantBlock;
|
||||||
|
import ru.betterend.registry.EndBlocks;
|
||||||
|
|
||||||
|
public class BlueVineBlock extends UpDownPlantBlock {
|
||||||
|
public static final EnumProperty<TripleShape> SHAPE = BlockProperties.TRIPLE_SHAPE;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> stateManager) {
|
||||||
|
stateManager.add(SHAPE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean isTerrain(BlockState state) {
|
||||||
|
return state.getBlock() == EndBlocks.END_MOSS || state.getBlock() == EndBlocks.END_MYCELIUM;
|
||||||
|
}
|
||||||
|
}
|
46
src/main/java/ru/betterend/blocks/BlueVineLanternBlock.java
Normal file
46
src/main/java/ru/betterend/blocks/BlueVineLanternBlock.java
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
package ru.betterend.blocks;
|
||||||
|
|
||||||
|
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
||||||
|
import net.fabricmc.fabric.api.tool.attribute.v1.FabricToolTags;
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.core.Direction;
|
||||||
|
import net.minecraft.world.level.LevelAccessor;
|
||||||
|
import net.minecraft.world.level.LevelReader;
|
||||||
|
import net.minecraft.world.level.block.Block;
|
||||||
|
import net.minecraft.world.level.block.Blocks;
|
||||||
|
import net.minecraft.world.level.block.SoundType;
|
||||||
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
|
import net.minecraft.world.level.block.state.StateDefinition;
|
||||||
|
import net.minecraft.world.level.block.state.properties.BooleanProperty;
|
||||||
|
import net.minecraft.world.level.material.Material;
|
||||||
|
import ru.betterend.blocks.basis.BlockBase;
|
||||||
|
import ru.betterend.registry.EndBlocks;
|
||||||
|
|
||||||
|
public class BlueVineLanternBlock extends BlockBase {
|
||||||
|
public static final BooleanProperty NATURAL = BlockProperties.NATURAL;
|
||||||
|
|
||||||
|
public BlueVineLanternBlock() {
|
||||||
|
super(FabricBlockSettings.of(Material.WOOD).breakByTool(FabricToolTags.AXES).luminance(15).sound(SoundType.WART_BLOCK));
|
||||||
|
this.registerDefaultState(this.stateDefinition.any().setValue(NATURAL, false));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canSurvive(BlockState state, LevelReader world, BlockPos pos) {
|
||||||
|
return !state.getValue(NATURAL) || world.getBlockState(pos.below()).getBlock() == EndBlocks.BLUE_VINE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BlockState updateShape(BlockState state, Direction facing, BlockState neighborState, LevelAccessor world, BlockPos pos, BlockPos neighborPos) {
|
||||||
|
if (!canSurvive(state, world, pos)) {
|
||||||
|
return Blocks.AIR.defaultBlockState();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> stateManager) {
|
||||||
|
stateManager.add(NATURAL);
|
||||||
|
}
|
||||||
|
}
|
55
src/main/java/ru/betterend/blocks/BlueVineSeedBlock.java
Normal file
55
src/main/java/ru/betterend/blocks/BlueVineSeedBlock.java
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
package ru.betterend.blocks;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.core.Direction;
|
||||||
|
import net.minecraft.world.level.WorldGenLevel;
|
||||||
|
import net.minecraft.world.level.block.state.BlockBehaviour;
|
||||||
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
|
import ru.betterend.blocks.BlockProperties.TripleShape;
|
||||||
|
import ru.betterend.blocks.basis.EndPlantWithAgeBlock;
|
||||||
|
import ru.betterend.blocks.basis.FurBlock;
|
||||||
|
import ru.betterend.registry.EndBlocks;
|
||||||
|
import ru.betterend.util.BlocksHelper;
|
||||||
|
import ru.betterend.util.MHelper;
|
||||||
|
|
||||||
|
public class BlueVineSeedBlock extends EndPlantWithAgeBlock {
|
||||||
|
@Override
|
||||||
|
public void growAdult(WorldGenLevel world, Random random, BlockPos pos) {
|
||||||
|
int height = MHelper.randRange(2, 5, random);
|
||||||
|
int h = BlocksHelper.upRay(world, pos, height + 2);
|
||||||
|
if (h < height + 1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
BlocksHelper.setWithoutUpdate(world, pos, EndBlocks.BLUE_VINE.defaultBlockState().setValue(BlockProperties.TRIPLE_SHAPE, TripleShape.BOTTOM));
|
||||||
|
for (int i = 1; i < height; i++) {
|
||||||
|
BlocksHelper.setWithoutUpdate(world, pos.above(i), EndBlocks.BLUE_VINE.defaultBlockState().setValue(BlockProperties.TRIPLE_SHAPE, TripleShape.MIDDLE));
|
||||||
|
}
|
||||||
|
BlocksHelper.setWithoutUpdate(world, pos.above(height), EndBlocks.BLUE_VINE.defaultBlockState().setValue(BlockProperties.TRIPLE_SHAPE, TripleShape.TOP));
|
||||||
|
placeLantern(world, pos.above(height + 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void placeLantern(WorldGenLevel world, BlockPos pos) {
|
||||||
|
BlocksHelper.setWithoutUpdate(world, pos, EndBlocks.BLUE_VINE_LANTERN.defaultBlockState().setValue(BlueVineLanternBlock.NATURAL, true));
|
||||||
|
for (Direction dir: BlocksHelper.HORIZONTAL) {
|
||||||
|
BlockPos p = pos.relative(dir);
|
||||||
|
if (world.isEmptyBlock(p)) {
|
||||||
|
BlocksHelper.setWithoutUpdate(world, p, EndBlocks.BLUE_VINE_FUR.defaultBlockState().setValue(FurBlock.FACING, dir));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (world.isEmptyBlock(pos.above())) {
|
||||||
|
BlocksHelper.setWithoutUpdate(world, pos.above(), EndBlocks.BLUE_VINE_FUR.defaultBlockState().setValue(FurBlock.FACING, Direction.UP));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean isTerrain(BlockState state) {
|
||||||
|
return state.is(EndBlocks.END_MOSS) || state.is(EndBlocks.END_MYCELIUM);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BlockBehaviour.OffsetType getOffsetType() {
|
||||||
|
return BlockBehaviour.OffsetType.NONE;
|
||||||
|
}
|
||||||
|
}
|
57
src/main/java/ru/betterend/blocks/BoluxMushroomBlock.java
Normal file
57
src/main/java/ru/betterend/blocks/BoluxMushroomBlock.java
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
package ru.betterend.blocks;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
import net.minecraft.world.level.BlockGetter;
|
||||||
|
import net.minecraft.world.level.Level;
|
||||||
|
import net.minecraft.world.level.block.Block;
|
||||||
|
import net.minecraft.world.level.block.state.BlockBehaviour;
|
||||||
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
|
import net.minecraft.world.level.storage.loot.LootContext;
|
||||||
|
import net.minecraft.world.phys.shapes.CollisionContext;
|
||||||
|
import net.minecraft.world.phys.shapes.VoxelShape;
|
||||||
|
import ru.betterend.blocks.basis.EndPlantBlock;
|
||||||
|
import ru.betterend.registry.EndBlocks;
|
||||||
|
|
||||||
|
public class BoluxMushroomBlock extends EndPlantBlock {
|
||||||
|
private static final VoxelShape SHAPE = Block.box(1, 0, 1, 15, 9, 15);
|
||||||
|
|
||||||
|
public BoluxMushroomBlock() {
|
||||||
|
super(10);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean isTerrain(BlockState state) {
|
||||||
|
return state.is(EndBlocks.RUTISCUS);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public VoxelShape getShape(BlockState state, BlockGetter view, BlockPos pos, CollisionContext ePos) {
|
||||||
|
return SHAPE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BlockBehaviour.OffsetType getOffsetType() {
|
||||||
|
return BlockBehaviour.OffsetType.NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isValidBonemealTarget(BlockGetter world, BlockPos pos, BlockState state, boolean isClient) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isBonemealSuccess(Level world, Random random, BlockPos pos, BlockState state) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<ItemStack> getDrops(BlockState state, LootContext.Builder builder) {
|
||||||
|
return Lists.newArrayList(new ItemStack(this));
|
||||||
|
}
|
||||||
|
}
|
102
src/main/java/ru/betterend/blocks/BrimstoneBlock.java
Normal file
102
src/main/java/ru/betterend/blocks/BrimstoneBlock.java
Normal file
|
@ -0,0 +1,102 @@
|
||||||
|
package ru.betterend.blocks;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
||||||
|
import net.minecraft.client.multiplayer.ClientLevel;
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.core.Direction;
|
||||||
|
import net.minecraft.server.level.ServerLevel;
|
||||||
|
import net.minecraft.world.entity.LivingEntity;
|
||||||
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
import net.minecraft.world.level.Level;
|
||||||
|
import net.minecraft.world.level.LevelAccessor;
|
||||||
|
import net.minecraft.world.level.block.Block;
|
||||||
|
import net.minecraft.world.level.block.Blocks;
|
||||||
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
|
import net.minecraft.world.level.block.state.StateDefinition;
|
||||||
|
import net.minecraft.world.level.block.state.properties.BooleanProperty;
|
||||||
|
import net.minecraft.world.level.material.Fluids;
|
||||||
|
import net.minecraft.world.level.material.MaterialColor;
|
||||||
|
import ru.betterend.blocks.basis.BlockBase;
|
||||||
|
import ru.betterend.registry.EndBlocks;
|
||||||
|
import ru.betterend.util.BlocksHelper;
|
||||||
|
|
||||||
|
public class BrimstoneBlock extends BlockBase {
|
||||||
|
public static final BooleanProperty ACTIVATED = BlockProperties.ACTIVE;
|
||||||
|
|
||||||
|
public BrimstoneBlock() {
|
||||||
|
super(FabricBlockSettings.copyOf(Blocks.END_STONE).materialColor(MaterialColor.COLOR_BROWN).randomTicks());
|
||||||
|
registerDefaultState(stateDefinition.any().setValue(ACTIVATED, false));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> stateManager) {
|
||||||
|
stateManager.add(ACTIVATED);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setPlacedBy(Level world, BlockPos pos, BlockState state, @Nullable LivingEntity placer, ItemStack itemStack) {
|
||||||
|
if (world.isClientSide()) {
|
||||||
|
updateChunks((ClientLevel) world, pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void destroy(LevelAccessor world, BlockPos pos, BlockState state) {
|
||||||
|
if (world.isClientSide()) {
|
||||||
|
updateChunks((ClientLevel) world, pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateChunks(ClientLevel world, BlockPos pos) {
|
||||||
|
int y = pos.getY() >> 4;
|
||||||
|
int x1 = (pos.getX() - 2) >> 4;
|
||||||
|
int z1 = (pos.getZ() - 2) >> 4;
|
||||||
|
int x2 = (pos.getX() + 2) >> 4;
|
||||||
|
int z2 = (pos.getZ() + 2) >> 4;
|
||||||
|
for (int x = x1; x <= x2; x++) {
|
||||||
|
for (int z = z1; z <= z2; z++) {
|
||||||
|
world.setSectionDirtyWithNeighbors(x, y, z);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void tick(BlockState state, ServerLevel world, BlockPos pos, Random random) {
|
||||||
|
boolean deactivate = true;
|
||||||
|
for (Direction dir: BlocksHelper.DIRECTIONS) {
|
||||||
|
if (world.getFluidState(pos.relative(dir)).getType().equals(Fluids.WATER)) {
|
||||||
|
deactivate = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (state.getValue(ACTIVATED)) {
|
||||||
|
if (deactivate) {
|
||||||
|
world.setBlockAndUpdate(pos, defaultBlockState().setValue(ACTIVATED, false));
|
||||||
|
}
|
||||||
|
else if (state.getValue(ACTIVATED) && random.nextInt(16) == 0) {
|
||||||
|
Direction dir = BlocksHelper.randomDirection(random);
|
||||||
|
BlockPos side = pos.relative(dir);
|
||||||
|
BlockState sideState = world.getBlockState(side);
|
||||||
|
if (sideState.getBlock() instanceof SulphurCrystalBlock) {
|
||||||
|
if (sideState.getValue(SulphurCrystalBlock.AGE) < 2 && sideState.getValue(SulphurCrystalBlock.WATERLOGGED)) {
|
||||||
|
int age = sideState.getValue(SulphurCrystalBlock.AGE) + 1;
|
||||||
|
world.setBlockAndUpdate(side, sideState.setValue(SulphurCrystalBlock.AGE, age));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (sideState.getFluidState().getType() == Fluids.WATER) {
|
||||||
|
BlockState crystal = EndBlocks.SULPHUR_CRYSTAL.defaultBlockState()
|
||||||
|
.setValue(SulphurCrystalBlock.FACING, dir)
|
||||||
|
.setValue(SulphurCrystalBlock.WATERLOGGED, true)
|
||||||
|
.setValue(SulphurCrystalBlock.AGE, 0);
|
||||||
|
world.setBlockAndUpdate(side, crystal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (!deactivate && !state.getValue(ACTIVATED)) {
|
||||||
|
world.setBlockAndUpdate(pos, defaultBlockState().setValue(ACTIVATED, true));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
60
src/main/java/ru/betterend/blocks/BubbleCoralBlock.java
Normal file
60
src/main/java/ru/betterend/blocks/BubbleCoralBlock.java
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
package ru.betterend.blocks;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
import net.fabricmc.api.EnvType;
|
||||||
|
import net.fabricmc.api.Environment;
|
||||||
|
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
||||||
|
import net.fabricmc.fabric.api.tool.attribute.v1.FabricToolTags;
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.core.particles.ParticleTypes;
|
||||||
|
import net.minecraft.world.level.BlockGetter;
|
||||||
|
import net.minecraft.world.level.Level;
|
||||||
|
import net.minecraft.world.level.block.Block;
|
||||||
|
import net.minecraft.world.level.block.SoundType;
|
||||||
|
import net.minecraft.world.level.block.state.BlockBehaviour;
|
||||||
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
|
import net.minecraft.world.level.material.Material;
|
||||||
|
import net.minecraft.world.phys.shapes.CollisionContext;
|
||||||
|
import net.minecraft.world.phys.shapes.VoxelShape;
|
||||||
|
import ru.betterend.blocks.basis.UnderwaterPlantBlock;
|
||||||
|
|
||||||
|
public class BubbleCoralBlock extends UnderwaterPlantBlock {
|
||||||
|
private static final VoxelShape SHAPE = Block.box(0, 0, 0, 16, 14, 16);
|
||||||
|
|
||||||
|
public BubbleCoralBlock() {
|
||||||
|
super(FabricBlockSettings.of(Material.WATER_PLANT)
|
||||||
|
.breakByTool(FabricToolTags.SHEARS)
|
||||||
|
.breakByHand(true)
|
||||||
|
.sound(SoundType.CORAL_BLOCK)
|
||||||
|
.noCollission());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BlockBehaviour.OffsetType getOffsetType() {
|
||||||
|
return BlockBehaviour.OffsetType.NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Environment(EnvType.CLIENT)
|
||||||
|
public void animateTick(BlockState state, Level world, BlockPos pos, Random random) {
|
||||||
|
double x = pos.getX() + random.nextDouble();
|
||||||
|
double y = pos.getY() + random.nextDouble() * 0.5F + 0.5F;
|
||||||
|
double z = pos.getZ() + random.nextDouble();
|
||||||
|
world.addParticle(ParticleTypes.BUBBLE, x, y, z, 0.0D, 0.0D, 0.0D);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public VoxelShape getShape(BlockState state, BlockGetter view, BlockPos pos, CollisionContext ePos) {
|
||||||
|
return SHAPE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isValidBonemealTarget(BlockGetter world, BlockPos pos, BlockState state, boolean isClient) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isBonemealSuccess(Level world, Random random, BlockPos pos, BlockState state) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
47
src/main/java/ru/betterend/blocks/BulbVineBlock.java
Normal file
47
src/main/java/ru/betterend/blocks/BulbVineBlock.java
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
package ru.betterend.blocks;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
import net.minecraft.world.level.BlockGetter;
|
||||||
|
import net.minecraft.world.level.LevelReader;
|
||||||
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
|
import net.minecraft.world.level.storage.loot.LootContext;
|
||||||
|
import ru.betterend.blocks.BlockProperties.TripleShape;
|
||||||
|
import ru.betterend.blocks.basis.VineBlock;
|
||||||
|
import ru.betterend.registry.EndBlocks;
|
||||||
|
import ru.betterend.registry.EndItems;
|
||||||
|
import ru.betterend.util.MHelper;
|
||||||
|
|
||||||
|
public class BulbVineBlock extends VineBlock {
|
||||||
|
public BulbVineBlock() {
|
||||||
|
super(15, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<ItemStack> getDrops(BlockState state, LootContext.Builder builder) {
|
||||||
|
if (state.getValue(SHAPE) == TripleShape.BOTTOM) {
|
||||||
|
return Lists.newArrayList(new ItemStack(EndItems.GLOWING_BULB));
|
||||||
|
}
|
||||||
|
else if (MHelper.RANDOM.nextInt(8) == 0) {
|
||||||
|
return Lists.newArrayList(new ItemStack(EndBlocks.BULB_VINE_SEED));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return Lists.newArrayList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isValidBonemealTarget(BlockGetter world, BlockPos pos, BlockState state, boolean isClient) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canSurvive(BlockState state, LevelReader world, BlockPos pos) {
|
||||||
|
boolean canPlace = super.canSurvive(state, world, pos);
|
||||||
|
return (state.is(this) && state.getValue(SHAPE) == TripleShape.BOTTOM) ? canPlace : canPlace && world.getBlockState(pos.below()).is(this);
|
||||||
|
}
|
||||||
|
}
|
90
src/main/java/ru/betterend/blocks/BulbVineLanternBlock.java
Normal file
90
src/main/java/ru/betterend/blocks/BulbVineLanternBlock.java
Normal file
|
@ -0,0 +1,90 @@
|
||||||
|
package ru.betterend.blocks;
|
||||||
|
|
||||||
|
import java.io.Reader;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import com.google.common.collect.Maps;
|
||||||
|
|
||||||
|
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
||||||
|
import net.fabricmc.fabric.api.tool.attribute.v1.FabricToolTags;
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.core.Registry;
|
||||||
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
import net.minecraft.world.level.BlockGetter;
|
||||||
|
import net.minecraft.world.level.block.Block;
|
||||||
|
import net.minecraft.world.level.block.SoundType;
|
||||||
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
|
import net.minecraft.world.level.material.Material;
|
||||||
|
import net.minecraft.world.level.material.MaterialColor;
|
||||||
|
import net.minecraft.world.phys.shapes.CollisionContext;
|
||||||
|
import net.minecraft.world.phys.shapes.VoxelShape;
|
||||||
|
import ru.betterend.blocks.basis.EndLanternBlock;
|
||||||
|
import ru.betterend.client.render.ERenderLayer;
|
||||||
|
import ru.betterend.interfaces.IRenderTypeable;
|
||||||
|
import ru.betterend.patterns.BlockPatterned;
|
||||||
|
import ru.betterend.patterns.Patterns;
|
||||||
|
|
||||||
|
public class BulbVineLanternBlock extends EndLanternBlock implements IRenderTypeable, BlockPatterned {
|
||||||
|
private static final VoxelShape SHAPE_CEIL = Block.box(4, 4, 4, 12, 16, 12);
|
||||||
|
private static final VoxelShape SHAPE_FLOOR = Block.box(4, 0, 4, 12, 12, 12);
|
||||||
|
|
||||||
|
public BulbVineLanternBlock() {
|
||||||
|
this(FabricBlockSettings.of(Material.METAL)
|
||||||
|
.hardness(1)
|
||||||
|
.resistance(1)
|
||||||
|
.breakByTool(FabricToolTags.PICKAXES)
|
||||||
|
.materialColor(MaterialColor.COLOR_LIGHT_GRAY)
|
||||||
|
.luminance(15)
|
||||||
|
.requiresCorrectToolForDrops()
|
||||||
|
.sound(SoundType.LANTERN));
|
||||||
|
}
|
||||||
|
|
||||||
|
public BulbVineLanternBlock(Properties settings) {
|
||||||
|
super(settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public VoxelShape getShape(BlockState state, BlockGetter view, BlockPos pos, CollisionContext ePos) {
|
||||||
|
return state.getValue(IS_FLOOR) ? SHAPE_FLOOR : SHAPE_CEIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ERenderLayer getRenderLayer() {
|
||||||
|
return ERenderLayer.CUTOUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getStatesPattern(Reader data) {
|
||||||
|
ResourceLocation blockId = Registry.BLOCK.getKey(this);
|
||||||
|
return Patterns.createJson(data, blockId.getPath(), blockId.getPath());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getModelPattern(String block) {
|
||||||
|
ResourceLocation blockId = Registry.BLOCK.getKey(this);
|
||||||
|
Map<String, String> map = Maps.newHashMap();
|
||||||
|
map.put("%glow%", getGlowTexture());
|
||||||
|
map.put("%metal%", getMetalTexture(blockId));
|
||||||
|
if (block.contains("item") || block.contains("ceil")) {
|
||||||
|
return Patterns.createJson(Patterns.BLOCK_BULB_LANTERN_CEIL, map);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return Patterns.createJson(Patterns.BLOCK_BULB_LANTERN_FLOOR, map);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String getMetalTexture(ResourceLocation blockId) {
|
||||||
|
String name = blockId.getPath();
|
||||||
|
name = name.substring(0, name.indexOf('_'));
|
||||||
|
return name + "_bulb_vine_lantern_metal";
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String getGlowTexture() {
|
||||||
|
return "bulb_vine_lantern_bulb";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResourceLocation statePatternId() {
|
||||||
|
return Patterns.STATE_BULB_LANTERN;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
package ru.betterend.blocks;
|
||||||
|
|
||||||
|
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
||||||
|
import net.minecraft.client.color.block.BlockColor;
|
||||||
|
import net.minecraft.client.color.item.ItemColor;
|
||||||
|
import ru.betterend.interfaces.IColorProvider;
|
||||||
|
import ru.betterend.util.BlocksHelper;
|
||||||
|
import ru.betterend.util.MHelper;
|
||||||
|
|
||||||
|
public class BulbVineLanternColoredBlock extends BulbVineLanternBlock implements IColorProvider {
|
||||||
|
public BulbVineLanternColoredBlock(FabricBlockSettings settings) {
|
||||||
|
super(settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BlockColor getProvider() {
|
||||||
|
return (state, world, pos, tintIndex) -> {
|
||||||
|
return getColor();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ItemColor getItemProvider() {
|
||||||
|
return (stack, tintIndex) -> {
|
||||||
|
return getColor();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getColor() {
|
||||||
|
int color = BlocksHelper.getBlockColor(this);
|
||||||
|
int b = (color & 255);
|
||||||
|
int g = ((color >> 8) & 255);
|
||||||
|
int r = ((color >> 16) & 255);
|
||||||
|
float[] hsv = MHelper.fromRGBtoHSB(r, g, b);
|
||||||
|
return MHelper.fromHSBtoRGB(hsv[0], hsv[1], hsv[1] > 0.2 ? 1 : hsv[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getGlowTexture() {
|
||||||
|
return "bulb_vine_lantern_overlay";
|
||||||
|
}
|
||||||
|
}
|
34
src/main/java/ru/betterend/blocks/BulbVineSeedBlock.java
Normal file
34
src/main/java/ru/betterend/blocks/BulbVineSeedBlock.java
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
package ru.betterend.blocks;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.tags.BlockTags;
|
||||||
|
import net.minecraft.world.level.LevelReader;
|
||||||
|
import net.minecraft.world.level.WorldGenLevel;
|
||||||
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
|
import ru.betterend.blocks.BlockProperties.TripleShape;
|
||||||
|
import ru.betterend.blocks.basis.EndPlantWithAgeBlock;
|
||||||
|
import ru.betterend.registry.EndBlocks;
|
||||||
|
import ru.betterend.registry.EndTags;
|
||||||
|
import ru.betterend.util.BlocksHelper;
|
||||||
|
|
||||||
|
public class BulbVineSeedBlock extends EndPlantWithAgeBlock {
|
||||||
|
@Override
|
||||||
|
public boolean canSurvive(BlockState state, LevelReader world, BlockPos pos) {
|
||||||
|
BlockState up = world.getBlockState(pos.above());
|
||||||
|
return up.is(EndTags.GEN_TERRAIN) || up.is(BlockTags.LOGS) || up.is(BlockTags.LEAVES);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void growAdult(WorldGenLevel world, Random random, BlockPos pos) {
|
||||||
|
int h = BlocksHelper.downRay(world, pos, random.nextInt(24)) - 1;
|
||||||
|
if (h > 2) {
|
||||||
|
BlocksHelper.setWithoutUpdate(world, pos, EndBlocks.BULB_VINE.defaultBlockState().setValue(BlockProperties.TRIPLE_SHAPE, TripleShape.TOP));
|
||||||
|
for (int i = 1; i < h; i++) {
|
||||||
|
BlocksHelper.setWithoutUpdate(world, pos.below(i), EndBlocks.BULB_VINE.defaultBlockState().setValue(BlockProperties.TRIPLE_SHAPE, TripleShape.MIDDLE));
|
||||||
|
}
|
||||||
|
BlocksHelper.setWithoutUpdate(world, pos.below(h), EndBlocks.BULB_VINE.defaultBlockState().setValue(BlockProperties.TRIPLE_SHAPE, TripleShape.BOTTOM));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
65
src/main/java/ru/betterend/blocks/CavePumpkinBlock.java
Normal file
65
src/main/java/ru/betterend/blocks/CavePumpkinBlock.java
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
package ru.betterend.blocks;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
import net.minecraft.world.level.BlockGetter;
|
||||||
|
import net.minecraft.world.level.block.Block;
|
||||||
|
import net.minecraft.world.level.block.Blocks;
|
||||||
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
|
import net.minecraft.world.level.block.state.StateDefinition;
|
||||||
|
import net.minecraft.world.level.block.state.properties.BooleanProperty;
|
||||||
|
import net.minecraft.world.level.storage.loot.LootContext;
|
||||||
|
import net.minecraft.world.phys.shapes.CollisionContext;
|
||||||
|
import net.minecraft.world.phys.shapes.Shapes;
|
||||||
|
import net.minecraft.world.phys.shapes.VoxelShape;
|
||||||
|
import ru.betterend.blocks.basis.BlockBaseNotFull;
|
||||||
|
import ru.betterend.client.render.ERenderLayer;
|
||||||
|
import ru.betterend.interfaces.IRenderTypeable;
|
||||||
|
import ru.betterend.registry.EndBlocks;
|
||||||
|
|
||||||
|
public class CavePumpkinBlock extends BlockBaseNotFull implements IRenderTypeable {
|
||||||
|
public static final BooleanProperty SMALL = BlockProperties.SMALL;
|
||||||
|
private static final VoxelShape SHAPE_SMALL;
|
||||||
|
private static final VoxelShape SHAPE_BIG;
|
||||||
|
|
||||||
|
public CavePumpkinBlock() {
|
||||||
|
super(FabricBlockSettings.copyOf(Blocks.PUMPKIN).luminance((state) -> state.getValue(SMALL) ? 10 : 15));
|
||||||
|
registerDefaultState(defaultBlockState().setValue(SMALL, false));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> stateManager) {
|
||||||
|
stateManager.add(SMALL);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ERenderLayer getRenderLayer() {
|
||||||
|
return ERenderLayer.CUTOUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public VoxelShape getShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext context) {
|
||||||
|
return state.getValue(SMALL) ? SHAPE_SMALL : SHAPE_BIG;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<ItemStack> getDrops(BlockState state, LootContext.Builder builder) {
|
||||||
|
return state.getValue(SMALL) ? Collections.singletonList(new ItemStack(EndBlocks.CAVE_PUMPKIN_SEED)) : Collections.singletonList(new ItemStack(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
static {
|
||||||
|
VoxelShape lantern = Block.box(1, 0, 1, 15, 13, 15);
|
||||||
|
VoxelShape cap = Block.box(0, 12, 0, 16, 15, 16);
|
||||||
|
VoxelShape top = Block.box(5, 15, 5, 11, 16, 11);
|
||||||
|
SHAPE_BIG = Shapes.or(lantern, cap, top);
|
||||||
|
|
||||||
|
lantern = Block.box(1, 7, 1, 15, 13, 15);
|
||||||
|
cap = Block.box(4, 12, 4, 12, 15, 12);
|
||||||
|
top = Block.box(6, 15, 6, 10, 16, 10);
|
||||||
|
SHAPE_SMALL = Shapes.or(lantern, cap, top);
|
||||||
|
}
|
||||||
|
}
|
70
src/main/java/ru/betterend/blocks/CavePumpkinVineBlock.java
Normal file
70
src/main/java/ru/betterend/blocks/CavePumpkinVineBlock.java
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
package ru.betterend.blocks;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.core.Direction;
|
||||||
|
import net.minecraft.server.level.ServerLevel;
|
||||||
|
import net.minecraft.world.level.BlockGetter;
|
||||||
|
import net.minecraft.world.level.LevelAccessor;
|
||||||
|
import net.minecraft.world.level.LevelReader;
|
||||||
|
import net.minecraft.world.level.WorldGenLevel;
|
||||||
|
import net.minecraft.world.level.block.Block;
|
||||||
|
import net.minecraft.world.level.block.state.BlockBehaviour;
|
||||||
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
|
import net.minecraft.world.phys.shapes.CollisionContext;
|
||||||
|
import net.minecraft.world.phys.shapes.VoxelShape;
|
||||||
|
import ru.betterend.blocks.basis.EndPlantWithAgeBlock;
|
||||||
|
import ru.betterend.registry.EndBlocks;
|
||||||
|
|
||||||
|
public class CavePumpkinVineBlock extends EndPlantWithAgeBlock {
|
||||||
|
private static final VoxelShape SHAPE = Block.box(4, 0, 4, 12, 16, 12);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canSurvive(BlockState state, LevelReader world, BlockPos pos) {
|
||||||
|
BlockState down = world.getBlockState(pos.above());
|
||||||
|
return isTerrain(down);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void performBonemeal(ServerLevel world, Random random, BlockPos pos, BlockState state) {
|
||||||
|
int age = state.getValue(AGE);
|
||||||
|
BlockState down = world.getBlockState(pos.below());
|
||||||
|
if (down.getMaterial().isReplaceable() || (down.is(EndBlocks.CAVE_PUMPKIN) && down.getValue(BlockProperties.SMALL))) {
|
||||||
|
if (age < 3) {
|
||||||
|
world.setBlockAndUpdate(pos, state.setValue(AGE, age + 1));
|
||||||
|
}
|
||||||
|
if (age == 2) {
|
||||||
|
world.setBlockAndUpdate(pos.below(), EndBlocks.CAVE_PUMPKIN.defaultBlockState().setValue(BlockProperties.SMALL, true));
|
||||||
|
}
|
||||||
|
else if (age == 3) {
|
||||||
|
world.setBlockAndUpdate(pos.below(), EndBlocks.CAVE_PUMPKIN.defaultBlockState());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void growAdult(WorldGenLevel world, Random random, BlockPos pos) {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BlockState updateShape(BlockState state, Direction facing, BlockState neighborState, LevelAccessor world, BlockPos pos, BlockPos neighborPos) {
|
||||||
|
state = super.updateShape(state, facing, neighborState, world, pos, neighborPos);
|
||||||
|
if (state.is(this) && state.getValue(BlockProperties.AGE) > 1) {
|
||||||
|
BlockState down = world.getBlockState(pos.below());
|
||||||
|
if (!down.is(EndBlocks.CAVE_PUMPKIN)) {
|
||||||
|
state = state.setValue(BlockProperties.AGE, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public VoxelShape getShape(BlockState state, BlockGetter view, BlockPos pos, CollisionContext ePos) {
|
||||||
|
return SHAPE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BlockBehaviour.OffsetType getOffsetType() {
|
||||||
|
return BlockBehaviour.OffsetType.NONE;
|
||||||
|
}
|
||||||
|
}
|
78
src/main/java/ru/betterend/blocks/ChandelierBlock.java
Normal file
78
src/main/java/ru/betterend/blocks/ChandelierBlock.java
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
package ru.betterend.blocks;
|
||||||
|
|
||||||
|
import java.io.Reader;
|
||||||
|
import java.util.EnumMap;
|
||||||
|
|
||||||
|
import com.google.common.collect.Maps;
|
||||||
|
|
||||||
|
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.core.Direction;
|
||||||
|
import net.minecraft.core.Registry;
|
||||||
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
import net.minecraft.world.level.BlockGetter;
|
||||||
|
import net.minecraft.world.level.block.Block;
|
||||||
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
|
import net.minecraft.world.phys.shapes.CollisionContext;
|
||||||
|
import net.minecraft.world.phys.shapes.Shapes;
|
||||||
|
import net.minecraft.world.phys.shapes.VoxelShape;
|
||||||
|
import ru.betterend.blocks.basis.AttachedBlock;
|
||||||
|
import ru.betterend.client.render.ERenderLayer;
|
||||||
|
import ru.betterend.interfaces.IRenderTypeable;
|
||||||
|
import ru.betterend.patterns.BlockPatterned;
|
||||||
|
import ru.betterend.patterns.Patterns;
|
||||||
|
|
||||||
|
public class ChandelierBlock extends AttachedBlock implements IRenderTypeable, BlockPatterned {
|
||||||
|
private static final EnumMap<Direction, VoxelShape> BOUNDING_SHAPES = Maps.newEnumMap(Direction.class);
|
||||||
|
|
||||||
|
public ChandelierBlock(Block source) {
|
||||||
|
super(FabricBlockSettings.copyOf(source).luminance(15).noCollission().noOcclusion().requiresCorrectToolForDrops());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ERenderLayer getRenderLayer() {
|
||||||
|
return ERenderLayer.CUTOUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public VoxelShape getShape(BlockState state, BlockGetter view, BlockPos pos, CollisionContext ePos) {
|
||||||
|
return BOUNDING_SHAPES.get(state.getValue(FACING));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getStatesPattern(Reader data) {
|
||||||
|
ResourceLocation blockId = Registry.BLOCK.getKey(this);
|
||||||
|
return Patterns.createJson(data, blockId.getPath(), blockId.getPath());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getModelPattern(String block) {
|
||||||
|
ResourceLocation blockId = Registry.BLOCK.getKey(this);
|
||||||
|
if (block.contains("item")) {
|
||||||
|
return Patterns.createJson(Patterns.ITEM_GENERATED, "item/" + blockId.getPath());
|
||||||
|
}
|
||||||
|
else if (block.contains("ceil")) {
|
||||||
|
return Patterns.createJson(Patterns.BLOCK_CHANDELIER_CEIL, blockId.getPath());
|
||||||
|
}
|
||||||
|
else if (block.contains("wall")) {
|
||||||
|
return Patterns.createJson(Patterns.BLOCK_CHANDELIER_WALL, blockId.getPath());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return Patterns.createJson(Patterns.BLOCK_CHANDELIER_FLOOR, blockId.getPath());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResourceLocation statePatternId() {
|
||||||
|
return Patterns.STATE_CHANDELIER;
|
||||||
|
}
|
||||||
|
|
||||||
|
static {
|
||||||
|
BOUNDING_SHAPES.put(Direction.UP, Block.box(5, 0, 5, 11, 13, 11));
|
||||||
|
BOUNDING_SHAPES.put(Direction.DOWN, Block.box(5, 3, 5, 11, 16, 11));
|
||||||
|
BOUNDING_SHAPES.put(Direction.NORTH, Shapes.box(0.0, 0.0, 0.5, 1.0, 1.0, 1.0));
|
||||||
|
BOUNDING_SHAPES.put(Direction.SOUTH, Shapes.box(0.0, 0.0, 0.0, 1.0, 1.0, 0.5));
|
||||||
|
BOUNDING_SHAPES.put(Direction.WEST, Shapes.box(0.5, 0.0, 0.0, 1.0, 1.0, 1.0));
|
||||||
|
BOUNDING_SHAPES.put(Direction.EAST, Shapes.box(0.0, 0.0, 0.0, 0.5, 1.0, 1.0));
|
||||||
|
}
|
||||||
|
}
|
13
src/main/java/ru/betterend/blocks/CharcoalBlock.java
Normal file
13
src/main/java/ru/betterend/blocks/CharcoalBlock.java
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
package ru.betterend.blocks;
|
||||||
|
|
||||||
|
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
||||||
|
import net.fabricmc.fabric.api.registry.FuelRegistry;
|
||||||
|
import net.minecraft.world.level.block.Blocks;
|
||||||
|
import ru.betterend.blocks.basis.BlockBase;
|
||||||
|
|
||||||
|
public class CharcoalBlock extends BlockBase {
|
||||||
|
public CharcoalBlock() {
|
||||||
|
super(FabricBlockSettings.copyOf(Blocks.COAL_BLOCK));
|
||||||
|
FuelRegistry.INSTANCE.add(this, 16000);
|
||||||
|
}
|
||||||
|
}
|
15
src/main/java/ru/betterend/blocks/CharniaBlock.java
Normal file
15
src/main/java/ru/betterend/blocks/CharniaBlock.java
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
package ru.betterend.blocks;
|
||||||
|
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.core.Direction;
|
||||||
|
import net.minecraft.world.level.LevelReader;
|
||||||
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
|
import net.minecraft.world.level.material.Fluids;
|
||||||
|
import ru.betterend.blocks.basis.UnderwaterPlantBlock;
|
||||||
|
|
||||||
|
public class CharniaBlock extends UnderwaterPlantBlock {
|
||||||
|
@Override
|
||||||
|
public boolean canSurvive(BlockState state, LevelReader world, BlockPos pos) {
|
||||||
|
return canSupportCenter(world, pos.below(), Direction.UP) && world.getFluidState(pos).getType() == Fluids.WATER;
|
||||||
|
}
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue