Skip to content

Commit

Permalink
feat(acid): add acid fluid
Browse files Browse the repository at this point in the history
  • Loading branch information
Elenterius committed Dec 11, 2023
1 parent f3fb0b9 commit 61da539
Show file tree
Hide file tree
Showing 13 changed files with 199 additions and 32 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ protected void addTranslations() {

addItemTranslations();
addBlockTranslations();
addFluidTranslations();
addEntityTranslations();
addEnchantmentTranslations();
addStatusEffectTranslations();
Expand Down Expand Up @@ -390,6 +391,7 @@ private void addItemTranslations() {
Looks like some objects are wrapped in an organic layer of skin. Might be filled with items or toxin if your language is set to German.
Right Click the Sac to retrieve the Items.""");
addItem(ModItems.ACID_BUCKET, "Acid Bucket");

addItem(ModItems.RAVENOUS_CLAWS, "Ravenous Claws", """
Extremely hungry and vicious Claws forged by starving living flesh and grafting claws onto it.
Expand Down Expand Up @@ -504,6 +506,8 @@ private void addBlockTranslations() {
addBlock(ModBlocks.MALIGNANT_FLESH_VEINS, "Malignant Flesh Veins", "They look almost feral...\nyou better not touch them.");
addBlock(ModBlocks.MALIGNANT_BLOOM, "Malignant Bloom", "An exotic flower of primordial beauty.\n\nIt will spread itself by launching it's ripe berry into the air.\nOn impact the berry explodes and spreads malignant veins as well.");
addBlock(ModBlocks.PRIMAL_ORIFICE, "Primal Orifice", "A primitive piece full of holes. It seems to leak an acidic substance.");

addBlock(ModBlocks.ACID_FLUID_BLOCK, "Acid");
}

private void addEntityTranslations() {
Expand All @@ -514,4 +518,7 @@ private void addEntityTranslations() {
addEntityType(ModEntityTypes.PRIMORDIAL_HUNGRY_FLESH_BLOB, "Primordial Hungry Flesh Blob");
}

private void addFluidTranslations() {
addFluidType(ModFluids.ACID_TYPE, "Acid");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,8 @@ protected void addTables() {
addCustom(ModBlocks.FULL_FLESH_DOOR.get(), ModBlockLoot::createFleshDoorTable);

addCustom(ModBlocks.FLESH_SPIKE.get(), ModBlockLoot::createFleshSpikeTable);

add(ModBlocks.ACID_FLUID_BLOCK.get(), noDrop());
}

protected <T extends Block> void addCustom(T block, Function<T, LootTable.Builder> function) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,8 @@ protected void registerModels() {
flatBlockItem(ModItems.FLESH_LADDER);
flatBlockItem(ModItems.MALIGNANT_FLESH_VEINS);

dynamicBucket(ModItems.ACID_BUCKET.get());

//generate models for all eggs
ModItems.ITEMS.getEntries().stream().map(RegistryObject::get).filter(SpawnEggItem.class::isInstance).forEach(this::spawnEggItem);
}
Expand Down
3 changes: 3 additions & 0 deletions src/generated/resources/assets/biomancy/lang/en_us.json
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@
"item.biomancy.fertilizer.tooltip": "Fertilizer that induces hyper-growth in plants, even for reeds, cactus, nether wart and chorus.",
"item.biomancy.gift_sac": "Gift Sac",
"item.biomancy.gift_sac.tooltip": "Looks like some objects are wrapped in an organic layer of skin. Might be filled with items or toxin if your language is set to German.\n\nRight Click the Sac to retrieve the Items.",
"item.biomancy.acid_bucket": "Acid Bucket",
"item.biomancy.ravenous_claws": "Ravenous Claws",
"item.biomancy.ravenous_claws.tooltip": "Extremely hungry and vicious Claws forged by starving living flesh and grafting claws onto it.\n\nRepair the famished claws by feeding them with food via the player inventory, as you would fill a bundle.\n\nKilling Mobs with these claws grants blood charges, which allow you to use the Awakened mode.",
"item.biomancy.dev_arm_cannon": "[Dev Tool] Arm Cannon",
Expand Down Expand Up @@ -239,6 +240,8 @@
"block.biomancy.malignant_bloom.tooltip": "An exotic flower of primordial beauty.\n\nIt will spread itself by launching it's ripe berry into the air.\nOn impact the berry explodes and spreads malignant veins as well.",
"block.biomancy.primal_orifice": "Primal Orifice",
"block.biomancy.primal_orifice.tooltip": "A primitive piece full of holes. It seems to leak an acidic substance.",
"block.biomancy.acid_fluid_block": "Acid",
"fluid_type.biomancy.acid": "Acid",
"entity.biomancy.hungry_flesh_blob": "Hungry Flesh Blob",
"entity.biomancy.flesh_blob": "Flesh Blob",
"entity.biomancy.legacy_flesh_blob": "Legacy Flesh Blob",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.github.elenterius.biomancy.event;

import com.github.elenterius.biomancy.BiomancyMod;
import com.github.elenterius.biomancy.fluid.AcidFluid;
import net.minecraftforge.event.entity.living.LivingEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;

@Mod.EventBusSubscriber(modid = BiomancyMod.MOD_ID, bus = Mod.EventBusSubscriber.Bus.FORGE)
public final class LivingEventHandler {

private LivingEventHandler() {}

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

}
134 changes: 134 additions & 0 deletions src/main/java/com/github/elenterius/biomancy/fluid/AcidFluid.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
package com.github.elenterius.biomancy.fluid;

import com.github.elenterius.biomancy.init.ModFluids;
import com.github.elenterius.biomancy.util.CombatUtil;
import net.minecraft.core.BlockPos;
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.Level;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.LevelEvent;
import net.minecraft.world.level.block.WeatheringCopper;
import net.minecraft.world.level.block.state.BlockState;
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;

public abstract class AcidFluid extends ForgeFlowingFluid {

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

public static void onEntityInside(LivingEntity livingEntity) {
if (livingEntity.tickCount % 5 == 0 && livingEntity.isInFluidType(ModFluids.ACID_TYPE.get())) {
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);
}
}
}
}

@Override
protected boolean isRandomlyTicking() {
return true;
}

@Override
protected void randomTick(Level level, BlockPos liquidPos, FluidState fluidState, RandomSource random) {
if (level.random.nextFloat() > 0.6f) return;

for (int i = 0; i < 3; i++) {
float p = level.random.nextFloat();
int yOffset = 0;
if (p < 0.2f) yOffset = 1;
else if (p < 0.6f) yOffset = -1;
BlockPos blockPos = liquidPos.offset(random.nextInt(3) - 1, yOffset, random.nextInt(3) - 1);

if (!level.isLoaded(blockPos)) return;

BlockState blockState = level.getBlockState(blockPos);
if (blockState.isAir()) return;

if (level.random.nextFloat() >= 0.057f) {
corrodeCopper(level, liquidPos, blockState, blockPos);
}
}
}

protected void corrodeCopper(Level level, BlockPos liquidPos, BlockState blockState, BlockPos pos) {
Block block = blockState.getBlock();
if (block instanceof WeatheringCopper weatheringCopper && WeatheringCopper.getNext(block).isPresent()) {
weatheringCopper.getNext(blockState).ifPresent(state -> level.setBlockAndUpdate(pos, ForgeEventFactory.fireFluidPlaceBlockEvent(level, pos, liquidPos, state)));
level.levelEvent(LevelEvent.LAVA_FIZZ, pos, 0);
}
}

@Override
protected void animateTick(Level level, BlockPos pos, FluidState state, RandomSource random) {
if (!state.isSource() && Boolean.FALSE.equals(state.getValue(FALLING))) {
if (random.nextInt(64) == 0) {
level.playLocalSound(pos.getX() + 0.5f, pos.getY() + 0.5f, pos.getZ() + 0.5f, SoundEvents.WATER_AMBIENT, SoundSource.BLOCKS, random.nextFloat() * 0.25f + 0.75f, random.nextFloat() + 0.5f, false);
}
}
else if (random.nextInt(10) == 0) {
level.addParticle(ParticleTypes.UNDERWATER, pos.getX() + random.nextDouble(), pos.getY() + random.nextDouble(), pos.getZ() + random.nextDouble(), 0, 0, 0);
}
}

public static class Flowing extends AcidFluid {
public Flowing(Properties properties) {
super(properties);
registerDefaultState(getStateDefinition().any().setValue(LEVEL, 7));
}

@Override
protected void createFluidStateDefinition(StateDefinition.Builder<Fluid, FluidState> builder) {
super.createFluidStateDefinition(builder);
builder.add(LEVEL);
}

@Override
public int getAmount(FluidState state) {
return state.getValue(LEVEL);
}

@Override
public boolean isSource(FluidState state) {
return false;
}
}

public static class Source extends AcidFluid {

public Source(Properties properties) {
super(properties);
}

@Override
public int getAmount(FluidState state) {
return 8;
}

@Override
public boolean isSource(FluidState state) {
return true;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,9 @@ public final class ModBlocks {
public static final RegistryObject<FleshLanternBlock> YELLOW_BIO_LANTERN = register("bio_lantern_yellow", properties -> new FleshLanternBlock(properties.sound(SoundType.SHROOMLIGHT).lightLevel(x -> 15).noOcclusion()));
public static final RegistryObject<FleshLanternBlock> BLUE_BIO_LANTERN = register("bio_lantern_blue", properties -> new FleshLanternBlock(properties.sound(SoundType.SHROOMLIGHT).lightLevel(x -> 15).noOcclusion()));

//## Fluids
public static final RegistryObject<LiquidBlock> ACID_FLUID_BLOCK = register("acid_fluid_block", () -> new LiquidBlock(ModFluids.ACID, copyProperties(Blocks.WATER)));

//## Misc
public static final RegistryObject<LadderBlock> FLESH_LADDER = register("flesh_ladder", () -> new LadderBlock(createFleshyBoneProperties().noOcclusion()));
public static final RegistryObject<FleshFenceBlock> FLESH_FENCE = register("flesh_fence", FleshFenceBlock::new);
Expand Down
17 changes: 17 additions & 0 deletions src/main/java/com/github/elenterius/biomancy/init/ModFluids.java
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
package com.github.elenterius.biomancy.init;

import com.github.elenterius.biomancy.BiomancyMod;
import com.github.elenterius.biomancy.fluid.AcidFluid;
import com.github.elenterius.biomancy.fluid.TintedFluidType;
import net.minecraft.client.Minecraft;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.material.Fluid;
import net.minecraftforge.client.extensions.common.IClientFluidTypeExtensions;
import net.minecraftforge.common.ForgeMod;
import net.minecraftforge.fluids.FluidInteractionRegistry;
import net.minecraftforge.fluids.FluidType;
import net.minecraftforge.fluids.ForgeFlowingFluid;
import net.minecraftforge.registries.DeferredRegister;
import net.minecraftforge.registries.ForgeRegistries;
import net.minecraftforge.registries.RegistryObject;
Expand All @@ -20,9 +25,21 @@ public final class ModFluids {
public static final DeferredRegister<FluidType> FLUID_TYPES = DeferredRegister.create(ForgeRegistries.Keys.FLUID_TYPES, BiomancyMod.MOD_ID);
public static final DeferredRegister<Fluid> FLUIDS = DeferredRegister.create(ForgeRegistries.FLUIDS, BiomancyMod.MOD_ID);

public static final RegistryObject<FluidType> ACID_TYPE = registerTintedType("acid", 0xFF_39FF14, properties -> properties.density(1024).viscosity(1024));
public static final Supplier<ForgeFlowingFluid.Properties> ACID_FLUID_PROPERTIES = () -> new ForgeFlowingFluid
.Properties(ACID_TYPE, ModFluids.ACID, ModFluids.FLOWING_ACID)
.slopeFindDistance(2)
.levelDecreasePerBlock(2)
.block(ModBlocks.ACID_FLUID_BLOCK)
.bucket(ModItems.ACID_BUCKET);
public static final RegistryObject<ForgeFlowingFluid> ACID = register("acid", () -> new AcidFluid.Source(ACID_FLUID_PROPERTIES.get()));
public static final RegistryObject<ForgeFlowingFluid> FLOWING_ACID = register("flowing_acid", () -> new AcidFluid.Flowing(ACID_FLUID_PROPERTIES.get()));

private ModFluids() {}

static void registerInteractions() {
FluidInteractionRegistry.addInteraction(ACID_TYPE.get(), new FluidInteractionRegistry
.InteractionInformation(ForgeMod.WATER_TYPE.get(), fluidState -> fluidState.isSource() ? Blocks.CALCITE.defaultBlockState() : Blocks.DIORITE.defaultBlockState()));
}

private static <T extends Fluid> RegistryObject<T> register(String name, Supplier<T> factory) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,9 @@ public final class ModItems {
// public static final RegistryObject<SerumItem> ADRENALINE_SERUM = registerSerumItem(ModSerums.ADRENALINE_SERUM);
// public static final RegistryObject<SerumItem> DECAY_AGENT = registerSerumItem(ModSerums.DECAY_AGENT);

//# Buckets
public static final RegistryObject<BucketItem> ACID_BUCKET = registerItem("acid_bucket", properties -> new BucketItem(ModFluids.ACID, properties.craftRemainder(Items.BUCKET).stacksTo(1).rarity(Rarity.COMMON)));

//# Misc
public static final RegistryObject<GiftSacItem> GIFT_SAC = registerItem("gift_sac", props -> new GiftSacItem(props.stacksTo(1).rarity(ModRarities.ULTRA_RARE).tab(null)));
public static final RegistryObject<SimpleItem> CREATOR_MIX = registerSimpleItem("creator_mix");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public final class ModMobEffects {

public static final DeferredRegister<MobEffect> EFFECTS = DeferredRegister.create(ForgeRegistries.MOB_EFFECTS, BiomancyMod.MOD_ID);

public static final RegistryObject<CorrosiveEffect> CORROSIVE = EFFECTS.register("corrosive", () -> new CorrosiveEffect(MobEffectCategory.HARMFUL, 0xbee040));
public static final RegistryObject<CorrosiveEffect> CORROSIVE = EFFECTS.register("corrosive", () -> new CorrosiveEffect(MobEffectCategory.HARMFUL, 0x39FF14));
public static final RegistryObject<StatusEffect> ARMOR_SHRED = EFFECTS.register("armor_shred", () -> new ArmorShredEffect(MobEffectCategory.HARMFUL, 20, 0x909090)
.addModifier(Attributes.ARMOR, "a15ed03e-c5db-4cf8-a0f5-4eb4657bb731", -1f, AttributeModifier.Operation.ADDITION));
public static final RegistryObject<BleedEffect> BLEED = EFFECTS.register("bleed", () -> new BleedEffect(MobEffectCategory.HARMFUL, 0x8a0303, 2));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,10 @@
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.entity.ThrownItemRenderer;
import net.minecraft.client.renderer.entity.WitherSkullRenderer;
import net.minecraft.world.item.BucketItem;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.client.event.*;
import net.minecraftforge.client.extensions.common.IClientFluidTypeExtensions;
import net.minecraftforge.client.settings.KeyConflictContext;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
Expand Down Expand Up @@ -104,7 +106,7 @@ private static void setBlockRenderLayers() {
ItemBlockRenderTypes.setRenderLayer(ModBlocks.DIGESTER.get(), RenderType.cutout());

ItemBlockRenderTypes.setRenderLayer(ModBlocks.VOICE_BOX.get(), RenderType.translucent());
// ItemBlockRenderTypes.setRenderLayer(ModBlocks.STORAGE_SAC.get(), RenderType.translucent());
//ItemBlockRenderTypes.setRenderLayer(ModBlocks.STORAGE_SAC.get(), RenderType.translucent());

ItemBlockRenderTypes.setRenderLayer(ModBlocks.FLESH_IRIS_DOOR.get(), RenderType.cutout());
ItemBlockRenderTypes.setRenderLayer(ModBlocks.FLESH_FENCE.get(), RenderType.cutout());
Expand All @@ -117,6 +119,9 @@ private static void setBlockRenderLayers() {
ItemBlockRenderTypes.setRenderLayer(ModBlocks.TENDON_CHAIN.get(), RenderType.cutout());
ItemBlockRenderTypes.setRenderLayer(ModBlocks.VIAL_HOLDER.get(), RenderType.cutout());

ItemBlockRenderTypes.setRenderLayer(ModFluids.ACID.get(), RenderType.translucent());
ItemBlockRenderTypes.setRenderLayer(ModFluids.FLOWING_ACID.get(), RenderType.translucent());

//block with "glowing" overlay texture, also needs a overlay model see onModelBakeEvent() in ClientSetupHandler
//ItemBlockRenderTypes.setRenderLayer(ModBlocks.FOOBAR.get(), renderType -> renderType == RenderType.getCutout() || renderType == RenderType.getTranslucent());
}
Expand Down Expand Up @@ -154,6 +159,7 @@ public static void onItemColorRegistry(final RegisterColorHandlersEvent.Item eve
event.register((stack, tintIndex) -> tintIndex == 1 ? 0xFF_09DF5B : 0xFF_FFFFFF, ModBlocks.BABY_PERMEABLE_MEMBRANE.get());
event.register((stack, tintIndex) -> tintIndex == 1 ? 0xFF_ACBF60 : 0xFF_FFFFFF, ModBlocks.ADULT_PERMEABLE_MEMBRANE.get());
event.register((stack, tintIndex) -> tintIndex == 1 ? 0xFF_F740FD : 0xFF_FFFFFF, ModBlocks.PRIMAL_PERMEABLE_MEMBRANE.get());
event.register((stack, index) -> index == 1 ? IClientFluidTypeExtensions.of(((BucketItem) stack.getItem()).getFluid()).getTintColor() : 0xFF_FFFFFF, ModItems.ACID_BUCKET.get());
}

@SubscribeEvent
Expand All @@ -166,7 +172,7 @@ public static void onBlockColorRegistry(final RegisterColorHandlersEvent.Block e

@SubscribeEvent
public static void registerGameOverlays(RegisterGuiOverlaysEvent event) {
// event.registerAboveAll("biomancy_gun", IngameOverlays.GUN_OVERLAY);
// event.registerAboveAll("biomancy_gun", IngameOverlays.GUN_OVERLAY);
event.registerAboveAll("biomancy_injector", IngameOverlays.INJECTOR_OVERLAY);
event.registerAboveAll("biomancy_charge_bar", IngameOverlays.CHARGE_BAR_OVERLAY);
event.registerAboveAll("biomancy_attack_reach", IngameOverlays.ATTACK_REACH_OVERLAY);
Expand Down
29 changes: 0 additions & 29 deletions src/main/java/com/github/elenterius/biomancy/util/CombatUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,6 @@

import com.github.elenterius.biomancy.init.ModDamageSources;
import com.github.elenterius.biomancy.init.ModMobEffects;
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.damagesource.CombatRules;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.effect.MobEffectInstance;
Expand All @@ -18,7 +14,6 @@
import net.minecraft.world.item.enchantment.Enchantments;
import net.minecraft.world.level.Level;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;

import java.util.List;

Expand All @@ -44,30 +39,6 @@ public static void performWaterAOE(Level world, Entity attacker, double maxDista
}
}

public static void doAcidFluidTick(LivingEntity livingEntity) {
if (livingEntity.tickCount % 5 == 0 && isInAcidFluid(livingEntity)) {
if (!livingEntity.level.isClientSide) {
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);
}
}
}
}

public static boolean isInAcidFluid(Entity entity) {
//return entity.isInFluidType(ModFluids.ACID_TYPE.get());
return false; //FIXME
}

public static boolean hasAcidEffect(LivingEntity livingEntity) {
return livingEntity.hasEffect(ModMobEffects.CORROSIVE.get());
}
Expand Down
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 61da539

Please sign in to comment.