Skip to content

Commit

Permalink
Berries (#60)
Browse files Browse the repository at this point in the history
* Preliminary berry items and texture files

* Berry medley recipes & berry item textures

* 1.9.4.1; fixes #55

* Some more work on berry crops

* Fix up efficiency calculation and placement rules

* 10 minutes of copy-pasting

* Refactor world generation a lot for trees and berries

* Blueberry spawning

* Full berry bush model and main texture :lets:

* Set temperature/rainfall for berries

* Texture time!

* Configuration

* Thorns + more lang

* AgriCraft + EIO integration + berry metas
  • Loading branch information
bruberu authored Oct 20, 2023
1 parent fd9ff1a commit 53d29b7
Show file tree
Hide file tree
Showing 93 changed files with 1,529 additions and 197 deletions.
11 changes: 10 additions & 1 deletion src/main/java/gregtechfoodoption/CommonProxy.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@

import crazypants.enderio.api.farm.IFarmerJoe;
import crazypants.enderio.base.farming.farmers.CustomSeedFarmer;
import crazypants.enderio.base.integration.natura.NaturaBerryFarmer;
import gregtech.api.block.VariantItemBlock;
import gregtech.api.recipes.RecipeMaps;
import gregtechfoodoption.block.GTFOBerryBush;
import gregtechfoodoption.block.GTFOCrop;
import gregtechfoodoption.block.GTFOMetaBlocks;
import gregtechfoodoption.block.GTFORootCrop;
import gregtechfoodoption.integration.enderio.GTFOBerryFarmer;
import gregtechfoodoption.integration.enderio.GTFORootCropFarmer;
import gregtechfoodoption.item.GTFOMetaItem;
import gregtechfoodoption.item.GTFOMetaItems;
Expand Down Expand Up @@ -158,7 +161,13 @@ public static void registerEIOFarmerJoes(@Nonnull RegistryEvent.Register<IFarmer
event.getRegistry().register(new GTFORootCropFarmer(crop, crop.getSeedStack())
.setRegistryName(crop.getRegistryName()));
continue;
};
}
if (crop instanceof GTFOBerryBush) {
event.getRegistry().register(new GTFOBerryFarmer(crop, crop.getSeedStack())
.setRegistryName(crop.getRegistryName()));

continue;
}
event.getRegistry().register(new CustomSeedFarmer(crop, crop.getSeedStack())
.setRegistryName(crop.getRegistryName()));
}
Expand Down
15 changes: 12 additions & 3 deletions src/main/java/gregtechfoodoption/GTFOConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,6 @@ public class GTFOConfig {
@Config.Comment("Show tooltips always, regardless of what keys are held?")
public static boolean showTooltipsAlways = true;

@Config.Comment("Turn on GTFO tree generation? Required for many mod features.")
public static boolean enableGTFOTrees = true;

@Config.Comment("Chain Options")
public static GTFOChainsConfig gtfoChainsConfig = new GTFOChainsConfig();

Expand All @@ -36,6 +33,10 @@ public class GTFOConfig {
@Config.Comment("Effect options for GTFO. NOTE: None of these actually remove the appearance of the effects in-game, they just remove the functionality.")
public static GTFOPotionConfig gtfoPotionConfig = new GTFOPotionConfig();

@Config.Comment("Worldgen Options")
public static GTFOWorldGenConfig gtfoWorldgenConfig = new GTFOWorldGenConfig();


@Config.Comment("Miscellaneous features for GTFO.")
public static GTFOMiscConfig gtfoMiscConfig = new GTFOMiscConfig();

Expand Down Expand Up @@ -222,4 +223,12 @@ public static class GTFOMiscConfig {
@Config.RequiresMcRestart
public boolean addLacedDungeonFoods = true;
}

public static class GTFOWorldGenConfig {
@Config.Comment("Turn on GTFO tree generation? Required for many mod features.")
public static boolean enableGTFOTrees = true;

@Config.Comment("Turn on GTFO berry generation? Required for some mod features.")
public static boolean enableGTFOBerries = true;
}
}
20 changes: 20 additions & 0 deletions src/main/java/gregtechfoodoption/GTFOEventHandler.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package gregtechfoodoption;

import gregtech.api.GTValues;
import gregtech.api.GregTechAPI;
import gregtech.api.items.metaitem.MetaItem;
import gregtech.api.unification.material.event.MaterialEvent;
import gregtech.api.util.GregFakePlayer;
import gregtechfoodoption.block.GTFOBerryBush;
import gregtechfoodoption.entity.EntityStrongSnowman;
import gregtechfoodoption.integration.GTFOGAMaterialHandler;
import gregtechfoodoption.integration.applecore.GTFOAppleCoreCompat;
Expand Down Expand Up @@ -32,9 +34,11 @@
import net.minecraftforge.event.entity.living.PotionColorCalculationEvent;
import net.minecraftforge.event.entity.living.PotionEvent;
import net.minecraftforge.event.entity.player.AdvancementEvent;
import net.minecraftforge.event.world.BlockEvent;
import net.minecraftforge.event.world.WorldEvent;
import net.minecraftforge.fml.common.Loader;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.eventhandler.Event;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.common.gameevent.PlayerEvent;

Expand Down Expand Up @@ -243,4 +247,20 @@ public static void onDrinkPotion(PotionEvent.PotionAddedEvent event) {
event.getPotionEffect().combine(new PotionEffect(type, newDuration));
}
}

