added the aura field creator

This commit is contained in:
Ellpeck 2018-11-13 00:36:47 +01:00
parent 13d6cf778a
commit 850e37889b
20 changed files with 397 additions and 51 deletions

View file

@ -12,6 +12,7 @@ import net.minecraft.world.chunk.Chunk;
import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.IItemHandler;
import org.apache.commons.lang3.mutable.MutableInt; import org.apache.commons.lang3.mutable.MutableInt;
import org.apache.commons.lang3.mutable.MutableObject; import org.apache.commons.lang3.mutable.MutableObject;
import org.lwjgl.util.vector.Vector3f;
import java.util.function.BiConsumer; import java.util.function.BiConsumer;
@ -46,8 +47,21 @@ public class InternalHooks implements NaturesAuraAPI.IInternalHooks {
} }
@Override @Override
public void spawnMagicParticle(World world, double posX, double posY, double posZ, double motionX, double motionY, double motionZ, int color, float scale, int maxAge, float gravity, boolean collision, boolean fade) { public void spawnMagicParticle(double posX, double posY, double posZ, double motionX, double motionY, double motionZ, int color, float scale, int maxAge, float gravity, boolean collision, boolean fade) {
NaturesAura.proxy.spawnMagicParticle(world, posX, posY, posZ, motionX, motionY, motionZ, color, scale, maxAge, gravity, collision, fade); NaturesAura.proxy.spawnMagicParticle(posX, posY, posZ, motionX, motionY, motionZ, color, scale, maxAge, gravity, collision, fade);
}
@Override
public void spawnParticleStream(float startX, float startY, float startZ, float endX, float endY, float endZ, float speed, int color, float scale) {
Vector3f dir = new Vector3f(endX - startX, endY - startY, endZ - startZ);
if (dir.length() > 0) {
int maxAge = (int) (dir.length() / speed);
dir.normalise();
this.spawnMagicParticle(startX, startY, startZ,
dir.x * speed, dir.y * speed, dir.z * speed,
color, scale, maxAge, 0F, false, false);
}
} }
@Override @Override

View file

