Skip to content

Commit

Permalink
chore: refactor & improve Acid Cauldron
Browse files Browse the repository at this point in the history
  • Loading branch information
Elenterius committed Jul 18, 2024
1 parent 749669e commit 5f13101
Show file tree
Hide file tree
Showing 20 changed files with 310 additions and 149 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
import com.github.elenterius.biomancy.init.ModBlocks;
import net.minecraft.core.Direction;
import net.minecraft.data.PackOutput;
import net.minecraft.data.models.model.TextureMapping;
import net.minecraft.data.models.model.TextureSlot;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.ItemDisplayContext;
import net.minecraft.world.level.block.*;
Expand Down Expand Up @@ -151,14 +153,32 @@ protected void registerStatesAndModels() {

particleOnly(ModBlocks.ACID_FLUID_BLOCK, new ResourceLocation("biomancy:block/acid_flat"));

cauldron(ModBlocks.ACID_CAULDRON,new ResourceLocation("biomancy:fluid/acid_overlay"));
layeredCauldron(ModBlocks.ACID_CAULDRON);
}

public <T extends Block> void cauldron(RegistryObject<T> block, ResourceLocation fluidTexture) {
BlockModelBuilder model = models().withExistingParent(path(block.get()),"minecraft:block/lava_cauldron")
.texture("content",fluidTexture);
public <T extends LayeredCauldronBlock> void layeredCauldron(RegistryObject<T> registryObject) {
T block = registryObject.get();
String path = path(block);

TextureMapping textureMapping = TextureMapping.cauldron(TextureMapping.getBlockTexture(Blocks.WATER, "_still"));
TextureSlot[] texturesSlots = {TextureSlot.CONTENT, TextureSlot.INSIDE, TextureSlot.TOP, TextureSlot.BOTTOM, TextureSlot.SIDE, TextureSlot.PARTICLE};

simpleBlock(block.get(),model);
ModelFile modelLevel1 = getTemplateModelWithTextures(path + "_level_1", new ResourceLocation("minecraft:block/template_cauldron_level1"), texturesSlots, textureMapping).renderType("translucent");
ModelFile modelLevel2 = getTemplateModelWithTextures(path + "_level_2", new ResourceLocation("minecraft:block/template_cauldron_level2"), texturesSlots, textureMapping).renderType("translucent");
ModelFile modelFull = getTemplateModelWithTextures(path + "_full", new ResourceLocation("minecraft:block/template_cauldron_full"), texturesSlots, textureMapping).renderType("translucent");

getVariantBuilder(block)
.partialState().with(LayeredCauldronBlock.LEVEL, 1).modelForState().modelFile(modelLevel1).addModel()
.partialState().with(LayeredCauldronBlock.LEVEL, 2).modelForState().modelFile(modelLevel2).addModel()
.partialState().with(LayeredCauldronBlock.LEVEL, 3).modelForState().modelFile(modelFull).addModel();
}

private BlockModelBuilder getTemplateModelWithTextures(String name, ResourceLocation template, TextureSlot[] texturesSlots, TextureMapping textureMapping) {
BlockModelBuilder modelBuilder = models().withExistingParent(name, template);
for (TextureSlot textureSlot : texturesSlots) {
modelBuilder.texture(textureSlot.getId(), textureMapping.get(textureSlot));
}
return modelBuilder;
}

public <T extends Block> void particleOnly(RegistryObject<T> block, ResourceLocation particleTexture) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
{
"variants": {
"": {
"model": "biomancy:block/acid_cauldron"
"level=1": {
"model": "biomancy:block/acid_cauldron_level_1"
},
"level=2": {
"model": "biomancy:block/acid_cauldron_level_2"
},
"level=3": {
"model": "biomancy:block/acid_cauldron_full"
}
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"parent": "minecraft:block/template_cauldron_full",
"render_type": "minecraft:translucent",
"textures": {
"bottom": "minecraft:block/cauldron_bottom",
"content": "minecraft:block/water_still",
"inside": "minecraft:block/cauldron_inner",
"particle": "minecraft:block/cauldron_side",
"side": "minecraft:block/cauldron_side",
"top": "minecraft:block/cauldron_top"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"parent": "minecraft:block/template_cauldron_level1",
"render_type": "minecraft:translucent",
"textures": {
"bottom": "minecraft:block/cauldron_bottom",
"content": "minecraft:block/water_still",
"inside": "minecraft:block/cauldron_inner",
"particle": "minecraft:block/cauldron_side",
"side": "minecraft:block/cauldron_side",
"top": "minecraft:block/cauldron_top"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"parent": "minecraft:block/template_cauldron_level2",
"render_type": "minecraft:translucent",
"textures": {
"bottom": "minecraft:block/cauldron_bottom",
"content": "minecraft:block/water_still",
"inside": "minecraft:block/cauldron_inner",
"particle": "minecraft:block/cauldron_side",
"side": "minecraft:block/cauldron_side",
"top": "minecraft:block/cauldron_top"
}
}
Original file line number Diff line number Diff line change
@@ -1,66 +1,73 @@
package com.github.elenterius.biomancy.block.cauldron;

import com.github.elenterius.biomancy.fluid.AcidFluid;
import com.github.elenterius.biomancy.init.ModFluids;
import com.github.elenterius.biomancy.init.ModItems;
import com.github.elenterius.biomancy.init.AcidInteractions;
import net.minecraft.core.BlockPos;
import net.minecraft.core.cauldron.CauldronInteraction;
import net.minecraft.sounds.SoundSource;
import net.minecraft.stats.Stats;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.BlockItem;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.AbstractCauldronBlock;
import net.minecraft.world.level.biome.Biome;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.LayeredCauldronBlock;
import net.minecraft.world.level.block.LevelEvent;
import net.minecraft.world.level.block.SoundType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraftforge.common.SoundActions;
import net.minecraftforge.registries.ForgeRegistries;
import org.jetbrains.annotations.NotNull;

import java.util.Map;
import java.util.Objects;
public class AcidCauldron extends LayeredCauldronBlock {

public class AcidCauldron extends AbstractCauldronBlock {
public AcidCauldron() {
super(Properties.copy(Blocks.CAULDRON),getInteractions());
public AcidCauldron(Properties properties) {
super(properties, precipitation -> false, AcidInteractions.ACID_CAULDRON);
}

private static Map<Item, CauldronInteraction> getInteractions() {
Map<Item,CauldronInteraction> map = CauldronInteraction.newInteractionMap();
map.put(Items.BUCKET, (pBlockState, pLevel, pPos, pPlayer, pHand, pEmptyStack) -> CauldronInteraction.fillBucket(pBlockState, pLevel, pPos, pPlayer, pHand, pEmptyStack, ModItems.ACID_BUCKET.get().getDefaultInstance(), (_stack)->true, Objects.requireNonNull(ModFluids.ACID_TYPE.get().getSound(SoundActions.BUCKET_FILL))));
return map;
@Override
protected boolean canReceiveStalactiteDrip(Fluid fluid) {
return false;
}

@Override
public void entityInside(BlockState state, Level level, BlockPos pos, Entity entity) {
if (!(entity instanceof LivingEntity)) return;
AcidFluid.onEntityInside((LivingEntity)entity);
if (entity instanceof LivingEntity livingEntity && isEntityInsideContent(state, pos, entity)) {
if (livingEntity.tickCount % 5 != 0) return;
AcidInteractions.handleEntityInsideAcid(livingEntity);
}
}

@Override
public boolean isFull(BlockState pState) {
return true;
protected void handleEntityOnFireInside(BlockState state, Level level, BlockPos pos) {
//do nothing
}

@Override
public void handlePrecipitation(BlockState state, Level level, BlockPos pos, Biome.Precipitation precipitation) {
//do nothing
}

@Override
public InteractionResult use(BlockState state, Level level, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit) {
//No idea why, but MC freaks out without this line. super.use() should cover it, but it doesn't so...
if (getInteractions().containsKey(player.getItemInHand(hand).getItem())) return getInteractions().get(player.getItemInHand(hand).getItem()).interact(state,level,pos,player,hand,player.getItemInHand(hand));
ItemStack stack = player.getItemInHand(hand);

if (stack.getItem() instanceof BlockItem blockItem) {
Block block = blockItem.getBlock();
Block convertedBlock = AcidInteractions.convertBlock(block);
if (convertedBlock != null) {
if (!level.isClientSide()) {
player.setItemInHand(hand, new ItemStack(convertedBlock.asItem(), stack.getCount()));
player.awardStat(Stats.USE_CAULDRON);

SoundType soundType = block.getSoundType(block.defaultBlockState(), level, pos, null);
level.playSound(null, pos, soundType.getHitSound(), SoundSource.BLOCKS, soundType.volume, soundType.pitch);
level.levelEvent(LevelEvent.LAVA_FIZZ, pos, 0);
}

//An attempt to allow the player to do all the erosion interactions inside the cauldron.
//It mostly works, copper being a weird exception.
Block block = ForgeRegistries.BLOCKS.getValue(ForgeRegistries.ITEMS.getKey(player.getItemInHand(hand).getItem()));
if (!Objects.isNull(block)) {
BlockState eroded = AcidFluid.getEroded(block.defaultBlockState());
if (!Objects.isNull(eroded)) {
player.setItemInHand(hand,new ItemStack(eroded.getBlock().asItem(),player.getItemInHand(hand).getCount()));
return InteractionResult.SUCCESS;
return InteractionResult.sidedSuccess(level.isClientSide());
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
@ParametersAreNonnullByDefault
@MethodsReturnNonnullByDefault
package com.github.elenterius.biomancy.block.cauldron;

import net.minecraft.MethodsReturnNonnullByDefault;

import javax.annotation.ParametersAreNonnullByDefault;
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.github.elenterius.biomancy.entity.projectile;

import com.github.elenterius.biomancy.block.cauldron.AcidCauldron;
import com.github.elenterius.biomancy.block.veins.FleshVeinsBlock;
import com.github.elenterius.biomancy.init.ModBlocks;
import com.github.elenterius.biomancy.init.ModEntityTypes;
Expand All @@ -13,6 +14,7 @@
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.LayeredCauldronBlock;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.BlockHitResult;
import software.bernie.geckolib.animatable.GeoEntity;
Expand Down Expand Up @@ -42,6 +44,10 @@ public void setCanPlaceAcidFluid(boolean flag) {
canPlaceAcidFluid = flag;
}

public boolean canPlaceAcidFluid() {
return canPlaceAcidFluid;
}

@Override
public void readAdditionalSaveData(CompoundTag tag) {
super.readAdditionalSaveData(tag);
Expand All @@ -64,6 +70,15 @@ protected void onHitBlock(BlockHitResult result) {
super.onHitBlock(result);
}

@Override
protected void onInsideBlock(BlockState state) {
if (!level().isClientSide && canPlaceAcidFluid) {
if (state.getBlock() == Blocks.CAULDRON || (state.getBlock() instanceof AcidCauldron cauldron && !cauldron.isFull(state))) {
level().setBlockAndUpdate(blockPosition(), ModBlocks.ACID_CAULDRON.get().defaultBlockState().setValue(LayeredCauldronBlock.LEVEL, 3));
}
}
}

private boolean placeAcidFluid(BlockHitResult result) {
BlockPos pos = result.getBlockPos();
BlockPos posRelative = pos.relative(result.getDirection());
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.github.elenterius.biomancy.event;

import com.github.elenterius.biomancy.BiomancyMod;
import com.github.elenterius.biomancy.fluid.AcidFluid;
import com.github.elenterius.biomancy.init.AcidInteractions;
import com.github.elenterius.biomancy.init.ModEnchantments;
import net.minecraftforge.event.TickEvent;
import net.minecraftforge.event.entity.living.LivingEvent;
Expand All @@ -16,7 +16,7 @@ private LivingEventHandler() {}

@SubscribeEvent
public static void onLivingTick(final LivingEvent.LivingTickEvent event) {
AcidFluid.onEntityInside(event.getEntity());
AcidInteractions.handleEntityInsideAcidFluid(event.getEntity());
}

@SubscribeEvent
Expand Down
56 changes: 3 additions & 53 deletions src/main/java/com/github/elenterius/biomancy/fluid/AcidFluid.java
Original file line number Diff line number Diff line change
@@ -1,17 +1,14 @@
package com.github.elenterius.biomancy.fluid;

import com.github.elenterius.biomancy.block.veins.FleshVeinsBlock;
import com.github.elenterius.biomancy.init.ModBlocks;
import com.github.elenterius.biomancy.init.ModFluids;
import com.github.elenterius.biomancy.init.AcidInteractions;
import com.github.elenterius.biomancy.init.tags.ModBlockTags;
import com.github.elenterius.biomancy.util.CombatUtil;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.core.particles.ParticleTypes;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.sounds.SoundSource;
import net.minecraft.util.RandomSource;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.LevelAccessor;
Expand All @@ -20,62 +17,15 @@
import net.minecraft.world.level.block.state.StateDefinition;
import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.level.material.FluidState;
import net.minecraft.world.phys.Vec3;
import net.minecraftforge.event.ForgeEventFactory;
import net.minecraftforge.fluids.ForgeFlowingFluid;
import org.jetbrains.annotations.Nullable;

import java.util.Map;

public abstract class AcidFluid extends ForgeFlowingFluid {

protected static final Map<Block, BlockState> NORMAL_TO_ERODED_BLOCK_CONVERSION = Map.of(
Blocks.GRASS_BLOCK, Blocks.DIRT.defaultBlockState(),
Blocks.COBBLESTONE, Blocks.GRAVEL.defaultBlockState(),
Blocks.STONE_BRICKS, Blocks.CRACKED_STONE_BRICKS.defaultBlockState(),
Blocks.DEEPSLATE_BRICKS, Blocks.CRACKED_DEEPSLATE_BRICKS.defaultBlockState(),
Blocks.DEEPSLATE_TILES, Blocks.CRACKED_DEEPSLATE_TILES.defaultBlockState(),
Blocks.POLISHED_BLACKSTONE_BRICKS, Blocks.CRACKED_POLISHED_BLACKSTONE_BRICKS.defaultBlockState(),
Blocks.NETHER_BRICKS, Blocks.CRACKED_NETHER_BRICKS.defaultBlockState()
);

protected AcidFluid(Properties properties) {
super(properties);
}

public static void onEntityInside(LivingEntity livingEntity) {
if (livingEntity.isSpectator()) return;
if (livingEntity.tickCount % 5 != 0) return;
if (!livingEntity.isInFluidType(ModFluids.ACID_TYPE.get()) && !livingEntity.getFeetBlockState().is(ModBlocks.ACID_CAULDRON.get())) return;

if (!livingEntity.level().isClientSide) {
CombatUtil.applyAcidEffect(livingEntity, 4);
}
else if (livingEntity.tickCount % 10 == 0 && livingEntity.getRandom().nextFloat() < 0.4f) {
Level level = livingEntity.level();
RandomSource random = livingEntity.getRandom();
Vec3 pos = livingEntity.position();
double height = livingEntity.getBoundingBox().getYsize() * 0.5f;

level.playLocalSound(pos.x, pos.y, pos.z, SoundEvents.LAVA_EXTINGUISH, SoundSource.BLOCKS, 0.5f, 2.6f + (random.nextFloat() - random.nextFloat()) * 0.8f, false);
for (int i = 0; i < 4; i++) {
level.addParticle(ParticleTypes.LARGE_SMOKE, pos.x + random.nextDouble(), pos.y + random.nextDouble() * height, pos.z + random.nextDouble(), 0, 0.1d, 0);
}
}
}

@Nullable
public static BlockState getEroded(BlockState state) {
if (state instanceof WeatheringCopper && WeatheringCopper.getNext(state.getBlock()).isPresent()) {
return WeatheringCopper.getNext(state.getBlock()).get().defaultBlockState();
} else if (state.is(ModBlockTags.ACID_DESTRUCTIBLE)) {
return Blocks.AIR.defaultBlockState();
} else if (NORMAL_TO_ERODED_BLOCK_CONVERSION.containsKey(state.getBlock())) {
return NORMAL_TO_ERODED_BLOCK_CONVERSION.get(state.getBlock());
}
return null;
}

@Override
protected boolean canPassThrough(BlockGetter level, Fluid fluid, BlockPos fromPos, BlockState fromBlockState, Direction direction, BlockPos toPos, BlockState toBlockState, FluidState toFluidState) {
return toBlockState.getBlock() instanceof FleshVeinsBlock || super.canPassThrough(level, fluid, fromPos, fromBlockState, direction, toPos, toBlockState, toFluidState);
Expand Down Expand Up @@ -163,10 +113,10 @@ protected boolean destroyBlock(Level level, BlockPos liquidPos, Block block, Blo
}

protected boolean erodeBlock(Level level, BlockPos liquidPos, Block block, BlockState blockState, BlockPos pos) {
if (!NORMAL_TO_ERODED_BLOCK_CONVERSION.containsKey(block)) return false;
if (!AcidInteractions.NORMAL_TO_ERODED_BLOCK_CONVERSION.containsKey(block)) return false;

SoundType soundType = block.getSoundType(blockState, level, pos, null);
level.setBlockAndUpdate(pos, ForgeEventFactory.fireFluidPlaceBlockEvent(level, pos, liquidPos, NORMAL_TO_ERODED_BLOCK_CONVERSION.get(block)));
level.setBlockAndUpdate(pos, ForgeEventFactory.fireFluidPlaceBlockEvent(level, pos, liquidPos, AcidInteractions.NORMAL_TO_ERODED_BLOCK_CONVERSION.get(block)));
level.playSound(null, pos, soundType.getBreakSound(), SoundSource.BLOCKS, soundType.volume, soundType.pitch);
level.levelEvent(LevelEvent.LAVA_FIZZ, pos, 0);
return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,4 +109,9 @@ public void renderOverlay(Minecraft mc, PoseStack poseStack) {
}
});
}

public int getTintColor() {
return colorARGB;
}

}
Loading

0 comments on commit 5f13101

Please sign in to comment.