added the canopy diminisher

This commit is contained in:
Ellpeck 2018-11-14 19:14:03 +01:00
parent 868a1eaf98
commit 7daacd17e3
16 changed files with 253 additions and 73 deletions

View file

@ -36,21 +36,23 @@ import org.lwjgl.opengl.GL11;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function;
public final class Helper {
public static void getTileEntitiesInArea(World world, BlockPos pos, int radius, Consumer<TileEntity> consumer) {
public static boolean getTileEntitiesInArea(World world, BlockPos pos, int radius, Function<TileEntity, Boolean> consumer) {
for (int x = (pos.getX() - radius) >> 4; x <= (pos.getX() + radius) >> 4; x++) {
for (int z = (pos.getZ() - radius) >> 4; z <= (pos.getZ() + radius) >> 4; z++) {
if (isChunkLoaded(world, x, z)) {
for (TileEntity tile : world.getChunk(x, z).getTileEntityMap().values()) {
if (tile.getPos().distanceSq(pos) <= radius * radius)
consumer.accept(tile);
if (consumer.apply(tile))
return true;
}
}
}
}
return false;
}
public static List<EntityItemFrame> getAttachedItemFrames(World world, BlockPos pos) {

View file

@ -10,7 +10,6 @@ import de.ellpeck.naturesaura.chunk.effect.DrainSpotEffects;
import de.ellpeck.naturesaura.commands.CommandAura;
import de.ellpeck.naturesaura.compat.Compat;
import de.ellpeck.naturesaura.events.CommonEvents;
import de.ellpeck.naturesaura.events.TerrainGenEvents;
import de.ellpeck.naturesaura.items.ModItems;
import de.ellpeck.naturesaura.packet.PacketHandler;
import de.ellpeck.naturesaura.proxy.IProxy;
@ -66,7 +65,6 @@ public final class NaturesAura {
ModRegistry.preInit(event);
new Multiblocks();
MinecraftForge.TERRAIN_GEN_BUS.register(new TerrainGenEvents());
MinecraftForge.EVENT_BUS.register(new CommonEvents());
proxy.preInit(event);

View file

@ -0,0 +1,53 @@
package de.ellpeck.naturesaura.blocks;
import de.ellpeck.naturesaura.Helper;
import de.ellpeck.naturesaura.api.NaturesAuraAPI;
import de.ellpeck.naturesaura.blocks.tiles.TileEntityOakGenerator;
import net.minecraft.block.BlockSapling;
import net.minecraft.block.SoundType;
import net.minecraft.block.material.Material;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.terraingen.SaplingGrowTreeEvent;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import java.util.Random;
public class BlockOakGenerator extends BlockContainerImpl {
public BlockOakGenerator() {
super(Material.WOOD, "oak_generator", TileEntityOakGenerator.class, "oak_generator");
this.setHardness(2F);
this.setSoundType(SoundType.WOOD);
MinecraftForge.TERRAIN_GEN_BUS.register(this);
}
@SubscribeEvent
public void onTreeGrow(SaplingGrowTreeEvent event) {
World world = event.getWorld();
BlockPos pos = event.getPos();
if (!world.isRemote && NaturesAuraAPI.TYPE_OVERWORLD.isPresentInWorld(world)
&& world.getBlockState(pos).getBlock() instanceof BlockSapling) {
Helper.getTileEntitiesInArea(world, pos, 10, tile -> {
if (!(tile instanceof TileEntityOakGenerator))
return false;
Random rand = event.getRand();
if (rand.nextInt(10) == 0)
((TileEntityOakGenerator) tile).scheduledBigTrees.add(pos);
long seed;
do {
seed = rand.nextLong();
rand.setSeed(seed);
}
while (rand.nextInt(10) == 0);
rand.setSeed(seed);
return true;
});
}
}
}

View file

@ -1,18 +1,31 @@
package de.ellpeck.naturesaura.blocks;
import de.ellpeck.naturesaura.Helper;
import de.ellpeck.naturesaura.api.NaturesAuraAPI;
import de.ellpeck.naturesaura.api.recipes.TreeRitualRecipe;
import de.ellpeck.naturesaura.blocks.multi.Multiblocks;
import de.ellpeck.naturesaura.blocks.tiles.TileEntityWoodStand;
import net.minecraft.block.SoundType;
import net.minecraft.block.material.Material;
import net.minecraft.block.state.BlockFaceShape;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
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.MinecraftForge;
import net.minecraftforge.event.terraingen.SaplingGrowTreeEvent;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import org.apache.commons.lang3.mutable.MutableObject;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class BlockWoodStand extends BlockContainerImpl {
@ -23,6 +36,54 @@ public class BlockWoodStand extends BlockContainerImpl {
this.setHardness(1.5F);
this.setSoundType(SoundType.WOOD);
this.setHarvestLevel("axe", 0);
MinecraftForge.TERRAIN_GEN_BUS.register(this);
}
@SubscribeEvent
public void onTreeGrow(SaplingGrowTreeEvent event) {
World world = event.getWorld();
BlockPos pos = event.getPos();
if (!world.isRemote) {
if (Multiblocks.TREE_RITUAL.isComplete(world, pos)) {
IBlockState sapling = world.getBlockState(pos);
ItemStack saplingStack = sapling.getBlock().getItem(world, pos, sapling);
if (!saplingStack.isEmpty()) {
for (TreeRitualRecipe recipe : NaturesAuraAPI.TREE_RITUAL_RECIPES.values()) {
if (Helper.areItemsEqual(saplingStack, recipe.saplingType, true)) {
List<ItemStack> required = new ArrayList<>(Arrays.asList(recipe.items));
MutableObject<TileEntityWoodStand> toPick = new MutableObject<>();
boolean fine = Multiblocks.TREE_RITUAL.forEach(pos, 'W', (tilePos, matcher) -> {
TileEntity tile = world.getTileEntity(tilePos);
if (tile instanceof TileEntityWoodStand) {
TileEntityWoodStand stand = (TileEntityWoodStand) tile;
ItemStack stack = stand.items.getStackInSlot(0);
if (!stack.isEmpty()) {
int index = Helper.getItemIndex(required, stack, true);
if (index >= 0) {
required.remove(index);
if (toPick.getValue() == null) {
toPick.setValue(stand);
}
} else {
return false;
}
}
}
return true;
});
if (fine && required.isEmpty()) {
toPick.getValue().setRitual(pos, recipe);
break;
}
}
}
}
}
}
}
@Override

View file

@ -32,4 +32,5 @@ public final class ModBlocks {
public static final Block PLACER = new BlockPlacer();
public static final Block HOPPER_UPGRADE = new BlockHopperUpgrade();
public static final Block FIELD_CREATOR = new BlockFieldCreator();
public static final Block OAK_GENERATOR = new BlockOakGenerator();
}

View file

@ -0,0 +1,32 @@
package de.ellpeck.naturesaura.blocks.tiles;
import de.ellpeck.naturesaura.api.aura.chunk.IAuraChunk;
import de.ellpeck.naturesaura.packet.PacketHandler;
import de.ellpeck.naturesaura.packet.PacketParticles;
import net.minecraft.block.BlockLog;
import net.minecraft.util.ITickable;
import net.minecraft.util.math.BlockPos;
import java.util.ArrayDeque;
import java.util.Queue;
public class TileEntityOakGenerator extends TileEntityImpl implements ITickable {
public Queue<BlockPos> scheduledBigTrees = new ArrayDeque<>();
@Override
public void update() {
if (!this.world.isRemote)
while (!this.scheduledBigTrees.isEmpty()) {
BlockPos pos = this.scheduledBigTrees.remove();
if (this.world.getBlockState(pos).getBlock() instanceof BlockLog) {
BlockPos spot = IAuraChunk.getLowestSpot(this.world, this.pos, 25, this.pos);
IAuraChunk.getAuraChunk(this.world, spot).storeAura(spot, 500);
PacketHandler.sendToAllAround(this.world, this.pos, 32, new PacketParticles(
this.pos.getX(), this.pos.getY(), this.pos.getZ(), 12,
pos.getX(), pos.getY(), pos.getZ()));
}
}
}
}

View file

@ -33,6 +33,7 @@ public class ReplenishingEffect implements IDrainSpotEffect {
tiles.add((ISpotDrainable) container);
}
}
return false;
});
if (!tiles.isEmpty()) {
IAuraType type = IAuraType.forWorld(world);

View file

@ -1,68 +0,0 @@
package de.ellpeck.naturesaura.events;
import de.ellpeck.naturesaura.Helper;
import de.ellpeck.naturesaura.api.NaturesAuraAPI;
import de.ellpeck.naturesaura.blocks.multi.Multiblocks;
import de.ellpeck.naturesaura.blocks.tiles.TileEntityWoodStand;
import de.ellpeck.naturesaura.api.recipes.TreeRitualRecipe;
import net.minecraft.block.state.IBlockState;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.event.terraingen.SaplingGrowTreeEvent;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import org.apache.commons.lang3.mutable.MutableObject;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class TerrainGenEvents {
@SubscribeEvent
public void onTreeGrow(SaplingGrowTreeEvent event) {
World world = event.getWorld();
BlockPos pos = event.getPos();
if (!world.isRemote) {
if (Multiblocks.TREE_RITUAL.isComplete(world, pos)) {
IBlockState sapling = world.getBlockState(pos);
ItemStack saplingStack = sapling.getBlock().getItem(world, pos, sapling);
if (!saplingStack.isEmpty()) {
for (TreeRitualRecipe recipe : NaturesAuraAPI.TREE_RITUAL_RECIPES.values()) {
if (Helper.areItemsEqual(saplingStack, recipe.saplingType, true)) {
List<ItemStack> required = new ArrayList<>(Arrays.asList(recipe.items));
MutableObject<TileEntityWoodStand> toPick = new MutableObject<>();
boolean fine = Multiblocks.TREE_RITUAL.forEach(pos, 'W', (tilePos, matcher) -> {
TileEntity tile = world.getTileEntity(tilePos);
if (tile instanceof TileEntityWoodStand) {
TileEntityWoodStand stand = (TileEntityWoodStand) tile;
ItemStack stack = stand.items.getStackInSlot(0);
if (!stack.isEmpty()) {
int index = Helper.getItemIndex(required, stack, true);
if (index >= 0) {
required.remove(index);
if (toPick.getValue() == null) {
toPick.setValue(stand);
}
} else {
return false;
}
}
}
return true;
});
if (fine && required.isEmpty()) {
toPick.getValue().setRitual(pos, recipe);
break;
}
}
}
}
}
}
}
}

View file

@ -9,6 +9,7 @@ import net.minecraft.client.Minecraft;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraft.world.biome.BiomeColorHelper;
import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler;
import net.minecraftforge.fml.common.network.simpleimpl.MessageContext;
@ -209,6 +210,28 @@ public class PacketParticles implements IMessage {
0x911b07, 3F, 10, 0F, false, true);
}
break;
case 12: // Oak generator
int sapX = message.data[0];
int sapY = message.data[1];
int sapZ = message.data[2];
for (int i = world.rand.nextInt(20) + 10; i >= 0; i--)
NaturesAuraAPI.instance().spawnParticleStream(
sapX + 0.5F + (float) world.rand.nextGaussian() * 3F,
sapY + 0.5F + world.rand.nextFloat() * 4F,
sapZ + 0.5F + (float) world.rand.nextGaussian() * 3F,
message.posX + 0.5F,
message.posY + 0.5F,
message.posZ + 0.5F,
0.6F, BiomeColorHelper.getFoliageColorAtPos(world, new BlockPos(sapX, sapY, sapZ)), 1.5F);
for (int i = world.rand.nextInt(10) + 10; i >= 0; i--)
NaturesAuraAPI.instance().spawnMagicParticle(
message.posX + 0.25F + world.rand.nextFloat() * 0.5F,
message.posY + 1.01F,
message.posZ + 0.25F + world.rand.nextFloat() * 0.5F,
world.rand.nextGaussian() * 0.03F,
world.rand.nextFloat() * 0.04F + 0.04F,
world.rand.nextGaussian() * 0.03F,
0x5ccc30, 1F + world.rand.nextFloat() * 1.5F, 60, 0F, false, true);
}
}
});

