mirror of
https://github.com/Ellpeck/NaturesAura.git
synced 2024-12-22 14:59:22 +01:00
some ritual work, needs finishing
This commit is contained in:
parent
c5ed74bfd5
commit
f2eca230e8
15 changed files with 797 additions and 59 deletions
|
@ -1,5 +1,7 @@
|
|||
package de.ellpeck.naturesaura;
|
||||
|
||||
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;
|
||||
|
@ -25,6 +27,16 @@ public final class Helper {
|
|||
return tiles;
|
||||
}
|
||||
|
||||
public static boolean checkMultiblock(World world, BlockPos pos, BlockPos[] positions, IBlockState state, boolean blockOnly) {
|
||||
for (BlockPos offset : positions) {
|
||||
IBlockState current = world.getBlockState(pos.add(offset));
|
||||
if (blockOnly ? current.getBlock() != state.getBlock() : current != state) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
public static int blendColors(int c1, int c2, float ratio) {
|
||||
int a = (int) ((c1 >> 24 & 0xFF) * ratio + (c2 >> 24 & 0xFF) * (1 - ratio));
|
||||
|
@ -33,4 +45,22 @@ public final class Helper {
|
|||
int b = (int) ((c1 & 0xFF) * ratio + (c2 & 0xFF) * (1 - ratio));
|
||||
return ((a & 255) << 24) | ((r & 255) << 16) | ((g & 255) << 8) | (b & 255);
|
||||
}
|
||||
|
||||
public static boolean containsItem(List<ItemStack> list, ItemStack item) {
|
||||
for (ItemStack stack : list) {
|
||||
if (stack.isItemEqual(item)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean containsItem(ItemStack[] array, ItemStack item) {
|
||||
for (ItemStack stack : array) {
|
||||
if (stack.isItemEqual(item)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,19 +1,18 @@
|
|||
package de.ellpeck.naturesaura;
|
||||
|
||||
import de.ellpeck.naturesaura.blocks.ModBlocks;
|
||||
import de.ellpeck.naturesaura.events.TreeRitualHandler;
|
||||
import de.ellpeck.naturesaura.items.ModItems;
|
||||
import de.ellpeck.naturesaura.packet.PacketHandler;
|
||||
import de.ellpeck.naturesaura.proxy.IProxy;
|
||||
import de.ellpeck.naturesaura.recipes.ModRecipes;
|
||||
import de.ellpeck.naturesaura.reg.ModRegistry;
|
||||
import net.minecraft.creativetab.CreativeTabs;
|
||||
import net.minecraft.init.Items;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
import net.minecraftforge.fml.common.Mod.EventHandler;
|
||||
import net.minecraftforge.fml.common.SidedProxy;
|
||||
import net.minecraftforge.fml.common.event.FMLInitializationEvent;
|
||||
import net.minecraftforge.fml.common.event.FMLPostInitializationEvent;
|
||||
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
|
||||
import net.minecraftforge.fml.common.event.*;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
|
@ -41,14 +40,20 @@ public final class NaturesAura {
|
|||
public void preInit(FMLPreInitializationEvent event) {
|
||||
new ModBlocks();
|
||||
new ModItems();
|
||||
|
||||
PacketHandler.init();
|
||||
ModRegistry.preInit(event);
|
||||
|
||||
new TreeRitualHandler();
|
||||
|
||||
proxy.preInit(event);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void init(FMLInitializationEvent event) {
|
||||
ModRecipes.init();
|
||||
ModRegistry.init(event);
|
||||
|
||||
proxy.init(event);
|
||||
}
|
||||
|
||||
|
@ -57,4 +62,9 @@ public final class NaturesAura {
|
|||
ModRegistry.postInit(event);
|
||||
proxy.postInit(event);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void serverStopped(FMLServerStoppedEvent event){
|
||||
TreeRitualHandler.clear();
|
||||
}
|
||||
}
|
||||
|
|
223
src/main/java/de/ellpeck/naturesaura/blocks/BlockGoldPowder.java
Normal file
223
src/main/java/de/ellpeck/naturesaura/blocks/BlockGoldPowder.java
Normal file
|
@ -0,0 +1,223 @@
|
|||
package de.ellpeck.naturesaura.blocks;
|
||||
|
||||
import de.ellpeck.naturesaura.Helper;
|
||||
import de.ellpeck.naturesaura.NaturesAura;
|
||||
import de.ellpeck.naturesaura.events.TreeRitualHandler;
|
||||
import de.ellpeck.naturesaura.reg.IColorProvidingBlock;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.SoundType;
|
||||
import net.minecraft.block.material.Material;
|
||||
import net.minecraft.block.properties.PropertyEnum;
|
||||
import net.minecraft.block.state.BlockFaceShape;
|
||||
import net.minecraft.block.state.BlockStateContainer;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.client.renderer.color.IBlockColor;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.util.BlockRenderLayer;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.util.IStringSerializable;
|
||||
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.fml.relauncher.Side;
|
||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Random;
|
||||
|
||||
public class BlockGoldPowder extends BlockImpl implements IColorProvidingBlock {
|
||||
|
||||
public static final PropertyEnum<AttachPos> NORTH = PropertyEnum.create("north", AttachPos.class);
|
||||
public static final PropertyEnum<AttachPos> EAST = PropertyEnum.create("east", AttachPos.class);
|
||||
public static final PropertyEnum<AttachPos> SOUTH = PropertyEnum.create("south", AttachPos.class);
|
||||
public static final PropertyEnum<AttachPos> WEST = PropertyEnum.create("west", AttachPos.class);
|
||||
protected static final AxisAlignedBB[] AABBS = new AxisAlignedBB[]{
|
||||
new AxisAlignedBB(0.1875D, 0.0D, 0.1875D, 0.8125D, 0.0625D, 0.8125D),
|
||||
new AxisAlignedBB(0.1875D, 0.0D, 0.1875D, 0.8125D, 0.0625D, 1.0D),
|
||||
new AxisAlignedBB(0.0D, 0.0D, 0.1875D, 0.8125D, 0.0625D, 0.8125D),
|
||||
new AxisAlignedBB(0.0D, 0.0D, 0.1875D, 0.8125D, 0.0625D, 1.0D),
|
||||
new AxisAlignedBB(0.1875D, 0.0D, 0.0D, 0.8125D, 0.0625D, 0.8125D),
|
||||
new AxisAlignedBB(0.1875D, 0.0D, 0.0D, 0.8125D, 0.0625D, 1.0D),
|
||||
new AxisAlignedBB(0.0D, 0.0D, 0.0D, 0.8125D, 0.0625D, 0.8125D),
|
||||
new AxisAlignedBB(0.0D, 0.0D, 0.0D, 0.8125D, 0.0625D, 1.0D),
|
||||
new AxisAlignedBB(0.1875D, 0.0D, 0.1875D, 1.0D, 0.0625D, 0.8125D),
|
||||
new AxisAlignedBB(0.1875D, 0.0D, 0.1875D, 1.0D, 0.0625D, 1.0D),
|
||||
new AxisAlignedBB(0.0D, 0.0D, 0.1875D, 1.0D, 0.0625D, 0.8125D),
|
||||
new AxisAlignedBB(0.0D, 0.0D, 0.1875D, 1.0D, 0.0625D, 1.0D),
|
||||
new AxisAlignedBB(0.1875D, 0.0D, 0.0D, 1.0D, 0.0625D, 0.8125D),
|
||||
new AxisAlignedBB(0.1875D, 0.0D, 0.0D, 1.0D, 0.0625D, 1.0D),
|
||||
new AxisAlignedBB(0.0D, 0.0D, 0.0D, 1.0D, 0.0625D, 0.8125D),
|
||||
new AxisAlignedBB(0.0D, 0.0D, 0.0D, 1.0D, 0.0625D, 1.0D)
|
||||
};
|
||||
|
||||
public BlockGoldPowder() {
|
||||
super("gold_powder", Material.CIRCUITS);
|
||||
this.setSoundType(SoundType.STONE);
|
||||
this.setHardness(0F);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void randomDisplayTick(IBlockState stateIn, World worldIn, BlockPos pos, Random rand) {
|
||||
if (rand.nextFloat() >= 0.8F) {
|
||||
for (BlockPos offsetToOrigin : TreeRitualHandler.GOLD_POWDER_POSITIONS) {
|
||||
BlockPos origin = pos.subtract(offsetToOrigin);
|
||||
if (Helper.checkMultiblock(worldIn, origin, TreeRitualHandler.GOLD_POWDER_POSITIONS, ModBlocks.GOLD_POWDER.getDefaultState(), true)) {
|
||||
NaturesAura.proxy.spawnMagicParticle(worldIn,
|
||||
pos.getX() + 0.375 + rand.nextFloat() * 0.25, pos.getY() + 0.1, pos.getZ() + 0.375 + rand.nextFloat() * 0.25,
|
||||
rand.nextGaussian() * 0.001, rand.nextFloat() * 0.001 + 0.005, rand.nextGaussian() * 0.001,
|
||||
0xf4cb42, 1F, 50, 0F, false, true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BlockStateContainer createBlockState() {
|
||||
return new BlockStateContainer(this, NORTH, EAST, SOUTH, WEST);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMetaFromState(IBlockState state) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBlockColor getBlockColor() {
|
||||
return (state, worldIn, pos, tintIndex) -> 0xf4cb42;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AxisAlignedBB getBoundingBox(IBlockState state, IBlockAccess source, BlockPos pos) {
|
||||
return AABBS[getAABBIndex(state.getActualState(source, pos))];
|
||||
}
|
||||
|
||||
private static int getAABBIndex(IBlockState state) {
|
||||
int i = 0;
|
||||
boolean n = state.getValue(NORTH) != AttachPos.NONE;
|
||||
boolean e = state.getValue(EAST) != AttachPos.NONE;
|
||||
boolean s = state.getValue(SOUTH) != AttachPos.NONE;
|
||||
boolean w = state.getValue(WEST) != AttachPos.NONE;
|
||||
|
||||
if (n || s && !n && !e && !w) {
|
||||
i |= 1 << EnumFacing.NORTH.getHorizontalIndex();
|
||||
}
|
||||
if (e || w && !n && !e && !s) {
|
||||
i |= 1 << EnumFacing.EAST.getHorizontalIndex();
|
||||
}
|
||||
if (s || n && !e && !s && !w) {
|
||||
i |= 1 << EnumFacing.SOUTH.getHorizontalIndex();
|
||||
}
|
||||
if (w || e && !n && !s && !w) {
|
||||
i |= 1 << EnumFacing.WEST.getHorizontalIndex();
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBlockState getActualState(IBlockState state, IBlockAccess worldIn, BlockPos pos) {
|
||||
state = state.withProperty(WEST, this.getAttachPosition(worldIn, pos, EnumFacing.WEST));
|
||||
state = state.withProperty(EAST, this.getAttachPosition(worldIn, pos, EnumFacing.EAST));
|
||||
state = state.withProperty(NORTH, this.getAttachPosition(worldIn, pos, EnumFacing.NORTH));
|
||||
state = state.withProperty(SOUTH, this.getAttachPosition(worldIn, pos, EnumFacing.SOUTH));
|
||||
return state;
|
||||
}
|
||||
|
||||
private AttachPos getAttachPosition(IBlockAccess worldIn, BlockPos pos, EnumFacing direction) {
|
||||
BlockPos dirPos = pos.offset(direction);
|
||||
IBlockState state = worldIn.getBlockState(pos.offset(direction));
|
||||
|
||||
if (!this.canConnectTo(worldIn.getBlockState(dirPos), direction, worldIn, dirPos)
|
||||
&& (state.isNormalCube() || !this.canConnectUpwardsTo(worldIn, dirPos.down()))) {
|
||||
IBlockState iblockstate1 = worldIn.getBlockState(pos.up());
|
||||
if (!iblockstate1.isNormalCube()) {
|
||||
boolean flag = worldIn.getBlockState(dirPos).isSideSolid(worldIn, dirPos, EnumFacing.UP)
|
||||
|| worldIn.getBlockState(dirPos).getBlock() == Blocks.GLOWSTONE;
|
||||
if (flag && this.canConnectUpwardsTo(worldIn, dirPos.up())) {
|
||||
if (state.isBlockNormalCube()) {
|
||||
return AttachPos.UP;
|
||||
}
|
||||
return AttachPos.SIDE;
|
||||
}
|
||||
}
|
||||
return AttachPos.NONE;
|
||||
} else {
|
||||
return AttachPos.SIDE;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public AxisAlignedBB getCollisionBoundingBox(IBlockState blockState, IBlockAccess worldIn, BlockPos pos) {
|
||||
return NULL_AABB;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOpaqueCube(IBlockState state) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFullCube(IBlockState state) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canPlaceBlockAt(World worldIn, BlockPos pos) {
|
||||
IBlockState downState = worldIn.getBlockState(pos.down());
|
||||
return downState.isTopSolid()
|
||||
|| downState.getBlockFaceShape(worldIn, pos.down(), EnumFacing.UP) == BlockFaceShape.SOLID
|
||||
|| worldIn.getBlockState(pos.down()).getBlock() == Blocks.GLOWSTONE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void neighborChanged(IBlockState state, World worldIn, BlockPos pos, Block blockIn, BlockPos fromPos) {
|
||||
if (!worldIn.isRemote) {
|
||||
if (!this.canPlaceBlockAt(worldIn, pos)) {
|
||||
this.dropBlockAsItem(worldIn, pos, state, 0);
|
||||
worldIn.setBlockToAir(pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean canConnectUpwardsTo(IBlockAccess worldIn, BlockPos pos) {
|
||||
return this.canConnectTo(worldIn.getBlockState(pos), null, worldIn, pos);
|
||||
}
|
||||
|
||||
private boolean canConnectTo(IBlockState blockState, @Nullable EnumFacing side, IBlockAccess world, BlockPos pos) {
|
||||
Block block = blockState.getBlock();
|
||||
return block == this;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SideOnly(Side.CLIENT)
|
||||
public BlockRenderLayer getRenderLayer() {
|
||||
return BlockRenderLayer.CUTOUT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockFaceShape getBlockFaceShape(IBlockAccess worldIn, IBlockState state, BlockPos pos, EnumFacing face) {
|
||||
return BlockFaceShape.UNDEFINED;
|
||||
}
|
||||
|
||||
private enum AttachPos implements IStringSerializable {
|
||||
UP("up"),
|
||||
SIDE("side"),
|
||||
NONE("none");
|
||||
|
||||
private final String name;
|
||||
|
||||
AttachPos(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return this.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -13,4 +13,5 @@ public final class ModBlocks {
|
|||
public static final Block NATURE_ALTAR = new BlockNatureAltar();
|
||||
public static final Block DECAYED_LEAVES = new BlockDecayedLeaves();
|
||||
public static final Block GOLDEN_LEAVES = new BlockGoldenLeaves();
|
||||
public static final Block GOLD_POWDER = new BlockGoldPowder();
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ import de.ellpeck.naturesaura.aura.BasicAuraContainer;
|
|||
import de.ellpeck.naturesaura.aura.IAuraContainer;
|
||||
import de.ellpeck.naturesaura.aura.IAuraContainerProvider;
|
||||
import de.ellpeck.naturesaura.packet.PacketHandler;
|
||||
import de.ellpeck.naturesaura.packet.PacketParticles;
|
||||
import de.ellpeck.naturesaura.packet.PacketParticleStream;
|
||||
import net.minecraft.block.BlockStoneBrick;
|
||||
import net.minecraft.block.BlockStoneBrick.EnumType;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
|
@ -129,7 +129,7 @@ public class TileEntityNatureAltar extends TileEntityImpl implements ITickable,
|
|||
if (stored > 0) {
|
||||
provider.container().drainAura(stored, false);
|
||||
|
||||
PacketHandler.sendToAllLoaded(this.world, this.pos, new PacketParticles(
|
||||
PacketHandler.sendToAllAround(this.world, this.pos, 32, new PacketParticleStream(
|
||||
pos.getX() + 0.5F, pos.getY() + 0.5F, pos.getZ() + 0.5F,
|
||||
this.pos.getX() + 0.5F, this.pos.getY() + 0.5F, this.pos.getZ() + 0.5F,
|
||||
rand.nextFloat() * 0.05F + 0.05F, provider.container().getAuraColor(), rand.nextFloat() * 1F + 1F
|
||||
|
@ -176,13 +176,7 @@ public class TileEntityNatureAltar extends TileEntityImpl implements ITickable,
|
|||
}
|
||||
|
||||
private boolean check(BlockPos[] positions, IBlockState state, boolean blockOnly) {
|
||||
for (BlockPos offset : positions) {
|
||||
IBlockState world = this.world.getBlockState(this.pos.add(offset));
|
||||
if (blockOnly ? world.getBlock() != state.getBlock() : world != state) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
return Helper.checkMultiblock(this.world, this.pos, positions, state, blockOnly);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -0,0 +1,178 @@
|
|||
package de.ellpeck.naturesaura.events;
|
||||
|
||||
import de.ellpeck.naturesaura.Helper;
|
||||
import de.ellpeck.naturesaura.blocks.ModBlocks;
|
||||
import de.ellpeck.naturesaura.packet.PacketHandler;
|
||||
import de.ellpeck.naturesaura.packet.PacketParticleStream;
|
||||
import de.ellpeck.naturesaura.packet.PacketParticles;
|
||||
import de.ellpeck.naturesaura.recipes.TreeRitualRecipe;
|
||||
import net.minecraft.block.BlockLog;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.entity.item.EntityItem;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.math.AxisAlignedBB;
|
||||
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 net.minecraftforge.fml.common.gameevent.TickEvent;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class TreeRitualHandler {
|
||||
|
||||
public static final BlockPos[] GOLD_POWDER_POSITIONS = new BlockPos[]{
|
||||
new BlockPos(-2, 0, 0),
|
||||
new BlockPos(2, 0, 0),
|
||||
new BlockPos(0, 0, -2),
|
||||
new BlockPos(0, 0, 2),
|
||||
new BlockPos(-1, 0, -1),
|
||||
new BlockPos(-1, 0, 1),
|
||||
new BlockPos(1, 0, 1),
|
||||
new BlockPos(1, 0, -1),
|
||||
new BlockPos(2, 0, -1),
|
||||
new BlockPos(2, 0, 1),
|
||||
new BlockPos(-2, 0, -1),
|
||||
new BlockPos(-2, 0, 1),
|
||||
new BlockPos(1, 0, 2),
|
||||
new BlockPos(-1, 0, 2),
|
||||
new BlockPos(1, 0, -2),
|
||||
new BlockPos(-1, 0, -2)
|
||||
};
|
||||
private static final List<ActiveRitual> ACTIVE_RITUALS = new ArrayList<>();
|
||||
|
||||
public TreeRitualHandler() {
|
||||
MinecraftForge.TERRAIN_GEN_BUS.register(this);
|
||||
MinecraftForge.EVENT_BUS.register(this);
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void onTreeGrow(SaplingGrowTreeEvent event) {
|
||||
World world = event.getWorld();
|
||||
BlockPos pos = event.getPos();
|
||||
if (!world.isRemote) {
|
||||
if (Helper.checkMultiblock(world, pos, GOLD_POWDER_POSITIONS, ModBlocks.GOLD_POWDER.getDefaultState(), true)) {
|
||||
List<EntityItem> items = world.getEntitiesWithinAABB(EntityItem.class, new AxisAlignedBB(pos).grow(4, 0, 4));
|
||||
List<ItemStack> usableItems = new ArrayList<>();
|
||||
Set<BlockPos> usedLogs = new HashSet<>();
|
||||
|
||||
for (EntityItem item : items) {
|
||||
BlockPos itemPos = item.getPosition();
|
||||
ItemStack stack = item.getItem();
|
||||
if (stack.getCount() == 1) {
|
||||
if (!usedLogs.contains(itemPos) && world.getBlockState(itemPos.down()).getBlock() instanceof BlockLog) {
|
||||
usedLogs.add(itemPos);
|
||||
usableItems.add(stack);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IBlockState sapling = world.getBlockState(pos);
|
||||
ItemStack saplingStack = sapling.getBlock().getItem(world, pos, sapling);
|
||||
if (!saplingStack.isEmpty()) {
|
||||
for (TreeRitualRecipe recipe : TreeRitualRecipe.RECIPES) {
|
||||
if (recipe.matchesItems(saplingStack, usableItems)) {
|
||||
ActiveRitual ritual = new ActiveRitual(pos, items, recipe);
|
||||
ACTIVE_RITUALS.add(ritual);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void onWorldTick(TickEvent.WorldTickEvent event) {
|
||||
World world = event.world;
|
||||
if (!world.isRemote) {
|
||||
for (int i = ACTIVE_RITUALS.size() - 1; i >= 0; i--) {
|
||||
ActiveRitual ritual = ACTIVE_RITUALS.get(i);
|
||||
if (ritual.isOkay(world)) {
|
||||
ritual.timer++;
|
||||
|
||||
if (ritual.timer % 3 == 0) {
|
||||
for (EntityItem item : ritual.involvedItems) {
|
||||
PacketHandler.sendToAllAround(world, ritual.pos, 32, new PacketParticleStream(
|
||||
(float) item.posX, (float) item.posY + 0.5F, (float) item.posZ,
|
||||
ritual.pos.getX() + 0.5F, ritual.pos.getY() + 1.5F, ritual.pos.getZ() + 0.5F,
|
||||
world.rand.nextFloat() * 0.05F + 0.05F, 0xFF00FF, world.rand.nextFloat() * 1F + 1F
|
||||
));
|
||||
}
|
||||
}
|
||||
if (ritual.timer % 5 == 0) {
|
||||
for (BlockPos offset : GOLD_POWDER_POSITIONS) {
|
||||
BlockPos dustPos = ritual.pos.add(offset);
|
||||
PacketHandler.sendToAllAround(world, ritual.pos, 32,
|
||||
new PacketParticles(
|
||||
(float) dustPos.getX() + 0.375F + world.rand.nextFloat() * 0.25F,
|
||||
(float) dustPos.getY() + 0.1F,
|
||||
(float) dustPos.getZ() + 0.375F + world.rand.nextFloat() * 0.25F,
|
||||
(float) world.rand.nextGaussian() * 0.01F,
|
||||
world.rand.nextFloat() * 0.005F + 0.01F,
|
||||
(float) world.rand.nextGaussian() * 0.01F,
|
||||
0xf4cb42, 2F, 100, 0F, false, true
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
if (ritual.timer >= ritual.recipe.time) {
|
||||
ACTIVE_RITUALS.remove(i);
|
||||
} else if (ritual.timer >= ritual.recipe.time / 2) {
|
||||
for (EntityItem item : ritual.involvedItems) {
|
||||
for (int j = world.rand.nextInt(20) + 10; j >= 0; j--) {
|
||||
PacketHandler.sendToAllAround(world, ritual.pos, 32, new PacketParticles(
|
||||
(float) item.posX, (float) item.posY + 0.5F, (float) item.posZ,
|
||||
(float) world.rand.nextGaussian() * 0.05F, world.rand.nextFloat() * 0.05F, (float) world.rand.nextGaussian() * 0.05F,
|
||||
0xFF00FF, 1.5F, 50, 0F, false, true));
|
||||
}
|
||||
item.setDead();
|
||||
}
|
||||
ritual.involvedItems.clear();
|
||||
}
|
||||
|
||||
} else {
|
||||
ACTIVE_RITUALS.remove(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void clear() {
|
||||
ACTIVE_RITUALS.clear();
|
||||
}
|
||||
|
||||
private static class ActiveRitual {
|
||||
|
||||
private final BlockPos pos;
|
||||
private final List<EntityItem> involvedItems;
|
||||
private final TreeRitualRecipe recipe;
|
||||
|
||||
private int timer;
|
||||
|
||||
public ActiveRitual(BlockPos pos, List<EntityItem> involvedItems, TreeRitualRecipe recipe) {
|
||||
this.pos = pos;
|
||||
this.recipe = recipe;
|
||||
|
||||
this.involvedItems = new ArrayList<>();
|
||||
for (EntityItem item : involvedItems) {
|
||||
if (Helper.containsItem(this.recipe.items, item.getItem())) {
|
||||
this.involvedItems.add(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isOkay(World world) {
|
||||
for (EntityItem item : this.involvedItems) {
|
||||
if (item.isDead || item.prevPosX != item.posX || item.prevPosY != item.posY || item.prevPosZ != item.posZ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return Helper.checkMultiblock(world, this.pos, GOLD_POWDER_POSITIONS, ModBlocks.GOLD_POWDER.getDefaultState(), true);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -14,11 +14,16 @@ public final class PacketHandler {
|
|||
|
||||
public static void init() {
|
||||
network = new SimpleNetworkWrapper(NaturesAura.MOD_ID);
|
||||
network.registerMessage(PacketParticles.Handler.class, PacketParticles.class, 0, Side.CLIENT);
|
||||
network.registerMessage(PacketParticleStream.Handler.class, PacketParticleStream.class, 0, Side.CLIENT);
|
||||
network.registerMessage(PacketParticles.Handler.class, PacketParticles.class, 1, Side.CLIENT);
|
||||
}
|
||||
|
||||
public static void sendToAllLoaded(World world, BlockPos pos, IMessage message) {
|
||||
network.sendToAllTracking(message, new NetworkRegistry.TargetPoint(world.provider.getDimension(), pos.getX(), pos.getY(), pos.getZ(), 0));
|
||||
}
|
||||
|
||||
public static void sendToAllAround(World world, BlockPos pos, int range, IMessage message) {
|
||||
network.sendToAllAround(message, new NetworkRegistry.TargetPoint(world.provider.getDimension(), pos.getX(), pos.getY(), pos.getZ(), range));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,91 @@
|
|||
package de.ellpeck.naturesaura.packet;
|
||||
|
||||
import de.ellpeck.naturesaura.NaturesAura;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
|
||||
import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler;
|
||||
import net.minecraftforge.fml.common.network.simpleimpl.MessageContext;
|
||||
import net.minecraftforge.fml.relauncher.Side;
|
||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
||||
import org.lwjgl.util.vector.Vector3f;
|
||||
|
||||
public class PacketParticleStream implements IMessage {
|
||||
|
||||
private float startX;
|
||||
private float startY;
|
||||
private float startZ;
|
||||
|
||||
private float endX;
|
||||
private float endY;
|
||||
private float endZ;
|
||||
|
||||
private float speed;
|
||||
private int color;
|
||||
private float scale;
|
||||
|
||||
public PacketParticleStream(float startX, float startY, float startZ, float endX, float endY, float endZ, float speed, int color, float scale) {
|
||||
this.startX = startX;
|
||||
this.startY = startY;
|
||||
this.startZ = startZ;
|
||||
this.endX = endX;
|
||||
this.endY = endY;
|
||||
this.endZ = endZ;
|
||||
this.speed = speed;
|
||||
this.color = color;
|
||||
this.scale = scale;
|
||||
}
|
||||
|
||||
public PacketParticleStream() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fromBytes(ByteBuf buf) {
|
||||
this.startX = buf.readFloat();
|
||||
this.startY = buf.readFloat();
|
||||
this.startZ = buf.readFloat();
|
||||
this.endX = buf.readFloat();
|
||||
this.endY = buf.readFloat();
|
||||
this.endZ = buf.readFloat();
|
||||
this.speed = buf.readFloat();
|
||||
this.color = buf.readInt();
|
||||
this.scale = buf.readFloat();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toBytes(ByteBuf buf) {
|
||||
buf.writeFloat(this.startX);
|
||||
buf.writeFloat(this.startY);
|
||||
buf.writeFloat(this.startZ);
|
||||
buf.writeFloat(this.endX);
|
||||
buf.writeFloat(this.endY);
|
||||
buf.writeFloat(this.endZ);
|
||||
buf.writeFloat(this.speed);
|
||||
buf.writeInt(this.color);
|
||||
buf.writeFloat(this.scale);
|
||||
}
|
||||
|
||||
public static class Handler implements IMessageHandler<PacketParticleStream, IMessage> {
|
||||
|
||||
@Override
|
||||
@SideOnly(Side.CLIENT)
|
||||
public IMessage onMessage(PacketParticleStream message, MessageContext ctx) {
|
||||
NaturesAura.proxy.scheduleTask(() -> {
|
||||
Vector3f dir = new Vector3f(
|
||||
message.endX - message.startX,
|
||||
message.endY - message.startY,
|
||||
message.endZ - message.startZ);
|
||||
int maxAge = (int) (dir.length() / message.speed);
|
||||
dir.normalise();
|
||||
|
||||
NaturesAura.proxy.spawnMagicParticle(Minecraft.getMinecraft().world,
|
||||
message.startX, message.startY, message.startZ,
|
||||
dir.x * message.speed, dir.y * message.speed, dir.z * message.speed,
|
||||
message.color, message.scale, maxAge, 0F, false, false);
|
||||
});
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -8,32 +8,35 @@ import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler;
|
|||
import net.minecraftforge.fml.common.network.simpleimpl.MessageContext;
|
||||
import net.minecraftforge.fml.relauncher.Side;
|
||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
||||
import org.lwjgl.util.vector.Vector3f;
|
||||
|
||||
public class PacketParticles implements IMessage {
|
||||
|
||||
private float startX;
|
||||
private float startY;
|
||||
private float startZ;
|
||||
|
||||
private float endX;
|
||||
private float endY;
|
||||
private float endZ;
|
||||
|
||||
private float speed;
|
||||
private float posX;
|
||||
private float posY;
|
||||
private float posZ;
|
||||
private float motionX;
|
||||
private float motionY;
|
||||
private float motionZ;
|
||||
private int color;
|
||||
private float scale;
|
||||
private int maxAge;
|
||||
private float gravity;
|
||||
private boolean collision;
|
||||
private boolean fade;
|
||||
|
||||
public PacketParticles(float startX, float startY, float startZ, float endX, float endY, float endZ, float speed, int color, float scale) {
|
||||
this.startX = startX;
|
||||
this.startY = startY;
|
||||
this.startZ = startZ;
|
||||
this.endX = endX;
|
||||
this.endY = endY;
|
||||
this.endZ = endZ;
|
||||
this.speed = speed;
|
||||
public PacketParticles(float posX, float posY, float posZ, float motionX, float motionY, float motionZ, int color, float scale, int maxAge, float gravity, boolean collision, boolean fade) {
|
||||
this.posX = posX;
|
||||
this.posY = posY;
|
||||
this.posZ = posZ;
|
||||
this.motionX = motionX;
|
||||
this.motionY = motionY;
|
||||
this.motionZ = motionZ;
|
||||
this.color = color;
|
||||
this.scale = scale;
|
||||
this.maxAge = maxAge;
|
||||
this.gravity = gravity;
|
||||
this.collision = collision;
|
||||
this.fade = fade;
|
||||
}
|
||||
|
||||
public PacketParticles() {
|
||||
|
@ -42,28 +45,34 @@ public class PacketParticles implements IMessage {
|
|||
|
||||
@Override
|
||||
public void fromBytes(ByteBuf buf) {
|
||||
this.startX = buf.readFloat();
|
||||
this.startY = buf.readFloat();
|
||||
this.startZ = buf.readFloat();
|
||||
this.endX = buf.readFloat();
|
||||
this.endY = buf.readFloat();
|
||||
this.endZ = buf.readFloat();
|
||||
this.speed = buf.readFloat();
|
||||
this.posX = buf.readFloat();
|
||||
this.posY = buf.readFloat();
|
||||
this.posZ = buf.readFloat();
|
||||
this.motionX = buf.readFloat();
|
||||
this.motionY = buf.readFloat();
|
||||
this.motionZ = buf.readFloat();
|
||||
this.color = buf.readInt();
|
||||
this.scale = buf.readFloat();
|
||||
this.maxAge = buf.readInt();
|
||||
this.gravity = buf.readFloat();
|
||||
this.collision = buf.readBoolean();
|
||||
this.fade = buf.readBoolean();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toBytes(ByteBuf buf) {
|
||||
buf.writeFloat(this.startX);
|
||||
buf.writeFloat(this.startY);
|
||||
buf.writeFloat(this.startZ);
|
||||
buf.writeFloat(this.endX);
|
||||
buf.writeFloat(this.endY);
|
||||
buf.writeFloat(this.endZ);
|
||||
buf.writeFloat(this.speed);
|
||||
buf.writeFloat(this.posX);
|
||||
buf.writeFloat(this.posY);
|
||||
buf.writeFloat(this.posZ);
|
||||
buf.writeFloat(this.motionX);
|
||||
buf.writeFloat(this.motionY);
|
||||
buf.writeFloat(this.motionZ);
|
||||
buf.writeInt(this.color);
|
||||
buf.writeFloat(this.scale);
|
||||
buf.writeInt(this.maxAge);
|
||||
buf.writeFloat(this.gravity);
|
||||
buf.writeBoolean(this.collision);
|
||||
buf.writeBoolean(this.fade);
|
||||
}
|
||||
|
||||
public static class Handler implements IMessageHandler<PacketParticles, IMessage> {
|
||||
|
@ -71,19 +80,11 @@ public class PacketParticles implements IMessage {
|
|||
@Override
|
||||
@SideOnly(Side.CLIENT)
|
||||
public IMessage onMessage(PacketParticles message, MessageContext ctx) {
|
||||
NaturesAura.proxy.scheduleTask(() -> {
|
||||
Vector3f dir = new Vector3f(
|
||||
message.endX - message.startX,
|
||||
message.endY - message.startY,
|
||||
message.endZ - message.startZ);
|
||||
int maxAge = (int) (dir.length() / message.speed);
|
||||
dir.normalise();
|
||||
|
||||
NaturesAura.proxy.spawnMagicParticle(Minecraft.getMinecraft().world,
|
||||
message.startX, message.startY, message.startZ,
|
||||
dir.x * message.speed, dir.y * message.speed, dir.z * message.speed,
|
||||
message.color, message.scale, maxAge, 0F, false, false);
|
||||
});
|
||||
NaturesAura.proxy.scheduleTask(() ->
|
||||
NaturesAura.proxy.spawnMagicParticle(Minecraft.getMinecraft().world,
|
||||
message.posX, message.posY, message.posZ,
|
||||
message.motionX, message.motionY, message.motionZ,
|
||||
message.color, message.scale, message.maxAge, message.gravity, message.collision, message.fade));
|
||||
|
||||
return null;
|
||||
}
|
||||
|
|
12
src/main/java/de/ellpeck/naturesaura/recipes/ModRecipes.java
Normal file
12
src/main/java/de/ellpeck/naturesaura/recipes/ModRecipes.java
Normal file
|
@ -0,0 +1,12 @@
|
|||
package de.ellpeck.naturesaura.recipes;
|
||||
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.init.Items;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
public final class ModRecipes {
|
||||
|
||||
public static void init() {
|
||||
new TreeRitualRecipe(new ItemStack(Blocks.SAPLING), new ItemStack(Items.APPLE, 16), 300, new ItemStack(Items.BEETROOT), new ItemStack(Items.ITEM_FRAME), new ItemStack(Items.COMMAND_BLOCK_MINECART)).add();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
package de.ellpeck.naturesaura.recipes;
|
||||
|
||||
import de.ellpeck.naturesaura.Helper;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class TreeRitualRecipe {
|
||||
|
||||
public static final List<TreeRitualRecipe> RECIPES = new ArrayList<>();
|
||||
|
||||
public final ItemStack saplingType;
|
||||
public final ItemStack[] items;
|
||||
public final ItemStack result;
|
||||
public final int time;
|
||||
|
||||
public TreeRitualRecipe(ItemStack saplingType, ItemStack result, int time, ItemStack... items) {
|
||||
this.saplingType = saplingType;
|
||||
this.items = items;
|
||||
this.result = result;
|
||||
this.time = time;
|
||||
}
|
||||
|
||||
public boolean matchesItems(ItemStack sapling, List<ItemStack> items) {
|
||||
if (this.saplingType.isItemEqual(sapling)) {
|
||||
for (ItemStack ingredient : this.items) {
|
||||
if (!Helper.containsItem(items, ingredient)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void add() {
|
||||
RECIPES.add(this);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,144 @@
|
|||
{
|
||||
"multipart": [
|
||||
{
|
||||
"when": {
|
||||
"OR": [
|
||||
{
|
||||
"north": "none",
|
||||
"east": "none",
|
||||
"south": "none",
|
||||
"west": "none"
|
||||
},
|
||||
{
|
||||
"north": "side|up",
|
||||
"east": "side|up"
|
||||
},
|
||||
{
|
||||
"east": "side|up",
|
||||
"south": "side|up"
|
||||
},
|
||||
{
|
||||
"south": "side|up",
|
||||
"west": "side|up"
|
||||
},
|
||||
{
|
||||
"west": "side|up",
|
||||
"north": "side|up"
|
||||
}
|
||||
]
|
||||
},
|
||||
"apply": {
|
||||
"model": "redstone_dot"
|
||||
}
|
||||
},
|
||||
{
|
||||
"when": {
|
||||
"OR": [
|
||||
{
|
||||
"north": "side|up"
|
||||
},
|
||||
{
|
||||
"north": "none",
|
||||
"east": "none",
|
||||
"south": "side|up",
|
||||
"west": "none"
|
||||
}
|
||||
]
|
||||
},
|
||||
"apply": {
|
||||
"model": "redstone_side0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"when": {
|
||||
"OR": [
|
||||
{
|
||||
"south": "side|up"
|
||||
},
|
||||
{
|
||||
"north": "side|up",
|
||||
"east": "none",
|
||||
"south": "none",
|
||||
"west": "none"
|
||||
}
|
||||
]
|
||||
},
|
||||
"apply": {
|
||||
"model": "redstone_side_alt0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"when": {
|
||||
"OR": [
|
||||
{
|
||||
"east": "side|up"
|
||||
},
|
||||
{
|
||||
"north": "none",
|
||||
"east": "none",
|
||||
"south": "none",
|
||||
"west": "side|up"
|
||||
}
|
||||
]
|
||||
},
|
||||
"apply": {
|
||||
"model": "redstone_side_alt1",
|
||||
"y": 270
|
||||
}
|
||||
},
|
||||
{
|
||||
"when": {
|
||||
"OR": [
|
||||
{
|
||||
"west": "side|up"
|
||||
},
|
||||
{
|
||||
"north": "none",
|
||||
"east": "side|up",
|
||||
"south": "none",
|
||||
"west": "none"
|
||||
}
|
||||
]
|
||||
},
|
||||
"apply": {
|
||||
"model": "redstone_side1",
|
||||
"y": 270
|
||||
}
|
||||
},
|
||||
{
|
||||
"when": {
|
||||
"north": "up"
|
||||
},
|
||||
"apply": {
|
||||
"model": "redstone_up"
|
||||
}
|
||||
},
|
||||
{
|
||||
"when": {
|
||||
"east": "up"
|
||||
},
|
||||
"apply": {
|
||||
"model": "redstone_up",
|
||||
"y": 90
|
||||
}
|
||||
},
|
||||
{
|
||||
"when": {
|
||||
"south": "up"
|
||||
},
|
||||
"apply": {
|
||||
"model": "redstone_up",
|
||||
"y": 180
|
||||
}
|
||||
},
|
||||
{
|
||||
"when": {
|
||||
"west": "up"
|
||||
},
|
||||
"apply": {
|
||||
"model": "redstone_up",
|
||||
"y": 270
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -7,6 +7,8 @@ tile.naturesaura.ancient_sapling.name=Ancient Sapling
|
|||
tile.naturesaura.nature_altar.name=Natural Altar
|
||||
tile.naturesaura.decayed_leaves.name=Decayed Leaves
|
||||
tile.naturesaura.golden_leaves.name=Golden Leaves
|
||||
tile.naturesaura.gold_powder.name=Gold Powder
|
||||
tile.naturesaura.tree_ritual.name=Drained Dirt
|
||||
|
||||
item.naturesaura.eye.name=Environmental Eye
|
||||
item.naturesaura.gold_fiber.name=Brilliant Fiber
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "item/generated",
|
||||
"textures": {
|
||||
"layer0": "naturesaura:items/gold_powder"
|
||||
}
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 256 B |
Loading…
Reference in a new issue