@SubscribeEvent
public static void handleBerryGrowth(BlockEvent.CropGrowEvent.Post event) {
if (event.getState().getBlock() instanceof GTFOBerryBush bush) {
event.getWorld().setBlockState(event.getPos(),
bush.withEfficiency(event.getState(), bush.getEfficiency(event.getWorld(), event.getPos(), event.getState())),
2);
}
}

@SubscribeEvent
public static void handleBerryGrowth(BlockEvent.CropGrowEvent.Pre event) {
if (event.getState().getBlock() instanceof GTFOBerryBush bush) {
event.setResult(GTValues.RNG.nextInt(bush.getGrowthSlowdown(event.getWorld(), event.getPos(), event.getState())) == 0 ? Event.Result.ALLOW : Event.Result.DENY);
}
}
}
24 changes: 22 additions & 2 deletions src/main/java/gregtechfoodoption/GTFOMaterialHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -434,10 +434,30 @@ public class GTFOMaterialHandler {
.color(0xCA190F)
.build();

public static final Material SourCream = fluidBuilder(21612, "sour_cream")
public static final Material CranberryExtract = fluidBuilder(21612, "cranberry_extract")
.color(0x8C0D22)
.build();
public static final Material EtirpsCranberry = fluidBuilder(21613, "etirps_cranberry")
.color(averageRGB(2, CranberryExtract.getMaterialRGB(), 0xbbddbb))
.build();
public static final Material CranberrySludge = fluidBuilder(21614, "cranberry_sludge")
.color(averageRGB(2, CranberryExtract.getMaterialRGB(), 0x222222))
.build();
public static final Material CranberrySodaSyrup = fluidBuilder(21615, "cranberry_soda_syrup")
.color(averageRGB(2, CranberryExtract.getMaterialRGB(), 0x333333))
.build();

public static final Material LingonberryJam = fluidBuilder(21616, "lingonberry_jam")
.color(0x61262D)
.build();
public static final Material ElderberryJam = fluidBuilder(21617, "elderberry_jam")
.color(0x5F414F)
.build();

public static final Material SourCream = fluidBuilder(21618, "sour_cream")
.color(0xe3de9d)
.build();
public static final Material LacticAcidBacteria = fluidBuilder(21613, "lactic_acid_bacteria")
public static final Material LacticAcidBacteria = fluidBuilder(21619, "lactic_acid_bacteria")
.color(0x371040)
.build();

Expand Down
189 changes: 189 additions & 0 deletions src/main/java/gregtechfoodoption/block/GTFOBerryBush.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
package gregtechfoodoption.block;

import gregtechfoodoption.utils.GTFOLog;
import net.minecraft.block.Block;
import net.minecraft.block.properties.PropertyInteger;
import net.minecraft.block.state.BlockStateContainer;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Blocks;
import net.minecraft.item.ItemStack;
import net.minecraft.util.DamageSource;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.NonNullList;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import net.minecraftforge.common.EnumPlantType;
import org.jetbrains.annotations.Nullable;

import java.util.Random;

public class GTFOBerryBush extends GTFOCrop {
public static final PropertyInteger EFFICIENCY_GTFO = PropertyInteger.create("efficiency", 0, 4);
private static final AxisAlignedBB SMALL_AABB = new AxisAlignedBB(0.25D, 0.0D, 0.25D, 0.75D, 0.5D, 0.75D);
private static final AxisAlignedBB LARGE_AABB = new AxisAlignedBB(0.0625D, 0.0D, 0.0625D, 0.9375D, 0.9375D, 0.9375D);
private boolean isThorny = false;

protected GTFOBerryBush(String name) {
super(name, 2);
this.setTranslationKey("gtfo_berry_bush_" + name);
this.setHardness(1F);
}

@Override
protected boolean canSustainBush(IBlockState state) {
return state.getBlock() == Blocks.DIRT || super.canSustainBush(state);
}

public static GTFOBerryBush create(String name) {
AGE_TEMP = PropertyInteger.create("age", 0, 2);
return new GTFOBerryBush(name);
}

protected BlockStateContainer createBlockState() {
return AGE_GTFO == null ? new BlockStateContainer(this, AGE_TEMP, EFFICIENCY_GTFO) : new BlockStateContainer(this, AGE_GTFO, EFFICIENCY_GTFO);
}

public void getDrops(NonNullList<ItemStack> drops, IBlockAccess world, BlockPos pos, IBlockState state, int fortune) {
int age = this.getAge(state);
int efficiency = this.getEfficiency(state);
Random rand = world instanceof World ? ((World) world).rand : new Random();

if (age >= this.getMaxAge()) {
drops.add(this.crop.copy());
for (int i = 0; i < 2 + efficiency; ++i) {
if (rand.nextInt(2) == 0) {
drops.add(this.crop.copy());
}
}
}

}

public int getEfficiency(IBlockState state) {
return state.getProperties().get(EFFICIENCY_GTFO) != null ? state.getValue(EFFICIENCY_GTFO).intValue() : -1;
}

@Override
public void grow(World worldIn, BlockPos pos, IBlockState state) {
if (worldIn.rand.nextInt(Math.max(2, getGrowthSlowdown(worldIn, pos, state) / 8)) != 0) {
return;
}
int i = this.getAge(state) + this.getBonemealAgeIncrease(worldIn);
int j = this.getMaxAge();

if (i > j)
{
i = j;
}

worldIn.setBlockState(pos, withEfficiency(this.withAge(i), getEfficiency(worldIn, pos, state)), 3);
}

public int getEfficiency(World worldIn, BlockPos pos, IBlockState state) {
int[] efficiencies = new int[EFFICIENCY_GTFO.getAllowedValues().stream().max(Integer::compare).get() + 1];
BlockPos.getAllInBox(pos.east().north(), pos.west().south()).forEach((blockpos) -> {
if (!blockpos.equals(pos))
efficiencies[getEfficiency(worldIn.getBlockState(blockpos)) + 1]++;
});
for (int i = efficiencies.length - 1; i >= 0; --i) {
if (efficiencies[i] > 2) {
return i;
}
}
return 0;
}

protected int getBonemealAgeIncrease(World worldIn) {
return 1;
}

public IBlockState withEfficiency(IBlockState state, int efficiency) {
if (efficiency > 4) {
efficiency = 4;
GTFOLog.logger.warn("Somehow, you managed to get your berry's efficiency higher than 4, which is really cool (or the result of a hacked mod/bug), but it's currently not available in GTFO. Please report this to the mod author, along with a screenshot of how great your berry setup is.");
}
return state.withProperty(EFFICIENCY_GTFO, Integer.valueOf(efficiency));
}

public int getGrowthSlowdown(World world, BlockPos pos, IBlockState state) {
if (getAge(state) == 0) {
return 4; // Usual value for growing crops
}
int growthSlowdown = 320 << getEfficiency(state);
if (!world.isDaytime()) {
growthSlowdown *= 2;
}
if (world.isRaining()) {
growthSlowdown = growthSlowdown * 2 / 3;
}

return growthSlowdown;
}

@Override
public EnumPlantType getPlantType(IBlockAccess world, BlockPos pos) {
return EnumPlantType.Plains;
}

@Override
public void onEntityCollision(World worldIn, BlockPos pos, IBlockState state, Entity entityIn) {
if (isThorny)
entityIn.attackEntityFrom(DamageSource.CACTUS, 1.0F);
}

public GTFOBerryBush setThorny(boolean thorny) {
isThorny = thorny;
return this;
}

@Nullable
@Override
public AxisAlignedBB getCollisionBoundingBox(IBlockState blockState, IBlockAccess worldIn, BlockPos pos) {
return this.getBoundingBox(blockState, worldIn, pos);
}

@Override
public AxisAlignedBB getBoundingBox(IBlockState state, IBlockAccess source, BlockPos pos) {
return this.getAge(state) == 0 ? SMALL_AABB : LARGE_AABB;
}

public int getMaxAge() {
return 2;
}

@Override
public boolean onBlockActivated(World worldIn, BlockPos pos, IBlockState state, EntityPlayer playerIn, EnumHand hand, EnumFacing facing, float hitX, float hitY, float hitZ) {
if (this.isMaxAge(state)) {
int berries = 1;
for (int i = 0; i < 2 + getEfficiency(state); ++i) {
if (worldIn.rand.nextInt(2) == 0) {
berries++;
}
}

ItemStack berryStack = this.getCropStack().copy();
berryStack.setCount(berries);
if (!playerIn.addItemStackToInventory(berryStack)) {
playerIn.dropItem(this.getCropStack(), false);
}
worldIn.setBlockState(pos, state.withProperty(AGE_GTFO, Integer.valueOf(this.getMaxAge() - 1)), 3);
return true;
}
return false;
}

@Override
public IBlockState getStateFromMeta(int meta) {
return this.withAge(meta % 3).withProperty(EFFICIENCY_GTFO, Integer.valueOf(meta / 3));
}

@Override
public int getMetaFromState(IBlockState state) {
return this.getEfficiency(state) * 3 + this.getAge(state);
}
}
8 changes: 4 additions & 4 deletions src/main/java/gregtechfoodoption/block/GTFOCrop.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public static GTFOCrop create(String name) {
return new GTFOCrop(name);
}

public AxisAlignedBB getBoundingBox(IBlockState state, IBlockAccess source, BlockPos pos){
public AxisAlignedBB getBoundingBox(IBlockState state, IBlockAccess source, BlockPos pos) {
return CROPS_AABB;
}

Expand All @@ -60,7 +60,7 @@ public int getMaxAge() {

public void getDrops(NonNullList<ItemStack> drops, IBlockAccess world, BlockPos pos, IBlockState state, int fortune) {
int age = this.getAge(state);
Random rand = world instanceof World ? ((World)world).rand : new Random();
Random rand = world instanceof World ? ((World) world).rand : new Random();

if (age >= this.getMaxAge()) {
if (!seed.isEmpty()) {
Expand All @@ -69,9 +69,8 @@ public void getDrops(NonNullList<ItemStack> drops, IBlockAccess world, BlockPos
drops.add(seed.copy());
}
}
int k = 3 + fortune;

for(int i = 0; i < 3 + fortune; ++i) {
for (int i = 0; i < 3 + fortune; ++i) {
if (rand.nextInt(2 * this.getMaxAge()) <= age) {
drops.add(this.crop.copy());
}
Expand Down Expand Up @@ -118,6 +117,7 @@ public ItemStack getSeedStack() {
protected PropertyInteger getAgeProperty() {
return AGE_GTFO == null ? AGE_TEMP : AGE_GTFO;
}

protected BlockStateContainer createBlockState() {
return AGE_GTFO == null ? new BlockStateContainer(this, AGE_TEMP) : new BlockStateContainer(this, AGE_GTFO);
}
Expand Down
12 changes: 12 additions & 0 deletions src/main/java/gregtechfoodoption/block/GTFOCrops.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,18 @@ public class GTFOCrops {
public static GTFOCrop CROP_RICE = GTFOCrop.create("rice");
public static GTFOCrop CROP_WHITE_GRAPE = GTFOCrop.create("white_grape");

public static GTFOBerryBush BUSH_BLUEBERRY = GTFOBerryBush.create("blueberry");
public static GTFOBerryBush BUSH_BLACKBERRY = GTFOBerryBush.create("blackberry").setThorny(true);
public static GTFOBerryBush BUSH_RASPBERRY = GTFOBerryBush.create("raspberry").setThorny(true);
public static GTFOBerryBush BUSH_STRAWBERRY = GTFOBerryBush.create("strawberry");
public static GTFOBerryBush BUSH_RED_CURRANT = GTFOBerryBush.create("red_currant");
public static GTFOBerryBush BUSH_BLACK_CURRANT = GTFOBerryBush.create("black_currant");
public static GTFOBerryBush BUSH_WHITE_CURRANT = GTFOBerryBush.create("white_currant");
public static GTFOBerryBush BUSH_LINGONBERRY = GTFOBerryBush.create("lingonberry");
public static GTFOBerryBush BUSH_ELDERBERRY = GTFOBerryBush.create("elderberry");
public static GTFOBerryBush BUSH_CRANBERRY = GTFOBerryBush.create("cranberry");


//public static GTFOCrop CROP_HOPS = GTFOCrop.create("hops");
public static void init() {

Expand Down
Loading

0 comments on commit 53d29b7

Please sign in to comment.