View file

@ -0,0 +1,20 @@
{
"forge_marker": 1,
"defaults": {
"model": "minecraft:cube",
"textures": {
"particle": "naturesaura:blocks/oak_generator",
"up": "naturesaura:blocks/oak_generator_top",
"down": "naturesaura:blocks/oak_generator_bottom",
"north": "#particle",
"east": "#particle",
"south": "#particle",
"west": "#particle"
},
"transform": "forge:default-block"
},
"variants": {
"normal": [{}],
"inventory": [{}]
}
}

View file

@ -29,6 +29,7 @@ tile.naturesaura.flower_generator.name=Herbivorous Absorber
tile.naturesaura.placer.name=Imperceptible Builder
tile.naturesaura.hopper_upgrade.name=Hopper Enhancement
tile.naturesaura.field_creator.name=Aura Field Creator
tile.naturesaura.oak_generator.name=Canopy Diminisher
item.naturesaura.eye.name=Environmental Eye
item.naturesaura.gold_fiber.name=Brilliant Fiber

View file

@ -0,0 +1,21 @@
{
"name": "Canopy Diminisher",
"icon": "naturesaura:oak_generator",
"category": "creating",
"advancement": "naturesaura:infused_materials",
"pages": [
{
"type": "text",
"text": "Surely, at one point in their lives, any person dealing with trees was faced with this well-known issue: An $(item)Oak Sapling$() grows into a $(thing)big tree$() which is hard to look at, to manage and to chop down.$(br)The $(item)Canopy Diminisher$() is a block that serves two purposes in and of itself:$(br)Placing it close to an area that oak trees are growing in, at most about 10 blocks away from them, will cause only"
},
{
"type": "text",
"text": "normal-sized oaks to grow.$(br)In the process, the additional natural energy of any saplings that were growing into big trees gets turned into a quite substantial amount of $(aura) that will be fed into the environment.$(p)Quite obviously, a great way to make use of this is for an automatic $(thing)tree farm$()."
},
{
"type": "crafting",
"recipe": "naturesaura:oak_generator",
"text": "Creating the $(item)Canopy Diminisher$()"
}
]
}

View file

@ -0,0 +1,35 @@
{
"type": "forge:ore_shaped",
"pattern": [
"MBI",
"SOS",
"IBM"
],
"key": {
"O": {
"type": "forge:ore_dict",
"ore": "logWood"
},
"S": {
"type": "forge:ore_dict",
"ore": "treeSapling"
},
"B": {
"type": "minecraft:item_nbt",
"item": "naturesaura:aura_bottle",
"nbt": {
"stored_type": "naturesaura:overworld"
}
},
"M": {
"item": "minecraft:dye",
"data": 15
},
"I": {
"item": "naturesaura:infused_iron"
}
},
"result": {
"item": "naturesaura:oak_generator"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 559 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 555 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 547 B