Merge pull request #1 from paulevsGitch/master

updoot fork
This commit is contained in:
saltyseadoggo 2021-04-29 15:05:30 -07:00 committed by GitHub
commit ed8c0febea
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2364 changed files with 47450 additions and 20161 deletions

View file

@ -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) {

View file

@ -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

View file

@ -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.

View file

@ -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) {

View 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;
}
}

View file

@ -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;
} }
} }

View file

@ -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));
} }
} }

View file

@ -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;
}
}

View 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));
}
}

View file

@ -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));
} }
} }

View file

@ -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();
}
}
}

View file

@ -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));
} }

View file

@ -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);
}
}

View file

@ -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;
}
}

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -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));
}
}
}

View file

@ -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;
}
}

View file

@ -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);
}
}

View file

@ -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));
}
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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));
}
}

View file

@ -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);
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -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;
}
}

View file

@ -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));
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -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();
}
}

View file

@ -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();
}
}

View file

@ -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();
}
}

View file

@ -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) {}
}

View file

@ -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);
}
}

View file

@ -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);
}
}
}
}

View file

@ -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);
}
}

View file

@ -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;
}
}
}

View file

@ -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);
}
}

View file

@ -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;
}
}

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -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;
}
}

View file

@ -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 TripleShape fromIndex(int index) {
return index > 1 ? BOTTOM : index == 1 ? MIDDLE : TOP;
}
} }
public static enum PedestalState implements StringIdentifiable { 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;
} }

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -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);
}
}
}

View file

@ -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);
}
}

View file

@ -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);
} }

View file

@ -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));
}
}

View file

@ -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));
}
}

View file

@ -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);
}
}

View file

@ -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;
}
}
}

View file

@ -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);
}
}

View file

@ -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));
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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);
}
}

View 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;
}
}

View 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);
}
}

View 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;
}
}

View 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));
}
}

View 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));
}
}
}

View 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;
}
}

View 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);
}
}

View 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;
}
}

View file

@ -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";
}
}

View 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));
}
}
}

View 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);
}
}

View 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;
}
}

View 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));
}
}

View 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);
}
}

View 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