some ritual work, needs finishing

This commit is contained in:
Ellpeck 2018-10-16 01:36:30 +02:00
parent c5ed74bfd5
commit f2eca230e8
15 changed files with 797 additions and 59 deletions

View file

@ -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;
}
}

View file

@ -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();
}
}

View 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;
}
}
}

View file

@ -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();
}

View file

@ -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

View file

@ -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);
}
}
}

View file

@ -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));
}
}

View file

@ -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;
}
}
}

View file

@ -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;
}

View 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();
}
}

View file

@ -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);
}
}

View file

@ -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
}
}
]
}

View file

@ -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

View file

@ -0,0 +1,6 @@
{
"parent": "item/generated",
"textures": {
"layer0": "naturesaura:items/gold_powder"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 256 B