@ -21,6 +21,9 @@ public final class ModConfig {
@Comment("Additional blocks that the Herbivorous Absorber can consume to generate Aura. Each entry needs to be formatted as modid:block[prop1=value1,...] where block state properties are optional") @Comment("Additional blocks that the Herbivorous Absorber can consume to generate Aura. Each entry needs to be formatted as modid:block[prop1=value1,...] where block state properties are optional")
public String[] additionalHerbivorousAbsorberFlowers = new String[0]; public String[] additionalHerbivorousAbsorberFlowers = new String[0];
@Comment("The amount of blocks that can be between two Aura Field Creators for them to be connectable and work together")
public int fieldCreatorRange = 8;
} }
public static class Client { public static class Client {

View file

@ -141,7 +141,6 @@ public final class NaturesAuraAPI {
* you want to send it from the server side, you need to create your own * you want to send it from the server side, you need to create your own
* packet. * packet.
* *
* @param world The world to spawn the particle in
* @param posX The x position * @param posX The x position
* @param posY The y position * @param posY The y position
* @param posZ The z position * @param posZ The z position
@ -157,7 +156,26 @@ public final class NaturesAuraAPI {
* @param fade If the particle should slowly fade out or suddenly * @param fade If the particle should slowly fade out or suddenly
* disappear * disappear
*/ */
void spawnMagicParticle(World world, double posX, double posY, double posZ, double motionX, double motionY, double motionZ, int color, float scale, int maxAge, float gravity, boolean collision, boolean fade); void spawnMagicParticle(double posX, double posY, double posZ, double motionX, double motionY, double motionZ, int color, float scale, int maxAge, float gravity, boolean collision, boolean fade);
/**
* This method can be used to spawn the magic particle effect used by
* Nature's Aura. The particle will be created to spawn at the start
* position and move towards the end position, dying when it reaches it.
* It will not have an effect on the client side, so if you want to send
* it from the server side, you need to create your own packet.
*
* @param startX The start x
* @param startY The start y
* @param startZ The start z
* @param endX The end x
* @param endY The end y
* @param endZ The end z
* @param speed The speed at which the particle should go
* @param color The color of the particle
* @param scale The scale of the particle
*/
void spawnParticleStream(float startX, float startY, float startZ, float endX, float endY, float endZ, float speed, int color, float scale);
/** /**
* @see IAuraChunk#getSpotsInArea(World, BlockPos, int, BiConsumer) * @see IAuraChunk#getSpotsInArea(World, BlockPos, int, BiConsumer)

View file

@ -15,7 +15,12 @@ public class StubHooks implements NaturesAuraAPI.IInternalHooks {
} }
@Override @Override
public void spawnMagicParticle(World world, double posX, double posY, double posZ, double motionX, double motionY, double motionZ, int color, float scale, int maxAge, float gravity, boolean collision, boolean fade) { public void spawnMagicParticle(double posX, double posY, double posZ, double motionX, double motionY, double motionZ, int color, float scale, int maxAge, float gravity, boolean collision, boolean fade) {
}
@Override
public void spawnParticleStream(float startX, float startY, float startZ, float endX, float endY, float endZ, float speed, int color, float scale) {
} }

View file

@ -133,7 +133,7 @@ public class BlockAncientLeaves extends BlockLeaves implements
TileEntity tile = worldIn.getTileEntity(pos); TileEntity tile = worldIn.getTileEntity(pos);
if (tile instanceof TileEntityAncientLeaves) { if (tile instanceof TileEntityAncientLeaves) {
if (((TileEntityAncientLeaves) tile).getAuraContainer(null).getStoredAura() > 0) { if (((TileEntityAncientLeaves) tile).getAuraContainer(null).getStoredAura() > 0) {
NaturesAuraAPI.instance().spawnMagicParticle(worldIn, NaturesAuraAPI.instance().spawnMagicParticle(
pos.getX() + rand.nextDouble(), pos.getY(), pos.getZ() + rand.nextDouble(), pos.getX() + rand.nextDouble(), pos.getY(), pos.getZ() + rand.nextDouble(),
0F, 0F, 0F, 0xc46df9, 0F, 0F, 0F, 0xc46df9,
rand.nextFloat() * 2F + 0.5F, rand.nextFloat() * 2F + 0.5F,

View file

@ -5,6 +5,7 @@ import de.ellpeck.naturesaura.blocks.tiles.TileEntityImpl;
import de.ellpeck.naturesaura.reg.IModItem; import de.ellpeck.naturesaura.reg.IModItem;
import de.ellpeck.naturesaura.reg.IModelProvider; import de.ellpeck.naturesaura.reg.IModelProvider;
import de.ellpeck.naturesaura.reg.ModRegistry; import de.ellpeck.naturesaura.reg.ModRegistry;
import net.minecraft.block.Block;
import net.minecraft.block.BlockContainer; import net.minecraft.block.BlockContainer;
import net.minecraft.block.material.Material; import net.minecraft.block.material.Material;
import net.minecraft.block.state.IBlockState; import net.minecraft.block.state.IBlockState;
@ -117,4 +118,30 @@ public class BlockContainerImpl extends BlockContainer implements IModItem, IMod
if (tile instanceof TileEntityImpl) if (tile instanceof TileEntityImpl)
((TileEntityImpl) tile).loadDataOnPlace(stack); ((TileEntityImpl) tile).loadDataOnPlace(stack);
} }
@Override
public void onBlockAdded(World worldIn, BlockPos pos, IBlockState state) {
this.updateRedstoneState(worldIn, pos);
}
@Override
public void neighborChanged(IBlockState state, World worldIn, BlockPos pos, Block blockIn, BlockPos fromPos) {
this.updateRedstoneState(worldIn, pos);
}
private void updateRedstoneState(World world, BlockPos pos) {
if (!world.isRemote) {
TileEntity tile = world.getTileEntity(pos);
if (tile instanceof TileEntityImpl) {
TileEntityImpl impl = (TileEntityImpl) tile;
boolean powered = world.getRedstonePowerFromNeighbors(pos) > 0;
boolean wasPowered = impl.isRedstonePowered;
if (powered && !wasPowered) {
impl.isRedstonePowered = true;
} else if (!powered && wasPowered) {
impl.isRedstonePowered = false;
}
}
}
}
} }

View file

@ -0,0 +1,90 @@
package de.ellpeck.naturesaura.blocks;
import de.ellpeck.naturesaura.NaturesAura;
import de.ellpeck.naturesaura.api.NaturesAuraAPI;
import de.ellpeck.naturesaura.blocks.tiles.TileEntityFieldCreator;
import net.minecraft.block.SoundType;
import net.minecraft.block.material.Material;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.text.TextComponentTranslation;
import net.minecraft.world.World;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import java.util.Random;
public class BlockFieldCreator extends BlockContainerImpl {
public BlockFieldCreator() {
super(Material.ROCK, "field_creator", TileEntityFieldCreator.class, "field_creator");
this.setSoundType(SoundType.STONE);
this.setHardness(2F);
}
@Override
public boolean onBlockActivated(World worldIn, BlockPos pos, IBlockState state, EntityPlayer playerIn, EnumHand hand, EnumFacing facing, float hitX, float hitY, float hitZ) {
TileEntity tile = worldIn.getTileEntity(pos);
if (tile instanceof TileEntityFieldCreator) {
if (!worldIn.isRemote) {
String key = NaturesAura.MOD_ID + ":field_creator_pos";
NBTTagCompound compound = playerIn.getEntityData();
if (!playerIn.isSneaking() && compound.hasKey(key)) {
BlockPos stored = BlockPos.fromLong(compound.getLong(key));
TileEntityFieldCreator creator = (TileEntityFieldCreator) tile;
if (!pos.equals(stored)) {
if (creator.isCloseEnough(stored)) {
TileEntity otherTile = worldIn.getTileEntity(stored);
if (otherTile instanceof TileEntityFieldCreator) {
creator.connectionOffset = stored.subtract(pos);
creator.isMain = true;
creator.sendToClients();
TileEntityFieldCreator otherCreator = (TileEntityFieldCreator) otherTile;
otherCreator.connectionOffset = pos.subtract(stored);
otherCreator.sendToClients();
compound.removeTag(key);
playerIn.sendStatusMessage(new TextComponentTranslation("info." + NaturesAura.MOD_ID + ".connected"), true);
} else
playerIn.sendStatusMessage(new TextComponentTranslation("info." + NaturesAura.MOD_ID + ".stored_pos_gone"), true);
} else
playerIn.sendStatusMessage(new TextComponentTranslation("info." + NaturesAura.MOD_ID + ".too_far"), true);
} else
playerIn.sendStatusMessage(new TextComponentTranslation("info." + NaturesAura.MOD_ID + ".same_position"), true);
} else {
compound.setLong(key, pos.toLong());
playerIn.sendStatusMessage(new TextComponentTranslation("info." + NaturesAura.MOD_ID + ".stored_pos"), true);
}
}
return true;
} else
return false;
}
@Override
@SideOnly(Side.CLIENT)
public void randomDisplayTick(IBlockState stateIn, World worldIn, BlockPos pos, Random rand) {
TileEntity tile = worldIn.getTileEntity(pos);
if (tile instanceof TileEntityFieldCreator) {
TileEntityFieldCreator creator = (TileEntityFieldCreator) tile;
if (creator.isCharged) {
BlockPos connected = creator.getConnectedPos();
if (connected != null)
NaturesAuraAPI.instance().spawnParticleStream(
pos.getX() + rand.nextFloat(),
pos.getY() + rand.nextFloat(),
pos.getZ() + rand.nextFloat(),
connected.getX() + rand.nextFloat(),
connected.getY() + rand.nextFloat(),
connected.getZ() + rand.nextFloat(),
0.65F, 0x4245f4, 1F
);
}
}
}
}

View file

@ -60,7 +60,7 @@ public class BlockFurnaceHeater extends BlockContainerImpl {
z = facing.getXOffset() != 0 ? (0.35F + rand.nextFloat() * 0.3F) : facing.getZOffset() < 0 ? 1 : 0; z = facing.getXOffset() != 0 ? (0.35F + rand.nextFloat() * 0.3F) : facing.getZOffset() < 0 ? 1 : 0;
} }
NaturesAuraAPI.instance().spawnMagicParticle(worldIn, NaturesAuraAPI.instance().spawnMagicParticle(
pos.getX() + x, pos.getY() + y, pos.getZ() + z, pos.getX() + x, pos.getY() + y, pos.getZ() + z,
(rand.nextFloat() * 0.016F + 0.01F) * facing.getXOffset(), (rand.nextFloat() * 0.016F + 0.01F) * facing.getXOffset(),
(rand.nextFloat() * 0.016F + 0.01F) * facing.getYOffset(), (rand.nextFloat() * 0.016F + 0.01F) * facing.getYOffset(),

View file

@ -67,7 +67,7 @@ public class BlockGoldenLeaves extends BlockLeaves implements
@SideOnly(Side.CLIENT) @SideOnly(Side.CLIENT)
public void randomDisplayTick(IBlockState stateIn, World worldIn, BlockPos pos, Random rand) { public void randomDisplayTick(IBlockState stateIn, World worldIn, BlockPos pos, Random rand) {
if (stateIn.getValue(STAGE) == HIGHEST_STAGE && rand.nextFloat() >= 0.75F) if (stateIn.getValue(STAGE) == HIGHEST_STAGE && rand.nextFloat() >= 0.75F)
NaturesAuraAPI.instance().spawnMagicParticle(worldIn, NaturesAuraAPI.instance().spawnMagicParticle(
pos.getX() + rand.nextFloat(), pos.getX() + rand.nextFloat(),
pos.getY() + rand.nextFloat(), pos.getY() + rand.nextFloat(),
pos.getZ() + rand.nextFloat(), pos.getZ() + rand.nextFloat(),

View file

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

View file

@ -0,0 +1,187 @@
package de.ellpeck.naturesaura.blocks.tiles;
import de.ellpeck.naturesaura.ModConfig;
import de.ellpeck.naturesaura.api.aura.chunk.IAuraChunk;
import de.ellpeck.naturesaura.api.aura.type.IAuraType;
import de.ellpeck.naturesaura.packet.PacketHandler;
import de.ellpeck.naturesaura.packet.PacketParticleStream;
import net.minecraft.block.Block;
import net.minecraft.block.BlockLiquid;
import net.minecraft.block.state.IBlockState;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.ITickable;
import net.minecraft.util.NonNullList;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.WorldServer;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.common.util.FakePlayer;
import net.minecraftforge.common.util.FakePlayerFactory;
import net.minecraftforge.event.ForgeEventFactory;
import net.minecraftforge.event.world.BlockEvent;
import net.minecraftforge.fluids.IFluidBlock;
public class TileEntityFieldCreator extends TileEntityImpl implements ITickable {
public BlockPos connectionOffset;
public boolean isMain;
public boolean isCharged;
private int chargeTimer;
@Override
public void update() {
if (this.world.isRemote || this.world.getTotalWorldTime() % 10 != 0)
return;
BlockPos connectedPos = this.getConnectedPos();
if (connectedPos == null)
return;
TileEntity other = this.world.getTileEntity(connectedPos);
if (!this.isCloseEnough(connectedPos)
|| !(other instanceof TileEntityFieldCreator)
|| !this.pos.equals(((TileEntityFieldCreator) other).getConnectedPos())) {
this.connectionOffset = null;
this.chargeTimer = 0;
this.isCharged = false;
this.isMain = false;
this.sendToClients();
return;
}
if (!this.isMain)
return;
TileEntityFieldCreator creator = (TileEntityFieldCreator) other;
if (!this.isRedstonePowered && !creator.isRedstonePowered) {
this.chargeTimer = 0;
if (this.isCharged) {
this.isCharged = false;
this.sendToClients();
creator.isCharged = false;
creator.sendToClients();
}
return;
}
BlockPos spot = IAuraChunk.getHighestSpot(this.world, this.pos, 32, this.pos);
IAuraChunk chunk = IAuraChunk.getAuraChunk(this.world, spot);
if (!this.isCharged) {
this.chargeTimer += 10;
if (this.chargeTimer >= 150) {
this.chargeTimer = 0;
this.isCharged = true;
this.sendToClients();
creator.isCharged = true;
creator.sendToClients();
}
chunk.drainAura(spot, 15);
this.sendParticles();
} else {
if (this.world.getTotalWorldTime() % 20 == 0)
chunk.drainAura(spot, 1);
Vec3d dist = new Vec3d(
this.pos.getX() - connectedPos.getX(),
this.pos.getY() - connectedPos.getY(),
this.pos.getZ() - connectedPos.getZ()
);
double length = dist.length();
Vec3d normal = new Vec3d(dist.x / length, dist.y / length, dist.z / length);
for (int i = MathHelper.floor(length); i > 0; i--) {
Vec3d scaled = normal.scale(i);
BlockPos pos = connectedPos.add(
MathHelper.floor(scaled.x + 0.5F),
MathHelper.floor(scaled.y + 0.5F),
MathHelper.floor(scaled.z + 0.5F));
if (pos.equals(this.pos) || pos.equals(connectedPos))
continue;
IBlockState state = this.world.getBlockState(pos);
Block block = state.getBlock();
if (!block.isAir(state, this.world, pos)
&& !(block instanceof BlockLiquid) && !(block instanceof IFluidBlock)
&& state.getBlockHardness(this.world, pos) >= 0F) {
FakePlayer fake = FakePlayerFactory.getMinecraft((WorldServer) this.world);
if (!MinecraftForge.EVENT_BUS.post(new BlockEvent.BreakEvent(this.world, pos, state, fake))) {
NonNullList<ItemStack> drops = NonNullList.create();
block.getDrops(drops, this.world, pos, state, 0);
float chance = ForgeEventFactory.fireBlockHarvesting(drops, this.world, pos, state, 0, 1, false, fake);
if (chance > 0 && this.world.rand.nextFloat() <= chance) {
this.world.destroyBlock(pos, false);
for (ItemStack stack : drops)
Block.spawnAsEntity(this.world, pos, stack);
chunk.drainAura(spot, 5);
this.sendParticles();
}
}
}
}
}
}
private void sendParticles() {
for (int j = 0; j < 2; j++) {
BlockPos p = j == 0 ? this.pos : this.getConnectedPos();
PacketHandler.sendToAllAround(this.world, p, 32, new PacketParticleStream(
p.getX() + (float) this.world.rand.nextGaussian() * 3F,
p.getY() + 1 + this.world.rand.nextFloat() * 3F,
p.getZ() + (float) this.world.rand.nextGaussian() * 3F,
p.getX() + this.world.rand.nextFloat(),
p.getY() + this.world.rand.nextFloat(),
p.getZ() + this.world.rand.nextFloat(),
this.world.rand.nextFloat() * 0.07F + 0.07F, IAuraType.forWorld(this.world).getColor(), this.world.rand.nextFloat() + 0.5F
));
}
}
public boolean isCloseEnough(BlockPos pos) {
int range = ModConfig.general.fieldCreatorRange + 1;
return this.pos.distanceSq(pos) <= range * range;
}
public BlockPos getConnectedPos() {
if (this.connectionOffset == null)
return null;
return this.pos.add(this.connectionOffset);
}
@Override
public void writeNBT(NBTTagCompound compound, SaveType type) {
super.writeNBT(compound, type);
if (type != SaveType.BLOCK) {
if (this.connectionOffset != null)
compound.setLong("connection", this.connectionOffset.toLong());
compound.setBoolean("main", this.isMain);
compound.setBoolean("charged", this.isCharged);
if (type == SaveType.TILE)
compound.setInteger("timer", this.chargeTimer);
}
}
@Override
public void readNBT(NBTTagCompound compound, SaveType type) {
super.readNBT(compound, type);
if (type != SaveType.BLOCK) {
if (compound.hasKey("connection"))
this.connectionOffset = BlockPos.fromLong(compound.getLong("connection"));
else
this.connectionOffset = null;
this.isMain = compound.getBoolean("main");
this.isCharged = compound.getBoolean("charged");
if (type == SaveType.TILE)
this.chargeTimer = compound.getInteger("timer");
}
}
}

View file

@ -2,6 +2,7 @@ package de.ellpeck.naturesaura.blocks.tiles;
import de.ellpeck.naturesaura.Helper; import de.ellpeck.naturesaura.Helper;
import de.ellpeck.naturesaura.api.aura.chunk.IAuraChunk; import de.ellpeck.naturesaura.api.aura.chunk.IAuraChunk;
import de.ellpeck.naturesaura.api.aura.type.IAuraType;
import de.ellpeck.naturesaura.blocks.BlockFurnaceHeater; import de.ellpeck.naturesaura.blocks.BlockFurnaceHeater;
import de.ellpeck.naturesaura.packet.PacketHandler; import de.ellpeck.naturesaura.packet.PacketHandler;
import de.ellpeck.naturesaura.packet.PacketParticleStream; import de.ellpeck.naturesaura.packet.PacketParticleStream;
@ -51,7 +52,7 @@ public class TileEntityFurnaceHeater extends TileEntityImpl implements ITickable
tilePos.getX() + this.world.rand.nextFloat(), tilePos.getX() + this.world.rand.nextFloat(),
tilePos.getY() + this.world.rand.nextFloat(), tilePos.getY() + this.world.rand.nextFloat(),
tilePos.getZ() + this.world.rand.nextFloat(), tilePos.getZ() + this.world.rand.nextFloat(),
this.world.rand.nextFloat() * 0.07F + 0.07F, 0x89cc37, this.world.rand.nextFloat() + 0.5F this.world.rand.nextFloat() * 0.07F + 0.07F, IAuraType.forWorld(this.world).getColor(), this.world.rand.nextFloat() + 0.5F
)); ));
} }
} }

View file

@ -23,6 +23,9 @@ import net.minecraftforge.items.IItemHandlerModifiable;
import javax.annotation.Nullable; import javax.annotation.Nullable;
public class TileEntityImpl extends TileEntity { public class TileEntityImpl extends TileEntity {
public boolean isRedstonePowered;
@Override @Override
public boolean shouldRefresh(World world, BlockPos pos, IBlockState oldState, IBlockState newState) { public boolean shouldRefresh(World world, BlockPos pos, IBlockState oldState, IBlockState newState) {
return oldState.getBlock() != newState.getBlock(); return oldState.getBlock() != newState.getBlock();
@ -40,13 +43,17 @@ public class TileEntityImpl extends TileEntity {
} }
public void writeNBT(NBTTagCompound compound, SaveType type) { public void writeNBT(NBTTagCompound compound, SaveType type) {
if (type != SaveType.BLOCK) if (type != SaveType.BLOCK) {
super.writeToNBT(compound); super.writeToNBT(compound);
compound.setBoolean("redstone", this.isRedstonePowered);
}
} }
public void readNBT(NBTTagCompound compound, SaveType type) { public void readNBT(NBTTagCompound compound, SaveType type) {
if (type != SaveType.BLOCK) if (type != SaveType.BLOCK) {
super.readFromNBT(compound); super.readFromNBT(compound);
this.isRedstonePowered = compound.getBoolean("redstone");
}
} }
@Override @Override

View file

@ -152,22 +152,22 @@ public class TileEntityNatureAltar extends TileEntityImpl implements ITickable {
if (rand.nextFloat() >= 0.7F) { if (rand.nextFloat() >= 0.7F) {
int fourths = this.container.getMaxAura() / 4; int fourths = this.container.getMaxAura() / 4;
if (this.container.getStoredAura() > 0) { if (this.container.getStoredAura() > 0) {
NaturesAuraAPI.instance().spawnMagicParticle(this.world, NaturesAuraAPI.instance().spawnMagicParticle(
this.pos.getX() - 4F + rand.nextFloat(), this.pos.getY() + 3F, this.pos.getZ() + rand.nextFloat(), this.pos.getX() - 4F + rand.nextFloat(), this.pos.getY() + 3F, this.pos.getZ() + rand.nextFloat(),
0F, 0F, 0F, this.container.getAuraColor(), rand.nextFloat() * 3F + 1F, rand.nextInt(100) + 50, -0.05F, true, true); 0F, 0F, 0F, this.container.getAuraColor(), rand.nextFloat() * 3F + 1F, rand.nextInt(100) + 50, -0.05F, true, true);
} }
if (this.container.getStoredAura() >= fourths) { if (this.container.getStoredAura() >= fourths) {
NaturesAuraAPI.instance().spawnMagicParticle(this.world, NaturesAuraAPI.instance().spawnMagicParticle(
this.pos.getX() + 4F + rand.nextFloat(), this.pos.getY() + 3F, this.pos.getZ() + rand.nextFloat(), this.pos.getX() + 4F + rand.nextFloat(), this.pos.getY() + 3F, this.pos.getZ() + rand.nextFloat(),
0F, 0F, 0F, this.container.getAuraColor(), rand.nextFloat() * 3F + 1F, rand.nextInt(100) + 50, -0.05F, true, true); 0F, 0F, 0F, this.container.getAuraColor(), rand.nextFloat() * 3F + 1F, rand.nextInt(100) + 50, -0.05F, true, true);
} }
if (this.container.getStoredAura() >= fourths * 2) { if (this.container.getStoredAura() >= fourths * 2) {
NaturesAuraAPI.instance().spawnMagicParticle(this.world, NaturesAuraAPI.instance().spawnMagicParticle(
this.pos.getX() + rand.nextFloat(), this.pos.getY() + 3F, this.pos.getZ() - 4F + rand.nextFloat(), this.pos.getX() + rand.nextFloat(), this.pos.getY() + 3F, this.pos.getZ() - 4F + rand.nextFloat(),
0F, 0F, 0F, this.container.getAuraColor(), rand.nextFloat() * 3F + 1F, rand.nextInt(100) + 50, -0.05F, true, true); 0F, 0F, 0F, this.container.getAuraColor(), rand.nextFloat() * 3F + 1F, rand.nextInt(100) + 50, -0.05F, true, true);
} }
if (this.container.getStoredAura() >= fourths * 3) { if (this.container.getStoredAura() >= fourths * 3) {
NaturesAuraAPI.instance().spawnMagicParticle(this.world, NaturesAuraAPI.instance().spawnMagicParticle(
this.pos.getX() + rand.nextFloat(), this.pos.getY() + 3F, this.pos.getZ() + 4F + rand.nextFloat(), this.pos.getX() + rand.nextFloat(), this.pos.getY() + 3F, this.pos.getZ() + 4F + rand.nextFloat(),
0F, 0F, 0F, this.container.getAuraColor(), rand.nextFloat() * 3F + 1F, rand.nextInt(100) + 50, -0.05F, true, true); 0F, 0F, 0F, this.container.getAuraColor(), rand.nextFloat() * 3F + 1F, rand.nextInt(100) + 50, -0.05F, true, true);
} }

View file

@ -3,13 +3,11 @@ package de.ellpeck.naturesaura.packet;
import de.ellpeck.naturesaura.NaturesAura; import de.ellpeck.naturesaura.NaturesAura;
import de.ellpeck.naturesaura.api.NaturesAuraAPI; import de.ellpeck.naturesaura.api.NaturesAuraAPI;
import io.netty.buffer.ByteBuf; 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.IMessage;
import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler; import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler;
import net.minecraftforge.fml.common.network.simpleimpl.MessageContext; import net.minecraftforge.fml.common.network.simpleimpl.MessageContext;
import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly; import net.minecraftforge.fml.relauncher.SideOnly;
import org.lwjgl.util.vector.Vector3f;
public class PacketParticleStream implements IMessage { public class PacketParticleStream implements IMessage {
@ -72,21 +70,10 @@ public class PacketParticleStream implements IMessage {
@Override @Override
@SideOnly(Side.CLIENT) @SideOnly(Side.CLIENT)
public IMessage onMessage(PacketParticleStream message, MessageContext ctx) { public IMessage onMessage(PacketParticleStream message, MessageContext ctx) {
NaturesAura.proxy.scheduleTask(() -> { NaturesAura.proxy.scheduleTask(() -> NaturesAuraAPI.instance().spawnParticleStream(
Vector3f dir = new Vector3f(
message.endX - message.startX,
message.endY - message.startY,
message.endZ - message.startZ);
if (dir.length() > 0) {
int maxAge = (int) (dir.length() / message.speed);
dir.normalise();
NaturesAuraAPI.instance().spawnMagicParticle(Minecraft.getMinecraft().world,
message.startX, message.startY, message.startZ, message.startX, message.startY, message.startZ,
dir.x * message.speed, dir.y * message.speed, dir.z * message.speed, message.endX, message.endY, message.endZ,
message.color, message.scale, maxAge, 0F, false, false); message.speed, message.color, message.scale));
}
});
return null; return null;
} }

View file

@ -75,7 +75,7 @@ public class PacketParticles implements IMessage {
Multiblocks.TREE_RITUAL.forEach(pos, 'G', (dustPos, matcher) -> { Multiblocks.TREE_RITUAL.forEach(pos, 'G', (dustPos, matcher) -> {
IBlockState state = world.getBlockState(dustPos); IBlockState state = world.getBlockState(dustPos);
AxisAlignedBB box = state.getBoundingBox(world, dustPos); AxisAlignedBB box = state.getBoundingBox(world, dustPos);
NaturesAuraAPI.instance().spawnMagicParticle(world, NaturesAuraAPI.instance().spawnMagicParticle(
dustPos.getX() + box.minX + (box.maxX - box.minX) * world.rand.nextFloat(), dustPos.getX() + box.minX + (box.maxX - box.minX) * world.rand.nextFloat(),
dustPos.getY() + 0.1F, dustPos.getY() + 0.1F,
dustPos.getZ() + box.minZ + (box.maxZ - box.minZ) * world.rand.nextFloat(), dustPos.getZ() + box.minZ + (box.maxZ - box.minZ) * world.rand.nextFloat(),
@ -88,7 +88,7 @@ public class PacketParticles implements IMessage {
break; break;
case 1: // Tree ritual: Consuming item case 1: // Tree ritual: Consuming item
for (int i = world.rand.nextInt(20) + 10; i >= 0; i--) { for (int i = world.rand.nextInt(20) + 10; i >= 0; i--) {
NaturesAuraAPI.instance().spawnMagicParticle(world, NaturesAuraAPI.instance().spawnMagicParticle(
message.posX + 0.5F, message.posY + 0.9F, message.posZ + 0.5F, message.posX + 0.5F, message.posY + 0.9F, message.posZ + 0.5F,
(float) world.rand.nextGaussian() * 0.04F, world.rand.nextFloat() * 0.04F, (float) world.rand.nextGaussian() * 0.04F, (float) world.rand.nextGaussian() * 0.04F, world.rand.nextFloat() * 0.04F, (float) world.rand.nextGaussian() * 0.04F,
0x89cc37, 1.5F, 25, 0F, false, true); 0x89cc37, 1.5F, 25, 0F, false, true);
@ -96,7 +96,7 @@ public class PacketParticles implements IMessage {
break; break;
case 2: // Tree ritual: Tree disappearing case 2: // Tree ritual: Tree disappearing
for (int i = world.rand.nextInt(5) + 3; i >= 0; i--) { for (int i = world.rand.nextInt(5) + 3; i >= 0; i--) {
NaturesAuraAPI.instance().spawnMagicParticle(world, NaturesAuraAPI.instance().spawnMagicParticle(
message.posX + world.rand.nextFloat(), message.posY + world.rand.nextFloat(), message.posZ + world.rand.nextFloat(), message.posX + world.rand.nextFloat(), message.posY + world.rand.nextFloat(), message.posZ + world.rand.nextFloat(),
0F, 0F, 0F, 0F, 0F, 0F,
0x33FF33, 1F, 50, 0F, false, true); 0x33FF33, 1F, 50, 0F, false, true);
@ -104,7 +104,7 @@ public class PacketParticles implements IMessage {
break; break;
case 3: // Tree ritual: Spawn result item case 3: // Tree ritual: Spawn result item
for (int i = world.rand.nextInt(10) + 10; i >= 0; i--) { for (int i = world.rand.nextInt(10) + 10; i >= 0; i--) {
NaturesAuraAPI.instance().spawnMagicParticle(world, NaturesAuraAPI.instance().spawnMagicParticle(
message.posX, message.posY, message.posZ, message.posX, message.posY, message.posZ,
world.rand.nextGaussian() * 0.1F, world.rand.nextGaussian() * 0.1F, world.rand.nextGaussian() * 0.1F, world.rand.nextGaussian() * 0.1F, world.rand.nextGaussian() * 0.1F, world.rand.nextGaussian() * 0.1F,
0x89cc37, 2F, 100, 0F, true, true); 0x89cc37, 2F, 100, 0F, true, true);
@ -112,7 +112,7 @@ public class PacketParticles implements IMessage {
break; break;
case 4: // Nature altar: Conversion case 4: // Nature altar: Conversion
for (int i = world.rand.nextInt(5) + 2; i >= 0; i--) { for (int i = world.rand.nextInt(5) + 2; i >= 0; i--) {
NaturesAuraAPI.instance().spawnMagicParticle(world, NaturesAuraAPI.instance().spawnMagicParticle(
message.posX + 0.25F + world.rand.nextFloat() * 0.5F, message.posX + 0.25F + world.rand.nextFloat() * 0.5F,
message.posY + 0.9F + 0.25F * world.rand.nextFloat(), message.posY + 0.9F + 0.25F * world.rand.nextFloat(),
message.posZ + 0.25F + world.rand.nextFloat() * 0.5F, message.posZ + 0.25F + world.rand.nextFloat() * 0.5F,
@ -124,7 +124,7 @@ public class PacketParticles implements IMessage {
int color = message.data[0]; int color = message.data[0];
boolean disperse = message.data[1] > 0; boolean disperse = message.data[1] > 0;
for (int i = world.rand.nextInt(5) + 5; i >= 0; i--) { for (int i = world.rand.nextInt(5) + 5; i >= 0; i--) {
NaturesAuraAPI.instance().spawnMagicParticle(world, NaturesAuraAPI.instance().spawnMagicParticle(
message.posX + world.rand.nextFloat(), message.posX + world.rand.nextFloat(),
message.posY + 1.1F, message.posY + 1.1F,
message.posZ + world.rand.nextFloat(), message.posZ + world.rand.nextFloat(),
@ -134,7 +134,7 @@ public class PacketParticles implements IMessage {
if (disperse) if (disperse)
for (int x = -1; x <= 1; x += 2) for (int x = -1; x <= 1; x += 2)
for (int z = -1; z <= 1; z += 2) { for (int z = -1; z <= 1; z += 2) {
NaturesAuraAPI.instance().spawnMagicParticle(world, NaturesAuraAPI.instance().spawnMagicParticle(
message.posX + x * 3 + 0.5F, message.posX + x * 3 + 0.5F,
message.posY + 2.5, message.posY + 2.5,
message.posZ + z * 3 + 0.5F, message.posZ + z * 3 + 0.5F,
@ -147,7 +147,7 @@ public class PacketParticles implements IMessage {
break; break;
case 6: // Plant boost effect case 6: // Plant boost effect
for (int i = world.rand.nextInt(20) + 15; i >= 0; i--) for (int i = world.rand.nextInt(20) + 15; i >= 0; i--)
NaturesAuraAPI.instance().spawnMagicParticle(world, NaturesAuraAPI.instance().spawnMagicParticle(
message.posX + world.rand.nextFloat(), message.posX + world.rand.nextFloat(),
message.posY + 0.25F + world.rand.nextFloat() * 0.5F, message.posY + 0.25F + world.rand.nextFloat() * 0.5F,
message.posZ + world.rand.nextFloat(), message.posZ + world.rand.nextFloat(),
@ -158,7 +158,7 @@ public class PacketParticles implements IMessage {
case 7: // Flower generator consumation case 7: // Flower generator consumation
color = message.data[0]; color = message.data[0];
for (int i = world.rand.nextInt(10) + 10; i >= 0; i--) for (int i = world.rand.nextInt(10) + 10; i >= 0; i--)
NaturesAuraAPI.instance().spawnMagicParticle(world, NaturesAuraAPI.instance().spawnMagicParticle(
message.posX + 0.25F + world.rand.nextFloat() * 0.5F, message.posX + 0.25F + world.rand.nextFloat() * 0.5F,
message.posY + 0.25F + world.rand.nextFloat() * 0.5F, message.posY + 0.25F + world.rand.nextFloat() * 0.5F,
message.posZ + 0.25F + world.rand.nextFloat() * 0.5F, message.posZ + 0.25F + world.rand.nextFloat() * 0.5F,
@ -169,7 +169,7 @@ public class PacketParticles implements IMessage {
break; break;
case 8: // Flower generator aura creation case 8: // Flower generator aura creation
for (int i = world.rand.nextInt(10) + 5; i >= 0; i--) for (int i = world.rand.nextInt(10) + 5; i >= 0; i--)
NaturesAuraAPI.instance().spawnMagicParticle(world, NaturesAuraAPI.instance().spawnMagicParticle(
message.posX + 0.25F + world.rand.nextFloat() * 0.5F, message.posX + 0.25F + world.rand.nextFloat() * 0.5F,
message.posY + 1.01F, message.posY + 1.01F,
message.posZ + 0.25F + world.rand.nextFloat() * 0.5F, message.posZ + 0.25F + world.rand.nextFloat() * 0.5F,
@ -183,7 +183,7 @@ public class PacketParticles implements IMessage {
boolean side = world.rand.nextBoolean(); boolean side = world.rand.nextBoolean();
float x = side ? world.rand.nextFloat() : (world.rand.nextBoolean() ? 1.1F : -0.1F); float x = side ? world.rand.nextFloat() : (world.rand.nextBoolean() ? 1.1F : -0.1F);
float z = !side ? world.rand.nextFloat() : (world.rand.nextBoolean() ? 1.1F : -0.1F); float z = !side ? world.rand.nextFloat() : (world.rand.nextBoolean() ? 1.1F : -0.1F);
NaturesAuraAPI.instance().spawnMagicParticle(world, NaturesAuraAPI.instance().spawnMagicParticle(
message.posX + x, message.posY + 0.1F + world.rand.nextFloat() * 0.98F, message.posZ + z, message.posX + x, message.posY + 0.1F + world.rand.nextFloat() * 0.98F, message.posZ + z,
0F, 0F, 0F, 0F, 0F, 0F,
0xad7a37, world.rand.nextFloat() + 1F, 50, 0F, true, true); 0xad7a37, world.rand.nextFloat() + 1F, 50, 0F, true, true);
@ -191,7 +191,7 @@ public class PacketParticles implements IMessage {
break; break;
case 10: // Hopper upgrade picking up case 10: // Hopper upgrade picking up
for (int i = world.rand.nextInt(20) + 10; i >= 0; i--) for (int i = world.rand.nextInt(20) + 10; i >= 0; i--)
NaturesAuraAPI.instance().spawnMagicParticle(world, NaturesAuraAPI.instance().spawnMagicParticle(
message.posX, message.posY + 0.45F, message.posZ, message.posX, message.posY + 0.45F, message.posZ,
world.rand.nextGaussian() * 0.015F, world.rand.nextGaussian() * 0.015F,
world.rand.nextGaussian() * 0.015F, world.rand.nextGaussian() * 0.015F,
@ -201,7 +201,7 @@ public class PacketParticles implements IMessage {
case 11: // Shockwave creator particles case 11: // Shockwave creator particles
for (int i = 0; i < 360; i += 2) { for (int i = 0; i < 360; i += 2) {
double rad = Math.toRadians(i); double rad = Math.toRadians(i);
NaturesAuraAPI.instance().spawnMagicParticle(world, NaturesAuraAPI.instance().spawnMagicParticle(
message.posX, message.posY + 0.01F, message.posZ, message.posX, message.posY + 0.01F, message.posZ,
(float) Math.sin(rad) * 0.65F, (float) Math.sin(rad) * 0.65F,
0F, 0F,

View file

@ -4,7 +4,6 @@ import de.ellpeck.naturesaura.blocks.tiles.TileEntityNatureAltar;
import de.ellpeck.naturesaura.blocks.tiles.TileEntityWoodStand; import de.ellpeck.naturesaura.blocks.tiles.TileEntityWoodStand;
import de.ellpeck.naturesaura.blocks.tiles.render.RenderNatureAltar; import de.ellpeck.naturesaura.blocks.tiles.render.RenderNatureAltar;
import de.ellpeck.naturesaura.blocks.tiles.render.RenderWoodStand; import de.ellpeck.naturesaura.blocks.tiles.render.RenderWoodStand;
import de.ellpeck.naturesaura.compat.Compat;
import de.ellpeck.naturesaura.events.ClientEvents; import de.ellpeck.naturesaura.events.ClientEvents;
import de.ellpeck.naturesaura.particles.ParticleHandler; import de.ellpeck.naturesaura.particles.ParticleHandler;
import de.ellpeck.naturesaura.particles.ParticleMagic; import de.ellpeck.naturesaura.particles.ParticleMagic;
@ -19,7 +18,6 @@ import net.minecraft.client.renderer.color.ItemColors;
import net.minecraft.client.renderer.entity.RenderPlayer; import net.minecraft.client.renderer.entity.RenderPlayer;
import net.minecraft.item.Item; import net.minecraft.item.Item;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.world.World;
import net.minecraftforge.client.model.ModelLoader; import net.minecraftforge.client.model.ModelLoader;
import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.fml.client.registry.ClientRegistry; import net.minecraftforge.fml.client.registry.ClientRegistry;
@ -77,8 +75,11 @@ public class ClientProxy implements IProxy {
} }
@Override @Override
public void spawnMagicParticle(World world, double posX, double posY, double posZ, double motionX, double motionY, double motionZ, int color, float scale, int maxAge, float gravity, boolean collision, boolean fade) { public void spawnMagicParticle(double posX, double posY, double posZ, double motionX, double motionY, double motionZ, int color, float scale, int maxAge, float gravity, boolean collision, boolean fade) {
ParticleHandler.spawnParticle(() -> new ParticleMagic(world, posX, posY, posZ, motionX, motionY, motionZ, color, scale, maxAge, gravity, collision, fade), posX, posY, posZ, 32); ParticleHandler.spawnParticle(() -> new ParticleMagic(Minecraft.getMinecraft().world,
posX, posY, posZ,
motionX, motionY, motionZ,
color, scale, maxAge, gravity, collision, fade), posX, posY, posZ, 32);
} }
@Override @Override

View file

@ -23,7 +23,7 @@ public interface IProxy {
void addColorProvidingBlock(IColorProvidingBlock block); void addColorProvidingBlock(IColorProvidingBlock block);
void spawnMagicParticle(World world, double posX, double posY, double posZ, double motionX, double motionY, double motionZ, int color, float scale, int maxAge, float gravity, boolean collision, boolean fade); void spawnMagicParticle(double posX, double posY, double posZ, double motionX, double motionY, double motionZ, int color, float scale, int maxAge, float gravity, boolean collision, boolean fade);
void scheduleTask(Runnable runnable); void scheduleTask(Runnable runnable);
} }

View file

@ -43,7 +43,7 @@ public class ServerProxy implements IProxy {
} }
@Override @Override
public void spawnMagicParticle(World world, double posX, double posY, double posZ, double motionX, double motionY, double motionZ, int color, float scale, int maxAge, float gravity, boolean collision, boolean fade) { public void spawnMagicParticle(double posX, double posY, double posZ, double motionX, double motionY, double motionZ, int color, float scale, int maxAge, float gravity, boolean collision, boolean fade) {
} }

View file

@ -56,6 +56,11 @@ container.naturesaura.altar.name=Natural Altar Infusion
info.naturesaura.aura_in_area=Aura Around info.naturesaura.aura_in_area=Aura Around
info.naturesaura.book.landing=$(aura) is a complicated matter, and creating, collecting and making use of it can be difficult.$(br)The $(item)Book of Natural Aura$() contains all the information one requires to do so. info.naturesaura.book.landing=$(aura) is a complicated matter, and creating, collecting and making use of it can be difficult.$(br)The $(item)Book of Natural Aura$() contains all the information one requires to do so.
info.naturesaura.book.subtitle=The guide to Nature's Aura info.naturesaura.book.subtitle=The guide to Nature's Aura
info.naturesaura.stored_pos=You jotted down the position
info.naturesaura.connected=You made a connection
info.naturesaura.same_position=This seems to be the position from your notes...
info.naturesaura.too_far=The distance seems too great...
info.naturesaura.stored_pos_gone=Your notes seem out of date...
advancement.naturesaura.root=Nature's Aura advancement.naturesaura.root=Nature's Aura
advancement.naturesaura.root.desc=Becoming a magical botanist advancement.naturesaura.root.desc=Becoming a magical botanist