Skip to content

Commit

Permalink
add a new Stone Cauldron so we don't have to deal with the hell of mi…
Browse files Browse the repository at this point in the history
…xing new properties into an existing block
  • Loading branch information
LemmaEOF committed Apr 1, 2019
1 parent 1d5bc93 commit 369cbce
Show file tree
Hide file tree
Showing 28 changed files with 977 additions and 174 deletions.
4 changes: 2 additions & 2 deletions project.gradle
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
ext {
projectName = "cotton";
group = "io.github.cottonmc";
version = "0.2.1+19w13b";
version = "0.3.0+19w13b";
snapshot = true;

minecraft = "19w13b";
mappings = "19w13b.1";
loader = "0.3.7.109";
fabricMod = "0.2.6.117";
silkMod = null;
silkMod = null; // change if we ever decide to make the stone cauldron a BE
jankson = "1.1.1"; //If needsShadow is false, jankson will not be included!
cotton = null;

Expand Down
49 changes: 24 additions & 25 deletions src/main/java/io/github/cottonmc/cotton/Cotton.java
Original file line number Diff line number Diff line change
@@ -1,20 +1,23 @@
package io.github.cottonmc.cotton;

import io.github.cottonmc.cotton.behavior.CauldronBehavior;
import io.github.cottonmc.cotton.behavior.CauldronUtils;
import io.github.cottonmc.cotton.block.CottonBlocks;
import io.github.cottonmc.cotton.cauldron.CauldronBehavior;
import io.github.cottonmc.cotton.cauldron.CauldronUtils;
import io.github.cottonmc.cotton.config.ConfigManager;
import io.github.cottonmc.cotton.config.CottonConfig;
import io.github.cottonmc.cotton.datapack.recipe.CottonRecipes;
import io.github.cottonmc.cotton.datapack.recipe.RecipeUtil;
import io.github.cottonmc.cotton.impl.BucketFluidAccessor;
import io.github.cottonmc.cotton.logging.Ansi;
import io.github.cottonmc.cotton.logging.ModLogger;
import io.github.cottonmc.cotton.datapack.PackMetaManager;
import io.github.cottonmc.cotton.registry.CommonTags;
import io.github.cottonmc.cotton.util.FluidProperty;
import net.fabricmc.api.ModInitializer;
import net.fabricmc.fabric.api.client.itemgroup.FabricItemGroupBuilder;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.block.Blocks;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.fluid.Fluids;
import net.minecraft.item.*;
import net.minecraft.sound.SoundCategory;
import net.minecraft.sound.SoundEvents;
Expand Down Expand Up @@ -46,6 +49,7 @@ public void onInitialize() {
//setup
logger.setPrefixFormat(Ansi.Blue);
PackMetaManager.saveMeta();
CottonBlocks.init();
CottonRecipes.init();

//example config and logger code
Expand All @@ -59,27 +63,22 @@ public void onInitialize() {
// LootTableManager.registerBasicBlockDropTable(new Identifier("minecraft", "dirt"));
// RecipeUtil.removeRecipe(new Identifier("crafting_table"));

//example cauldron behavior code - lets you make obsidian in a cauldron
// CauldronBehavior.registerBehavior(
// (ctx) -> ctx.getStack().getItem() == Items.WATER_BUCKET
// && FluidTags.LAVA.contains(ctx.getCauldronFluid())
// && ctx.getCauldronLevel() == 3 && !ctx.getWorld().isClient(),
// (ctx) -> {
// PlayerEntity player = ctx.getPlayer();
// World world = ctx.getWorld();
// BlockPos pos = ctx.getPos();
// if (!player.abilities.creativeMode) {
// player.setStackInHand(ctx.getHand(), new ItemStack(Items.BUCKET));
// player.increaseStat(Stats.USE_CAULDRON);
// CauldronUtils.tryEmptyFluid(world, pos, ctx.getState());
// ItemStack obsidian = new ItemStack(Items.OBSIDIAN);
// if (!player.inventory.insertStack(obsidian)) {
// player.dropItem(obsidian, false);
// }
// }
//
// ctx.getWorld().playSound(null, ctx.getPos(), SoundEvents.BLOCK_LAVA_EXTINGUISH, SoundCategory.BLOCK, 1.0f, 1.0f);
// }
// );
//example cauldron behavior code - lets you fill a stone cauldron with fluid
CauldronBehavior.registerBehavior(
(ctx) -> ctx.getStack().getItem() instanceof BucketItem
&& ctx.getStack().getItem() != Items.BUCKET
&& CauldronUtils.canPlaceFluid(ctx.getState(), new FluidProperty.Wrapper(((BucketFluidAccessor)ctx.getStack().getItem()).cotton_getFluid()))
&& ctx.getCauldronLevel() == 3 && !ctx.getWorld().isClient(),
(ctx) -> {
PlayerEntity player = ctx.getPlayer();
World world = ctx.getWorld();
BlockPos pos = ctx.getPos();
player.increaseStat(Stats.USE_CAULDRON);
FluidProperty.Wrapper fluid = new FluidProperty.Wrapper(((BucketFluidAccessor)ctx.getStack().getItem()).cotton_getFluid());
CauldronUtils.placeFluid(world, pos, ctx.getState(), 3, fluid);
if (!player.abilities.creativeMode) player.setStackInHand(ctx.getHand(), new ItemStack(Items.BUCKET));
ctx.getWorld().playSound(null, ctx.getPos(), fluid.getFluid() == Fluids.LAVA ? SoundEvents.ITEM_BUCKET_EMPTY_LAVA : SoundEvents.ITEM_BUCKET_EMPTY, SoundCategory.BLOCK, 1.0f, 1.0f);
}
);
}
}
17 changes: 17 additions & 0 deletions src/main/java/io/github/cottonmc/cotton/CottonClient.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package io.github.cottonmc.cotton;

import io.github.cottonmc.cotton.block.CottonBlocks;
import net.fabricmc.api.ClientModInitializer;
import net.fabricmc.fabric.api.client.render.ColorProviderRegistry;
import net.minecraft.block.Blocks;
import net.minecraft.client.render.block.BlockColorMapper;

public class CottonClient implements ClientModInitializer {
@Override
public void onInitializeClient() {
ColorProviderRegistry.BLOCK.register((block, pos, world, layer) -> {
BlockColorMapper provider = ColorProviderRegistry.BLOCK.get(Blocks.WATER);
return provider == null ? -1 : provider.getColor(block, pos, world, layer);
}, CottonBlocks.STONE_CAULDRON);
}
}
29 changes: 29 additions & 0 deletions src/main/java/io/github/cottonmc/cotton/block/CottonBlocks.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package io.github.cottonmc.cotton.block;

import io.github.cottonmc.cotton.Cotton;
import io.github.cottonmc.cotton.cauldron.StoneCauldronBlock;
import net.minecraft.block.Block;
import net.minecraft.item.Item;
import net.minecraft.item.ItemGroup;
import net.minecraft.item.block.BlockItem;
import net.minecraft.util.Identifier;
import net.minecraft.util.registry.Registry;

public class CottonBlocks {

public static Block STONE_CAULDRON;

public static void init() {
STONE_CAULDRON = register("stone_cauldron", new StoneCauldronBlock(), ItemGroup.DECORATIONS);
}

public static Block register(String name, Block block, ItemGroup group) {
Identifier id = new Identifier(Cotton.MODID, name);

Registry.register(Registry.BLOCK, id, block);
BlockItem item = new BlockItem(block, new Item.Settings().itemGroup(group));
Registry.register(Registry.ITEM, id, item);

return block;
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package io.github.cottonmc.cotton.behavior;
package io.github.cottonmc.cotton.cauldron;

import java.util.HashMap;
import java.util.Map;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package io.github.cottonmc.cotton.behavior;
package io.github.cottonmc.cotton.cauldron;

import blue.endless.jankson.annotation.Nullable;
import io.github.cottonmc.cotton.util.FluidProperty;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.block.CauldronBlock;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.fluid.Fluid;
import net.minecraft.fluid.Fluids;
import net.minecraft.item.ItemStack;
import net.minecraft.util.Hand;
import net.minecraft.util.math.BlockPos;
Expand Down Expand Up @@ -68,6 +70,7 @@ public ItemStack getStack() {
}

public Fluid getCauldronFluid() {
if (state.getBlock() == Blocks.CAULDRON) return state.get(CauldronBlock.LEVEL) == 0? Fluids.EMPTY : Fluids.WATER;
return state.get(FluidProperty.ANY_FLUID).getFluid();
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
package io.github.cottonmc.cotton.behavior;
package io.github.cottonmc.cotton.cauldron;

import io.github.cottonmc.cotton.util.FluidProperty;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.block.CauldronBlock;
import net.minecraft.fluid.Fluid;
import net.minecraft.fluid.Fluids;
Expand All @@ -16,25 +17,27 @@ public class CauldronUtils {
private static final IntegerProperty LEVEL = CauldronBlock.LEVEL;

public static boolean canPlaceFluid(BlockState state, FluidProperty.Wrapper fluid) {
Fluid blockFluid = state.get(FLUID).getFluid();
Fluid blockFluid = (state.getBlock() == Blocks.CAULDRON)? Fluids.WATER : state.get(FLUID).getFluid();
Fluid bucketFluid = fluid.getFluid();

return blockFluid.matchesType(bucketFluid) || blockFluid == Fluids.EMPTY;
}

public static void placeFluid(World world, BlockPos pos, BlockState state, int level, FluidProperty.Wrapper fluid) {
world.setBlockState(pos, state.with(LEVEL, MathHelper.clamp(level, 0, 3)).with(FLUID, fluid), 2);
world.setBlockState(pos, state.with(LEVEL, MathHelper.clamp(level, 0, 3)));
if (!(world.getBlockState(pos).getBlock() == Blocks.CAULDRON)) world.setBlockState(pos, state.with(FLUID, fluid), 2);
world.updateHorizontalAdjacent(pos, state.getBlock());
}

public static void setFluidFromLevel(IWorld world, BlockPos pos) {
BlockState state = world.getBlockState(pos);
if (state.getBlock() == Blocks.CAULDRON) return;
world.setBlockState(pos, state.with(FLUID, state.get(LEVEL) == 0 ? FluidProperty.EMPTY : state.get(FLUID)), 3);
}

public static Fluid tryEmptyFluid(IWorld world, BlockPos pos, BlockState state) {
int level = state.get(LEVEL);
Fluid fluid = state.get(FLUID).getFluid();
Fluid fluid = (state.getBlock() == Blocks.CAULDRON)? Fluids.WATER : state.get(FLUID).getFluid();

if (level == 3) {
world.setBlockState(pos, state.with(LEVEL, 0), 3);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
package io.github.cottonmc.cotton.cauldron;

import io.github.cottonmc.cotton.Cotton;
import io.github.cottonmc.cotton.util.FluidProperty;
import net.fabricmc.fabric.api.block.FabricBlockSettings;
import net.fabricmc.fabric.api.tag.FabricItemTags;
import net.minecraft.block.*;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.fluid.BaseFluid;
import net.minecraft.fluid.Fluid;
import net.minecraft.fluid.FluidState;
import net.minecraft.fluid.Fluids;
import net.minecraft.item.BucketItem;
import net.minecraft.item.ItemPlacementContext;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.sound.SoundCategory;
import net.minecraft.sound.SoundEvents;
import net.minecraft.state.StateFactory;
import net.minecraft.state.property.IntegerProperty;
import net.minecraft.tag.FluidTags;
import net.minecraft.util.Hand;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.shape.VoxelShape;
import net.minecraft.world.BlockView;
import net.minecraft.world.IWorld;
import net.minecraft.world.World;

import java.util.function.Predicate;

public class StoneCauldronBlock extends CauldronBlock implements FluidFillable, FluidDrainable {

public static final IntegerProperty LEVEL = CauldronBlock.LEVEL;
private static final FluidProperty FLUID = FluidProperty.ANY_FLUID;

public StoneCauldronBlock() {
super(FabricBlockSettings.of(Material.STONE).breakByTool(FabricItemTags.PICKAXES).build());
this.setDefaultState(this.getStateFactory().getDefaultState().with(LEVEL, 0).with(FLUID, FluidProperty.EMPTY));
}

@Override
public BlockState getPlacementState(ItemPlacementContext ctx) {
FluidState state = ctx.getWorld().getFluidState(ctx.getBlockPos());

if (state.getFluid() instanceof BaseFluid) {
BaseFluid baseFluid = (BaseFluid) state.getFluid();
Fluid still = baseFluid.getStill();
BlockState superState = super.getPlacementState(ctx);

if (superState != null) {
return superState.with(LEVEL, 3).with(FLUID, new FluidProperty.Wrapper(still));
}
}

return super.getPlacementState(ctx);
}

@Override
protected void appendProperties(StateFactory.Builder<Block, BlockState> builder) {
builder.with(LEVEL, FLUID);
}

@Override
public boolean activate(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult result) {
ItemStack stack = player.getStackInHand(hand);
if (stack.getItem() == Items.BUCKET) return false;

CauldronContext ctx = new CauldronContext(world, pos, state, player, hand, player.getStackInHand(hand));
for (Predicate<CauldronContext> pred : CauldronBehavior.BEHAVIORS.keySet()) {
if (pred.test(ctx)) {
CauldronBehavior behavior = CauldronBehavior.BEHAVIORS.get(pred);
behavior.interact(ctx);
return true;
}
}

if (stack.getItem() instanceof BucketItem) return false;

// Item destruction with lava
// Must not be a registered cauldron behavior, otherwise it'd override anything anyone else would wanna do with lava
int lavaLevel = state.get(FLUID).getFluid().matches(FluidTags.LAVA) ? state.get(LEVEL) : 0;

if (lavaLevel == 0) {
boolean ret = super.activate(state, world, pos, player, hand, result);
CauldronUtils.setFluidFromLevel(world, pos);
return ret;
}

if (Cotton.config.cauldronTrashCan) {
stack.subtractAmount(1);
world.playSound(player, pos, SoundEvents.BLOCK_LAVA_EXTINGUISH, SoundCategory.BLOCK, 1f, 1f);
world.setBlockState(pos, state.with(LEVEL, lavaLevel - 1));
CauldronUtils.setFluidFromLevel(world, pos);
}
return true;
}

@Override
public Fluid tryDrainFluid(IWorld world, BlockPos pos, BlockState state) {
int level = state.get(LEVEL);
Fluid fluid = state.get(FLUID).getFluid();

if (level == 3) {
world.setBlockState(pos, state.with(LEVEL, 0), 3);
CauldronUtils.setFluidFromLevel(world, pos);
return fluid;
}

return Fluids.EMPTY;
}

@Override
public VoxelShape getRayTraceShape(BlockState state, BlockView view, BlockPos pos) {
return createCuboidShape(2.0D, 4.0D, 2.0D, 14.0D, 16.0D, 14.0D);
}

@Override
public boolean canFillWithFluid(BlockView view, BlockPos pos, BlockState state, Fluid fluid) {
System.out.println(state.get(FLUID).getFluid().toString() + fluid.toString());
//TODO: remove once we've got non-vanilla fluid compat
if (!FluidProperty.VANILLA_FLUIDS.getValues().contains(new FluidProperty.Wrapper(fluid))) return false;
return CauldronUtils.canPlaceFluid(state, new FluidProperty.Wrapper(fluid));
}

@Override
public boolean tryFillWithFluid(IWorld world, BlockPos pos, BlockState state, FluidState fluidState) {
setFluidLevel(world.getWorld(), pos, state, fluidState.getFluid(), 3);
return true;
}

@Override
public int getLuminance(BlockState state) {
// TODO: Remove hardcoding when we switch to the fluid renderer
if (state.get(FLUID).getFluid().matches(FluidTags.LAVA)) {
return 15;
} else {
return super.getLuminance(state);
}
}

@Override
public void onEntityCollision(BlockState state, World world, BlockPos pos, Entity entity) {
if (state.get(FLUID).getFluid() == Fluids.WATER) {
int level = state.get(LEVEL);
float float_1 = pos.getY() + (6.0F + (float)(3 * level)) / 16.0F;
if (!world.isClient && entity.isOnFire() && level > 0 && entity.getBoundingBox().minY <= (double)float_1) {
entity.extinguish();
this.setLevel(world, pos, state, level - 1);
}
}
}

public void setLevel(World world, BlockPos pos, BlockState state, int level) {
setFluidLevel(world, pos, state, state.get(FLUID).getFluid(), level);
}

public void setFluidLevel(World world, BlockPos pos, BlockState state, Fluid fluid, int level) {
world.setBlockState(pos, state.with(LEVEL, MathHelper.clamp(level, 0, 3)).with(FLUID, new FluidProperty.Wrapper(fluid)), 2);
world.updateHorizontalAdjacent(pos, this);
}

public void onRainTick(World world, BlockPos pos) {
if (world.random.nextInt(20) == 1) {
float temp = world.getBiome(pos).getTemperature(pos);
if (temp >= 0.15F) {
BlockState state = world.getBlockState(pos);
if (state.get(LEVEL) < 3 && (state.get(FLUID) == FluidProperty.WATER || state.get(FLUID) == FluidProperty.EMPTY)) {
world.setBlockState(pos, state.method_11572(LEVEL), 2);
}

}
}
}
}
Loading

0 comments on commit 369cbce

Please sign in to comment.