mirror of
https://github.com/GTNewHorizons/ForestryMC.git
synced 2026-11-15 01:24:59 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dea1fb144a | ||
|
|
a01190a242 | ||
|
|
0ebced9609 |
No files matched your search
+1
-1
@@ -11,4 +11,4 @@ ic2_version=2.8.24-ex112
|
||||
|
||||
version_major=5
|
||||
version_minor=5
|
||||
version_patch=2
|
||||
version_patch=4
|
||||
+1
-1
Submodule lang updated: 192d6f8584...774ccbb680.
@@ -13,8 +13,10 @@ import forestry.api.core.IErrorState;
|
||||
import forestry.api.genetics.IEffectData;
|
||||
import forestry.api.genetics.IIndividual;
|
||||
import forestry.api.genetics.IIndividualLiving;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.NonNullList;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.biome.Biome;
|
||||
import net.minecraftforge.fml.relauncher.Side;
|
||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
||||
@@ -85,8 +87,26 @@ public interface IBee extends IIndividualLiving {
|
||||
|
||||
List<IBee> spawnDrones(IBeeHousing housing);
|
||||
|
||||
/**
|
||||
* @deprecated since Forestry 5.5.4. Use {@link #plantFlowerRandom(IBeeHousing, List)}
|
||||
*/
|
||||
@Deprecated
|
||||
void plantFlowerRandom(IBeeHousing housing);
|
||||
|
||||
/**
|
||||
* Plants a random flower from the given list near the housing
|
||||
* @param housing the location the bee is living
|
||||
* @param potentialFlowers the flowers to choose from
|
||||
* @return the position of the planted flower, or null of none were planted
|
||||
* @since Forestry 5.5.4
|
||||
*/
|
||||
@Nullable
|
||||
default BlockPos plantFlowerRandom(IBeeHousing housing, List<IBlockState> potentialFlowers) {
|
||||
//noinspection deprecation
|
||||
plantFlowerRandom(housing);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
IIndividual retrievePollen(IBeeHousing housing);
|
||||
|
||||
|
||||
@@ -10,10 +10,9 @@ import java.util.List;
|
||||
|
||||
import forestry.api.core.INbtReadable;
|
||||
import forestry.api.core.INbtWritable;
|
||||
import forestry.core.network.IStreamable;
|
||||
import forestry.core.network.PacketBufferForestry;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.network.PacketBuffer;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraftforge.fml.relauncher.Side;
|
||||
@@ -24,7 +23,7 @@ import net.minecraftforge.fml.relauncher.SideOnly;
|
||||
* Get one with BeeManager.beeRoot.createBeekeepingLogic(IBeeHousing housing)
|
||||
* Save and load it to NBT using the INbtWritable methods.
|
||||
*/
|
||||
public interface IBeekeepingLogic extends INbtWritable, INbtReadable, IStreamable {
|
||||
public interface IBeekeepingLogic extends INbtWritable, INbtReadable {
|
||||
|
||||
/* SERVER */
|
||||
|
||||
@@ -83,13 +82,11 @@ public interface IBeekeepingLogic extends INbtWritable, INbtReadable, IStreamabl
|
||||
*/
|
||||
List<BlockPos> getFlowerPositions();
|
||||
|
||||
@Override
|
||||
default void readData(PacketBufferForestry data) throws IOException {
|
||||
default void readData(PacketBuffer data) throws IOException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
default void writeData(PacketBufferForestry data) {
|
||||
default void writeData(PacketBuffer data) {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,9 @@
|
||||
******************************************************************************/
|
||||
package forestry.api.genetics;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
@@ -13,6 +16,19 @@ public interface IFlowerGrowthHelper {
|
||||
* Plants a random flower from flowerType at the specified position.
|
||||
*
|
||||
* @return true if successful, false if it could not be planted.
|
||||
* @deprecated since Forestry 5.5.4. Use {@link #plantRandomFlower(String, World, BlockPos, Collection)}
|
||||
*/
|
||||
@Deprecated
|
||||
boolean plantRandomFlower(String flowerType, World world, BlockPos pos);
|
||||
|
||||
/**
|
||||
* Plants a random flower from flowerType at the specified position.
|
||||
* @param flowerType the flower type that can be planted
|
||||
* @param world the world to plant flowers in
|
||||
* @param pos the position to plant the flowers
|
||||
* @param potentialFlowers the potential flowers that can be planted
|
||||
* @return true if a flower was planted, false otherwise
|
||||
* @since Forestry 5.5.4
|
||||
*/
|
||||
boolean plantRandomFlower(String flowerType, World world, BlockPos pos, Collection<IBlockState> potentialFlowers);
|
||||
}
|
||||
@@ -5,6 +5,9 @@
|
||||
******************************************************************************/
|
||||
package forestry.api.genetics;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
@@ -18,6 +21,20 @@ public interface IFlowerGrowthRule {
|
||||
* For implementers, you can plant a random flower using IFlowerGrowthHelper.plantRandomFlower
|
||||
*
|
||||
* @since Forestry 4.0.8
|
||||
* @deprecated since Forestry 5.5.4. Use {@link #growFlower(IFlowerGrowthHelper, String, World, BlockPos, Collection)}
|
||||
*/
|
||||
@Deprecated
|
||||
boolean growFlower(IFlowerGrowthHelper helper, String flowerType, World world, BlockPos pos);
|
||||
|
||||
/**
|
||||
* Checks a position for suitability, and then plants a flower there.
|
||||
* Returns true on success.
|
||||
* For implementers, you can plant a random flower using IFlowerGrowthHelper.plantRandomFlower
|
||||
*
|
||||
* @since Forestry 5.5.4
|
||||
*/
|
||||
default boolean growFlower(IFlowerGrowthHelper helper, String flowerType, World world, BlockPos pos, Collection<IBlockState> potentialFlowers) {
|
||||
//noinspection deprecation
|
||||
return growFlower(helper, flowerType, world, pos);
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@
|
||||
******************************************************************************/
|
||||
package forestry.api.genetics;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
@@ -59,8 +60,9 @@ public interface IFlowerRegistry {
|
||||
|
||||
/**
|
||||
* Calls the appropriate IFlowerGrowthRule to grow a flower at a specified position.
|
||||
* @since Forestry 5.5.4
|
||||
*/
|
||||
boolean growFlower(String flowerType, World world, IIndividual individual, BlockPos pos);
|
||||
boolean growFlower(String flowerType, World world, IIndividual individual, BlockPos pos, Collection<IBlockState> potentialFlowers);
|
||||
|
||||
/**
|
||||
* Gets an iterator over the area a bee can travel from its beeHousing.
|
||||
@@ -96,4 +98,11 @@ public interface IFlowerRegistry {
|
||||
*/
|
||||
@Deprecated
|
||||
boolean isAcceptedFlower(String flowerType, World world, BlockPos pos);
|
||||
|
||||
/**
|
||||
* Calls the appropriate IFlowerGrowthRule to grow a flower at a specified position.
|
||||
* @deprecated since Forestry 5.5.4. Use {@link #growFlower(String, World, IIndividual, BlockPos, Collection)}
|
||||
*/
|
||||
@Deprecated
|
||||
boolean growFlower(String flowerType, World world, IIndividual individual, BlockPos pos);
|
||||
}
|
||||
@@ -38,16 +38,16 @@ import forestry.apiculture.network.packets.PacketBeeLogicActive;
|
||||
import forestry.apiculture.network.packets.PacketBeeLogicActiveEntity;
|
||||
import forestry.core.config.Constants;
|
||||
import forestry.core.errors.EnumErrorCode;
|
||||
import forestry.core.network.IStreamable;
|
||||
import forestry.core.network.PacketBufferForestry;
|
||||
import forestry.core.utils.Log;
|
||||
import forestry.core.utils.NetworkUtil;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.nbt.NBTTagList;
|
||||
import net.minecraft.network.PacketBuffer;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
@@ -136,7 +136,7 @@ public class BeekeepingLogic implements IBeekeepingLogic {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeData(PacketBufferForestry data) {
|
||||
public void writeData(PacketBuffer data) {
|
||||
data.writeBoolean(active);
|
||||
if (active) {
|
||||
data.writeItemStack(queenStack);
|
||||
@@ -145,7 +145,7 @@ public class BeekeepingLogic implements IBeekeepingLogic {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readData(PacketBufferForestry data) throws IOException {
|
||||
public void readData(PacketBuffer data) throws IOException {
|
||||
boolean active = data.readBoolean();
|
||||
setActive(active);
|
||||
if (active) {
|
||||
@@ -203,11 +203,13 @@ public class BeekeepingLogic implements IBeekeepingLogic {
|
||||
if (this.queenStack != queenStack) {
|
||||
if (!queenStack.isEmpty()) {
|
||||
this.queen = BeeManager.beeRoot.getMember(queenStack);
|
||||
if (this.queen != null) {
|
||||
hasFlowersCache.onNewQueen(queen, housing);
|
||||
}
|
||||
} else {
|
||||
this.queen = null;
|
||||
}
|
||||
this.queenStack = queenStack;
|
||||
hasFlowersCache.clear();
|
||||
queenCanWorkCache.clear();
|
||||
}
|
||||
|
||||
@@ -251,9 +253,11 @@ public class BeekeepingLogic implements IBeekeepingLogic {
|
||||
@Override
|
||||
public void clearCachedValues() {
|
||||
if (!housing.getWorldObj().isRemote) {
|
||||
hasFlowersCache.clear();
|
||||
queenCanWorkCache.clear();
|
||||
canWork();
|
||||
if (queen != null) {
|
||||
hasFlowersCache.forceLookForFlowers(queen, housing);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -273,14 +277,21 @@ public class BeekeepingLogic implements IBeekeepingLogic {
|
||||
queenWorkCycleThrottle = 0;
|
||||
|
||||
doProduction(queen, housing, beeListener);
|
||||
queen.plantFlowerRandom(housing);
|
||||
World world = housing.getWorldObj();
|
||||
List<IBlockState> flowers = hasFlowersCache.getFlowers(world);
|
||||
if (flowers.size() < PluginApiculture.maxFlowersSpawnedPerHive) {
|
||||
BlockPos blockPos = queen.plantFlowerRandom(housing, flowers);
|
||||
if (blockPos != null) {
|
||||
hasFlowersCache.addFlowerPos(blockPos);
|
||||
}
|
||||
}
|
||||
pollenHandler.doPollination(queen, housing, beeListener);
|
||||
|
||||
// Age the queen
|
||||
IBeeGenome mate = queen.getMate();
|
||||
Preconditions.checkState(mate != null);
|
||||
float lifespanModifier = beeModifier.getLifespanModifier(queen.getGenome(), mate, 1.0f);
|
||||
queen.age(housing.getWorldObj(), lifespanModifier);
|
||||
queen.age(world, lifespanModifier);
|
||||
|
||||
// Write the changed queen back into the item stack.
|
||||
NBTTagCompound nbttagcompound = new NBTTagCompound();
|
||||
|
||||
@@ -19,19 +19,21 @@ import java.util.List;
|
||||
|
||||
import forestry.api.apiculture.FlowerManager;
|
||||
import forestry.api.apiculture.IBee;
|
||||
import forestry.api.apiculture.IBeeGenome;
|
||||
import forestry.api.apiculture.IBeeHousing;
|
||||
import forestry.api.core.INbtReadable;
|
||||
import forestry.api.core.INbtWritable;
|
||||
import forestry.api.core.IBlockPosPredicate;
|
||||
import forestry.api.genetics.IFlowerProvider;
|
||||
import forestry.core.network.IStreamable;
|
||||
import forestry.core.network.PacketBufferForestry;
|
||||
import forestry.core.utils.TickHelper;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.network.PacketBuffer;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Vec3i;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class HasFlowersCache implements INbtWritable, INbtReadable, IStreamable {
|
||||
public class HasFlowersCache implements INbtWritable, INbtReadable {
|
||||
private static final String NBT_KEY = "hasFlowerCache";
|
||||
private static final String NBT_KEY_FLOWERS = "flowers";
|
||||
private static final int FLOWER_CHECK_INTERVAL = 200;
|
||||
@@ -41,17 +43,20 @@ public class HasFlowersCache implements INbtWritable, INbtReadable, IStreamable
|
||||
@Nullable
|
||||
private FlowerData flowerData;
|
||||
private final List<BlockPos> flowerCoords = new ArrayList<>();
|
||||
private final List<IBlockState> flowers = new ArrayList<>();
|
||||
|
||||
private boolean needsSync = false;
|
||||
|
||||
private static class FlowerData {
|
||||
public final String flowerType;
|
||||
public final Vec3i territory;
|
||||
public final IBlockPosPredicate flowerPredicate;
|
||||
public Iterator<BlockPos.MutableBlockPos> areaIterator;
|
||||
|
||||
public FlowerData(IBee queen, IBeeHousing beeHousing) {
|
||||
IFlowerProvider flowerProvider = queen.getGenome().getFlowerProvider();
|
||||
this.flowerType = flowerProvider.getFlowerType();
|
||||
this.territory = queen.getGenome().getTerritory();
|
||||
this.flowerPredicate = FlowerManager.flowerRegistry.createAcceptedFlowerPredicate(flowerType);
|
||||
this.areaIterator = FlowerManager.flowerRegistry.getAreaIterator(beeHousing, queen);
|
||||
}
|
||||
@@ -65,6 +70,7 @@ public class HasFlowersCache implements INbtWritable, INbtReadable, IStreamable
|
||||
if (flowerData == null) {
|
||||
this.flowerData = new FlowerData(queen, beeHousing);
|
||||
this.flowerCoords.clear();
|
||||
this.flowers.clear();
|
||||
}
|
||||
World world = beeHousing.getWorldObj();
|
||||
tickHelper.onTick();
|
||||
@@ -75,6 +81,7 @@ public class HasFlowersCache implements INbtWritable, INbtReadable, IStreamable
|
||||
BlockPos flowerPos = iterator.next();
|
||||
if (!flowerData.flowerPredicate.test(world, flowerPos) && world.isBlockLoaded(flowerPos)) {
|
||||
iterator.remove();
|
||||
flowers.clear();
|
||||
needsSync = true;
|
||||
}
|
||||
}
|
||||
@@ -87,8 +94,7 @@ public class HasFlowersCache implements INbtWritable, INbtReadable, IStreamable
|
||||
if (flowerData.areaIterator.hasNext()) {
|
||||
BlockPos.MutableBlockPos blockPos = flowerData.areaIterator.next();
|
||||
if (flowerData.flowerPredicate.test(world, blockPos)) {
|
||||
flowerCoords.add(blockPos.toImmutable());
|
||||
needsSync = true;
|
||||
addFlowerPos(blockPos.toImmutable());
|
||||
}
|
||||
} else {
|
||||
flowerData.resetIterator(queen, beeHousing);
|
||||
@@ -106,15 +112,55 @@ public class HasFlowersCache implements INbtWritable, INbtReadable, IStreamable
|
||||
return returnVal;
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
flowerCoords.clear();
|
||||
flowerData = null;
|
||||
public void onNewQueen(IBee queen, IBeeHousing housing) {
|
||||
if (this.flowerData != null) {
|
||||
IBeeGenome genome = queen.getGenome();
|
||||
String flowerType = genome.getFlowerProvider().getFlowerType();
|
||||
if (!this.flowerData.flowerType.equals(flowerType)
|
||||
|| !this.flowerData.territory.equals(genome.getTerritory())) {
|
||||
flowerData = new FlowerData(queen, housing);
|
||||
flowerCoords.clear();
|
||||
flowers.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public List<BlockPos> getFlowerCoords() {
|
||||
return Collections.unmodifiableList(flowerCoords);
|
||||
}
|
||||
|
||||
public List<IBlockState> getFlowers(World world) {
|
||||
if (flowers.isEmpty() && !flowerCoords.isEmpty()) {
|
||||
flowers.clear();
|
||||
for (BlockPos flowerCoord : flowerCoords) {
|
||||
IBlockState blockState = world.getBlockState(flowerCoord);
|
||||
flowers.add(blockState);
|
||||
}
|
||||
}
|
||||
return Collections.unmodifiableList(flowers);
|
||||
}
|
||||
|
||||
public void addFlowerPos(BlockPos blockPos) {
|
||||
flowerCoords.add(blockPos);
|
||||
flowers.clear();
|
||||
needsSync = true;
|
||||
}
|
||||
|
||||
public void forceLookForFlowers(IBee queen, IBeeHousing housing) {
|
||||
if (flowerData != null) {
|
||||
flowerCoords.clear();
|
||||
flowers.clear();
|
||||
flowerData.resetIterator(queen, housing);
|
||||
World world = housing.getWorldObj();
|
||||
while (flowerData.areaIterator.hasNext()) {
|
||||
BlockPos.MutableBlockPos blockPos = flowerData.areaIterator.next();
|
||||
if (flowerData.flowerPredicate.test(world, blockPos)) {
|
||||
addFlowerPos(blockPos.toImmutable());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFromNBT(NBTTagCompound nbttagcompound) {
|
||||
if (!nbttagcompound.hasKey(NBT_KEY)) {
|
||||
@@ -134,6 +180,7 @@ public class HasFlowersCache implements INbtWritable, INbtReadable, IStreamable
|
||||
needsSync = true;
|
||||
}
|
||||
}
|
||||
flowers.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -157,8 +204,7 @@ public class HasFlowersCache implements INbtWritable, INbtReadable, IStreamable
|
||||
return nbttagcompound;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeData(PacketBufferForestry data) {
|
||||
public void writeData(PacketBuffer data) {
|
||||
int size = flowerCoords.size();
|
||||
data.writeVarInt(size);
|
||||
if (size > 0) {
|
||||
@@ -170,9 +216,9 @@ public class HasFlowersCache implements INbtWritable, INbtReadable, IStreamable
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readData(PacketBufferForestry data) throws IOException {
|
||||
public void readData(PacketBuffer data) throws IOException {
|
||||
flowerCoords.clear();
|
||||
flowers.clear();
|
||||
|
||||
int size = data.readVarInt();
|
||||
while (size > 0) {
|
||||
|
||||
@@ -151,6 +151,7 @@ public class PluginApiculture extends BlankForestryPlugin {
|
||||
|
||||
public static String beekeepingMode = "NORMAL";
|
||||
public static final int ticksPerBeeWorkCycle = 550;
|
||||
public static int maxFlowersSpawnedPerHive = 20;
|
||||
@Nullable
|
||||
public static VillagerRegistry.VillagerProfession villagerApiarist;
|
||||
|
||||
@@ -261,6 +262,8 @@ public class PluginApiculture extends BlankForestryPlugin {
|
||||
|
||||
secondPrincessChance = config.getFloatLocalized("beekeeping", "second.princess", secondPrincessChance, 0.0f, 100.0f);
|
||||
|
||||
maxFlowersSpawnedPerHive = config.getIntLocalized("beekeeping", "flowers.spawn", 20, 0, 1000);
|
||||
|
||||
String[] blacklist = config.getStringListLocalized("species", "blacklist", Constants.EMPTY_STRINGS);
|
||||
parseBeeBlacklist(blacklist);
|
||||
|
||||
|
||||
@@ -18,12 +18,12 @@ import forestry.api.apiculture.IBeekeepingLogic;
|
||||
import forestry.api.genetics.IEffectData;
|
||||
import forestry.apiculture.network.packets.PacketBeeLogicActive;
|
||||
import forestry.apiculture.tiles.TileHive;
|
||||
import forestry.core.network.PacketBufferForestry;
|
||||
import forestry.core.utils.NetworkUtil;
|
||||
import forestry.core.utils.TickHelper;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.network.PacketBuffer;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.fml.relauncher.Side;
|
||||
@@ -58,7 +58,7 @@ public class WorldgenBeekeepingLogic implements IBeekeepingLogic {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeData(PacketBufferForestry data) {
|
||||
public void writeData(PacketBuffer data) {
|
||||
data.writeBoolean(active);
|
||||
if (active) {
|
||||
hasFlowersCache.writeData(data);
|
||||
@@ -66,7 +66,7 @@ public class WorldgenBeekeepingLogic implements IBeekeepingLogic {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readData(PacketBufferForestry data) throws IOException {
|
||||
public void readData(PacketBuffer data) throws IOException {
|
||||
boolean active = data.readBoolean();
|
||||
setActive(active);
|
||||
if (active) {
|
||||
@@ -116,10 +116,7 @@ public class WorldgenBeekeepingLogic implements IBeekeepingLogic {
|
||||
|
||||
@Override
|
||||
public void clearCachedValues() {
|
||||
if (!housing.getWorldObj().isRemote) {
|
||||
hasFlowersCache.clear();
|
||||
canWork();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* CLIENT */
|
||||
|
||||
@@ -10,14 +10,16 @@
|
||||
******************************************************************************/
|
||||
package forestry.apiculture.flowers;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.collect.ArrayListMultimap;
|
||||
@@ -36,6 +38,7 @@ import forestry.api.genetics.IFlowerRegistry;
|
||||
import forestry.api.genetics.IIndividual;
|
||||
import forestry.core.utils.BlockStateSet;
|
||||
import forestry.core.utils.VectUtil;
|
||||
import forestry.core.utils.WeightedCollection;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.init.Blocks;
|
||||
@@ -50,7 +53,7 @@ public final class FlowerRegistry implements IFlowerRegistry, IFlowerGrowthHelpe
|
||||
private final HashMultimap<String, Flower> plantableFlowers;
|
||||
|
||||
private final ArrayListMultimap<String, IFlowerGrowthRule> growthRules;
|
||||
private final Map<String, TreeMap<Double, Flower>> chances;
|
||||
private final Map<String, WeightedCollection<Flower>> chances;
|
||||
|
||||
public FlowerRegistry() {
|
||||
this.registeredRules = HashMultimap.create();
|
||||
@@ -197,6 +200,7 @@ public final class FlowerRegistry implements IFlowerRegistry, IFlowerGrowthHelpe
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public boolean growFlower(String flowerType, World world, IIndividual individual, BlockPos pos) {
|
||||
if (!this.growthRules.containsKey(flowerType)) {
|
||||
return false;
|
||||
@@ -211,6 +215,23 @@ public final class FlowerRegistry implements IFlowerRegistry, IFlowerGrowthHelpe
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean growFlower(String flowerType, World world, IIndividual individual, BlockPos pos, Collection<IBlockState> potentialFlowers) {
|
||||
if (!this.growthRules.containsKey(flowerType)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
List<IFlowerGrowthRule> growthRules = this.growthRules.get(flowerType);
|
||||
Collections.shuffle(growthRules);
|
||||
for (IFlowerGrowthRule rule : growthRules) {
|
||||
if (rule.growFlower(this, flowerType, world, pos, potentialFlowers)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerGrowthRule(IFlowerGrowthRule rule, String... flowerTypes) {
|
||||
Preconditions.checkNotNull(rule);
|
||||
@@ -220,20 +241,18 @@ public final class FlowerRegistry implements IFlowerRegistry, IFlowerGrowthHelpe
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Flower getRandomPlantableFlower(String flowerType, Random rand) {
|
||||
TreeMap<Double, Flower> chancesMap = getChancesMap(flowerType);
|
||||
double maxKey = chancesMap.lastKey() + 1.0;
|
||||
return chancesMap.get(chancesMap.lowerKey(rand.nextDouble() * maxKey));
|
||||
WeightedCollection<Flower> chancesMap = getFlowerChances(flowerType);
|
||||
return chancesMap.getRandom(rand);
|
||||
}
|
||||
|
||||
private TreeMap<Double, Flower> getChancesMap(String flowerType) {
|
||||
private WeightedCollection<Flower> getFlowerChances(String flowerType) {
|
||||
if (!this.chances.containsKey(flowerType)) {
|
||||
TreeMap<Double, Flower> flowerChances = new TreeMap<>();
|
||||
double count = 0.0;
|
||||
WeightedCollection<Flower> flowerChances = new WeightedCollection<>();
|
||||
for (Flower flower : this.plantableFlowers.get(flowerType)) {
|
||||
if (flower.isPlantable()) {
|
||||
flowerChances.put(count, flower);
|
||||
count += flower.getWeight();
|
||||
flowerChances.put(flower.getWeight(), flower);
|
||||
}
|
||||
}
|
||||
this.chances.put(flowerType, flowerChances);
|
||||
@@ -253,7 +272,24 @@ public final class FlowerRegistry implements IFlowerRegistry, IFlowerGrowthHelpe
|
||||
@Override
|
||||
public boolean plantRandomFlower(String flowerType, World world, BlockPos pos) {
|
||||
Flower flower = getRandomPlantableFlower(flowerType, world.rand);
|
||||
return world.setBlockState(pos, flower.getBlockState());
|
||||
return flower != null && world.setBlockState(pos, flower.getBlockState());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean plantRandomFlower(String flowerType, World world, BlockPos pos, Collection<IBlockState> potentialFlowers) {
|
||||
WeightedCollection<Flower> chances = getFlowerChances(flowerType);
|
||||
WeightedCollection<IBlockState> potentialChances = new WeightedCollection<>();
|
||||
|
||||
for (Map.Entry<Double, Flower> entry : chances.entrySet()) {
|
||||
Flower flower = entry.getValue();
|
||||
IBlockState blockState = flower.getBlockState();
|
||||
if (potentialFlowers.contains(blockState)) {
|
||||
potentialChances.put(entry.getKey(), blockState);
|
||||
}
|
||||
}
|
||||
|
||||
final IBlockState blockState = potentialChances.getRandom(world.rand);
|
||||
return blockState != null && world.setBlockState(pos, blockState);
|
||||
}
|
||||
|
||||
private static class AcceptedFlowerPredicate implements IBlockPosPredicate {
|
||||
|
||||
@@ -10,9 +10,12 @@
|
||||
******************************************************************************/
|
||||
package forestry.apiculture.flowers;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import forestry.api.genetics.IFlowerGrowthHelper;
|
||||
import forestry.api.genetics.IFlowerGrowthRule;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
@@ -20,14 +23,24 @@ import net.minecraft.world.World;
|
||||
public class GrowthRuleDirtGrass implements IFlowerGrowthRule {
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public boolean growFlower(IFlowerGrowthHelper helper, String flowerType, World world, BlockPos pos) {
|
||||
return isValidSpot(world, pos) &&
|
||||
helper.plantRandomFlower(flowerType, world, pos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean growFlower(IFlowerGrowthHelper helper, String flowerType, World world, BlockPos pos, Collection<IBlockState> potentialFlowers) {
|
||||
return isValidSpot(world, pos) &&
|
||||
helper.plantRandomFlower(flowerType, world, pos, potentialFlowers);
|
||||
}
|
||||
|
||||
private boolean isValidSpot(World world, BlockPos pos) {
|
||||
if (!world.isBlockLoaded(pos) || !world.isAirBlock(pos)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Block ground = world.getBlockState(new BlockPos(pos.getX(), pos.getY() - 1, pos.getZ())).getBlock();
|
||||
return (ground == Blocks.DIRT || ground == Blocks.GRASS) &&
|
||||
helper.plantRandomFlower(flowerType, world, pos);
|
||||
return (ground == Blocks.DIRT || ground == Blocks.GRASS);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -11,6 +11,7 @@
|
||||
package forestry.apiculture.flowers;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import forestry.api.genetics.IFlowerGrowthHelper;
|
||||
@@ -33,6 +34,11 @@ public class GrowthRuleFertilize implements IFlowerGrowthRule {
|
||||
return growFlower(world, pos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean growFlower(IFlowerGrowthHelper helper, String flowerType, World world, BlockPos pos, Collection<IBlockState> potentialFlowers) {
|
||||
return growFlower(world, pos);
|
||||
}
|
||||
|
||||
private boolean growFlower(World world, BlockPos pos) {
|
||||
if (!world.isBlockLoaded(pos)) {
|
||||
return false;
|
||||
|
||||
@@ -10,9 +10,12 @@
|
||||
******************************************************************************/
|
||||
package forestry.apiculture.flowers;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import forestry.api.genetics.IFlowerGrowthHelper;
|
||||
import forestry.api.genetics.IFlowerGrowthRule;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
@@ -20,14 +23,25 @@ import net.minecraft.world.World;
|
||||
public class GrowthRuleMycelium implements IFlowerGrowthRule {
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public boolean growFlower(IFlowerGrowthHelper helper, String flowerType, World world, BlockPos pos) {
|
||||
return isValidSpot(world, pos) &&
|
||||
helper.plantRandomFlower(flowerType, world, pos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean growFlower(IFlowerGrowthHelper helper, String flowerType, World world, BlockPos pos, Collection<IBlockState> potentialFlowers) {
|
||||
return isValidSpot(world, pos) &&
|
||||
helper.plantRandomFlower(flowerType, world, pos, potentialFlowers);
|
||||
}
|
||||
|
||||
private boolean isValidSpot(World world, BlockPos pos) {
|
||||
if (!world.isBlockLoaded(pos) || !world.isAirBlock(pos)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Block ground = world.getBlockState(new BlockPos(pos.getX(), pos.getY() - 1, pos.getZ())).getBlock();
|
||||
return ground == Blocks.MYCELIUM &&
|
||||
helper.plantRandomFlower(flowerType, world, pos);
|
||||
return ground == Blocks.MYCELIUM;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -10,8 +10,11 @@
|
||||
******************************************************************************/
|
||||
package forestry.apiculture.flowers;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import forestry.api.genetics.IFlowerGrowthHelper;
|
||||
import forestry.api.genetics.IFlowerGrowthRule;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
@@ -22,4 +25,8 @@ public class GrowthRuleNone implements IFlowerGrowthRule {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean growFlower(IFlowerGrowthHelper helper, String flowerType, World world, BlockPos pos, Collection<IBlockState> potentialFlowers) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -10,9 +10,12 @@
|
||||
******************************************************************************/
|
||||
package forestry.apiculture.flowers;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import forestry.api.genetics.IFlowerGrowthHelper;
|
||||
import forestry.api.genetics.IFlowerGrowthRule;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
@@ -20,14 +23,24 @@ import net.minecraft.world.World;
|
||||
public class GrowthRuleSnow implements IFlowerGrowthRule {
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public boolean growFlower(IFlowerGrowthHelper helper, String flowerType, World world, BlockPos pos) {
|
||||
return isValidSpot(world, pos) &&
|
||||
helper.plantRandomFlower(flowerType, world, pos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean growFlower(IFlowerGrowthHelper helper, String flowerType, World world, BlockPos pos, Collection<IBlockState> potentialFlowers) {
|
||||
return isValidSpot(world, pos) &&
|
||||
helper.plantRandomFlower(flowerType, world, pos, potentialFlowers);
|
||||
}
|
||||
|
||||
private boolean isValidSpot(World world, BlockPos pos) {
|
||||
if (!world.isBlockLoaded(pos) || world.getBlockState(pos).getBlock() != Blocks.SNOW) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Block ground = world.getBlockState(new BlockPos(pos.getX(), pos.getY() - 1, pos.getZ())).getBlock();
|
||||
return (ground == Blocks.DIRT || ground == Blocks.GRASS) &&
|
||||
helper.plantRandomFlower(flowerType, world, pos);
|
||||
return (ground == Blocks.DIRT || ground == Blocks.GRASS);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -19,6 +19,7 @@ import java.util.Map;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.item.EnumRarity;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
@@ -735,7 +736,11 @@ public class Bee extends IndividualLiving implements IBee {
|
||||
|
||||
@Override
|
||||
public void plantFlowerRandom(IBeeHousing housing) {
|
||||
plantFlowerRandom(housing, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockPos plantFlowerRandom(IBeeHousing housing, @Nullable List<IBlockState> potentialFlowers) {
|
||||
IBeeModifier beeModifier = BeeManager.beeRoot.createBeeHousingModifier(housing);
|
||||
|
||||
int chance = Math.round(genome.getFlowering() * beeModifier.getFloweringModifier(getGenome(), 1f));
|
||||
@@ -745,9 +750,8 @@ public class Bee extends IndividualLiving implements IBee {
|
||||
|
||||
// Correct speed
|
||||
if (random.nextInt(100) >= chance) {
|
||||
return;
|
||||
return null;
|
||||
}
|
||||
|
||||
// Gather required info
|
||||
IFlowerProvider provider = genome.getFlowerProvider();
|
||||
Vec3i area = getArea(genome, beeModifier);
|
||||
@@ -758,10 +762,18 @@ public class Bee extends IndividualLiving implements IBee {
|
||||
BlockPos randomPos = VectUtil.getRandomPositionInArea(random, area);
|
||||
BlockPos posBlock = VectUtil.add(housingPos, randomPos, offset);
|
||||
|
||||
if (FlowerManager.flowerRegistry.growFlower(provider.getFlowerType(), world, this, posBlock)) {
|
||||
break;
|
||||
if (potentialFlowers != null) {
|
||||
if (FlowerManager.flowerRegistry.growFlower(provider.getFlowerType(), world, this, posBlock, potentialFlowers)) {
|
||||
return posBlock;
|
||||
}
|
||||
} else { // legacy
|
||||
//noinspection deprecation
|
||||
if (FlowerManager.flowerRegistry.growFlower(provider.getFlowerType(), world, this, posBlock)) {
|
||||
return posBlock;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static Vec3i getArea(IBeeGenome genome, IBeeModifier beeModifier) {
|
||||
|
||||
@@ -286,7 +286,9 @@ public class VillageApiaristHouse extends StructureVillagePieces.House1 {
|
||||
|
||||
FlowerRegistry flowerRegistry = (FlowerRegistry) FlowerManager.flowerRegistry;
|
||||
Flower flower = flowerRegistry.getRandomPlantableFlower(FlowerManager.FlowerTypeVanilla, world.rand);
|
||||
setBlockState(world, flower.getBlockState(), j, i, k, box);
|
||||
if (flower != null) {
|
||||
setBlockState(world, flower.getBlockState(), j, i, k, box);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
package forestry.core.utils;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.NavigableMap;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
|
||||
public class WeightedCollection<T> {
|
||||
private final NavigableMap<Double, T> map = new TreeMap<>();
|
||||
private double total = 0;
|
||||
|
||||
public void put(double weight, T value) {
|
||||
Preconditions.checkArgument(weight > 0);
|
||||
total += weight;
|
||||
map.put(total, value);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public T getRandom(Random random) {
|
||||
double value = random.nextDouble() * total;
|
||||
Map.Entry<Double, T> higherEntry = map.higherEntry(value);
|
||||
if (higherEntry == null) {
|
||||
return null;
|
||||
}
|
||||
return higherEntry.getValue();
|
||||
}
|
||||
|
||||
public Set<Map.Entry<Double, T>> entrySet() {
|
||||
return Collections.unmodifiableSet(map.entrySet());
|
||||
}
|
||||
}
|
||||
@@ -85,9 +85,11 @@ public class WorldGenerator implements IWorldGenerator {
|
||||
|
||||
// / APATITE
|
||||
if (Config.generateApatiteOre) {
|
||||
final int lowest = Math.round(world.getActualHeight() * 0.22f); // 56
|
||||
final int range = Math.round(world.getActualHeight() * 0.72f); // 184
|
||||
if (random.nextFloat() < 0.8f) {
|
||||
int randPosX = x + random.nextInt(16);
|
||||
int randPosY = random.nextInt(world.getActualHeight() - 72) + 56; // Does not generate below y = 64
|
||||
int randPosY = random.nextInt(range) + lowest;
|
||||
int randPosZ = y + random.nextInt(16);
|
||||
apatiteGenerator.generate(world, random, new BlockPos(randPosX, randPosY, randPosZ));
|
||||
}
|
||||
@@ -96,8 +98,10 @@ public class WorldGenerator implements IWorldGenerator {
|
||||
// / COPPER
|
||||
if (Config.generateCopperOre) {
|
||||
for (int i = 0; i < 20; i++) {
|
||||
final int lowest = Math.round(world.getActualHeight() / 8f); // 32
|
||||
final int range = Math.round(world.getActualHeight() * 0.297f); // 76
|
||||
int randPosX = x + random.nextInt(16);
|
||||
int randPosY = random.nextInt(76) + 32;
|
||||
int randPosY = random.nextInt(range) + lowest;
|
||||
int randPosZ = y + random.nextInt(16);
|
||||
copperGenerator.generate(world, random, new BlockPos(randPosX, randPosY, randPosZ));
|
||||
}
|
||||
@@ -106,8 +110,10 @@ public class WorldGenerator implements IWorldGenerator {
|
||||
// / TIN
|
||||
if (Config.generateTinOre) {
|
||||
for (int i = 0; i < 18; i++) {
|
||||
final int lowest = Math.round(world.getActualHeight() / 16f); // 16
|
||||
final int range = Math.round(world.getActualHeight() * 0.297f); // 76
|
||||
int randPosX = x + random.nextInt(16);
|
||||
int randPosY = random.nextInt(76) + 16;
|
||||
int randPosY = random.nextInt(range) + lowest;
|
||||
int randPosZ = y + random.nextInt(16);
|
||||
tinGenerator.generate(world, random, new BlockPos(randPosX, randPosY, randPosZ));
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user