The great particle refactoring part 2: Splitting and Streamlining!
- Splits all particle textures into individual files intead of sprite sheets - Replaces arc and lightning pulse entities with particles - Pulls particle code up to the general ParticleWizardry so behaviours such as spin can be applied to all particle types - Renames a few ParticleBuilder methods for conciseness. - Adds a few new particle effects to various spells and entities, with a slight tweak to EntityMagicArrow#onBlockHit to facilitate impact effects
This commit is contained in:
@@ -70,8 +70,6 @@ public class CommonProxy {
|
|||||||
public void spawnTornadoParticle(World world, double x, double y, double z, double velX, double velZ, double radius,
|
public void spawnTornadoParticle(World world, double x, double y, double z, double velX, double velZ, double radius,
|
||||||
int maxAge, IBlockState block, BlockPos pos){
|
int maxAge, IBlockState block, BlockPos pos){
|
||||||
}
|
}
|
||||||
|
|
||||||
public void spawnEntityParticle(World world, Entity entity, int maxAge, float r, float g, float b){}
|
|
||||||
|
|
||||||
// SECTION Items
|
// SECTION Items
|
||||||
// ===============================================================================================================
|
// ===============================================================================================================
|
||||||
|
|||||||
@@ -206,22 +206,13 @@ public final class WizardryEventHandler {
|
|||||||
// Static Aura
|
// Static Aura
|
||||||
if(event.getEntityLiving().isPotionActive(WizardryPotions.static_aura)){
|
if(event.getEntityLiving().isPotionActive(WizardryPotions.static_aura)){
|
||||||
|
|
||||||
if(!world.isRemote){
|
if(world.isRemote){
|
||||||
EntityArc arc = new EntityArc(world);
|
|
||||||
arc.setEndpointCoords(event.getEntityLiving().posX, event.getEntityLiving().posY + 1,
|
ParticleBuilder.create(Type.LIGHTNING).entity(event.getEntity()).pos(0, event.getEntity().height/2, 0)
|
||||||
event.getEntityLiving().posZ, attacker.posX, attacker.posY + attacker.height / 2,
|
.target(attacker).spawn(world);
|
||||||
attacker.posZ);
|
|
||||||
world.spawnEntity(arc);
|
ParticleBuilder.spawnShockParticles(world, attacker.posX,
|
||||||
}else{
|
attacker.getEntityBoundingBox().minY + attacker.height, attacker.posZ);
|
||||||
for(int i = 0; i < 8; i++){
|
|
||||||
ParticleBuilder.create(Type.SPARK).pos(attacker.posX + world.rand.nextFloat() - 0.5,
|
|
||||||
attacker.getEntityBoundingBox().minY + attacker.height / 2 + world.rand.nextFloat() * 2 - 1,
|
|
||||||
attacker.posZ + world.rand.nextFloat() - 0.5).spawn(world);
|
|
||||||
world.spawnParticle(EnumParticleTypes.SMOKE_LARGE, attacker.posX + world.rand.nextFloat() - 0.5,
|
|
||||||
attacker.getEntityBoundingBox().minY + attacker.height / 2 + world.rand.nextFloat() * 2
|
|
||||||
- 1,
|
|
||||||
attacker.posZ + world.rand.nextFloat() - 0.5, 0, 0, 0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
attacker.attackEntityFrom(
|
attacker.attackEntityFrom(
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ public class BlockCrystalFlower extends BlockBush {
|
|||||||
if(world.isRemote && random.nextBoolean()){
|
if(world.isRemote && random.nextBoolean()){
|
||||||
ParticleBuilder.create(Type.SPARKLE)
|
ParticleBuilder.create(Type.SPARKLE)
|
||||||
.pos(pos.getX() + random.nextDouble(), pos.getY() + random.nextDouble() / 2 + 0.5, pos.getZ() + random.nextDouble()).vel(0, 0.01, 0)
|
.pos(pos.getX() + random.nextDouble(), pos.getY() + random.nextDouble() / 2 + 0.5, pos.getZ() + random.nextDouble()).vel(0, 0.01, 0)
|
||||||
.lifetime(20 + random.nextInt(10)).colour(0.5f + (random.nextFloat() / 2), 0.5f + (random.nextFloat() / 2),
|
.time(20 + random.nextInt(10)).clr(0.5f + (random.nextFloat() / 2), 0.5f + (random.nextFloat() / 2),
|
||||||
0.5f + (random.nextFloat() / 2)).spawn(world);
|
0.5f + (random.nextFloat() / 2)).spawn(world);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -70,9 +70,9 @@ public class BlockSpectral extends BlockContainer {
|
|||||||
// Top surface
|
// Top surface
|
||||||
for(int i=0; i<2; i++){
|
for(int i=0; i<2; i++){
|
||||||
ParticleBuilder.create(Type.DUST)
|
ParticleBuilder.create(Type.DUST)
|
||||||
.pos(pos.getX() + random.nextDouble(), pos.getY() + 1, pos.getZ() + random.nextDouble())
|
.pos(pos.getX() + random.nextDouble(), pos.getY() + random.nextDouble(), pos.getZ() + random.nextDouble())
|
||||||
.lifetime((int)(16.0D / (Math.random() * 0.8D + 0.2D)))
|
.time((int)(16.0D / (Math.random() * 0.8D + 0.2D)))
|
||||||
.colour(0.4f + random.nextFloat() * 0.2f, 0.6f + random.nextFloat() * 0.4f, 0.6f + random.nextFloat() * 0.4f)
|
.clr(0.4f + random.nextFloat() * 0.2f, 0.6f + random.nextFloat() * 0.4f, 0.6f + random.nextFloat() * 0.4f)
|
||||||
.shaded(true).spawn(world);
|
.shaded(true).spawn(world);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,25 +13,9 @@ import electroblob.wizardry.Wizardry;
|
|||||||
import electroblob.wizardry.client.gui.GuiSpellDisplay;
|
import electroblob.wizardry.client.gui.GuiSpellDisplay;
|
||||||
import electroblob.wizardry.client.gui.GuiWizardHandbook;
|
import electroblob.wizardry.client.gui.GuiWizardHandbook;
|
||||||
import electroblob.wizardry.client.model.ModelWizardArmour;
|
import electroblob.wizardry.client.model.ModelWizardArmour;
|
||||||
import electroblob.wizardry.client.particle.ParticleBlizzard;
|
import electroblob.wizardry.client.particle.*;
|
||||||
import electroblob.wizardry.client.particle.ParticleBuff;
|
|
||||||
import electroblob.wizardry.client.particle.ParticleDarkMagic;
|
|
||||||
import electroblob.wizardry.client.particle.ParticleDust;
|
|
||||||
import electroblob.wizardry.client.particle.ParticleFlash;
|
|
||||||
import electroblob.wizardry.client.particle.ParticleIce;
|
|
||||||
import electroblob.wizardry.client.particle.ParticleLeaf;
|
|
||||||
import electroblob.wizardry.client.particle.ParticleMagicBubble;
|
|
||||||
import electroblob.wizardry.client.particle.ParticleMagicFlame;
|
|
||||||
import electroblob.wizardry.client.particle.ParticlePath;
|
|
||||||
import electroblob.wizardry.client.particle.ParticleRotatingSparkle;
|
|
||||||
import electroblob.wizardry.client.particle.ParticleSnow;
|
|
||||||
import electroblob.wizardry.client.particle.ParticleSpark;
|
|
||||||
import electroblob.wizardry.client.particle.ParticleSparkle;
|
|
||||||
import electroblob.wizardry.client.particle.ParticleTornado;
|
|
||||||
import electroblob.wizardry.client.particle.ParticleWizardry;
|
|
||||||
import electroblob.wizardry.client.particle.ParticleWizardry.IWizardryParticleFactory;
|
import electroblob.wizardry.client.particle.ParticleWizardry.IWizardryParticleFactory;
|
||||||
import electroblob.wizardry.client.renderer.LayerStone;
|
import electroblob.wizardry.client.renderer.LayerStone;
|
||||||
import electroblob.wizardry.client.renderer.RenderArc;
|
|
||||||
import electroblob.wizardry.client.renderer.RenderArcaneWorkbench;
|
import electroblob.wizardry.client.renderer.RenderArcaneWorkbench;
|
||||||
import electroblob.wizardry.client.renderer.RenderBlackHole;
|
import electroblob.wizardry.client.renderer.RenderBlackHole;
|
||||||
import electroblob.wizardry.client.renderer.RenderBlank;
|
import electroblob.wizardry.client.renderer.RenderBlank;
|
||||||
@@ -45,7 +29,6 @@ import electroblob.wizardry.client.renderer.RenderHammer;
|
|||||||
import electroblob.wizardry.client.renderer.RenderIceGiant;
|
import electroblob.wizardry.client.renderer.RenderIceGiant;
|
||||||
import electroblob.wizardry.client.renderer.RenderIceSpike;
|
import electroblob.wizardry.client.renderer.RenderIceSpike;
|
||||||
import electroblob.wizardry.client.renderer.RenderLightningDisc;
|
import electroblob.wizardry.client.renderer.RenderLightningDisc;
|
||||||
import electroblob.wizardry.client.renderer.RenderLightningPulse;
|
|
||||||
import electroblob.wizardry.client.renderer.RenderMagicArrow;
|
import electroblob.wizardry.client.renderer.RenderMagicArrow;
|
||||||
import electroblob.wizardry.client.renderer.RenderMagicLight;
|
import electroblob.wizardry.client.renderer.RenderMagicLight;
|
||||||
import electroblob.wizardry.client.renderer.RenderPhoenix;
|
import electroblob.wizardry.client.renderer.RenderPhoenix;
|
||||||
@@ -55,7 +38,6 @@ import electroblob.wizardry.client.renderer.RenderSpiritHorse;
|
|||||||
import electroblob.wizardry.client.renderer.RenderSpiritWolf;
|
import electroblob.wizardry.client.renderer.RenderSpiritWolf;
|
||||||
import electroblob.wizardry.client.renderer.RenderStatue;
|
import electroblob.wizardry.client.renderer.RenderStatue;
|
||||||
import electroblob.wizardry.client.renderer.RenderWizard;
|
import electroblob.wizardry.client.renderer.RenderWizard;
|
||||||
import electroblob.wizardry.entity.EntityArc;
|
|
||||||
import electroblob.wizardry.entity.EntityShield;
|
import electroblob.wizardry.entity.EntityShield;
|
||||||
import electroblob.wizardry.entity.construct.EntityArrowRain;
|
import electroblob.wizardry.entity.construct.EntityArrowRain;
|
||||||
import electroblob.wizardry.entity.construct.EntityBlackHole;
|
import electroblob.wizardry.entity.construct.EntityBlackHole;
|
||||||
@@ -71,7 +53,6 @@ import electroblob.wizardry.entity.construct.EntityHailstorm;
|
|||||||
import electroblob.wizardry.entity.construct.EntityHammer;
|
import electroblob.wizardry.entity.construct.EntityHammer;
|
||||||
import electroblob.wizardry.entity.construct.EntityHealAura;
|
import electroblob.wizardry.entity.construct.EntityHealAura;
|
||||||
import electroblob.wizardry.entity.construct.EntityIceSpike;
|
import electroblob.wizardry.entity.construct.EntityIceSpike;
|
||||||
import electroblob.wizardry.entity.construct.EntityLightningPulse;
|
|
||||||
import electroblob.wizardry.entity.construct.EntityLightningSigil;
|
import electroblob.wizardry.entity.construct.EntityLightningSigil;
|
||||||
import electroblob.wizardry.entity.construct.EntityTornado;
|
import electroblob.wizardry.entity.construct.EntityTornado;
|
||||||
import electroblob.wizardry.entity.living.EntityDecoy;
|
import electroblob.wizardry.entity.living.EntityDecoy;
|
||||||
@@ -291,27 +272,30 @@ public class ClientProxy extends CommonProxy {
|
|||||||
public void initParticleFactories(){
|
public void initParticleFactories(){
|
||||||
|
|
||||||
factories = new HashMap<>();
|
factories = new HashMap<>();
|
||||||
|
|
||||||
factories.put(Type.BLIZZARD, (world, x, y, z) -> new ParticleBlizzard(world, x, y, z));
|
factories.put(Type.BEAM, ParticleBeam::new);
|
||||||
factories.put(Type.DARK_MAGIC, (world, x, y, z) -> new ParticleDarkMagic(world, x, y, z));
|
factories.put(Type.BUFF, ParticleBuff::new);
|
||||||
factories.put(Type.DUST, (world, x, y, z) -> new ParticleDust(world, x, y, z));
|
factories.put(Type.DARK_MAGIC, ParticleDarkMagic::new);
|
||||||
factories.put(Type.FLASH, (world, x, y, z) -> new ParticleFlash(world, x, y, z));
|
factories.put(Type.DUST, ParticleDust::new);
|
||||||
factories.put(Type.ICE, (world, x, y, z) -> new ParticleIce(world, x, y, z));
|
factories.put(Type.FLASH, ParticleFlash::new);
|
||||||
factories.put(Type.LEAF, (world, x, y, z) -> new ParticleLeaf(world, x, y, z));
|
factories.put(Type.ICE, ParticleIce::new);
|
||||||
factories.put(Type.MAGIC_BUBBLE, (world, x, y, z) -> new ParticleMagicBubble(world, x, y, z));
|
factories.put(Type.LEAF, ParticleLeaf::new);
|
||||||
factories.put(Type.MAGIC_FIRE, (world, x, y, z) -> new ParticleMagicFlame(world, x, y, z));
|
factories.put(Type.LIGHTNING, ParticleLightning::new);
|
||||||
factories.put(Type.PATH, (world, x, y, z) -> new ParticlePath(world, x, y, z));
|
factories.put(Type.LIGHTNING_PULSE, ParticleLightningPulse::new);
|
||||||
factories.put(Type.SNOW, (world, x, y, z) -> new ParticleSnow(world, x, y, z));
|
factories.put(Type.MAGIC_BUBBLE, ParticleMagicBubble::new);
|
||||||
factories.put(Type.SPARK, (world, x, y, z) -> new ParticleSpark(world, x, y, z));
|
factories.put(Type.MAGIC_FIRE, ParticleMagicFlame::new);
|
||||||
factories.put(Type.SPARKLE, (world, x, y, z) -> new ParticleSparkle(world, x, y, z));
|
factories.put(Type.PATH, ParticlePath::new);
|
||||||
factories.put(Type.SPARKLE_ROTATING, (world, x, y, z) -> new ParticleRotatingSparkle(world, x, y, z));
|
factories.put(Type.SCORCH, ParticleScorch::new);
|
||||||
|
factories.put(Type.SNOW, ParticleSnow::new);
|
||||||
|
factories.put(Type.SPARK, ParticleSpark::new);
|
||||||
|
factories.put(Type.SPARKLE, ParticleSparkle::new);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ParticleWizardry createParticle(Type type, World world, double x, double y, double z){
|
public ParticleWizardry createParticle(Type type, World world, double x, double y, double z){
|
||||||
IWizardryParticleFactory factory = factories.get(type);
|
IWizardryParticleFactory factory = factories.get(type);
|
||||||
if(factory == null){
|
if(factory == null){
|
||||||
Wizardry.logger.warn("Unrecognised particle type %s! Ensure the particle is properly registered.", type);
|
Wizardry.logger.warn("Unrecognised particle type %s ! Ensure the particle is properly registered.", type);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return factory.createParticle(world, x, y, z);
|
return factory.createParticle(world, x, y, z);
|
||||||
@@ -431,8 +415,8 @@ public class ClientProxy extends CommonProxy {
|
|||||||
double x = caster.posX + radius * Math.cos(angle);
|
double x = caster.posX + radius * Math.cos(angle);
|
||||||
double y = caster.getEntityBoundingBox().minY + world.rand.nextDouble() * 2;
|
double y = caster.getEntityBoundingBox().minY + world.rand.nextDouble() * 2;
|
||||||
double z = caster.posZ + radius * Math.sin(angle);
|
double z = caster.posZ + radius * Math.sin(angle);
|
||||||
ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).vel(0, 0.02, 0).colour(0.6f, 1, 0.6f)
|
ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).vel(0, 0.02, 0).clr(0.6f, 1, 0.6f)
|
||||||
.lifetime(80 + world.rand.nextInt(10)).spawn(world);
|
.time(80 + world.rand.nextInt(10)).spawn(world);
|
||||||
}
|
}
|
||||||
for(int i = 0; i < 20; i++){
|
for(int i = 0; i < 20; i++){
|
||||||
double radius = 1;
|
double radius = 1;
|
||||||
@@ -578,7 +562,6 @@ public class ClientProxy extends CommonProxy {
|
|||||||
manager -> new RenderProjectile(manager, 0.6f, new ResourceLocation(Wizardry.MODID, "textures/items/smoke_bomb.png"), false));
|
manager -> new RenderProjectile(manager, 0.6f, new ResourceLocation(Wizardry.MODID, "textures/items/smoke_bomb.png"), false));
|
||||||
|
|
||||||
// Effects and constructs
|
// Effects and constructs
|
||||||
RenderingRegistry.registerEntityRenderingHandler(EntityArc.class, RenderArc::new);
|
|
||||||
RenderingRegistry.registerEntityRenderingHandler(EntityBlackHole.class, RenderBlackHole::new);
|
RenderingRegistry.registerEntityRenderingHandler(EntityBlackHole.class, RenderBlackHole::new);
|
||||||
RenderingRegistry.registerEntityRenderingHandler(EntityShield.class, RenderBlank::new);
|
RenderingRegistry.registerEntityRenderingHandler(EntityShield.class, RenderBlank::new);
|
||||||
RenderingRegistry.registerEntityRenderingHandler(EntityBubble.class, RenderBubble::new);
|
RenderingRegistry.registerEntityRenderingHandler(EntityBubble.class, RenderBubble::new);
|
||||||
@@ -608,7 +591,6 @@ public class ClientProxy extends CommonProxy {
|
|||||||
RenderingRegistry.registerEntityRenderingHandler(EntityFireRing.class,
|
RenderingRegistry.registerEntityRenderingHandler(EntityFireRing.class,
|
||||||
manager -> new RenderFireRing(manager, new ResourceLocation(Wizardry.MODID, "textures/entity/ring_of_fire.png"), 5.0f));
|
manager -> new RenderFireRing(manager, new ResourceLocation(Wizardry.MODID, "textures/entity/ring_of_fire.png"), 5.0f));
|
||||||
RenderingRegistry.registerEntityRenderingHandler(EntityDecay.class, RenderDecay::new);
|
RenderingRegistry.registerEntityRenderingHandler(EntityDecay.class, RenderDecay::new);
|
||||||
RenderingRegistry.registerEntityRenderingHandler(EntityLightningPulse.class, manager -> new RenderLightningPulse(manager, 8.0f));
|
|
||||||
|
|
||||||
// TESRs
|
// TESRs
|
||||||
ClientRegistry.bindTileEntitySpecialRenderer(TileEntityArcaneWorkbench.class, new RenderArcaneWorkbench());
|
ClientRegistry.bindTileEntitySpecialRenderer(TileEntityArcaneWorkbench.class, new RenderArcaneWorkbench());
|
||||||
|
|||||||
@@ -0,0 +1,95 @@
|
|||||||
|
package electroblob.wizardry.client.particle;
|
||||||
|
|
||||||
|
import org.lwjgl.opengl.GL11;
|
||||||
|
|
||||||
|
import net.minecraft.client.renderer.BufferBuilder;
|
||||||
|
import net.minecraft.client.renderer.GlStateManager;
|
||||||
|
import net.minecraft.client.renderer.OpenGlHelper;
|
||||||
|
import net.minecraft.client.renderer.Tessellator;
|
||||||
|
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
|
public class ParticleBeam extends ParticleTargeted {
|
||||||
|
|
||||||
|
/** Half the width of the outermost layer. */
|
||||||
|
private static final float THICKNESS = 0.1f;
|
||||||
|
|
||||||
|
public ParticleBeam(World world, double x, double y, double z){
|
||||||
|
super(world, x, y, z); // Does not have a texture!
|
||||||
|
this.setRBGColorF(1, 1, 1);
|
||||||
|
this.setMaxAge(1);
|
||||||
|
this.particleScale = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getFXLayer(){
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void draw(Tessellator tessellator, double length, float partialTicks){
|
||||||
|
|
||||||
|
float scale = this.particleScale;
|
||||||
|
|
||||||
|
if(this.particleMaxAge > 1){
|
||||||
|
float ageFraction = (particleAge + partialTicks - 1)/particleMaxAge;
|
||||||
|
// Squaring this makes it look smoother than a linear shrinking effect
|
||||||
|
scale = this.particleScale * (1 - ageFraction*ageFraction);
|
||||||
|
}
|
||||||
|
|
||||||
|
GlStateManager.disableLighting();
|
||||||
|
GlStateManager.enableBlend();
|
||||||
|
GlStateManager.disableTexture2D();
|
||||||
|
GlStateManager.blendFunc(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE);
|
||||||
|
OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240f, 240f);
|
||||||
|
|
||||||
|
for(int layer=0; layer<3; layer++){
|
||||||
|
drawSegment(tessellator, layer, 0, 0, 0, 0, 0, length, THICKNESS * scale);
|
||||||
|
}
|
||||||
|
|
||||||
|
GlStateManager.enableTexture2D();
|
||||||
|
GlStateManager.enableLighting();
|
||||||
|
GlStateManager.disableBlend();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Draws the given layer of a segment of the arc, from the point (x1, y1, z1) to the point (x2, y2, z2), with the given thickness. */
|
||||||
|
private void drawSegment(Tessellator tessellator, int layer, double x1, double y1, double z1, double x2, double y2, double z2, float thickness){
|
||||||
|
|
||||||
|
BufferBuilder buffer = tessellator.getBuffer();
|
||||||
|
buffer.begin(GL11.GL_TRIANGLE_STRIP, DefaultVertexFormats.POSITION_COLOR);
|
||||||
|
|
||||||
|
switch(layer){
|
||||||
|
|
||||||
|
case 0:
|
||||||
|
drawShearedBox(buffer, x1, y1, z1, x2, y2, z2, 0.25f*thickness, 1, 1, 1, 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
drawShearedBox(buffer, x1, y1, z1, x2, y2, z2, 0.6f*thickness, (particleRed + 1)/2, (particleGreen + 1)/2,
|
||||||
|
(particleBlue + 1)/2, 0.65f);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
drawShearedBox(buffer, x1, y1, z1, x2, y2, z2, thickness, particleRed, particleGreen, particleBlue, 0.3f);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
tessellator.draw();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Draws a single box for one segment of the arc, from the point (x1, y1, z1) to the point (x2, y2, z2), with given width and colour. */
|
||||||
|
private void drawShearedBox(BufferBuilder buffer, double x1, double y1, double z1, double x2, double y2, double z2, float width, float r, float g, float b, float a){
|
||||||
|
|
||||||
|
buffer.pos(x1-width, y1-width, z1).color(r, g, b, a).endVertex();
|
||||||
|
buffer.pos(x2-width, y2-width, z2).color(r, g, b, a).endVertex();
|
||||||
|
buffer.pos(x1-width, y1+width, z1).color(r, g, b, a).endVertex();
|
||||||
|
buffer.pos(x2-width, y2+width, z2).color(r, g, b, a).endVertex();
|
||||||
|
buffer.pos(x1+width, y1+width, z1).color(r, g, b, a).endVertex();
|
||||||
|
buffer.pos(x2+width, y2+width, z2).color(r, g, b, a).endVertex();
|
||||||
|
buffer.pos(x1+width, y1-width, z1).color(r, g, b, a).endVertex();
|
||||||
|
buffer.pos(x2+width, y2-width, z2).color(r, g, b, a).endVertex();
|
||||||
|
buffer.pos(x1-width, y1-width, z1).color(r, g, b, a).endVertex();
|
||||||
|
buffer.pos(x2-width, y2-width, z2).color(r, g, b, a).endVertex();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,67 +0,0 @@
|
|||||||
package electroblob.wizardry.client.particle;
|
|
||||||
|
|
||||||
import net.minecraft.world.World;
|
|
||||||
import net.minecraftforge.fml.relauncher.Side;
|
|
||||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
|
||||||
|
|
||||||
@SideOnly(Side.CLIENT)
|
|
||||||
public class ParticleBlizzard extends ParticleSnow {
|
|
||||||
|
|
||||||
private double angle;
|
|
||||||
private double radius;
|
|
||||||
private double speed;
|
|
||||||
|
|
||||||
public ParticleBlizzard(World world, double ox, double y, double oz){
|
|
||||||
super(world, ox, y, oz);
|
|
||||||
this.angle = this.rand.nextDouble() * Math.PI * 2;
|
|
||||||
double x = ox - Math.cos(angle) * radius;
|
|
||||||
double z = oz + radius * Math.sin(angle);
|
|
||||||
this.setPosition(x, y, z);
|
|
||||||
this.prevPosX = x;
|
|
||||||
this.prevPosY = y;
|
|
||||||
this.prevPosZ = z;
|
|
||||||
if(rand.nextBoolean()){
|
|
||||||
speed = rand.nextDouble() * 2 + 1;
|
|
||||||
}else{
|
|
||||||
speed = rand.nextDouble() * -2 - 1;
|
|
||||||
}
|
|
||||||
this.multipleParticleScaleBy(1.5f);
|
|
||||||
}
|
|
||||||
|
|
||||||
// @Override
|
|
||||||
// public void renderParticle(VertexBuffer buffer, Entity entity, float partialTicks, float rotationX, float
|
|
||||||
// rotationZ, float rotationYZ, float rotationXY, float rotationXZ){
|
|
||||||
// if(this.particleAge < this.particleMaxAge / 3 || (this.particleAge + this.particleMaxAge) / 3 % 2 == 0){
|
|
||||||
// super.renderParticle(buffer, entity, partialTicks, rotationX, rotationZ, rotationYZ, rotationXY, rotationXZ);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onUpdate(){
|
|
||||||
|
|
||||||
this.prevPosX = this.posX;
|
|
||||||
this.prevPosY = this.posY;
|
|
||||||
this.prevPosZ = this.posZ;
|
|
||||||
|
|
||||||
if(this.particleAge++ >= this.particleMaxAge){
|
|
||||||
this.setExpired();
|
|
||||||
}
|
|
||||||
|
|
||||||
// This is in radians per tick...
|
|
||||||
double omega = Math.signum(speed) * ((Math.PI * 2) / 20 - speed / (20 * radius));
|
|
||||||
|
|
||||||
// v = r times omega; therefore the normalised velocity vector needs to be r times the angle increment / 2 pi.
|
|
||||||
this.angle += omega;
|
|
||||||
|
|
||||||
this.motionY -= 0.04D * (double)this.particleGravity;
|
|
||||||
this.motionZ = radius * omega * Math.cos(angle);
|
|
||||||
this.motionX = radius * omega * Math.sin(angle);
|
|
||||||
this.move(motionX, motionY, motionZ);
|
|
||||||
|
|
||||||
if(this.particleAge > this.particleMaxAge / 2){
|
|
||||||
this.setAlphaF(
|
|
||||||
1.0F - ((float)this.particleAge - (float)(this.particleMaxAge / 2)) / (float)this.particleMaxAge);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -21,36 +21,41 @@ import net.minecraftforge.fml.relauncher.Side;
|
|||||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
import net.minecraftforge.fml.relauncher.SideOnly;
|
||||||
|
|
||||||
@SideOnly(Side.CLIENT)
|
@SideOnly(Side.CLIENT)
|
||||||
public class ParticleBuff extends ParticleEntityLinked {
|
public class ParticleBuff extends ParticleWizardry {
|
||||||
|
|
||||||
private static final ResourceLocation TEXTURE = new ResourceLocation(Wizardry.MODID, "textures/particle/buff.png");
|
private static final ResourceLocation TEXTURE = new ResourceLocation(Wizardry.MODID, "textures/particle/buff.png");
|
||||||
private final boolean mirror;
|
private final boolean mirror;
|
||||||
|
|
||||||
public ParticleBuff(World world, Entity entity, float r, float g, float b, boolean mirror){
|
public ParticleBuff(World world, double x, double y, double z){
|
||||||
super(world, entity);
|
super(world, x, y, z);
|
||||||
this.setRBGColorF(r, g, b);
|
this.setVelocity(0, 0.27, 0); // Approximately what it was before
|
||||||
this.mirror = mirror;
|
this.mirror = world.rand.nextBoolean();
|
||||||
}
|
this.setMaxAge(15);
|
||||||
|
this.setGravity(false);
|
||||||
public ParticleBuff(World world, Entity entity, int maxAge, float r, float g, float b, boolean mirror){
|
this.canCollide = false;
|
||||||
super(world, entity, maxAge);
|
|
||||||
this.setRBGColorF(r, g, b);
|
|
||||||
this.mirror = mirror;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void init(){
|
|
||||||
this.particleGravity = 0;
|
|
||||||
this.posY += 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onUpdate(){
|
public void onUpdate(){
|
||||||
super.onUpdate();
|
super.onUpdate();
|
||||||
this.setPosition(this.entity.posX, this.entity.posY + 1 + 4f * this.particleAge/this.particleMaxAge, this.entity.posZ);
|
|
||||||
if(this.particleAge > this.particleMaxAge/2) this.particleAlpha = 2f - 2f*(float)this.particleAge/(float)this.particleMaxAge;
|
if(this.particleAge > this.particleMaxAge/2) this.particleAlpha = 2f - 2f*(float)this.particleAge/(float)this.particleMaxAge;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* There are 4 layers of particles, specified as 0-3 by the method below. - Layer 0 causes the normal particles.png
|
||||||
|
* to be bound to the render engine for normal particles. - Layer 1 causes the block textures to be bound to the
|
||||||
|
* render engine for digging fx and falling fx. - Layer 2 causes the item textures to be bound to the render engine
|
||||||
|
* for tool breaking fx, snowballpoofs, slime particles, etc. - Layer 3 is not used in vanilla minecraft and was
|
||||||
|
* presumably added by forge for exactly this reason. This means no texture is bound by vanilla minecraft, meaning
|
||||||
|
* you are free to do as you wish without possibly overwriting vanilla particles. Mod particles won't be overwritten
|
||||||
|
* anyway since they bind their own textures. It is of course important to bind the texture every time you render a
|
||||||
|
* custom particle, but I don't see how you could do it any other way, since you don't have access to
|
||||||
|
* EffectRenderer. */
|
||||||
|
@Override
|
||||||
|
public int getFXLayer(){
|
||||||
|
// This can only be 0-3 or it will cause an ArrayIndexOutOfBoundsException in EffectRenderer.
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void renderParticle(BufferBuilder buffer, Entity viewer, float partialTicks, float rotationX, float rotationZ,
|
public void renderParticle(BufferBuilder buffer, Entity viewer, float partialTicks, float rotationX, float rotationZ,
|
||||||
float rotationYZ, float rotationXY, float rotationXZ){
|
float rotationYZ, float rotationXY, float rotationXZ){
|
||||||
|
|||||||
@@ -1,130 +0,0 @@
|
|||||||
package electroblob.wizardry.client.particle;
|
|
||||||
|
|
||||||
import org.lwjgl.opengl.GL11;
|
|
||||||
|
|
||||||
import net.minecraft.client.Minecraft;
|
|
||||||
import net.minecraft.client.particle.Particle;
|
|
||||||
import net.minecraft.client.renderer.BufferBuilder;
|
|
||||||
import net.minecraft.client.renderer.GlStateManager;
|
|
||||||
import net.minecraft.client.renderer.OpenGlHelper;
|
|
||||||
import net.minecraft.client.renderer.RenderHelper;
|
|
||||||
import net.minecraft.client.renderer.Tessellator;
|
|
||||||
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
|
|
||||||
import net.minecraft.entity.Entity;
|
|
||||||
import net.minecraft.util.ResourceLocation;
|
|
||||||
import net.minecraft.world.World;
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public abstract class ParticleCustomTexture extends ParticleWizardry {
|
|
||||||
|
|
||||||
public ParticleCustomTexture(World world, double x, double y, double z){
|
|
||||||
super(world, x, y, z);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a ResourceLocation for the particle's texture sheet. Do not create a new ResourceLocation in this method,
|
|
||||||
* only return a constant.
|
|
||||||
*/
|
|
||||||
public abstract ResourceLocation getTexture();
|
|
||||||
|
|
||||||
/** Returns how many 'frames' there are in the x direction on the texture. */
|
|
||||||
protected abstract int getXFrames();
|
|
||||||
|
|
||||||
/** Returns how many 'frames' there are in the y direction on the texture. */
|
|
||||||
protected abstract int getYFrames();
|
|
||||||
|
|
||||||
/* There are 4 layers of particles, specified as 0-3 by the method below. - Layer 0 causes the normal particles.png
|
|
||||||
* to be bound to the render engine for normal particles. - Layer 1 causes the block textures to be bound to the
|
|
||||||
* render engine for digging fx and falling fx. - Layer 2 causes the item textures to be bound to the render engine
|
|
||||||
* for tool breaking fx, snowballpoofs, slime particles, etc. - Layer 3 is not used in vanilla minecraft and was
|
|
||||||
* presumably added by forge for exactly this reason. This means no texture is bound by vanilla minecraft, meaning
|
|
||||||
* you are free to do as you wish without possibly overwriting vanilla particles. Mod particles won't be overwritten
|
|
||||||
* anyway since they bind their own textures. It is of course important to bind the texture every time you render a
|
|
||||||
* custom particle, but I don't see how you could do it any other way, since you don't have access to
|
|
||||||
* EffectRenderer. */
|
|
||||||
@Override
|
|
||||||
public int getFXLayer(){
|
|
||||||
// This can only be 0-3 or it will cause an ArrayIndexOutOfBoundsException in EffectRenderer.
|
|
||||||
return 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setParticleTextureIndex(int index){
|
|
||||||
this.particleTextureIndexX = index % getXFrames();
|
|
||||||
this.particleTextureIndexY = index / getYFrames();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Overridden to bind the new texture. I think this can be done with TextureAtlasSprite, but this works as it is
|
|
||||||
// so I'm not changing it for the time being.
|
|
||||||
@Override
|
|
||||||
public void renderParticle(BufferBuilder buffer, Entity viewer, float partialTicks, float rotationX, float rotationZ,
|
|
||||||
float rotationYZ, float rotationXY, float rotationXZ){
|
|
||||||
|
|
||||||
GlStateManager.pushMatrix();
|
|
||||||
|
|
||||||
this.applyGLStateChanges();
|
|
||||||
|
|
||||||
// This stuff does the shading. It vanilla does this later on for each point, but this also seems to work.
|
|
||||||
int brightness = this.getBrightnessForRender(partialTicks);
|
|
||||||
int lightmapX = brightness % 65536;
|
|
||||||
int lightmapY = brightness / 65536;
|
|
||||||
OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, (float)lightmapX / 1.0F,
|
|
||||||
(float)lightmapY / 1.0F);
|
|
||||||
|
|
||||||
RenderHelper.disableStandardItemLighting();
|
|
||||||
|
|
||||||
Minecraft.getMinecraft().getTextureManager().bindTexture(getTexture());
|
|
||||||
|
|
||||||
buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX_COLOR);
|
|
||||||
|
|
||||||
float u1 = (float)this.particleTextureIndexX / (float)getXFrames();
|
|
||||||
float u2 = u1 + 1.0f / getXFrames();
|
|
||||||
float v1 = (float)this.particleTextureIndexY / (float)getYFrames();
|
|
||||||
float v2 = v1 + 1.0f / getYFrames();
|
|
||||||
float scale = 0.1F * this.particleScale;
|
|
||||||
|
|
||||||
// I'm pretty sure these were always static.
|
|
||||||
Particle.interpPosX = viewer.lastTickPosX + (viewer.posX - viewer.lastTickPosX) * (double)partialTicks;
|
|
||||||
Particle.interpPosY = viewer.lastTickPosY + (viewer.posY - viewer.lastTickPosY) * (double)partialTicks;
|
|
||||||
Particle.interpPosZ = viewer.lastTickPosZ + (viewer.posZ - viewer.lastTickPosZ) * (double)partialTicks;
|
|
||||||
|
|
||||||
float x = (float)(this.prevPosX + (this.posX - this.prevPosX) * (double)partialTicks - interpPosX);
|
|
||||||
float y = (float)(this.prevPosY + (this.posY - this.prevPosY) * (double)partialTicks - interpPosY);
|
|
||||||
float z = (float)(this.prevPosZ + (this.posZ - this.prevPosZ) * (double)partialTicks - interpPosZ);
|
|
||||||
|
|
||||||
buffer.pos((double)(x - rotationX * scale - rotationXY * scale), (double)(y - rotationZ * scale),
|
|
||||||
(double)(z - rotationYZ * scale - rotationXZ * scale)).tex(u2, v2)
|
|
||||||
.color(particleRed, particleGreen, particleBlue, particleAlpha).endVertex();
|
|
||||||
buffer.pos((double)(x - rotationX * scale + rotationXY * scale), (double)(y + rotationZ * scale),
|
|
||||||
(double)(z - rotationYZ * scale + rotationXZ * scale)).tex(u2, v1)
|
|
||||||
.color(particleRed, particleGreen, particleBlue, particleAlpha).endVertex();
|
|
||||||
buffer.pos((double)(x + rotationX * scale + rotationXY * scale), (double)(y + rotationZ * scale),
|
|
||||||
(double)(z + rotationYZ * scale + rotationXZ * scale)).tex(u1, v1)
|
|
||||||
.color(particleRed, particleGreen, particleBlue, particleAlpha).endVertex();
|
|
||||||
buffer.pos((double)(x + rotationX * scale - rotationXY * scale), (double)(y - rotationZ * scale),
|
|
||||||
(double)(z + rotationYZ * scale - rotationXZ * scale)).tex(u1, v2)
|
|
||||||
.color(particleRed, particleGreen, particleBlue, particleAlpha).endVertex();
|
|
||||||
;
|
|
||||||
|
|
||||||
Tessellator.getInstance().draw();
|
|
||||||
|
|
||||||
this.undoGLStateChanges();
|
|
||||||
|
|
||||||
GlStateManager.popMatrix();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Override to add any GL state changes, like blending. Does nothing by default. <b>State changes should be done
|
|
||||||
* using GLStateManager, not using GL11 directly</b> (as is the case with all rendering code now).
|
|
||||||
*/
|
|
||||||
public void applyGLStateChanges(){
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Override to undo any GL state changes, like blending. Does nothing by default. <b>State changes should be done
|
|
||||||
* using GLStateManager, not using GL11 directly</b> (as is the case with all rendering code now).
|
|
||||||
*/
|
|
||||||
public void undoGLStateChanges(){
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,61 +0,0 @@
|
|||||||
package electroblob.wizardry.client.particle;
|
|
||||||
|
|
||||||
import net.minecraft.client.particle.Particle;
|
|
||||||
import net.minecraft.entity.Entity;
|
|
||||||
import net.minecraft.world.World;
|
|
||||||
import net.minecraftforge.fml.relauncher.Side;
|
|
||||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Abstract superclass for particles that are linked to entities, i.e. move with a given entity. This is generally used
|
|
||||||
* for visual effects in spell casting.
|
|
||||||
*
|
|
||||||
* @author Electroblob
|
|
||||||
* @since Wizardry 4.2
|
|
||||||
*/
|
|
||||||
@SideOnly(Side.CLIENT)
|
|
||||||
public abstract class ParticleEntityLinked extends Particle {
|
|
||||||
|
|
||||||
/** True if the particle always renders at full brightness. Defaults to false. */
|
|
||||||
protected boolean fullBrightness = false;
|
|
||||||
|
|
||||||
/** The entity this particle is linked to. The particle will move with this entity. */
|
|
||||||
protected Entity entity;
|
|
||||||
|
|
||||||
public ParticleEntityLinked(World world, Entity entity){
|
|
||||||
super(world, entity.posX, entity.posY, entity.posZ, entity.motionX, entity.motionY, entity.motionZ);
|
|
||||||
this.entity = entity;
|
|
||||||
this.init();
|
|
||||||
}
|
|
||||||
|
|
||||||
public ParticleEntityLinked(World world, Entity entity, int maxAge){
|
|
||||||
this(world, entity);
|
|
||||||
this.particleMaxAge = maxAge;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called from both constructors to set constants, avoiding duplicate code. Common fields to set here include:
|
|
||||||
* particleScale, particleGravity, canCollide, fullBrightness and setting the texture index.
|
|
||||||
*/
|
|
||||||
public abstract void init();
|
|
||||||
|
|
||||||
/* There are 4 layers of particles, specified as 0-3 by the method below. - Layer 0 causes the normal particles.png
|
|
||||||
* to be bound to the render engine for normal particles. - Layer 1 causes the block textures to be bound to the
|
|
||||||
* render engine for digging fx and falling fx. - Layer 2 causes the item textures to be bound to the render engine
|
|
||||||
* for tool breaking fx, snowballpoofs, slime particles, etc. - Layer 3 is not used in vanilla minecraft and was
|
|
||||||
* presumably added by forge for exactly this reason. This means no texture is bound by vanilla minecraft, meaning
|
|
||||||
* you are free to do as you wish without possibly overwriting vanilla particles. Mod particles won't be overwritten
|
|
||||||
* anyway since they bind their own textures. It is of course important to bind the texture every time you render a
|
|
||||||
* custom particle, but I don't see how you could do it any other way, since you don't have access to
|
|
||||||
* EffectRenderer. */
|
|
||||||
@Override
|
|
||||||
public int getFXLayer(){
|
|
||||||
// This can only be 0-3 or it will cause an ArrayIndexOutOfBoundsException in EffectRenderer.
|
|
||||||
return 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getBrightnessForRender(float partialTick){
|
|
||||||
return fullBrightness ? 15728880 : super.getBrightnessForRender(partialTick);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -17,13 +17,13 @@ public class ParticleFlash extends ParticleWizardry {
|
|||||||
super(world, x, y, z);
|
super(world, x, y, z);
|
||||||
this.setRBGColorF(1, 1, 1);
|
this.setRBGColorF(1, 1, 1);
|
||||||
this.particleScale = 0.6f; // 7.1f is the value used in fireworks
|
this.particleScale = 0.6f; // 7.1f is the value used in fireworks
|
||||||
this.particleMaxAge = 4;
|
this.particleMaxAge = 6;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void renderParticle(BufferBuilder buffer, Entity entityIn, float partialTicks, float rotationX, float rotationZ, float rotationYZ, float rotationXY, float rotationXZ){
|
public void renderParticle(BufferBuilder buffer, Entity entityIn, float partialTicks, float rotationX, float rotationZ, float rotationYZ, float rotationXY, float rotationXZ){
|
||||||
float f4 = particleScale * MathHelper.sin(((float)this.particleAge + partialTicks - 1.0F) * 0.25F * (float)Math.PI);
|
float f4 = particleScale * MathHelper.sin(((float)this.particleAge + partialTicks - 1.0F)/particleMaxAge * (float)Math.PI);
|
||||||
this.setAlphaF(0.6F - ((float)this.particleAge + partialTicks - 1.0F) * 0.25F * 0.5F);
|
this.setAlphaF(0.6F - ((float)this.particleAge + partialTicks - 1.0F)/particleMaxAge * 0.5F);
|
||||||
float f5 = (float)(this.prevPosX + (this.posX - this.prevPosX) * (double)partialTicks - interpPosX);
|
float f5 = (float)(this.prevPosX + (this.posX - this.prevPosX) * (double)partialTicks - interpPosX);
|
||||||
float f6 = (float)(this.prevPosY + (this.posY - this.prevPosY) * (double)partialTicks - interpPosY);
|
float f6 = (float)(this.prevPosY + (this.posY - this.prevPosY) * (double)partialTicks - interpPosY);
|
||||||
float f7 = (float)(this.prevPosZ + (this.posZ - this.prevPosZ) * (double)partialTicks - interpPosZ);
|
float f7 = (float)(this.prevPosZ + (this.posZ - this.prevPosZ) * (double)partialTicks - interpPosZ);
|
||||||
|
|||||||
@@ -1,40 +1,36 @@
|
|||||||
package electroblob.wizardry.client.particle;
|
package electroblob.wizardry.client.particle;
|
||||||
|
|
||||||
import electroblob.wizardry.Wizardry;
|
|
||||||
import net.minecraft.util.ResourceLocation;
|
import net.minecraft.util.ResourceLocation;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
import net.minecraftforge.client.event.TextureStitchEvent;
|
||||||
|
import net.minecraftforge.fml.common.Mod;
|
||||||
|
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
||||||
import net.minecraftforge.fml.relauncher.Side;
|
import net.minecraftforge.fml.relauncher.Side;
|
||||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
import net.minecraftforge.fml.relauncher.SideOnly;
|
||||||
|
|
||||||
@SideOnly(Side.CLIENT)
|
@SideOnly(Side.CLIENT)
|
||||||
public class ParticleIce extends ParticleCustomTexture {
|
@Mod.EventBusSubscriber(Side.CLIENT)
|
||||||
|
public class ParticleIce extends ParticleWizardry {
|
||||||
private static final ResourceLocation TEXTURE = new ResourceLocation(Wizardry.MODID, "textures/particle/ice_particles.png");
|
|
||||||
|
|
||||||
|
private static final ResourceLocation[] TEXTURES = generateTextures("ice", 8);
|
||||||
|
|
||||||
public ParticleIce(World world, double x, double y, double z){
|
public ParticleIce(World world, double x, double y, double z){
|
||||||
super(world, x, y, z);
|
|
||||||
|
|
||||||
this.setParticleTextureIndex(rand.nextInt(8));
|
super(world, x, y, z, TEXTURES[world.rand.nextInt(TEXTURES.length)]);
|
||||||
|
|
||||||
this.canCollide = true;
|
this.canCollide = true;
|
||||||
|
|
||||||
// Defaults
|
// Defaults
|
||||||
|
this.setRBGColorF(1, 1, 1);
|
||||||
this.particleScale *= 0.75f;
|
this.particleScale *= 0.75f;
|
||||||
this.setGravity(true);
|
this.setGravity(true);
|
||||||
this.shaded = false;
|
this.shaded = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@SubscribeEvent
|
||||||
public ResourceLocation getTexture(){
|
public static void onTextureStitchEvent(TextureStitchEvent.Pre event){
|
||||||
return TEXTURE;
|
for(ResourceLocation texture : TEXTURES){
|
||||||
}
|
event.getMap().registerSprite(texture);
|
||||||
|
}
|
||||||
@Override
|
|
||||||
protected int getXFrames(){
|
|
||||||
return 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected int getYFrames(){
|
|
||||||
return 4;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,41 +1,47 @@
|
|||||||
package electroblob.wizardry.client.particle;
|
package electroblob.wizardry.client.particle;
|
||||||
|
|
||||||
import electroblob.wizardry.Wizardry;
|
|
||||||
import net.minecraft.util.ResourceLocation;
|
import net.minecraft.util.ResourceLocation;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
import net.minecraftforge.client.event.TextureStitchEvent;
|
||||||
|
import net.minecraftforge.fml.common.Mod;
|
||||||
|
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
||||||
import net.minecraftforge.fml.relauncher.Side;
|
import net.minecraftforge.fml.relauncher.Side;
|
||||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
import net.minecraftforge.fml.relauncher.SideOnly;
|
||||||
|
|
||||||
@SideOnly(Side.CLIENT)
|
@SideOnly(Side.CLIENT)
|
||||||
public class ParticleLeaf extends ParticleCustomTexture {
|
@Mod.EventBusSubscriber(Side.CLIENT)
|
||||||
|
public class ParticleLeaf extends ParticleWizardry {
|
||||||
|
|
||||||
private static final ResourceLocation TEXTURE = new ResourceLocation(Wizardry.MODID,
|
private static final ResourceLocation[] TEXTURES = generateTextures("leaf", 16);
|
||||||
"textures/particle/leaf_particles.png");
|
|
||||||
|
|
||||||
public ParticleLeaf(World world, double x, double y, double z){
|
public ParticleLeaf(World world, double x, double y, double z){
|
||||||
super(world, x, y, z);
|
|
||||||
|
super(world, x, y, z, TEXTURES[world.rand.nextInt(TEXTURES.length)]);
|
||||||
|
|
||||||
this.setVelocity(0, -0.03, 0);
|
this.setVelocity(0, -0.03, 0);
|
||||||
this.setLifetime(10 + rand.nextInt(5));
|
this.setMaxAge(10 + rand.nextInt(5));
|
||||||
this.setParticleTextureIndex(rand.nextInt(16));
|
|
||||||
this.particleScale *= 1.4f;
|
this.particleScale *= 1.4f;
|
||||||
this.particleGravity = 0;
|
this.particleGravity = 0;
|
||||||
this.canCollide = true;
|
this.canCollide = true;
|
||||||
// Produces a variety of browns and greens
|
// Produces a variety of browns and greens
|
||||||
this.setRBGColorF(0.1f + 0.3f * world.rand.nextFloat(), 0.5f + 0.3f * world.rand.nextFloat(), 0.1f);
|
this.setRBGColorF(0.1f + 0.3f * world.rand.nextFloat(), 0.5f + 0.3f * world.rand.nextFloat(), 0.1f);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ResourceLocation getTexture(){
|
public void onUpdate(){
|
||||||
return TEXTURE;
|
|
||||||
|
super.onUpdate();
|
||||||
|
|
||||||
|
// Fading
|
||||||
|
if(this.particleAge > this.particleMaxAge / 2){
|
||||||
|
this.setAlphaF(1 - ((float)this.particleAge - (float)(this.particleMaxAge / 2)) / (float)this.particleMaxAge);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@SubscribeEvent
|
||||||
protected int getXFrames(){
|
public static void onTextureStitchEvent(TextureStitchEvent.Pre event){
|
||||||
return 4;
|
for(ResourceLocation texture : TEXTURES){
|
||||||
}
|
event.getMap().registerSprite(texture);
|
||||||
|
}
|
||||||
@Override
|
|
||||||
protected int getYFrames(){
|
|
||||||
return 4;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,167 @@
|
|||||||
|
package electroblob.wizardry.client.particle;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
import org.lwjgl.opengl.GL11;
|
||||||
|
|
||||||
|
import net.minecraft.client.renderer.BufferBuilder;
|
||||||
|
import net.minecraft.client.renderer.GlStateManager;
|
||||||
|
import net.minecraft.client.renderer.OpenGlHelper;
|
||||||
|
import net.minecraft.client.renderer.Tessellator;
|
||||||
|
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
|
public class ParticleLightning extends ParticleTargeted {
|
||||||
|
|
||||||
|
/** Half the width of the outermost layer. */
|
||||||
|
private static final float THICKNESS = 0.04f;
|
||||||
|
/** Maximum length of a segment. */
|
||||||
|
private static final double MAX_SEGMENT_LENGTH = 0.6;
|
||||||
|
/** Minimum length of a segment. */
|
||||||
|
private static final double MIN_SEGMENT_LENGTH = 0.2;
|
||||||
|
/** Maximum deviation (in x or y, as drawn before transformations) from the centreline. */
|
||||||
|
private static final double VERTEX_JITTER = 0.15;
|
||||||
|
/** Maximum number of segments a fork can have before ending. */
|
||||||
|
private static final int MAX_FORK_SEGMENTS = 3;
|
||||||
|
/** Probability (as a fraction) that a vertex will have a fork. */
|
||||||
|
private static final float FORK_CHANCE = 0.3f;
|
||||||
|
/** Number of ticks to wait before the arc changes shape again. */
|
||||||
|
private static final int UPDATE_PERIOD = 1;
|
||||||
|
|
||||||
|
/** A random long value used by the renderer as a seed to generate its vertices from, ensuring they remain the same
|
||||||
|
* across multiple frames. Not synced. */
|
||||||
|
public final long seed;
|
||||||
|
|
||||||
|
public ParticleLightning(World world, double x, double y, double z){
|
||||||
|
super(world, x, y, z); // Does not have a texture!
|
||||||
|
seed = this.rand.nextLong();
|
||||||
|
this.setRBGColorF(0.2f, 0.6f, 1); // Default blue colour
|
||||||
|
this.setMaxAge(3);
|
||||||
|
this.particleScale = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getFXLayer(){
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void draw(Tessellator tessellator, double length, float partialTicks){
|
||||||
|
|
||||||
|
GlStateManager.disableLighting();
|
||||||
|
GlStateManager.enableBlend();
|
||||||
|
GlStateManager.disableTexture2D();
|
||||||
|
GlStateManager.blendFunc(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE);
|
||||||
|
OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240f, 240f);
|
||||||
|
|
||||||
|
// The direction of the arc drawn by the tessellator is always along the z axis and is rotated to the
|
||||||
|
// correct orientation, that way there isn't a ton of trigonometry and the code is way neater.
|
||||||
|
|
||||||
|
boolean freeEnd = this.target == null;
|
||||||
|
|
||||||
|
int numberOfSegments = (int)Math.round(length/MAX_SEGMENT_LENGTH); // Number of segments
|
||||||
|
|
||||||
|
for(int layer=0; layer<3; layer++){
|
||||||
|
|
||||||
|
double px=0, py=0, pz=0;
|
||||||
|
// Creates a random from the arc's seed field + the number of ticks it has existed/the update period.
|
||||||
|
// By using a seed, we can ensure the vertex positions and forks are identical a) for each layer, even
|
||||||
|
// though they are rendered sequentially, and b) across many frames (and ticks, if updateTime > 1).
|
||||||
|
Random random = new Random(this.seed + this.particleAge/UPDATE_PERIOD);
|
||||||
|
|
||||||
|
// numberOfSegments-1 because the last segment is handled separately.
|
||||||
|
for(int i=0; i<numberOfSegments-1; i++){
|
||||||
|
|
||||||
|
double px2 = (random.nextDouble()*2-1)*VERTEX_JITTER*particleScale;
|
||||||
|
double py2 = (random.nextDouble()*2-1)*VERTEX_JITTER*particleScale;
|
||||||
|
double pz2 = pz + length/(double)numberOfSegments; // For now they are all the same length
|
||||||
|
|
||||||
|
drawSegment(tessellator, layer, px, py, pz, px2, py2, pz2, THICKNESS*particleScale);
|
||||||
|
|
||||||
|
// Forks
|
||||||
|
if(random.nextFloat() < FORK_CHANCE){
|
||||||
|
|
||||||
|
double px3=px, py3=py, pz3=pz;
|
||||||
|
|
||||||
|
for(int j=0; j<random.nextInt(MAX_FORK_SEGMENTS-1)+1; j++){
|
||||||
|
// Forks set their centreline to the x/y coordinates of the vertex they originate from
|
||||||
|
double px4 = px3 + (random.nextDouble()*2-1)*VERTEX_JITTER*particleScale;
|
||||||
|
double py4 = py3 + (random.nextDouble()*2-1)*VERTEX_JITTER*particleScale;
|
||||||
|
double pz4 = pz3 + MIN_SEGMENT_LENGTH + random.nextDouble()*(MAX_SEGMENT_LENGTH - MIN_SEGMENT_LENGTH);
|
||||||
|
|
||||||
|
drawSegment(tessellator, layer, px3, py3, pz3, px4, py4, pz4, THICKNESS*0.8f*particleScale);
|
||||||
|
|
||||||
|
// Forks of forks
|
||||||
|
if(random.nextFloat() < FORK_CHANCE){
|
||||||
|
|
||||||
|
double px5 = px3 + (random.nextDouble()*2-1)*VERTEX_JITTER*particleScale;
|
||||||
|
double py5 = py3 + (random.nextDouble()*2-1)*VERTEX_JITTER*particleScale;
|
||||||
|
double pz5 = pz3 + MIN_SEGMENT_LENGTH + random.nextDouble()*(MAX_SEGMENT_LENGTH - MIN_SEGMENT_LENGTH);
|
||||||
|
|
||||||
|
drawSegment(tessellator, layer, px3, py3, pz3, px5, py5, pz5, THICKNESS*0.6f*particleScale);
|
||||||
|
}
|
||||||
|
|
||||||
|
px3 = px4;
|
||||||
|
py3 = py4;
|
||||||
|
pz3 = pz4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
px = px2;
|
||||||
|
py = py2;
|
||||||
|
pz = pz2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Last segment has a specific end position and cannot fork.
|
||||||
|
double px2 = freeEnd ? (random.nextDouble()*2-1)*VERTEX_JITTER*particleScale : 0;
|
||||||
|
double py2 = freeEnd ? (random.nextDouble()*2-1)*VERTEX_JITTER*particleScale : 0;
|
||||||
|
drawSegment(tessellator, layer, px, py, pz, px2, py2, length, THICKNESS*particleScale);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
GlStateManager.enableTexture2D();
|
||||||
|
GlStateManager.enableLighting();
|
||||||
|
GlStateManager.disableBlend();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Draws the given layer of a segment of the arc, from the point (x1, y1, z1) to the point (x2, y2, z2), with the given thickness. */
|
||||||
|
private void drawSegment(Tessellator tessellator, int layer, double x1, double y1, double z1, double x2, double y2, double z2, float thickness){
|
||||||
|
|
||||||
|
BufferBuilder buffer = tessellator.getBuffer();
|
||||||
|
buffer.begin(GL11.GL_TRIANGLE_STRIP, DefaultVertexFormats.POSITION_COLOR);
|
||||||
|
|
||||||
|
switch(layer){
|
||||||
|
|
||||||
|
case 0:
|
||||||
|
drawShearedBox(buffer, x1, y1, z1, x2, y2, z2, 0.25f*thickness, 1, 1, 1, 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
drawShearedBox(buffer, x1, y1, z1, x2, y2, z2, 0.6f*thickness, (particleRed + 1)/2, (particleGreen + 1)/2,
|
||||||
|
(particleBlue + 1)/2, 0.65f);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
drawShearedBox(buffer, x1, y1, z1, x2, y2, z2, thickness, particleRed, particleGreen, particleBlue, 0.3f);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
tessellator.draw();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Draws a single box for one segment of the arc, from the point (x1, y1, z1) to the point (x2, y2, z2), with given width and colour. */
|
||||||
|
private void drawShearedBox(BufferBuilder buffer, double x1, double y1, double z1, double x2, double y2, double z2, float width, float r, float g, float b, float a){
|
||||||
|
|
||||||
|
buffer.pos(x1-width, y1-width, z1).color(r, g, b, a).endVertex();
|
||||||
|
buffer.pos(x2-width, y2-width, z2).color(r, g, b, a).endVertex();
|
||||||
|
buffer.pos(x1-width, y1+width, z1).color(r, g, b, a).endVertex();
|
||||||
|
buffer.pos(x2-width, y2+width, z2).color(r, g, b, a).endVertex();
|
||||||
|
buffer.pos(x1+width, y1+width, z1).color(r, g, b, a).endVertex();
|
||||||
|
buffer.pos(x2+width, y2+width, z2).color(r, g, b, a).endVertex();
|
||||||
|
buffer.pos(x1+width, y1-width, z1).color(r, g, b, a).endVertex();
|
||||||
|
buffer.pos(x2+width, y2-width, z2).color(r, g, b, a).endVertex();
|
||||||
|
buffer.pos(x1-width, y1-width, z1).color(r, g, b, a).endVertex();
|
||||||
|
buffer.pos(x2-width, y2-width, z2).color(r, g, b, a).endVertex();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
package electroblob.wizardry.client.particle;
|
||||||
|
|
||||||
|
import net.minecraft.util.ResourceLocation;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
import net.minecraftforge.client.event.TextureStitchEvent;
|
||||||
|
import net.minecraftforge.fml.common.Mod;
|
||||||
|
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
||||||
|
import net.minecraftforge.fml.relauncher.Side;
|
||||||
|
import net.minecraftforge.fml.relauncher.SideOnly;
|
||||||
|
|
||||||
|
@SideOnly(Side.CLIENT)
|
||||||
|
@Mod.EventBusSubscriber(Side.CLIENT)
|
||||||
|
public class ParticleLightningPulse extends ParticleWizardry {
|
||||||
|
|
||||||
|
private static final ResourceLocation[] TEXTURES = generateTextures("lightning_pulse", 8);
|
||||||
|
|
||||||
|
public ParticleLightningPulse(World world, double x, double y, double z){
|
||||||
|
|
||||||
|
super(world, x, y, z, TEXTURES);
|
||||||
|
|
||||||
|
this.particleScale = 32f;
|
||||||
|
this.setRBGColorF(1, 1, 1);
|
||||||
|
this.shaded = false;
|
||||||
|
this.canCollide = false;
|
||||||
|
this.setMaxAge(7); // Lifetime defaults to 7 (and is very unlikely to be changed)
|
||||||
|
// Faces up by default
|
||||||
|
this.pitch = 90;
|
||||||
|
this.yaw = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SubscribeEvent
|
||||||
|
public static void onTextureStitchEvent(TextureStitchEvent.Pre event){
|
||||||
|
for(ResourceLocation texture : TEXTURES){
|
||||||
|
event.getMap().registerSprite(texture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -9,9 +9,7 @@ public class ParticleMagicBubble extends ParticleWizardry {
|
|||||||
|
|
||||||
public ParticleMagicBubble(World world, double x, double y, double z){
|
public ParticleMagicBubble(World world, double x, double y, double z){
|
||||||
super(world, x, y, z);
|
super(world, x, y, z);
|
||||||
this.particleRed = 1.0F;
|
this.setRBGColorF(1, 1, 1);
|
||||||
this.particleGreen = 1.0F;
|
|
||||||
this.particleBlue = 1.0F;
|
|
||||||
this.setParticleTextureIndex(32);
|
this.setParticleTextureIndex(32);
|
||||||
this.setSize(0.02F, 0.02F);
|
this.setSize(0.02F, 0.02F);
|
||||||
this.particleScale *= this.rand.nextFloat() * 0.6F + 0.2F;
|
this.particleScale *= this.rand.nextFloat() * 0.6F + 0.2F;
|
||||||
|
|||||||
@@ -15,14 +15,11 @@ public class ParticleMagicFlame extends ParticleWizardry {
|
|||||||
|
|
||||||
public ParticleMagicFlame(World world, double x, double y, double z){
|
public ParticleMagicFlame(World world, double x, double y, double z){
|
||||||
super(world, x, y, z);
|
super(world, x, y, z);
|
||||||
// Not sure what these did but they sure as heck won't do anything now...
|
|
||||||
// TESTME: If it looks the same as before, delete these.
|
|
||||||
// this.motionX = this.motionX * 0.009999999776482582D + par8;
|
|
||||||
// this.motionY = this.motionY * 0.009999999776482582D + par10;
|
|
||||||
// this.motionZ = this.motionZ * 0.009999999776482582D + par12;
|
|
||||||
this.flameScale = 1 + world.rand.nextFloat();
|
this.flameScale = 1 + world.rand.nextFloat();
|
||||||
this.setRBGColorF(1, 1, 1);
|
this.setRBGColorF(1, 1, 1);
|
||||||
|
this.particleAlpha = 1;
|
||||||
this.particleMaxAge = (int)(2.0D / (Math.random() * 0.8D + 0.2D));
|
this.particleMaxAge = (int)(2.0D / (Math.random() * 0.8D + 0.2D));
|
||||||
|
this.shaded = false;
|
||||||
// IDEA: Make the particles for ray spells collide properly and not spawn on the other side of stuff.
|
// IDEA: Make the particles for ray spells collide properly and not spawn on the other side of stuff.
|
||||||
this.canCollide = false;
|
this.canCollide = false;
|
||||||
this.setParticleTextureIndex(48);
|
this.setParticleTextureIndex(48);
|
||||||
|
|||||||
@@ -1,32 +1,31 @@
|
|||||||
package electroblob.wizardry.client.particle;
|
package electroblob.wizardry.client.particle;
|
||||||
|
|
||||||
import org.lwjgl.opengl.GL11;
|
|
||||||
|
|
||||||
import electroblob.wizardry.Wizardry;
|
import electroblob.wizardry.Wizardry;
|
||||||
import electroblob.wizardry.spell.Clairvoyance;
|
import electroblob.wizardry.spell.Clairvoyance;
|
||||||
import net.minecraft.client.renderer.GlStateManager;
|
|
||||||
import net.minecraft.client.renderer.OpenGlHelper;
|
|
||||||
import net.minecraft.util.ResourceLocation;
|
import net.minecraft.util.ResourceLocation;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
import net.minecraftforge.client.event.TextureStitchEvent;
|
||||||
|
import net.minecraftforge.fml.common.Mod;
|
||||||
|
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
||||||
import net.minecraftforge.fml.relauncher.Side;
|
import net.minecraftforge.fml.relauncher.Side;
|
||||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
import net.minecraftforge.fml.relauncher.SideOnly;
|
||||||
|
|
||||||
@SideOnly(Side.CLIENT)
|
@SideOnly(Side.CLIENT)
|
||||||
public class ParticlePath extends ParticleCustomTexture {
|
@Mod.EventBusSubscriber(Side.CLIENT)
|
||||||
|
public class ParticlePath extends ParticleWizardry {
|
||||||
|
|
||||||
private static final ResourceLocation TEXTURE = new ResourceLocation(Wizardry.MODID,
|
private static final ResourceLocation TEXTURE = new ResourceLocation(Wizardry.MODID, "particle/path");
|
||||||
"textures/particle/path_particles.png");
|
|
||||||
|
|
||||||
private final double originX, originY, originZ;
|
private final double originX, originY, originZ;
|
||||||
|
|
||||||
public ParticlePath(World world, double x, double y, double z){
|
public ParticlePath(World world, double x, double y, double z){
|
||||||
super(world, x, y, z);
|
|
||||||
|
super(world, x, y, z, TEXTURE); // This particle only has 1 texture
|
||||||
|
|
||||||
this.originX = x;
|
this.originX = x;
|
||||||
this.originY = y;
|
this.originY = y;
|
||||||
this.originZ = z;
|
this.originZ = z;
|
||||||
|
|
||||||
this.setParticleTextureIndex(0);
|
|
||||||
// Set to a constant to remove the randomness from Particle.
|
// Set to a constant to remove the randomness from Particle.
|
||||||
this.particleScale = 1.25f;
|
this.particleScale = 1.25f;
|
||||||
this.particleGravity = 0;
|
this.particleGravity = 0;
|
||||||
@@ -35,23 +34,10 @@ public class ParticlePath extends ParticleCustomTexture {
|
|||||||
this.setRBGColorF(1, 1, 1);
|
this.setRBGColorF(1, 1, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public ResourceLocation getTexture(){
|
|
||||||
return TEXTURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected int getXFrames(){
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected int getYFrames(){
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onUpdate(){
|
public void onUpdate(){
|
||||||
|
|
||||||
|
super.onUpdate();
|
||||||
|
|
||||||
this.prevPosX = this.posX;
|
this.prevPosX = this.posX;
|
||||||
this.prevPosY = this.posY;
|
this.prevPosY = this.posY;
|
||||||
@@ -77,19 +63,10 @@ public class ParticlePath extends ParticleCustomTexture {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@SubscribeEvent
|
||||||
public void applyGLStateChanges(){
|
public static void onTextureStitchEvent(TextureStitchEvent.Pre event){
|
||||||
GlStateManager.enableBlend();
|
event.getMap().registerSprite(TEXTURE);
|
||||||
GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
|
|
||||||
// TESTME: Are these two actually necessary?
|
|
||||||
GlStateManager.disableLighting();
|
|
||||||
OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240, 240);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void undoGLStateChanges(){
|
|
||||||
GlStateManager.disableBlend();
|
|
||||||
GlStateManager.enableLighting();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,60 +0,0 @@
|
|||||||
package electroblob.wizardry.client.particle;
|
|
||||||
|
|
||||||
import net.minecraft.world.World;
|
|
||||||
import net.minecraftforge.fml.relauncher.Side;
|
|
||||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
|
||||||
|
|
||||||
@SideOnly(Side.CLIENT)
|
|
||||||
public class ParticleRotatingSparkle extends ParticleSparkle {
|
|
||||||
|
|
||||||
private double angle;
|
|
||||||
private double radius;
|
|
||||||
private double speed;
|
|
||||||
|
|
||||||
public ParticleRotatingSparkle(World world, double ox, double y, double oz){
|
|
||||||
super(world, ox, y, oz);
|
|
||||||
this.angle = this.rand.nextDouble() * Math.PI * 2;
|
|
||||||
double x = ox - Math.cos(angle) * radius;
|
|
||||||
double z = oz + radius * Math.sin(angle);
|
|
||||||
this.radius = 1; // TODO: Find a suitable default value
|
|
||||||
this.setPosition(x, y, z);
|
|
||||||
this.prevPosX = x;
|
|
||||||
this.prevPosY = y;
|
|
||||||
this.prevPosZ = z;
|
|
||||||
if(rand.nextBoolean()){
|
|
||||||
speed = rand.nextDouble() * 2 + 1;
|
|
||||||
}else{
|
|
||||||
speed = rand.nextDouble() * -2 - 1;
|
|
||||||
}
|
|
||||||
this.multipleParticleScaleBy(1.5f);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onUpdate(){
|
|
||||||
|
|
||||||
this.prevPosX = this.posX;
|
|
||||||
this.prevPosY = this.posY;
|
|
||||||
this.prevPosZ = this.posZ;
|
|
||||||
|
|
||||||
if(this.particleAge++ >= this.particleMaxAge){
|
|
||||||
this.setExpired();
|
|
||||||
}
|
|
||||||
|
|
||||||
// This is in radians per tick...
|
|
||||||
double omega = Math.signum(speed) * ((Math.PI * 2) / 20 - speed / (20 * radius));
|
|
||||||
|
|
||||||
// v = r times omega; therefore the normalised velocity vector needs to be r times the angle increment / 2 pi.
|
|
||||||
this.angle += omega;
|
|
||||||
|
|
||||||
this.motionY -= 0.04D * (double)this.particleGravity;
|
|
||||||
this.motionZ = radius * omega * Math.cos(angle);
|
|
||||||
this.motionX = radius * omega * Math.sin(angle);
|
|
||||||
this.move(motionX, motionY, motionZ);
|
|
||||||
|
|
||||||
if(this.particleAge > this.particleMaxAge / 2){
|
|
||||||
this.setAlphaF(
|
|
||||||
1.0F - ((float)this.particleAge - (float)(this.particleMaxAge / 2)) / (float)this.particleMaxAge);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,70 @@
|
|||||||
|
package electroblob.wizardry.client.particle;
|
||||||
|
|
||||||
|
import net.minecraft.util.EnumFacing;
|
||||||
|
import net.minecraft.util.ResourceLocation;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
import net.minecraftforge.client.event.TextureStitchEvent;
|
||||||
|
import net.minecraftforge.fml.common.Mod;
|
||||||
|
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
||||||
|
import net.minecraftforge.fml.relauncher.Side;
|
||||||
|
import net.minecraftforge.fml.relauncher.SideOnly;
|
||||||
|
|
||||||
|
@SideOnly(Side.CLIENT)
|
||||||
|
@Mod.EventBusSubscriber(Side.CLIENT)
|
||||||
|
public class ParticleScorch extends ParticleWizardry {
|
||||||
|
|
||||||
|
private static final ResourceLocation[] TEXTURES = generateTextures("scorch", 8);
|
||||||
|
|
||||||
|
public ParticleScorch(World world, double x, double y, double z){
|
||||||
|
|
||||||
|
super(world, x, y, z, TEXTURES[world.rand.nextInt(TEXTURES.length)]);
|
||||||
|
|
||||||
|
this.particleGravity = 0;
|
||||||
|
this.setMaxAge(100 + rand.nextInt(40));
|
||||||
|
this.particleScale *= 2;
|
||||||
|
// Defaults to black (which looks like a 'normal' scorch mark)
|
||||||
|
this.setRBGColorF(0, 0, 0);
|
||||||
|
this.shaded = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setRBGColorF(float r, float g, float b){
|
||||||
|
super.setRBGColorF(r, g, b);
|
||||||
|
this.setFadeColour(0, 0, 0); // Scorch particles fade to black by default
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onUpdate(){
|
||||||
|
|
||||||
|
super.onUpdate();
|
||||||
|
|
||||||
|
// Colour fading (scorch particles do this slightly differently)
|
||||||
|
float ageFraction = Math.min((float)this.particleAge / ((float)this.particleMaxAge * 0.5f), 1);
|
||||||
|
// No longer uses setRBGColorF because that method now also sets the initial values
|
||||||
|
this.particleRed = this.initialRed + (this.fadeRed - this.initialRed) * ageFraction;
|
||||||
|
this.particleGreen = this.initialGreen + (this.fadeGreen - this.initialGreen) * ageFraction;
|
||||||
|
this.particleBlue = this.initialBlue + (this.fadeBlue - this.initialBlue) * ageFraction;
|
||||||
|
|
||||||
|
// Fading
|
||||||
|
if(this.particleAge > this.particleMaxAge/2){
|
||||||
|
this.setAlphaF(1 - ((float)this.particleAge - (float)(this.particleMaxAge/2)) / (float)this.particleMaxAge);
|
||||||
|
}
|
||||||
|
|
||||||
|
EnumFacing facing = EnumFacing.fromAngle(yaw);
|
||||||
|
if(pitch == 90) facing = EnumFacing.UP;
|
||||||
|
if(pitch == -90) facing = EnumFacing.DOWN;
|
||||||
|
|
||||||
|
// Disappears if there is no block behind it (this is the same check used to spawn it)
|
||||||
|
if(!world.getBlockState(new BlockPos(posX, posY, posZ).offset(facing.getOpposite())).getMaterial().isSolid()){
|
||||||
|
this.setExpired();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SubscribeEvent
|
||||||
|
public static void onTextureStitchEvent(TextureStitchEvent.Pre event){
|
||||||
|
for(ResourceLocation texture : TEXTURES){
|
||||||
|
event.getMap().registerSprite(texture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,39 +1,36 @@
|
|||||||
package electroblob.wizardry.client.particle;
|
package electroblob.wizardry.client.particle;
|
||||||
|
|
||||||
import electroblob.wizardry.Wizardry;
|
|
||||||
import net.minecraft.util.ResourceLocation;
|
import net.minecraft.util.ResourceLocation;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
import net.minecraftforge.client.event.TextureStitchEvent;
|
||||||
|
import net.minecraftforge.fml.common.Mod;
|
||||||
|
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
||||||
import net.minecraftforge.fml.relauncher.Side;
|
import net.minecraftforge.fml.relauncher.Side;
|
||||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
import net.minecraftforge.fml.relauncher.SideOnly;
|
||||||
|
|
||||||
@SideOnly(Side.CLIENT)
|
@SideOnly(Side.CLIENT)
|
||||||
public class ParticleSnow extends ParticleCustomTexture {
|
@Mod.EventBusSubscriber(Side.CLIENT)
|
||||||
|
public class ParticleSnow extends ParticleWizardry {
|
||||||
|
|
||||||
private static final ResourceLocation TEXTURE = new ResourceLocation(Wizardry.MODID,
|
private static final ResourceLocation[] TEXTURES = generateTextures("snow", 4);
|
||||||
"textures/particle/snow_particles.png");
|
|
||||||
|
|
||||||
public ParticleSnow(World world, double x, double y, double z){
|
public ParticleSnow(World world, double x, double y, double z){
|
||||||
super(world, x, y, z);
|
|
||||||
this.setParticleTextureIndex(rand.nextInt(8));
|
super(world, x, y, z, TEXTURES[world.rand.nextInt(TEXTURES.length)]);
|
||||||
|
|
||||||
this.setVelocity(0, -0.02, 0);
|
this.setVelocity(0, -0.02, 0);
|
||||||
this.particleScale *= 0.6f;
|
this.particleScale *= 0.6f;
|
||||||
this.particleGravity = 0;
|
this.particleGravity = 0;
|
||||||
this.canCollide = true;
|
this.canCollide = true;
|
||||||
this.setLifetime(40 + rand.nextInt(10));
|
this.setMaxAge(40 + rand.nextInt(10));
|
||||||
|
// Produces a variety of light blues and whites
|
||||||
|
this.setRBGColorF(0.9f + 0.1f * world.rand.nextFloat(), 0.95f + 0.05f * world.rand.nextFloat(), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@SubscribeEvent
|
||||||
public ResourceLocation getTexture(){
|
public static void onTextureStitchEvent(TextureStitchEvent.Pre event){
|
||||||
return TEXTURE;
|
for(ResourceLocation texture : TEXTURES){
|
||||||
}
|
event.getMap().registerSprite(texture);
|
||||||
|
}
|
||||||
@Override
|
|
||||||
protected int getXFrames(){
|
|
||||||
return 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected int getYFrames(){
|
|
||||||
return 4;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,66 +1,55 @@
|
|||||||
package electroblob.wizardry.client.particle;
|
package electroblob.wizardry.client.particle;
|
||||||
|
|
||||||
import org.lwjgl.opengl.GL11;
|
|
||||||
|
|
||||||
import electroblob.wizardry.Wizardry;
|
|
||||||
import net.minecraft.client.renderer.GlStateManager;
|
|
||||||
import net.minecraft.client.renderer.OpenGlHelper;
|
|
||||||
import net.minecraft.util.ResourceLocation;
|
import net.minecraft.util.ResourceLocation;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
import net.minecraftforge.client.event.TextureStitchEvent;
|
||||||
|
import net.minecraftforge.fml.common.Mod;
|
||||||
|
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
||||||
import net.minecraftforge.fml.relauncher.Side;
|
import net.minecraftforge.fml.relauncher.Side;
|
||||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
import net.minecraftforge.fml.relauncher.SideOnly;
|
||||||
|
|
||||||
@SideOnly(Side.CLIENT)
|
@SideOnly(Side.CLIENT)
|
||||||
public class ParticleSpark extends ParticleCustomTexture {
|
@Mod.EventBusSubscriber(Side.CLIENT)
|
||||||
|
public class ParticleSpark extends ParticleWizardry {
|
||||||
|
|
||||||
private static final ResourceLocation TEXTURE = new ResourceLocation(Wizardry.MODID,
|
// 8 different animation strips, 4 in each strip
|
||||||
"textures/particle/lightning_particles.png");
|
private static final ResourceLocation[][] TEXTURES = generateTextures("lightning", 8, 4);
|
||||||
|
|
||||||
public ParticleSpark(World world, double x, double y, double z){
|
public ParticleSpark(World world, double x, double y, double z){
|
||||||
super(world, x, y, z);
|
|
||||||
// Multiplied by 4 because the index works slightly differently for spark particles.
|
super(world, x, y, z, TEXTURES[world.rand.nextInt(TEXTURES.length)]);
|
||||||
this.setParticleTextureIndex(rand.nextInt(8) * 4);
|
|
||||||
this.particleScale *= 1.4f;
|
this.particleScale *= 1.4f;
|
||||||
|
this.setRBGColorF(1, 1, 1);
|
||||||
this.shaded = false;
|
this.shaded = false;
|
||||||
this.canCollide = false;
|
this.canCollide = false;
|
||||||
this.setLifetime(3); // Lifetime defaults to 3 (and is very unlikely to be changed)
|
this.setMaxAge(3); // Lifetime defaults to 3 (and is very unlikely to be changed)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// May no longer be necessary, ParticleManager seems to enable blending now
|
||||||
|
|
||||||
@Override
|
// @Override
|
||||||
public void onUpdate(){
|
// public void applyGLStateChanges(){
|
||||||
super.onUpdate();
|
// GlStateManager.enableBlend();
|
||||||
// Well this is handy! Looks like vanilla uses the texture index like this too.
|
// GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
|
||||||
this.nextTextureIndexX();
|
// // TESTME: Are these two actually necessary?
|
||||||
}
|
// GlStateManager.disableLighting();
|
||||||
|
// OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240, 240);
|
||||||
@Override
|
// }
|
||||||
public ResourceLocation getTexture(){
|
//
|
||||||
return TEXTURE;
|
// @Override
|
||||||
}
|
// public void undoGLStateChanges(){
|
||||||
|
// GlStateManager.disableBlend();
|
||||||
@Override
|
// GlStateManager.enableLighting();
|
||||||
protected int getXFrames(){
|
// }
|
||||||
return 4;
|
|
||||||
}
|
@SubscribeEvent
|
||||||
|
public static void onTextureStitchEvent(TextureStitchEvent.Pre event){
|
||||||
@Override
|
for(ResourceLocation[] array : TEXTURES){
|
||||||
protected int getYFrames(){
|
for(ResourceLocation texture : array){
|
||||||
return 8;
|
event.getMap().registerSprite(texture);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
@Override
|
|
||||||
public void applyGLStateChanges(){
|
|
||||||
GlStateManager.enableBlend();
|
|
||||||
GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
|
|
||||||
// TESTME: Are these two actually necessary?
|
|
||||||
GlStateManager.disableLighting();
|
|
||||||
OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240, 240);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void undoGLStateChanges(){
|
|
||||||
GlStateManager.disableBlend();
|
|
||||||
GlStateManager.enableLighting();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,24 +1,23 @@
|
|||||||
package electroblob.wizardry.client.particle;
|
package electroblob.wizardry.client.particle;
|
||||||
|
|
||||||
import electroblob.wizardry.Wizardry;
|
|
||||||
import net.minecraft.util.ResourceLocation;
|
import net.minecraft.util.ResourceLocation;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
import net.minecraftforge.client.event.TextureStitchEvent;
|
||||||
|
import net.minecraftforge.fml.common.Mod;
|
||||||
|
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
||||||
import net.minecraftforge.fml.relauncher.Side;
|
import net.minecraftforge.fml.relauncher.Side;
|
||||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
import net.minecraftforge.fml.relauncher.SideOnly;
|
||||||
|
|
||||||
@SideOnly(Side.CLIENT)
|
@SideOnly(Side.CLIENT)
|
||||||
public class ParticleSparkle extends ParticleCustomTexture {
|
@Mod.EventBusSubscriber(Side.CLIENT)
|
||||||
|
public class ParticleSparkle extends ParticleWizardry {
|
||||||
|
|
||||||
private static final ResourceLocation TEXTURE = new ResourceLocation(Wizardry.MODID,
|
private static final ResourceLocation[] TEXTURES = generateTextures("sparkle", 11);
|
||||||
"textures/particle/sparkle_particles.png");
|
|
||||||
|
|
||||||
// Implementation of colour fading (perhaps these belong in ParticleWizardry?)
|
|
||||||
private float initialRed;
|
|
||||||
private float initialGreen;
|
|
||||||
private float initialBlue;
|
|
||||||
|
|
||||||
public ParticleSparkle(World world, double x, double y, double z){
|
public ParticleSparkle(World world, double x, double y, double z){
|
||||||
super(world, x, y, z);
|
|
||||||
|
super(world, x, y, z, TEXTURES); // This time the textures are all one long animation
|
||||||
|
|
||||||
this.setRBGColorF(1, 1, 1);
|
this.setRBGColorF(1, 1, 1);
|
||||||
this.particleMaxAge = 48 + this.rand.nextInt(12);
|
this.particleMaxAge = 48 + this.rand.nextInt(12);
|
||||||
this.particleScale *= 0.75f;
|
this.particleScale *= 0.75f;
|
||||||
@@ -27,30 +26,6 @@ public class ParticleSparkle extends ParticleCustomTexture {
|
|||||||
this.shaded = false;
|
this.shaded = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Overridden to set the initial colour values
|
|
||||||
@Override
|
|
||||||
public void setRBGColorF(float r, float g, float b){
|
|
||||||
super.setRBGColorF(r, g, b);
|
|
||||||
initialRed = r;
|
|
||||||
initialGreen = g;
|
|
||||||
initialBlue = b;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ResourceLocation getTexture(){
|
|
||||||
return TEXTURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected int getXFrames(){
|
|
||||||
return 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected int getYFrames(){
|
|
||||||
return 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onUpdate(){
|
public void onUpdate(){
|
||||||
|
|
||||||
@@ -58,24 +33,14 @@ public class ParticleSparkle extends ParticleCustomTexture {
|
|||||||
|
|
||||||
// Fading
|
// Fading
|
||||||
if(this.particleAge > this.particleMaxAge / 2){
|
if(this.particleAge > this.particleMaxAge / 2){
|
||||||
this.setAlphaF(
|
this.setAlphaF(1 - ((float)this.particleAge - (float)(this.particleMaxAge / 2)) / (float)this.particleMaxAge);
|
||||||
1.0F - ((float)this.particleAge - (float)(this.particleMaxAge / 2)) / (float)this.particleMaxAge);
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SubscribeEvent
|
||||||
|
public static void onTextureStitchEvent(TextureStitchEvent.Pre event){
|
||||||
|
for(ResourceLocation texture : TEXTURES){
|
||||||
|
event.getMap().registerSprite(texture);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Colour fading
|
|
||||||
float ageFraction = (float)this.particleAge / (float)this.particleMaxAge;
|
|
||||||
// No longer uses setRBGColorF because that method now also sets the initial values
|
|
||||||
this.particleRed = this.initialRed + (this.fadeRed - this.initialRed)*ageFraction;
|
|
||||||
this.particleGreen = this.initialGreen + (this.fadeGreen - this.initialGreen)*ageFraction;
|
|
||||||
this.particleBlue = this.initialBlue + (this.fadeBlue - this.initialBlue)*ageFraction;
|
|
||||||
|
|
||||||
this.setParticleTextureIndex((this.particleAge * 11)/this.particleMaxAge);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* As a side note, I see a lot of magic mods with fancy-looking particle effects that really seem to 'glow'. It's
|
|
||||||
* actually not that hard - you simply create a reasonably high-res texture with translucency and then set the
|
|
||||||
* OpenGL blend function to something like SRC_ALPHA, SRC_ALPHA or ONE, ONE. The thing is... they're not very
|
|
||||||
* Minecraft-y. I still maintain that part of wizardry's appeal is that it stays true to the game's pixelated charm,
|
|
||||||
* rather than trying to make it something it's not. Still, the newer textures are much better than the defaults I
|
|
||||||
* used to use. */
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,105 @@
|
|||||||
|
package electroblob.wizardry.client.particle;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
import org.lwjgl.opengl.GL11;
|
||||||
|
|
||||||
|
import electroblob.wizardry.Wizardry;
|
||||||
|
import net.minecraft.client.renderer.BufferBuilder;
|
||||||
|
import net.minecraft.client.renderer.GlStateManager;
|
||||||
|
import net.minecraft.client.renderer.Tessellator;
|
||||||
|
import net.minecraft.entity.Entity;
|
||||||
|
import net.minecraft.util.ResourceLocation;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
|
/** Superclass for particles with a second target entity or target position. */
|
||||||
|
public abstract class ParticleTargeted extends ParticleWizardry {
|
||||||
|
|
||||||
|
protected double targetX;
|
||||||
|
protected double targetY;
|
||||||
|
protected double targetZ;
|
||||||
|
|
||||||
|
/** The target this particle is linked to. The particle will stretch to touch this entity. */
|
||||||
|
@Nullable
|
||||||
|
protected Entity target = null;
|
||||||
|
|
||||||
|
public ParticleTargeted(World world, double x, double y, double z, ResourceLocation... textures){
|
||||||
|
super(world, x, y, z, textures);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setTargetPosition(double x, double y, double z){
|
||||||
|
this.targetX = x;
|
||||||
|
this.targetY = y;
|
||||||
|
this.targetZ = z;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setTargetEntity(Entity target){
|
||||||
|
this.target = target;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void renderParticle(BufferBuilder buffer, Entity viewer, float partialTicks, float rotationX, float rotationZ, float rotationYZ,
|
||||||
|
float rotationXY, float rotationXZ){
|
||||||
|
|
||||||
|
if(this.target != null){
|
||||||
|
this.targetX = this.target.posX;
|
||||||
|
this.targetY = this.target.getEntityBoundingBox().minY + target.height/2;
|
||||||
|
this.targetZ = this.target.posZ;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(Double.isNaN(targetX) || Double.isNaN(targetY) || Double.isNaN(targetZ)){
|
||||||
|
Wizardry.logger.warn("Attempted to render a targeted particle, but neither its target entity nor target"
|
||||||
|
+ "position was set!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// I'm pretty sure these were always static.
|
||||||
|
interpPosX = viewer.lastTickPosX + (viewer.posX - viewer.lastTickPosX) * (double)partialTicks;
|
||||||
|
interpPosY = viewer.lastTickPosY + (viewer.posY - viewer.lastTickPosY) * (double)partialTicks;
|
||||||
|
interpPosZ = viewer.lastTickPosZ + (viewer.posZ - viewer.lastTickPosZ) * (double)partialTicks;
|
||||||
|
|
||||||
|
float x = (float)(this.prevPosX + (this.posX - this.prevPosX) * (double)partialTicks - interpPosX);
|
||||||
|
float y = (float)(this.prevPosY + (this.posY - this.prevPosY) * (double)partialTicks - interpPosY);
|
||||||
|
float z = (float)(this.prevPosZ + (this.posZ - this.prevPosZ) * (double)partialTicks - interpPosZ);
|
||||||
|
|
||||||
|
GlStateManager.pushMatrix();
|
||||||
|
GlStateManager.translate(x, y, z);
|
||||||
|
|
||||||
|
double dx = this.targetX - this.posX;
|
||||||
|
double dy = this.targetY - this.posY;
|
||||||
|
double dz = this.targetZ - this.posZ;
|
||||||
|
|
||||||
|
// The distance from origin to endpoint
|
||||||
|
double length = Math.sqrt(dx*dx+dy*dy+dz*dz);
|
||||||
|
|
||||||
|
// Math.atan2 computes within -180 to +180, rather than -90 to +90.
|
||||||
|
float yaw = (float)(180d/Math.PI * Math.atan2(dx, dz));
|
||||||
|
float pitch = (float)(180f/(float)Math.PI * Math.atan(-dy/Math.sqrt(dz*dz+dx*dx)));
|
||||||
|
|
||||||
|
GL11.glRotatef(yaw, 0, 1, 0);
|
||||||
|
GL11.glRotatef(pitch, 1, 0, 0);
|
||||||
|
|
||||||
|
Tessellator tessellator = Tessellator.getInstance();
|
||||||
|
|
||||||
|
this.draw(tessellator, length, partialTicks);
|
||||||
|
|
||||||
|
GlStateManager.popMatrix();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Called from {@link ParticleTargeted#renderParticle(BufferBuilder, Entity, float, float, float, float, float, float)},
|
||||||
|
* once the appropriate calculations and transformations have been applied, to actually render the particle. Subclasses
|
||||||
|
* override this <i>instead</i> of overriding {@code renderParticle} directly, and inside render the particle <b>along
|
||||||
|
* the z-axis, starting at (0, 0, 0)</b> - it will be translated and rotated automatically.
|
||||||
|
* <p>
|
||||||
|
* <i>N.B. Other than transformations, no GL state changes are applied; these should be done within this method.</i>
|
||||||
|
*
|
||||||
|
* @param tessellator A reference to the tessellator, for convenience.
|
||||||
|
* @param length The distance from the origin to the endpoint for the particle being rendered; the particle should
|
||||||
|
* therefore be rendered between (0, 0, 0) and (0, 0, length) within this method.
|
||||||
|
* @param partialTicks The partial tick time.
|
||||||
|
*/
|
||||||
|
protected abstract void draw(Tessellator tessellator, double length, float partialTicks);
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,7 +1,20 @@
|
|||||||
package electroblob.wizardry.client.particle;
|
package electroblob.wizardry.client.particle;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
import electroblob.wizardry.Wizardry;
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.particle.Particle;
|
import net.minecraft.client.particle.Particle;
|
||||||
|
import net.minecraft.client.renderer.BufferBuilder;
|
||||||
|
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||||
|
import net.minecraft.entity.Entity;
|
||||||
|
import net.minecraft.util.ResourceLocation;
|
||||||
|
import net.minecraft.util.math.MathHelper;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
import net.minecraftforge.client.event.TextureStitchEvent;
|
||||||
import net.minecraftforge.fml.relauncher.Side;
|
import net.minecraftforge.fml.relauncher.Side;
|
||||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
import net.minecraftforge.fml.relauncher.SideOnly;
|
||||||
|
|
||||||
@@ -9,7 +22,7 @@ import net.minecraftforge.fml.relauncher.SideOnly;
|
|||||||
* Abstract superclass for all of wizardry's particles. This replaces {@code ParticleCustomTexture} (the functionality of
|
* Abstract superclass for all of wizardry's particles. This replaces {@code ParticleCustomTexture} (the functionality of
|
||||||
* which is no longer necessary since wizardry now uses {@code TextureAtlasSprite}s to do the rendering), and fits into
|
* which is no longer necessary since wizardry now uses {@code TextureAtlasSprite}s to do the rendering), and fits into
|
||||||
* {@code ParticleBuilder} by exposing all the necessary variables through getters, allowing them to be set on the fly
|
* {@code ParticleBuilder} by exposing all the necessary variables through getters, allowing them to be set on the fly
|
||||||
* rather than needing to be passed into the constructor.
|
* rather than needing to be passed into the constructor.
|
||||||
* <p>
|
* <p>
|
||||||
* The new system is as follows:
|
* The new system is as follows:
|
||||||
* <p>
|
* <p>
|
||||||
@@ -17,28 +30,94 @@ import net.minecraftforge.fml.relauncher.SideOnly;
|
|||||||
* - Each particle class defines any relevant default values in its constructor, including velocity.<br>
|
* - Each particle class defines any relevant default values in its constructor, including velocity.<br>
|
||||||
* - The particle builder then overwrites any other values that were set during building.
|
* - The particle builder then overwrites any other values that were set during building.
|
||||||
* <p>
|
* <p>
|
||||||
* This beauty of this system is that there are never any redundant parameters when spawning particles. For example,
|
* This beauty of this system is that there are never any redundant parameters when spawning particles, since you can set
|
||||||
|
* as many or as few parameters as necessary - and in addition, common defaults don't need setting at all. For example,
|
||||||
* snow particles nearly always fall at the same speed, which can now be defined in the particle class and no longer
|
* snow particles nearly always fall at the same speed, which can now be defined in the particle class and no longer
|
||||||
* needs to be defined when spawning the particle - but importantly, it can still be overridden if desired.
|
* needs to be defined when spawning the particle - but importantly, it can still be overridden if desired.
|
||||||
*
|
*
|
||||||
* @author Electroblob
|
* @author Electroblob
|
||||||
* @since Wizardry 4.2.0
|
* @since Wizardry 4.2.0
|
||||||
* @see electroblob.wizardry.util.ParticleBuilder ParticleBuilder
|
* @see electroblob.wizardry.util.ParticleBuilder ParticleBuilder
|
||||||
*/
|
*/
|
||||||
@SideOnly(Side.CLIENT)
|
@SideOnly(Side.CLIENT)
|
||||||
public abstract class ParticleWizardry extends Particle {
|
public abstract class ParticleWizardry extends Particle {
|
||||||
|
|
||||||
|
/** Implementation of animated particles using the TextureAtlasSprite system. Why vanilla doesn't support this I
|
||||||
|
* don't know, considering it too has animated particles. */
|
||||||
|
protected final TextureAtlasSprite[] sprites;
|
||||||
|
|
||||||
/** True if the particle is shaded, false if the particle always renders at full brightness. Defaults to false. */
|
/** True if the particle is shaded, false if the particle always renders at full brightness. Defaults to false. */
|
||||||
protected boolean shaded = false;
|
protected boolean shaded = false;
|
||||||
|
|
||||||
protected float fadeRed = 1;
|
|
||||||
protected float fadeGreen = 1;
|
|
||||||
protected float fadeBlue = 0;
|
|
||||||
|
|
||||||
public ParticleWizardry(World world, double x, double y, double z){
|
protected float initialRed;
|
||||||
|
protected float initialGreen;
|
||||||
|
protected float initialBlue;
|
||||||
|
|
||||||
|
protected float fadeRed = 0;
|
||||||
|
protected float fadeGreen = 0;
|
||||||
|
protected float fadeBlue = 0;
|
||||||
|
|
||||||
|
protected float angle;
|
||||||
|
protected double radius = 0;
|
||||||
|
protected double speed = 0;
|
||||||
|
|
||||||
|
/** The entity this particle is linked to. The particle will move with this entity. */
|
||||||
|
@Nullable
|
||||||
|
protected Entity entity = null;
|
||||||
|
/** Coordinates of this particle relative to the linked entity. If the linked entity is null, these are not used. */
|
||||||
|
protected double relativeX, relativeY, relativeZ;
|
||||||
|
/** Velocity of this particle relative to the linked entity. The relative x and z velocities are also used when
|
||||||
|
* the particle has spin to move the centre of rotation. If the linked entity is null and the particle is not
|
||||||
|
* spinning, these are not used and will be {@code NaN}. */
|
||||||
|
protected double relativeMotionX = Double.NaN, relativeMotionY = Double.NaN, relativeMotionZ = Double.NaN;
|
||||||
|
// Note that roll (equivalent to rotating the texture) is effectively handled by particleAngle - although that is
|
||||||
|
// actually the rotation speed and not the angle itself.
|
||||||
|
/** The yaw angle this particle is facing, or {@code NaN} if this particle always faces the viewer (default behaviour). */
|
||||||
|
protected float yaw = Float.NaN;
|
||||||
|
/** The pitch angle this particle is facing, or {@code NaN} if this particle always faces the viewer (default behaviour). */
|
||||||
|
protected float pitch = Float.NaN;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new particle in the given world at the given position. All other parameters are set via the various
|
||||||
|
* setter methods ({@link electroblob.wizardry.util.ParticleBuilder ParticleBuilder} deals with all of that anyway).
|
||||||
|
* @param world The world in which to create the particle.
|
||||||
|
* @param x The x-coordinate at which to create the particle.
|
||||||
|
* @param y The y-coordinate at which to create the particle.
|
||||||
|
* @param z The z-coordinate at which to create the particle.
|
||||||
|
* @param textures One or more {@code ResourceLocation}s representing the texture(s) used by this particle. These
|
||||||
|
* <b>must</b> be registered as {@link TextureAtlasSprite}s using {@link TextureStitchEvent} or the textures will be
|
||||||
|
* missing. If more than one {@code ResourceLocation} is specified, the particle will be animated with each texture
|
||||||
|
* shown in order for an equal proportion of the particle's lifetime. If this argument is omitted (or a zero-length
|
||||||
|
* array is given), the particle will use the vanilla system instead (based on the X/Y texture indices).
|
||||||
|
*/
|
||||||
|
public ParticleWizardry(World world, double x, double y, double z, ResourceLocation... textures){
|
||||||
|
|
||||||
super(world, x, y, z);
|
super(world, x, y, z);
|
||||||
|
|
||||||
|
// Sets the relative coordinates in case they are needed
|
||||||
|
this.relativeX = x;
|
||||||
|
this.relativeY = y;
|
||||||
|
this.relativeZ = z;
|
||||||
|
|
||||||
|
// Deals with the textures
|
||||||
|
if(textures.length > 0){
|
||||||
|
|
||||||
|
sprites = Arrays.stream(textures).map(t -> Minecraft.getMinecraft().getTextureMapBlocks().getAtlasSprite(
|
||||||
|
t.toString())).collect(Collectors.toList()).toArray(new TextureAtlasSprite[0]);
|
||||||
|
|
||||||
|
this.setParticleTexture(sprites[0]);
|
||||||
|
|
||||||
|
}else{
|
||||||
|
|
||||||
|
sprites = new TextureAtlasSprite[0];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ============================================== Parameter Setters ==============================================
|
||||||
|
|
||||||
|
// Setters for parameters that affect all particles - these are implemented in this class (although they may be
|
||||||
|
// reimplemented in subclasses)
|
||||||
|
|
||||||
/** Sets whether the particle should render at full brightness or not. True if the particle is shaded, false if
|
/** Sets whether the particle should render at full brightness or not. True if the particle is shaded, false if
|
||||||
* the particle always renders at full brightness. Defaults to false.*/
|
* the particle always renders at full brightness. Defaults to false.*/
|
||||||
public void setShaded(boolean shaded){
|
public void setShaded(boolean shaded){
|
||||||
@@ -50,9 +129,9 @@ public abstract class ParticleWizardry extends Particle {
|
|||||||
this.particleGravity = gravity ? 1 : 0;
|
this.particleGravity = gravity ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Sets this particle's lifetime in ticks.*/
|
/** Sets this particle's collisions. True to enable block collisions, false to disable. Defaults to false.*/
|
||||||
public void setLifetime(int lifetime){
|
public void setCollisions(boolean canCollide){
|
||||||
this.particleMaxAge = lifetime;
|
this.canCollide = canCollide;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -67,25 +146,252 @@ public abstract class ParticleWizardry extends Particle {
|
|||||||
this.motionZ = vz;
|
this.motionZ = vz;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the spin parameters of the particle.
|
||||||
|
* @param radius The spin radius
|
||||||
|
* @param speed The spin speed in rotations per tick
|
||||||
|
*/
|
||||||
|
public void setSpin(double radius, double speed){
|
||||||
|
this.radius = radius;
|
||||||
|
this.speed = speed * 2 * Math.PI; // Converts rotations per tick into radians per tick for the trig functions
|
||||||
|
this.angle = this.rand.nextFloat() * (float)Math.PI * 2; // Random start angle TODO: Perhaps this should be specified?
|
||||||
|
// Need to set the start position or the circle won't be centred on the correct position
|
||||||
|
this.relativeX = radius * -MathHelper.cos(angle);
|
||||||
|
this.relativeZ = radius * MathHelper.sin(angle);
|
||||||
|
this.setPosition(posX + relativeX, posY, posZ + relativeZ);
|
||||||
|
this.prevPosX = posX;
|
||||||
|
this.prevPosZ = posZ;
|
||||||
|
// Set these to the correct values
|
||||||
|
this.relativeMotionX = motionX;
|
||||||
|
this.relativeMotionY = motionY;
|
||||||
|
this.relativeMotionZ = motionZ;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Links this particle to the given entity. This will cause its position and velocity to be relative to the entity.
|
||||||
|
* @param entity The entity to link to.
|
||||||
|
*/
|
||||||
|
public void setEntity(Entity entity){
|
||||||
|
this.entity = entity;
|
||||||
|
// Set these to the correct values
|
||||||
|
if(entity != null){
|
||||||
|
this.setPosition(this.entity.posX + relativeX, this.entity.getEntityBoundingBox().minY
|
||||||
|
+ relativeY, this.entity.posZ + relativeZ);
|
||||||
|
this.prevPosX = this.posX;
|
||||||
|
this.prevPosY = this.posY;
|
||||||
|
this.prevPosZ = this.posZ;
|
||||||
|
this.relativeMotionX = motionX;
|
||||||
|
this.relativeMotionY = motionY;
|
||||||
|
this.relativeMotionZ = motionZ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Overridden to set the initial colour values
|
||||||
|
/**
|
||||||
|
* Sets the base colour of the particle. <i>Note that this also sets the fade colour so that particles without a
|
||||||
|
* fade colour do not change colour at all; as such fade colour must be set <b>after</b> calling this method.</i>
|
||||||
|
* @param r The red colour component
|
||||||
|
* @param g The green colour component
|
||||||
|
* @param b The blue colour component
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void setRBGColorF(float r, float g, float b){
|
||||||
|
super.setRBGColorF(r, g, b);
|
||||||
|
initialRed = r;
|
||||||
|
initialGreen = g;
|
||||||
|
initialBlue = b;
|
||||||
|
// If fade colour is not specified, it defaults to the main colour - this method is always called first
|
||||||
|
setFadeColour(r, g, b);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the fade colour of the particle.
|
* Sets the fade colour of the particle.
|
||||||
* @param r The red colour component
|
* @param r The red colour component
|
||||||
* @param g The green colour component
|
* @param g The green colour component
|
||||||
* @param g The blue colour component
|
* @param b The blue colour component
|
||||||
*/
|
*/
|
||||||
public void setFadeColour(float r, float g, float b){
|
public void setFadeColour(float r, float g, float b){
|
||||||
this.fadeRed = r;
|
this.fadeRed = r;
|
||||||
this.fadeGreen = g;
|
this.fadeGreen = g;
|
||||||
this.fadeBlue = b;
|
this.fadeBlue = b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the direction this particle faces. This will cause the particle to render facing the given direction.
|
||||||
|
* @param yaw The yaw angle of this particle in degrees, where 0 is [TODO south?].
|
||||||
|
* @param pitch The pitch angle of this particle in degrees, where 0 is horizontal.
|
||||||
|
*/
|
||||||
|
public void setFacing(float yaw, float pitch){
|
||||||
|
this.yaw = yaw;
|
||||||
|
this.pitch = pitch;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Setters for parameters that only affect some particles - these are unimplemented in this class because they
|
||||||
|
// doesn't make sense for most particles
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the target position for this particle. This will cause it to stretch to touch the given position,
|
||||||
|
* if supported.
|
||||||
|
* @param x The x-coordinate of the target position.
|
||||||
|
* @param y The y-coordinate of the target position.
|
||||||
|
* @param z The z-coordinate of the target position.
|
||||||
|
*/
|
||||||
|
public void setTargetPosition(double x, double y, double z){
|
||||||
|
// Does nothing for normal particles since normal particles always render at a single point
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Links this particle to the given target. This will cause it to stretch to touch the target, if supported.
|
||||||
|
* @param target The target to link to.
|
||||||
|
*/
|
||||||
|
public void setTargetEntity(Entity target){
|
||||||
|
// Does nothing for normal particles since normal particles always render at a single point
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================== Method Overrides ==============================================
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getFXLayer(){
|
||||||
|
return sprites.length == 0 ? super.getFXLayer() : 1; // This has to be 1 for the TextureAtlasSprites to work
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getBrightnessForRender(float partialTick){
|
public int getBrightnessForRender(float partialTick){
|
||||||
return shaded ? super.getBrightnessForRender(partialTick) : 15728880;
|
return shaded ? super.getBrightnessForRender(partialTick) : 15728880;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renders the particle. The mapping names given to the parameters in this method are very misleading; see below for
|
||||||
|
* details of what they actually do. (They're also in a strange order...)
|
||||||
|
* @param buffer The {@code BufferBuilder} object.
|
||||||
|
* @param viewer The entity whose viewpoint the particle is being rendered from; this should always be the
|
||||||
|
* client-side player.
|
||||||
|
* @param partialTicks The partial tick time.
|
||||||
|
* @param lookZ Equal to the cosine of {@code viewer.rotationYaw}. Will be -1 when facing north (negative Z), 0 when
|
||||||
|
* east/west, and +1 when facing south (positive Z). Independent of pitch.
|
||||||
|
* @param lookY Equal to the cosine of {@code viewer.rotationPitch}. Will be 1 when facing directly up or down, and 0
|
||||||
|
* when facing directly horizontally.
|
||||||
|
* @param lookX Equal to the sine of {@code viewer.rotationYaw}. Will be -1 when facing east (positive X), 0 when
|
||||||
|
* facing north/south, and +1 when facing west (negative X). Independent of pitch.
|
||||||
|
* @param lookXY Equal to {@code lookX} times the sine of {@code viewer.rotationPitch}. Will be 0 when facing directly horizontal.
|
||||||
|
* When facing directly up, will be equal to {@code -lookX}. When facing directly down, will be equal to {@code lookX}.
|
||||||
|
* @param lookYZ Equal to {@code -lookZ} times the sine of {@code viewer.rotationPitch}. Will be 0 when facing directly horizontal.
|
||||||
|
* When facing directly up, will be equal to {@code -lookZ}. When facing directly down, will be equal to {@code lookZ}.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void renderParticle(BufferBuilder buffer, Entity viewer, float partialTicks, float lookZ, float lookY,
|
||||||
|
float lookX, float lookXY, float lookYZ){
|
||||||
|
|
||||||
|
if(Float.isNaN(this.yaw) || Float.isNaN(this.pitch)){
|
||||||
|
|
||||||
|
// Normal behaviour (rotates to face the viewer)
|
||||||
|
super.renderParticle(buffer, viewer, partialTicks, lookZ, lookY, lookX, lookXY, lookYZ);
|
||||||
|
|
||||||
|
}else{
|
||||||
|
|
||||||
|
// Specific rotation
|
||||||
|
|
||||||
|
// Copied from ActiveRenderInfo; converts yaw and pitch into the weird parameters used by renderParticle.
|
||||||
|
// The 1st/3rd person distinction has been removed since this has nothing to do with the view angle.
|
||||||
|
|
||||||
|
float degToRadFactor = 0.017453292f; // Conversion from degrees to radians
|
||||||
|
|
||||||
|
float rotationX = MathHelper.cos(yaw * degToRadFactor);
|
||||||
|
float rotationZ = MathHelper.sin(yaw * degToRadFactor);
|
||||||
|
float rotationY = MathHelper.cos(pitch * degToRadFactor);
|
||||||
|
float rotationYZ = -rotationZ * MathHelper.sin(pitch * degToRadFactor);
|
||||||
|
float rotationXY = rotationX * MathHelper.sin(pitch * degToRadFactor);
|
||||||
|
|
||||||
|
super.renderParticle(buffer, viewer, partialTicks, rotationX, rotationY, rotationZ, rotationYZ, rotationXY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onUpdate(){
|
||||||
|
|
||||||
/** Simple particle factory interface which takes a world and a position and returns a particle. Used (via lambda
|
super.onUpdate();
|
||||||
* expressions) in the client proxy to link particle enum types to actual particle classes. */
|
|
||||||
|
// If any of these values is NaN, the particle has neither an entity nor a spin
|
||||||
|
if(!Double.isNaN(relativeMotionX) && !Double.isNaN(relativeMotionY) && !Double.isNaN(relativeMotionZ)){
|
||||||
|
|
||||||
|
// This allows velocity changes from entity linking and spin to stack
|
||||||
|
double vx = relativeMotionX;
|
||||||
|
double vy = relativeMotionY;
|
||||||
|
double vz = relativeMotionZ;
|
||||||
|
|
||||||
|
// Entity linking
|
||||||
|
if(this.entity != null){
|
||||||
|
|
||||||
|
if(this.entity.isDead) this.setExpired();
|
||||||
|
|
||||||
|
this.setPosition(this.entity.posX + relativeX, this.entity.getEntityBoundingBox().minY + relativeY,
|
||||||
|
this.entity.posZ + relativeZ);
|
||||||
|
// Velocity is set so that the renderer will interpolate correctly between ticks
|
||||||
|
vx += this.entity.motionX;
|
||||||
|
vy += this.entity.motionY;
|
||||||
|
vz += this.entity.motionZ;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Spin
|
||||||
|
if(radius > 0){
|
||||||
|
angle += speed;
|
||||||
|
vx += radius * speed * MathHelper.sin(angle);
|
||||||
|
vz += radius * speed * MathHelper.cos(angle);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.relativeX += vx;
|
||||||
|
this.relativeY += vy;
|
||||||
|
this.relativeZ += vz;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Colour fading
|
||||||
|
float ageFraction = (float)this.particleAge / (float)this.particleMaxAge;
|
||||||
|
// No longer uses setRBGColorF because that method now also sets the initial values
|
||||||
|
this.particleRed = this.initialRed + (this.fadeRed - this.initialRed) * ageFraction;
|
||||||
|
this.particleGreen = this.initialGreen + (this.fadeGreen - this.initialGreen) * ageFraction;
|
||||||
|
this.particleBlue = this.initialBlue + (this.fadeBlue - this.initialBlue) * ageFraction;
|
||||||
|
|
||||||
|
// Animation
|
||||||
|
if(sprites.length > 1){
|
||||||
|
// Math.min included for safety so the index cannot possibly exceed the length - 1 an cause an AIOOBE
|
||||||
|
// (which would probably otherwise happen if particleAge == particleMaxAge)
|
||||||
|
this.setParticleTexture(sprites[Math.min((int)(ageFraction * sprites.length), sprites.length - 1)]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// =============================================== Helper Methods ===============================================
|
||||||
|
|
||||||
|
/** Static helper method that generates an array of n ResourceLocations using the particle file naming convention,
|
||||||
|
* which is the given stem plus an underscore plus the integer index. */
|
||||||
|
public static ResourceLocation[] generateTextures(String stem, int n){
|
||||||
|
|
||||||
|
ResourceLocation[] textures = new ResourceLocation[n];
|
||||||
|
|
||||||
|
for(int i=0; i<n; i++){
|
||||||
|
textures[i] = new ResourceLocation(Wizardry.MODID, "particle/" + stem + "_" + i);
|
||||||
|
}
|
||||||
|
|
||||||
|
return textures;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Static helper method that generates a 2D m x n array of ResourceLocations using the particle file naming
|
||||||
|
* convention, which is the given stem plus an underscore plus the first index, plus an underscore plus the second
|
||||||
|
* index. Useful for animated particles that also pick a random animation strip. */
|
||||||
|
public static ResourceLocation[][] generateTextures(String stem, int m, int n){
|
||||||
|
|
||||||
|
ResourceLocation[][] textures = new ResourceLocation[m][n];
|
||||||
|
|
||||||
|
for(int i=0; i<m; i++){
|
||||||
|
for(int j=0; j<n; j++){
|
||||||
|
textures[i][j] = new ResourceLocation(Wizardry.MODID, "particle/" + stem + "_" + i + "_" + j);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return textures;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Simple particle factory interface which takes a world and a position and returns a particle. Used (via method
|
||||||
|
* references) in the client proxy to link particle enum types to actual particle classes. */
|
||||||
@SideOnly(Side.CLIENT)
|
@SideOnly(Side.CLIENT)
|
||||||
@FunctionalInterface
|
@FunctionalInterface
|
||||||
public interface IWizardryParticleFactory {
|
public interface IWizardryParticleFactory {
|
||||||
|
|||||||
@@ -1,187 +0,0 @@
|
|||||||
package electroblob.wizardry.client.renderer;
|
|
||||||
|
|
||||||
import java.util.Random;
|
|
||||||
|
|
||||||
import org.lwjgl.opengl.GL11;
|
|
||||||
|
|
||||||
import electroblob.wizardry.entity.EntityArc;
|
|
||||||
import net.minecraft.client.renderer.BufferBuilder;
|
|
||||||
import net.minecraft.client.renderer.GlStateManager;
|
|
||||||
import net.minecraft.client.renderer.OpenGlHelper;
|
|
||||||
import net.minecraft.client.renderer.Tessellator;
|
|
||||||
import net.minecraft.client.renderer.entity.Render;
|
|
||||||
import net.minecraft.client.renderer.entity.RenderManager;
|
|
||||||
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
|
|
||||||
import net.minecraft.util.ResourceLocation;
|
|
||||||
|
|
||||||
public class RenderArc extends Render<EntityArc> {
|
|
||||||
|
|
||||||
public RenderArc(RenderManager renderManager){
|
|
||||||
super(renderManager);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void doRender(EntityArc arc, double x, double y, double z, float viewPitch, float viewYaw) {
|
|
||||||
|
|
||||||
GlStateManager.pushMatrix();
|
|
||||||
GlStateManager.translate(x, y, z);
|
|
||||||
GlStateManager.disableLighting();
|
|
||||||
GlStateManager.enableBlend();
|
|
||||||
GlStateManager.disableTexture2D();
|
|
||||||
GlStateManager.blendFunc(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE);
|
|
||||||
OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240f, 240f);
|
|
||||||
|
|
||||||
Tessellator tessellator = Tessellator.getInstance();
|
|
||||||
|
|
||||||
/* Note: A lot of the maths here works on similar triangles and the ratios between them, avoiding too much
|
|
||||||
* pythagoras and eliminating the need for any trig. Ratios are used for the positioning of the arc endpoints.
|
|
||||||
* Ratios are usually used swapping x and z because the triangles are rotated through 90 degrees. */
|
|
||||||
|
|
||||||
double dx = -x;
|
|
||||||
double dy = -y;
|
|
||||||
double dz = -z;
|
|
||||||
|
|
||||||
if(arc.x1 != 0){
|
|
||||||
|
|
||||||
dx = arc.x1 - arc.posX;
|
|
||||||
dy = arc.y1 - arc.posY;
|
|
||||||
dz = arc.z1 - arc.posZ;
|
|
||||||
|
|
||||||
// The distance from origin to endpoint
|
|
||||||
double arcLength = Math.sqrt(dx*dx+dy*dy+dz*dz);
|
|
||||||
|
|
||||||
GL11.glTranslated(dx, dy, dz);
|
|
||||||
|
|
||||||
// Math.atan2 computes within -180 to +180, rather than -90 to +90.
|
|
||||||
float yaw = (float)(180d/Math.PI * Math.atan2(-dx, -dz));
|
|
||||||
float pitch = (float)(180f/(float)Math.PI * Math.atan(dy/Math.sqrt(dz*dz+dx*dx)));
|
|
||||||
|
|
||||||
GL11.glRotatef(yaw, 0, 1, 0);
|
|
||||||
GL11.glRotatef(pitch, 1, 0, 0);
|
|
||||||
|
|
||||||
// The direction of the arc drawn by the tessellator is always along the z axis and is rotated to the
|
|
||||||
// correct orientation, that way there isn't a ton of trigonometry and the code is way neater.
|
|
||||||
|
|
||||||
boolean freeEnd = arc.freeEnd;
|
|
||||||
|
|
||||||
// == To be extracted as constants later ==
|
|
||||||
float thickness = 0.04f; // Half the width of the outermost layer
|
|
||||||
double maxSegmentLength = 0.6; // Max length of a segment, obviously
|
|
||||||
double minSegmentLength = 0.2; // Min length of a segment
|
|
||||||
double vertexDither = 0.15; // Max deviation in x or y axis from the centreline
|
|
||||||
int maxForkSegments = 3; // Max number of segments a fork can have
|
|
||||||
float forkChance = 0.3f; // Chance (as a fraction) that a vertex will have a fork
|
|
||||||
int updateTime = 1; // Number of ticks to wait before the arc changes shape again
|
|
||||||
|
|
||||||
int numberOfSegments = (int)Math.round(arcLength/maxSegmentLength); // Number of segments
|
|
||||||
|
|
||||||
for(int layer=0; layer<3; layer++){
|
|
||||||
|
|
||||||
double px=0, py=0, pz=0;
|
|
||||||
// Creates a random from the arc's seed field + the number of ticks it has existed/the update period.
|
|
||||||
// By using a seed, we can ensure the vertex positions and forks are identical a) for each layer, even
|
|
||||||
// though they are rendered sequentially, and b) across many frames (and ticks, if updateTime > 1).
|
|
||||||
Random random = new Random(arc.seed + arc.ticksExisted/updateTime);
|
|
||||||
|
|
||||||
// numberOfSegments-1 because the last segment is handled separately.
|
|
||||||
for(int i=0; i<numberOfSegments-1; i++){
|
|
||||||
|
|
||||||
double px2 = (random.nextDouble()*2-1)*vertexDither; // Maybe use Gaussians?
|
|
||||||
double py2 = (random.nextDouble()*2-1)*vertexDither;
|
|
||||||
double pz2 = pz + arcLength/(double)numberOfSegments; // For now they are all the same length
|
|
||||||
|
|
||||||
drawSegment(tessellator, layer, px, py, pz, px2, py2, pz2, thickness);
|
|
||||||
|
|
||||||
// Forks
|
|
||||||
if(random.nextFloat() < forkChance){
|
|
||||||
|
|
||||||
double px3=px, py3=py, pz3=pz;
|
|
||||||
|
|
||||||
for(int j=0; j<random.nextInt(maxForkSegments-1)+1; j++){
|
|
||||||
// Forks set their centreline to the x/y coordinates of the vertex they originate from
|
|
||||||
double px4 = px3 + (random.nextDouble()*2-1)*vertexDither;
|
|
||||||
double py4 = py3 + (random.nextDouble()*2-1)*vertexDither;
|
|
||||||
double pz4 = pz3 + minSegmentLength + random.nextDouble()*(maxSegmentLength - minSegmentLength);
|
|
||||||
|
|
||||||
drawSegment(tessellator, layer, px3, py3, pz3, px4, py4, pz4, thickness*0.8f);
|
|
||||||
|
|
||||||
// Forks of forks
|
|
||||||
if(random.nextFloat() < forkChance){
|
|
||||||
|
|
||||||
double px5 = px3 + (random.nextDouble()*2-1)*vertexDither;
|
|
||||||
double py5 = py3 + (random.nextDouble()*2-1)*vertexDither;
|
|
||||||
double pz5 = pz3 + minSegmentLength + random.nextDouble()*(maxSegmentLength - minSegmentLength);
|
|
||||||
|
|
||||||
drawSegment(tessellator, layer, px3, py3, pz3, px5, py5, pz5, thickness*0.6f);
|
|
||||||
}
|
|
||||||
|
|
||||||
px3 = px4;
|
|
||||||
py3 = py4;
|
|
||||||
pz3 = pz4;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
px = px2;
|
|
||||||
py = py2;
|
|
||||||
pz = pz2;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Last segment has a specific end position and cannot fork.
|
|
||||||
double px2 = freeEnd ? (random.nextDouble()*2-1)*vertexDither : 0;
|
|
||||||
double py2 = freeEnd ? (random.nextDouble()*2-1)*vertexDither : 0;
|
|
||||||
drawSegment(tessellator, layer, px, py, pz, px2, py2, arcLength, thickness);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
GlStateManager.enableTexture2D();
|
|
||||||
GlStateManager.enableLighting();
|
|
||||||
GlStateManager.disableBlend();
|
|
||||||
GlStateManager.popMatrix();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Draws the given layer of a segment of the arc, from the point (x1, y1, z1) to the point (x2, y2, z2), with the given thickness. */
|
|
||||||
private void drawSegment(Tessellator tessellator, int layer, double x1, double y1, double z1, double x2, double y2, double z2, float thickness){
|
|
||||||
|
|
||||||
BufferBuilder buffer = tessellator.getBuffer();
|
|
||||||
buffer.begin(GL11.GL_TRIANGLE_STRIP, DefaultVertexFormats.POSITION_COLOR);
|
|
||||||
|
|
||||||
switch(layer){
|
|
||||||
case 0:
|
|
||||||
// TODO: Extract these colours as constants
|
|
||||||
drawShearedBox(buffer, x1, y1, z1, x2, y2, z2, 0.25f*thickness, 255, 255, 255, 255);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 1:
|
|
||||||
drawShearedBox(buffer, x1, y1, z1, x2, y2, z2, 0.6f*thickness, 200, 255, 255, 165);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 2:
|
|
||||||
drawShearedBox(buffer, x1, y1, z1, x2, y2, z2, thickness, 50, 150, 255, 75);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
tessellator.draw();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Draws a single box for one segment of the arc, from the point (x1, y1, z1) to the point (x2, y2, z2), with given width and colour. */
|
|
||||||
private void drawShearedBox(BufferBuilder buffer, double x1, double y1, double z1, double x2, double y2, double z2, float width, int r, int g, int b, int a){
|
|
||||||
|
|
||||||
buffer.pos(x1-width, y1-width, z1).color(r, g, b, a).endVertex();
|
|
||||||
buffer.pos(x2-width, y2-width, z2).color(r, g, b, a).endVertex();
|
|
||||||
buffer.pos(x1-width, y1+width, z1).color(r, g, b, a).endVertex();
|
|
||||||
buffer.pos(x2-width, y2+width, z2).color(r, g, b, a).endVertex();
|
|
||||||
buffer.pos(x1+width, y1+width, z1).color(r, g, b, a).endVertex();
|
|
||||||
buffer.pos(x2+width, y2+width, z2).color(r, g, b, a).endVertex();
|
|
||||||
buffer.pos(x1+width, y1-width, z1).color(r, g, b, a).endVertex();
|
|
||||||
buffer.pos(x2+width, y2-width, z2).color(r, g, b, a).endVertex();
|
|
||||||
buffer.pos(x1-width, y1-width, z1).color(r, g, b, a).endVertex();
|
|
||||||
buffer.pos(x2-width, y2-width, z2).color(r, g, b, a).endVertex();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected ResourceLocation getEntityTexture(EntityArc entity){
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,72 +0,0 @@
|
|||||||
package electroblob.wizardry.client.renderer;
|
|
||||||
|
|
||||||
import org.lwjgl.opengl.GL11;
|
|
||||||
|
|
||||||
import electroblob.wizardry.Wizardry;
|
|
||||||
import electroblob.wizardry.entity.construct.EntityLightningPulse;
|
|
||||||
import net.minecraft.client.renderer.BufferBuilder;
|
|
||||||
import net.minecraft.client.renderer.GlStateManager;
|
|
||||||
import net.minecraft.client.renderer.OpenGlHelper;
|
|
||||||
import net.minecraft.client.renderer.Tessellator;
|
|
||||||
import net.minecraft.client.renderer.entity.Render;
|
|
||||||
import net.minecraft.client.renderer.entity.RenderManager;
|
|
||||||
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
|
|
||||||
import net.minecraft.util.ResourceLocation;
|
|
||||||
|
|
||||||
public class RenderLightningPulse extends Render<EntityLightningPulse> {
|
|
||||||
|
|
||||||
private final ResourceLocation[] textures = new ResourceLocation[8];
|
|
||||||
private float scale = 1.0f;
|
|
||||||
|
|
||||||
public RenderLightningPulse(RenderManager renderManager, float scale){
|
|
||||||
super(renderManager);
|
|
||||||
for(int i = 0; i < textures.length; i++){
|
|
||||||
textures[i] = new ResourceLocation(Wizardry.MODID, "textures/entity/lightning_pulse_" + i + ".png");
|
|
||||||
}
|
|
||||||
this.scale = scale;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void doRender(EntityLightningPulse entity, double par2, double par4, double par6, float par8, float par9){
|
|
||||||
|
|
||||||
GlStateManager.pushMatrix();
|
|
||||||
GlStateManager.enableBlend();
|
|
||||||
GlStateManager.disableLighting();
|
|
||||||
OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240, 240);
|
|
||||||
GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
|
|
||||||
|
|
||||||
float yOffset = 0;
|
|
||||||
|
|
||||||
GlStateManager.translate((float)par2, (float)par4 + yOffset, (float)par6);
|
|
||||||
|
|
||||||
this.bindTexture(textures[entity.ticksExisted]);
|
|
||||||
float f6 = 1.0F;
|
|
||||||
float f7 = 0.5F;
|
|
||||||
float f8 = 0.5F;
|
|
||||||
|
|
||||||
GlStateManager.rotate(-90, 1, 0, 0);
|
|
||||||
|
|
||||||
GlStateManager.scale(scale, scale, scale);
|
|
||||||
|
|
||||||
Tessellator tessellator = Tessellator.getInstance();
|
|
||||||
BufferBuilder buffer = tessellator.getBuffer();
|
|
||||||
buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX);
|
|
||||||
buffer.pos((double)(0.0F - f7), (double)(0.0F - f8), 0.01).tex(0, 1).endVertex();
|
|
||||||
buffer.pos((double)(f6 - f7), (double)(0.0F - f8), 0.01).tex(1, 1).endVertex();
|
|
||||||
buffer.pos((double)(f6 - f7), (double)(1.0F - f8), 0.01).tex(1, 0).endVertex();
|
|
||||||
buffer.pos((double)(0.0F - f7), (double)(1.0F - f8), 0.01).tex(0, 0).endVertex();
|
|
||||||
|
|
||||||
tessellator.draw();
|
|
||||||
|
|
||||||
GlStateManager.disableBlend();
|
|
||||||
GlStateManager.enableLighting();
|
|
||||||
GlStateManager.disableRescaleNormal();
|
|
||||||
GlStateManager.popMatrix();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected ResourceLocation getEntityTexture(EntityLightningPulse entity){
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,78 +0,0 @@
|
|||||||
package electroblob.wizardry.entity;
|
|
||||||
|
|
||||||
import io.netty.buffer.ByteBuf;
|
|
||||||
import net.minecraft.entity.Entity;
|
|
||||||
import net.minecraft.nbt.NBTTagCompound;
|
|
||||||
import net.minecraft.world.World;
|
|
||||||
import net.minecraftforge.fml.common.registry.IEntityAdditionalSpawnData;
|
|
||||||
|
|
||||||
public class EntityArc extends Entity implements IEntityAdditionalSpawnData {
|
|
||||||
|
|
||||||
public double x1, y1, z1, x2, y2, z2;
|
|
||||||
/** The number of ticks the arc lasts for before disappearing. */
|
|
||||||
public int lifetime = 3;
|
|
||||||
/** False if the arc is locked to an entity, true otherwise. False by default. */
|
|
||||||
public boolean freeEnd = false;
|
|
||||||
/** A random long value used by the renderer as a seed to generate its vertices from, ensuring they remain the same
|
|
||||||
* across multiple frames. Not synced. */
|
|
||||||
public final long seed;
|
|
||||||
|
|
||||||
public EntityArc(World par1World){
|
|
||||||
super(par1World);
|
|
||||||
seed = this.rand.nextLong();
|
|
||||||
this.ignoreFrustumCheck = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setEndpointCoords(double x1, double y1, double z1, double x2, double y2, double z2){
|
|
||||||
this.x1 = x1;
|
|
||||||
this.y1 = y1;
|
|
||||||
this.z1 = z1;
|
|
||||||
this.x2 = x2;
|
|
||||||
this.y2 = y2;
|
|
||||||
this.z2 = z2;
|
|
||||||
this.setPosition(x2, y2, z2);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onUpdate(){
|
|
||||||
if(this.ticksExisted >= lifetime){
|
|
||||||
this.setDead();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void entityInit(){
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void readEntityFromNBT(NBTTagCompound nbttagcompound){
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void writeEntityToNBT(NBTTagCompound nbttagcompound){
|
|
||||||
// Nothing needed here; arc is merely a graphic effect that only exists for a few ticks; as such there is no
|
|
||||||
// need to save it.
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isInRangeToRenderDist(double distance){
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void writeSpawnData(ByteBuf data){
|
|
||||||
data.writeDouble(this.x1);
|
|
||||||
data.writeDouble(this.y1);
|
|
||||||
data.writeDouble(this.z1);
|
|
||||||
data.writeBoolean(freeEnd);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void readSpawnData(ByteBuf data){
|
|
||||||
this.x1 = data.readDouble();
|
|
||||||
this.y1 = data.readDouble();
|
|
||||||
this.z1 = data.readDouble();
|
|
||||||
this.freeEnd = data.readBoolean();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -53,24 +53,13 @@ public class EntityBlizzard extends EntityMagicConstruct {
|
|||||||
if(!MagicDamage.isEntityImmune(DamageType.FROST, target))
|
if(!MagicDamage.isEntityImmune(DamageType.FROST, target))
|
||||||
target.addPotionEffect(new PotionEffect(WizardryPotions.frost, 20, 0));
|
target.addPotionEffect(new PotionEffect(WizardryPotions.frost, 20, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
}else{
|
}else{
|
||||||
for(int i=1; i<6; i++){
|
|
||||||
|
for(int i=1; i<12; i++){
|
||||||
float brightness = 0.5f + (rand.nextFloat() / 2);
|
double speed = (rand.nextBoolean() ? 1 : -1) * 0.1 + 0.05 * rand.nextDouble();
|
||||||
|
ParticleBuilder.create(Type.SNOW).pos(this.posX, this.posY + rand.nextDouble() * 3, this.posZ).vel(0, 0, 0)
|
||||||
ParticleBuilder.create(Type.BLIZZARD)
|
.time(100).scale(2).spin(rand.nextDouble() * 2.5 + 0.5, speed).spawn(world);
|
||||||
.pos(this.posX, this.posY + rand.nextDouble() * 3, this.posZ)
|
|
||||||
.lifetime(100)
|
|
||||||
.colour(brightness, brightness + 0.1f, 1.0f)
|
|
||||||
.radius(rand.nextDouble() * 2.5d + 0.5d)
|
|
||||||
.spawn(world);
|
|
||||||
|
|
||||||
ParticleBuilder.create(Type.BLIZZARD)
|
|
||||||
.pos(this.posX, this.posY + rand.nextDouble() * 3, this.posZ)
|
|
||||||
.lifetime(100)
|
|
||||||
.colour(1, 1, 1)
|
|
||||||
.radius(rand.nextDouble() * 2.5d + 0.5d)
|
|
||||||
.spawn(world);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ public class EntityDecay extends EntityMagicConstruct {
|
|||||||
|
|
||||||
ParticleBuilder.create(Type.DARK_MAGIC)
|
ParticleBuilder.create(Type.DARK_MAGIC)
|
||||||
.pos(this.posX + radius * Math.cos(angle), this.posY, this.posZ + radius * Math.sin(angle))
|
.pos(this.posX + radius * Math.cos(angle), this.posY, this.posZ + radius * Math.sin(angle))
|
||||||
.colour(brightness, 0, brightness + 0.1f)
|
.clr(brightness, 0, brightness + 0.1f)
|
||||||
.spawn(world);
|
.spawn(world);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -66,8 +66,8 @@ public class EntityForcefield extends EntityMagicConstruct {
|
|||||||
ParticleBuilder.create(Type.DUST)
|
ParticleBuilder.create(Type.DUST)
|
||||||
.pos(this.posX + radius * Math.cos(yaw) * Math.cos(pitch), this.posY + 3 + radius * Math.sin(pitch),
|
.pos(this.posX + radius * Math.cos(yaw) * Math.cos(pitch), this.posY + 3 + radius * Math.sin(pitch),
|
||||||
this.posZ + radius * Math.sin(yaw) * Math.cos(pitch))
|
this.posZ + radius * Math.sin(yaw) * Math.cos(pitch))
|
||||||
.lifetime(48 + this.rand.nextInt(12))
|
.time(48 + this.rand.nextInt(12))
|
||||||
.colour(brightness, brightness, 1.0f).spawn(world);
|
.clr(brightness, brightness, 1.0f).spawn(world);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package electroblob.wizardry.entity.construct;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import electroblob.wizardry.Wizardry;
|
import electroblob.wizardry.Wizardry;
|
||||||
import electroblob.wizardry.entity.EntityArc;
|
|
||||||
import electroblob.wizardry.registry.WizardrySounds;
|
import electroblob.wizardry.registry.WizardrySounds;
|
||||||
import electroblob.wizardry.util.MagicDamage;
|
import electroblob.wizardry.util.MagicDamage;
|
||||||
import electroblob.wizardry.util.MagicDamage.DamageType;
|
import electroblob.wizardry.util.MagicDamage.DamageType;
|
||||||
@@ -98,24 +97,12 @@ public class EntityHammer extends EntityMagicConstruct {
|
|||||||
|
|
||||||
if(this.isValidTarget(target)){
|
if(this.isValidTarget(target)){
|
||||||
|
|
||||||
if(!world.isRemote){
|
if(world.isRemote){
|
||||||
EntityArc arc = new EntityArc(world);
|
|
||||||
arc.setEndpointCoords(this.posX, this.posY + this.height - 0.1, this.posZ, target.posX,
|
ParticleBuilder.create(Type.LIGHTNING).pos(posX, posY + height - 0.1, posZ) .target(target).spawn(world);
|
||||||
target.posY + target.height / 2, target.posZ);
|
|
||||||
world.spawnEntity(arc);
|
ParticleBuilder.spawnShockParticles(world, target.posX,
|
||||||
}else{
|
target.getEntityBoundingBox().minY + target.height, target.posZ);
|
||||||
// TODO: Move all the arc particle (and sound?) stuff into a method in WizardryUtilities
|
|
||||||
for(int j=0; j<8; j++){
|
|
||||||
ParticleBuilder.create(Type.SPARK)
|
|
||||||
.pos(target.posX + world.rand.nextFloat() - 0.5,
|
|
||||||
target.getEntityBoundingBox().minY + target.height / 2 + world.rand.nextFloat() * 2 - 1,
|
|
||||||
target.posZ + world.rand.nextFloat() - 0.5)
|
|
||||||
.spawn(world);
|
|
||||||
|
|
||||||
world.spawnParticle(EnumParticleTypes.SMOKE_LARGE, target.posX + rand.nextFloat(),
|
|
||||||
target.getEntityBoundingBox().minY + target.height / 2 + rand.nextFloat(),
|
|
||||||
target.posZ + rand.nextFloat(), 0, 0, 0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
target.playSound(WizardrySounds.SPELL_SPARK, 1.0F, rand.nextFloat() * 0.4F + 1.5F);
|
target.playSound(WizardrySounds.SPELL_SPARK, 1.0F, rand.nextFloat() * 0.4F + 1.5F);
|
||||||
|
|||||||
@@ -69,8 +69,8 @@ public class EntityHealAura extends EntityMagicConstruct {
|
|||||||
ParticleBuilder.create(Type.SPARKLE)
|
ParticleBuilder.create(Type.SPARKLE)
|
||||||
.pos(this.posX + radius * Math.cos(angle), this.posY, this.posZ + radius * Math.sin(angle))
|
.pos(this.posX + radius * Math.cos(angle), this.posY, this.posZ + radius * Math.sin(angle))
|
||||||
.vel(0, 0.05, 0)
|
.vel(0, 0.05, 0)
|
||||||
.lifetime(48 + this.rand.nextInt(12))
|
.time(48 + this.rand.nextInt(12))
|
||||||
.colour(1.0f, 1.0f, brightness)
|
.clr(1.0f, 1.0f, brightness)
|
||||||
.spawn(world);
|
.spawn(world);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,18 +0,0 @@
|
|||||||
package electroblob.wizardry.entity.construct;
|
|
||||||
|
|
||||||
import net.minecraft.world.World;
|
|
||||||
|
|
||||||
@Deprecated // This needs changing into a particle
|
|
||||||
public class EntityLightningPulse extends EntityMagicConstruct {
|
|
||||||
|
|
||||||
public EntityLightningPulse(World world){
|
|
||||||
super(world);
|
|
||||||
this.setSize(6, 0.2f);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean canRenderOnFire(){
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -2,7 +2,6 @@ package electroblob.wizardry.entity.construct;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import electroblob.wizardry.entity.EntityArc;
|
|
||||||
import electroblob.wizardry.registry.WizardrySounds;
|
import electroblob.wizardry.registry.WizardrySounds;
|
||||||
import electroblob.wizardry.util.MagicDamage;
|
import electroblob.wizardry.util.MagicDamage;
|
||||||
import electroblob.wizardry.util.MagicDamage.DamageType;
|
import electroblob.wizardry.util.MagicDamage.DamageType;
|
||||||
@@ -11,7 +10,6 @@ import electroblob.wizardry.util.ParticleBuilder.Type;
|
|||||||
import electroblob.wizardry.util.WizardryUtilities;
|
import electroblob.wizardry.util.WizardryUtilities;
|
||||||
import net.minecraft.entity.EntityLivingBase;
|
import net.minecraft.entity.EntityLivingBase;
|
||||||
import net.minecraft.util.DamageSource;
|
import net.minecraft.util.DamageSource;
|
||||||
import net.minecraft.util.EnumParticleTypes;
|
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
public class EntityLightningSigil extends EntityMagicConstruct {
|
public class EntityLightningSigil extends EntityMagicConstruct {
|
||||||
@@ -65,25 +63,14 @@ public class EntityLightningSigil extends EntityMagicConstruct {
|
|||||||
|
|
||||||
if(secondaryTarget != target && this.isValidTarget(secondaryTarget)){
|
if(secondaryTarget != target && this.isValidTarget(secondaryTarget)){
|
||||||
|
|
||||||
if(!world.isRemote){
|
if(world.isRemote){
|
||||||
EntityArc arc = new EntityArc(world);
|
|
||||||
arc.setEndpointCoords(target.posX, target.posY + target.height / 2, target.posZ,
|
ParticleBuilder.create(Type.LIGHTNING).entity(target)
|
||||||
secondaryTarget.posX, secondaryTarget.posY + secondaryTarget.height / 2,
|
.pos(0, target.height/2, 0).target(secondaryTarget).spawn(world);
|
||||||
|
|
||||||
|
ParticleBuilder.spawnShockParticles(world, secondaryTarget.posX,
|
||||||
|
secondaryTarget.getEntityBoundingBox().minY + secondaryTarget.height / 2,
|
||||||
secondaryTarget.posZ);
|
secondaryTarget.posZ);
|
||||||
world.spawnEntity(arc);
|
|
||||||
}else{
|
|
||||||
for(int k = 0; k < 8; k++){
|
|
||||||
ParticleBuilder.create(Type.SPARK)
|
|
||||||
.pos(secondaryTarget.posX + world.rand.nextFloat() - 0.5,
|
|
||||||
secondaryTarget.getEntityBoundingBox().minY + secondaryTarget.height / 2 + world.rand.nextFloat() * 2 - 1,
|
|
||||||
secondaryTarget.posZ + world.rand.nextFloat() - 0.5)
|
|
||||||
.spawn(world);
|
|
||||||
world.spawnParticle(EnumParticleTypes.SMOKE_LARGE,
|
|
||||||
secondaryTarget.posX + world.rand.nextFloat() - 0.5,
|
|
||||||
secondaryTarget.getEntityBoundingBox().minY + secondaryTarget.height / 2
|
|
||||||
+ world.rand.nextFloat() * 2 - 1,
|
|
||||||
secondaryTarget.posZ + world.rand.nextFloat() - 0.5, 0, 0, 0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
secondaryTarget.playSound(WizardrySounds.SPELL_SPARK, 1.0F,
|
secondaryTarget.playSound(WizardrySounds.SPELL_SPARK, 1.0F,
|
||||||
|
|||||||
@@ -140,12 +140,14 @@ public class EntityTornado extends EntityMagicConstruct {
|
|||||||
if(block.getMaterial() == Material.SNOW || block.getMaterial() == Material.CRAFTED_SNOW)
|
if(block.getMaterial() == Material.SNOW || block.getMaterial() == Material.CRAFTED_SNOW)
|
||||||
type = Type.SNOW;
|
type = Type.SNOW;
|
||||||
|
|
||||||
double yPos1 = rand.nextDouble() * 8;
|
if(type != null){
|
||||||
ParticleBuilder.create(type)
|
double yPos1 = rand.nextDouble() * 8;
|
||||||
.pos(this.posX + (rand.nextDouble() * 2 - 1) * (yPos1 / 3 + 0.5d), this.posY + yPos1,
|
ParticleBuilder.create(type)
|
||||||
this.posZ + (rand.nextDouble() * 2 - 1) * (yPos1 / 3 + 0.5d))
|
.pos(this.posX + (rand.nextDouble() * 2 - 1) * (yPos1 / 3 + 0.5d), this.posY + yPos1,
|
||||||
.lifetime(40 + rand.nextInt(10))
|
this.posZ + (rand.nextDouble() * 2 - 1) * (yPos1 / 3 + 0.5d))
|
||||||
.spawn(world);
|
.time(40 + rand.nextInt(10))
|
||||||
|
.spawn(world);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,14 +41,17 @@ public class EntityDecoy extends EntitySummonedCreature {
|
|||||||
@Override
|
@Override
|
||||||
public void onDespawn(){
|
public void onDespawn(){
|
||||||
super.onDespawn();
|
super.onDespawn();
|
||||||
for(int i = 0; i < 20; i++){
|
|
||||||
ParticleBuilder.create(Type.DUST)
|
if(world.isRemote){
|
||||||
.pos(this.posX + (this.rand.nextDouble() - 0.5) * this.width, this.getEntityBoundingBox().minY
|
for(int i = 0; i < 20; i++){
|
||||||
+ this.rand.nextDouble() * this.height, this.posZ + (this.rand.nextDouble() - 0.5) * this.width)
|
ParticleBuilder.create(Type.DUST)
|
||||||
.lifetime(40)
|
.pos(this.posX + (this.rand.nextDouble() - 0.5) * this.width, this.getEntityBoundingBox().minY
|
||||||
.colour(0.2f, 1.0f, 0.8f)
|
+ this.rand.nextDouble() * this.height, this.posZ + (this.rand.nextDouble() - 0.5) * this.width)
|
||||||
.shaded(true)
|
.time(40)
|
||||||
.spawn(world);
|
.clr(0.2f, 1.0f, 0.8f)
|
||||||
|
.shaded(true)
|
||||||
|
.spawn(world);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -221,7 +221,7 @@ public class EntityEvilWizard extends EntityMob implements ISpellCaster, IEntity
|
|||||||
// 0.5F.
|
// 0.5F.
|
||||||
double y = (double)((float)this.posY - 0.5F + rand.nextFloat());
|
double y = (double)((float)this.posY - 0.5F + rand.nextFloat());
|
||||||
double z = (double)((float)this.posZ + rand.nextFloat() * 2 - 1.0F);
|
double z = (double)((float)this.posZ + rand.nextFloat() * 2 - 1.0F);
|
||||||
ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).vel(0, 0.1F, 0).colour(1, 1, 0.3f).spawn(world);
|
ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).vel(0, 0.1F, 0).clr(1, 1, 0.3f).spawn(world);
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
if(this.getHealth() < 10){
|
if(this.getHealth() < 10){
|
||||||
|
|||||||
@@ -99,8 +99,8 @@ public class EntityIceGiant extends EntityIronGolem implements ISummonedCreature
|
|||||||
if(this.world.isRemote){
|
if(this.world.isRemote){
|
||||||
for(int i = 0; i < 30; i++){
|
for(int i = 0; i < 30; i++){
|
||||||
float brightness = 0.5f + (rand.nextFloat() / 2);
|
float brightness = 0.5f + (rand.nextFloat() / 2);
|
||||||
ParticleBuilder.create(Type.SPARKLE, this).vel(0, -0.02, 0).lifetime(12 + rand.nextInt(8))
|
ParticleBuilder.create(Type.SPARKLE, this).vel(0, -0.02, 0).time(12 + rand.nextInt(8))
|
||||||
.colour(brightness, brightness + 0.1f, 1.0f).spawn(world);
|
.clr(brightness, brightness + 0.1f, 1.0f).spawn(world);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,8 +51,8 @@ public class EntityIceWraith extends EntityBlazeMinion {
|
|||||||
.pos(this.posX - 0.5d + rand.nextDouble(), this.posY + this.height / 2 - 0.5d + rand.nextDouble(),
|
.pos(this.posX - 0.5d + rand.nextDouble(), this.posY + this.height / 2 - 0.5d + rand.nextDouble(),
|
||||||
this.posZ - 0.5d + rand.nextDouble())
|
this.posZ - 0.5d + rand.nextDouble())
|
||||||
.vel(0, 0.05f, 0)
|
.vel(0, 0.05f, 0)
|
||||||
.lifetime(20 + rand.nextInt(10))
|
.time(20 + rand.nextInt(10))
|
||||||
.colour(brightness, brightness + 0.1f, 1.0f)
|
.clr(brightness, brightness + 0.1f, 1.0f)
|
||||||
.spawn(world);
|
.spawn(world);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,8 +40,8 @@ public class EntityLightningWraith extends EntityBlazeMinion {
|
|||||||
if(this.world.isRemote){
|
if(this.world.isRemote){
|
||||||
for(int i = 0; i < 15; i++){
|
for(int i = 0; i < 15; i++){
|
||||||
float brightness = 0.3f + (rand.nextFloat() / 2);
|
float brightness = 0.3f + (rand.nextFloat() / 2);
|
||||||
ParticleBuilder.create(Type.SPARKLE, this).vel(0, 0.05, 0).lifetime(20 + rand.nextInt(10))
|
ParticleBuilder.create(Type.SPARKLE, this).vel(0, 0.05, 0).time(20 + rand.nextInt(10))
|
||||||
.colour(brightness, brightness + 0.2f, 1.0f).spawn(world);
|
.clr(brightness, brightness + 0.2f, 1.0f).spawn(world);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -125,8 +125,8 @@ public class EntityShadowWraith extends EntitySummonedCreature implements ISpell
|
|||||||
if(this.world.isRemote){
|
if(this.world.isRemote){
|
||||||
for(int i = 0; i < 15; i++){
|
for(int i = 0; i < 15; i++){
|
||||||
float brightness = rand.nextFloat() * 0.4f;
|
float brightness = rand.nextFloat() * 0.4f;
|
||||||
ParticleBuilder.create(Type.SPARKLE, this).vel(0, 0.05, 0).lifetime(20 + rand.nextInt(10))
|
ParticleBuilder.create(Type.SPARKLE, this).vel(0, 0.05, 0).time(20 + rand.nextInt(10))
|
||||||
.colour(brightness, 0.0f, brightness).spawn(world);
|
.clr(brightness, 0.0f, brightness).spawn(world);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -160,10 +160,10 @@ public class EntityShadowWraith extends EntitySummonedCreature implements ISpell
|
|||||||
|
|
||||||
float brightness = rand.nextFloat() * 0.2f;
|
float brightness = rand.nextFloat() * 0.2f;
|
||||||
|
|
||||||
ParticleBuilder.create(Type.SPARKLE, this).vel(0, 0.05, 0).lifetime(20 + rand.nextInt(10))
|
ParticleBuilder.create(Type.SPARKLE, this).vel(0, 0.05, 0).time(20 + rand.nextInt(10))
|
||||||
.colour(brightness, 0.0f, brightness).spawn(world);
|
.clr(brightness, 0.0f, brightness).spawn(world);
|
||||||
|
|
||||||
ParticleBuilder.create(Type.DARK_MAGIC, this).colour(0.1f, 0.0f, 0.0f).spawn(world);
|
ParticleBuilder.create(Type.DARK_MAGIC, this).clr(0.1f, 0.0f, 0.0f).spawn(world);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ public class EntitySilverfishMinion extends EntitySilverfish implements ISummone
|
|||||||
for(int i = 0; i < 15; i++){
|
for(int i = 0; i < 15; i++){
|
||||||
ParticleBuilder.create(Type.DARK_MAGIC)
|
ParticleBuilder.create(Type.DARK_MAGIC)
|
||||||
.pos(this.posX + this.rand.nextFloat(), this.posY + this.rand.nextFloat(), this.posZ + this.rand.nextFloat())
|
.pos(this.posX + this.rand.nextFloat(), this.posY + this.rand.nextFloat(), this.posZ + this.rand.nextFloat())
|
||||||
.colour(0.3f, 0.3f, 0.3f)
|
.clr(0.3f, 0.3f, 0.3f)
|
||||||
.spawn(world);
|
.spawn(world);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -110,7 +110,7 @@ public class EntitySpiderMinion extends EntityCaveSpider implements ISummonedCre
|
|||||||
for(int i = 0; i < 15; i++){
|
for(int i = 0; i < 15; i++){
|
||||||
ParticleBuilder.create(Type.DARK_MAGIC)
|
ParticleBuilder.create(Type.DARK_MAGIC)
|
||||||
.pos(this.posX + this.rand.nextFloat(), this.posY + this.rand.nextFloat(), this.posZ + this.rand.nextFloat())
|
.pos(this.posX + this.rand.nextFloat(), this.posY + this.rand.nextFloat(), this.posZ + this.rand.nextFloat())
|
||||||
.colour(0.1f, 0.2f, 0.0f)
|
.clr(0.1f, 0.2f, 0.0f)
|
||||||
.spawn(world);
|
.spawn(world);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -120,7 +120,7 @@ public class EntitySpiritHorse extends EntityHorse {
|
|||||||
double x = this.posX - this.width / 2 + this.rand.nextFloat() * width;
|
double x = this.posX - this.width / 2 + this.rand.nextFloat() * width;
|
||||||
double y = this.posY + this.height * this.rand.nextFloat() + 0.2f;
|
double y = this.posY + this.height * this.rand.nextFloat() + 0.2f;
|
||||||
double z = this.posZ - this.width / 2 + this.rand.nextFloat() * width;
|
double z = this.posZ - this.width / 2 + this.rand.nextFloat() * width;
|
||||||
ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).colour(0.8f, 0.8f, 1.0f).spawn(world);
|
ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).clr(0.8f, 0.8f, 1.0f).spawn(world);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -158,7 +158,7 @@ public class EntitySpiritHorse extends EntityHorse {
|
|||||||
double x = this.posX - this.width / 2 + this.rand.nextFloat() * width;
|
double x = this.posX - this.width / 2 + this.rand.nextFloat() * width;
|
||||||
double y = this.posY + this.height * this.rand.nextFloat() + 0.2f;
|
double y = this.posY + this.height * this.rand.nextFloat() + 0.2f;
|
||||||
double z = this.posZ - this.width / 2 + this.rand.nextFloat() * width;
|
double z = this.posZ - this.width / 2 + this.rand.nextFloat() * width;
|
||||||
ParticleBuilder.create(Type.DUST).pos(x, y, z).colour(0.8f, 0.8f, 1.0f).shaded(true).spawn(world);
|
ParticleBuilder.create(Type.DUST).pos(x, y, z).clr(0.8f, 0.8f, 1.0f).shaded(true).spawn(world);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Spirit horse disappears a short time after being dismounted.
|
// Spirit horse disappears a short time after being dismounted.
|
||||||
|
|||||||
@@ -89,7 +89,7 @@ public class EntitySpiritWolf extends EntityWolf {
|
|||||||
double x = this.posX - this.width / 2 + this.rand.nextFloat() * width;
|
double x = this.posX - this.width / 2 + this.rand.nextFloat() * width;
|
||||||
double y = this.posY + this.height * this.rand.nextFloat() + 0.2f;
|
double y = this.posY + this.height * this.rand.nextFloat() + 0.2f;
|
||||||
double z = this.posZ - this.width / 2 + this.rand.nextFloat() * width;
|
double z = this.posZ - this.width / 2 + this.rand.nextFloat() * width;
|
||||||
ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).colour(0.8f, 0.8f, 1.0f).spawn(world);
|
ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).clr(0.8f, 0.8f, 1.0f).spawn(world);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -103,7 +103,7 @@ public class EntitySpiritWolf extends EntityWolf {
|
|||||||
double x = this.posX - this.width / 2 + this.rand.nextFloat() * width;
|
double x = this.posX - this.width / 2 + this.rand.nextFloat() * width;
|
||||||
double y = this.posY + this.height * this.rand.nextFloat() + 0.2f;
|
double y = this.posY + this.height * this.rand.nextFloat() + 0.2f;
|
||||||
double z = this.posZ - this.width / 2 + this.rand.nextFloat() * width;
|
double z = this.posZ - this.width / 2 + this.rand.nextFloat() * width;
|
||||||
ParticleBuilder.create(Type.DUST).pos(x, y, z).colour(0.8f, 0.8f, 1.0f).shaded(true).spawn(world);
|
ParticleBuilder.create(Type.DUST).pos(x, y, z).clr(0.8f, 0.8f, 1.0f).shaded(true).spawn(world);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -148,8 +148,9 @@ public class EntityStormElemental extends EntitySummonedCreature implements ISpe
|
|||||||
float brightness = rand.nextFloat() * 0.2f;
|
float brightness = rand.nextFloat() * 0.2f;
|
||||||
double dy = this.rand.nextDouble() * (double)this.height;
|
double dy = this.rand.nextDouble() * (double)this.height;
|
||||||
|
|
||||||
ParticleBuilder.create(Type.SPARKLE_ROTATING).pos(this.posX, this.posY + dy, this.posZ)
|
ParticleBuilder.create(Type.SPARKLE).pos(this.posX, this.posY + dy, this.posZ)
|
||||||
.lifetime(20 + rand.nextInt(10)).colour(0, brightness, brightness).radius(0.2f + 0.5f * dy).spawn(world);
|
.time(20 + rand.nextInt(10)).clr(0, brightness, brightness)//.entity(this)
|
||||||
|
.spin(0.2 + 0.5 * dy, 0.1 + 0.05 * world.rand.nextDouble()).spawn(world);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -310,7 +310,7 @@ public class EntityWizard extends EntityCreature implements INpc, IMerchant, ISp
|
|||||||
// 0.5F.
|
// 0.5F.
|
||||||
double y = (double)((float)this.posY - 0.5F + rand.nextFloat());
|
double y = (double)((float)this.posY - 0.5F + rand.nextFloat());
|
||||||
double z = (double)((float)this.posZ + rand.nextFloat() * 2 - 1.0F);
|
double z = (double)((float)this.posZ + rand.nextFloat() * 2 - 1.0F);
|
||||||
ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).vel(0, 0.1F, 0).colour(1, 1, 0.3f).spawn(world);
|
ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).vel(0, 0.1F, 0).clr(1, 1, 0.3f).spawn(world);
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
if(this.getHealth() < 10){
|
if(this.getHealth() < 10){
|
||||||
|
|||||||
@@ -308,7 +308,7 @@ public interface ISummonedCreature extends IEntityAdditionalSpawnData {
|
|||||||
if(this.hasParticleEffect() && thisEntity.world.isRemote && thisEntity.world.rand.nextInt(8) == 0)
|
if(this.hasParticleEffect() && thisEntity.world.isRemote && thisEntity.world.rand.nextInt(8) == 0)
|
||||||
ParticleBuilder.create(Type.DARK_MAGIC)
|
ParticleBuilder.create(Type.DARK_MAGIC)
|
||||||
.pos(thisEntity.posX, thisEntity.posY + thisEntity.world.rand.nextDouble() * 1.5, thisEntity.posZ)
|
.pos(thisEntity.posX, thisEntity.posY + thisEntity.world.rand.nextDouble() * 1.5, thisEntity.posZ)
|
||||||
.colour(0.1f, 0.0f, 0.0f)
|
.clr(0.1f, 0.0f, 0.0f)
|
||||||
.spawn(thisEntity.world);
|
.spawn(thisEntity.world);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,10 +47,10 @@ public class EntityDarknessOrb extends EntityMagicProjectile {
|
|||||||
|
|
||||||
float brightness = rand.nextFloat() * 0.2f;
|
float brightness = rand.nextFloat() * 0.2f;
|
||||||
|
|
||||||
ParticleBuilder.create(Type.SPARKLE, this).lifetime(20 + rand.nextInt(10))
|
ParticleBuilder.create(Type.SPARKLE, this).time(20 + rand.nextInt(10))
|
||||||
.colour(brightness, 0.0f, brightness).spawn(world);
|
.clr(brightness, 0.0f, brightness).spawn(world);
|
||||||
|
|
||||||
ParticleBuilder.create(Type.DARK_MAGIC, this).colour(0.1f, 0.0f, 0.0f).spawn(world);
|
ParticleBuilder.create(Type.DARK_MAGIC, this).clr(0.1f, 0.0f, 0.0f).spawn(world);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(this.ticksExisted > 150){
|
if(this.ticksExisted > 150){
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ public class EntityDart extends EntityMagicArrow {
|
|||||||
@Override
|
@Override
|
||||||
public void tickInAir(){
|
public void tickInAir(){
|
||||||
if(this.world.isRemote){
|
if(this.world.isRemote){
|
||||||
ParticleBuilder.create(Type.LEAF, this).lifetime(10 + rand.nextInt(5)).spawn(world);
|
ParticleBuilder.create(Type.LEAF, this).time(10 + rand.nextInt(5)).spawn(world);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -39,16 +39,19 @@ public class EntityFirebomb extends EntityBomb {
|
|||||||
// Particle effect
|
// Particle effect
|
||||||
if(world.isRemote){
|
if(world.isRemote){
|
||||||
|
|
||||||
this.world.spawnParticle(EnumParticleTypes.EXPLOSION_LARGE, this.posX, this.posY, this.posZ, 0, 0, 0);
|
ParticleBuilder.create(Type.FLASH).pos(this.getPositionVector()).scale(5 * blastMultiplier).clr(1, 0.6f, 0)
|
||||||
|
.spawn(world);
|
||||||
|
|
||||||
for(int i = 0; i < 60 * blastMultiplier; i++){
|
for(int i = 0; i < 60 * blastMultiplier; i++){
|
||||||
|
|
||||||
ParticleBuilder.create(Type.MAGIC_FIRE, rand, posX, posY, posZ, 2*blastMultiplier, false)
|
ParticleBuilder.create(Type.MAGIC_FIRE, rand, posX, posY, posZ, 2*blastMultiplier, false)
|
||||||
.lifetime(15 + rand.nextInt(5)).scale(2 + rand.nextFloat()).spawn(world);
|
.time(15 + rand.nextInt(5)).scale(2 + rand.nextFloat()).spawn(world);
|
||||||
|
|
||||||
ParticleBuilder.create(Type.DARK_MAGIC, rand, posX, posY, posZ, 2*blastMultiplier, false)
|
ParticleBuilder.create(Type.DARK_MAGIC, rand, posX, posY, posZ, 2*blastMultiplier, false)
|
||||||
.colour(1.0f, 0.2f + rand.nextFloat() * 0.4f, 0.0f).spawn(world);
|
.clr(1.0f, 0.2f + rand.nextFloat() * 0.4f, 0.0f).spawn(world);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.world.spawnParticle(EnumParticleTypes.EXPLOSION_LARGE, this.posX, this.posY, this.posZ, 0, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!this.world.isRemote){
|
if(!this.world.isRemote){
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
package electroblob.wizardry.entity.projectile;
|
package electroblob.wizardry.entity.projectile;
|
||||||
|
|
||||||
import electroblob.wizardry.util.MagicDamage.DamageType;
|
import electroblob.wizardry.util.MagicDamage.DamageType;
|
||||||
|
import electroblob.wizardry.util.ParticleBuilder;
|
||||||
|
import electroblob.wizardry.util.ParticleBuilder.Type;
|
||||||
import net.minecraft.entity.EntityLivingBase;
|
import net.minecraft.entity.EntityLivingBase;
|
||||||
import net.minecraft.init.SoundEvents;
|
import net.minecraft.init.SoundEvents;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
@@ -15,6 +17,8 @@ public class EntityForceArrow extends EntityMagicArrow {
|
|||||||
@Override
|
@Override
|
||||||
public void onEntityHit(EntityLivingBase entityHit){
|
public void onEntityHit(EntityLivingBase entityHit){
|
||||||
this.playSound(SoundEvents.ENTITY_FIREWORK_BLAST, 1.0F, 1.0F);
|
this.playSound(SoundEvents.ENTITY_FIREWORK_BLAST, 1.0F, 1.0F);
|
||||||
|
if(this.world.isRemote)
|
||||||
|
ParticleBuilder.create(Type.FLASH).pos(posX, posY, posZ).scale(1.3f).clr(0.75f, 1, 0.85f).spawn(world);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -25,6 +29,13 @@ public class EntityForceArrow extends EntityMagicArrow {
|
|||||||
@Override
|
@Override
|
||||||
public void onBlockHit(){
|
public void onBlockHit(){
|
||||||
this.playSound(SoundEvents.ENTITY_FIREWORK_BLAST, 1.0F, 1.0F);
|
this.playSound(SoundEvents.ENTITY_FIREWORK_BLAST, 1.0F, 1.0F);
|
||||||
|
if(this.world.isRemote){
|
||||||
|
// Gets a position slightly away from the block hit so the particle doesn't get cut in half by the block face
|
||||||
|
Vec3d vec = hit.hitVec.add(new Vec3d(hit.sideHit.getDirectionVec()).scale(0.15));
|
||||||
|
ParticleBuilder.create(Type.FLASH).pos(vec).scale(1.3f).clr(0.75f, 1, 0.85f).spawn(world);
|
||||||
|
vec = hit.hitVec.add(new Vec3d(hit.sideHit.getDirectionVec()).scale(WizardryUtilities.ANTI_Z_FIGHTING_OFFSET));
|
||||||
|
ParticleBuilder.create(Type.SCORCH).pos(vec).face(hit.sideHit).clr(0, 1, 0.5f).spawn(world);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -31,8 +31,8 @@ public class EntityForceOrb extends EntityBomb {
|
|||||||
if(this.world.isRemote){
|
if(this.world.isRemote){
|
||||||
for(int j = 0; j < 20; j++){
|
for(int j = 0; j < 20; j++){
|
||||||
float brightness = 0.5f + (rand.nextFloat() / 2);
|
float brightness = 0.5f + (rand.nextFloat() / 2);
|
||||||
ParticleBuilder.create(Type.SPARKLE, rand, posX, posY, posZ, 0.25, true).lifetime(6)
|
ParticleBuilder.create(Type.SPARKLE, rand, posX, posY, posZ, 0.25, true).time(6)
|
||||||
.colour(brightness, 1.0f, brightness + 0.2f).spawn(world);
|
.clr(brightness, 1.0f, brightness + 0.2f).spawn(world);
|
||||||
}
|
}
|
||||||
this.world.spawnParticle(EnumParticleTypes.EXPLOSION_LARGE, this.posX, this.posY, this.posZ, 0, 0, 0);
|
this.world.spawnParticle(EnumParticleTypes.EXPLOSION_LARGE, this.posX, this.posY, this.posZ, 0, 0, 0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,11 +47,11 @@ public class EntityIceCharge extends EntityBomb {
|
|||||||
for(int i = 0; i < 30 * blastMultiplier; i++){
|
for(int i = 0; i < 30 * blastMultiplier; i++){
|
||||||
|
|
||||||
ParticleBuilder.create(Type.ICE, rand, this.posX, this.posY, this.posZ, 2 * blastMultiplier, false)
|
ParticleBuilder.create(Type.ICE, rand, this.posX, this.posY, this.posZ, 2 * blastMultiplier, false)
|
||||||
.lifetime(35).gravity(true).spawn(world);
|
.time(35).gravity(true).spawn(world);
|
||||||
|
|
||||||
float brightness = 0.4f + rand.nextFloat() * 0.5f;
|
float brightness = 0.4f + rand.nextFloat() * 0.5f;
|
||||||
ParticleBuilder.create(Type.DARK_MAGIC, rand, this.posX, this.posY, this.posZ, 2 * blastMultiplier, false)
|
ParticleBuilder.create(Type.DARK_MAGIC, rand, this.posX, this.posY, this.posZ, 2 * blastMultiplier, false)
|
||||||
.colour(brightness, brightness + 0.1f, 1.0f).spawn(world);
|
.clr(brightness, brightness + 0.1f, 1.0f).spawn(world);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ public class EntityIceLance extends EntityMagicArrow {
|
|||||||
if(this.world.isRemote){
|
if(this.world.isRemote){
|
||||||
for(int j = 0; j < 10; j++){
|
for(int j = 0; j < 10; j++){
|
||||||
ParticleBuilder.create(Type.ICE, this.rand, this.posX, this.posY, this.posZ, 0.5, true)
|
ParticleBuilder.create(Type.ICE, this.rand, this.posX, this.posY, this.posZ, 0.5, true)
|
||||||
.lifetime(20 + rand.nextInt(10)).gravity(true).spawn(world);
|
.time(20 + rand.nextInt(10)).gravity(true).spawn(world);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Parameters for sound: sound event name, volume, pitch.
|
// Parameters for sound: sound event name, volume, pitch.
|
||||||
|
|||||||
@@ -41,9 +41,13 @@ public class EntityIceShard extends EntityMagicArrow {
|
|||||||
public void onBlockHit(){
|
public void onBlockHit(){
|
||||||
// Adds a particle effect when the ice shard hits a block.
|
// Adds a particle effect when the ice shard hits a block.
|
||||||
if(this.world.isRemote){
|
if(this.world.isRemote){
|
||||||
|
// Gets a position slightly away from the block hit so the particle doesn't get cut in half by the block face
|
||||||
|
Vec3d vec = hit.hitVec.add(new Vec3d(hit.sideHit.getDirectionVec()).scale(0.15));
|
||||||
|
ParticleBuilder.create(Type.FLASH).pos(vec).clr(0.75f, 1, 1).spawn(world);
|
||||||
|
|
||||||
for(int j = 0; j < 10; j++){
|
for(int j = 0; j < 10; j++){
|
||||||
ParticleBuilder.create(Type.ICE, this.rand, this.posX, this.posY, this.posZ, 0.5, true)
|
ParticleBuilder.create(Type.ICE, this.rand, this.posX, this.posY, this.posZ, 0.5, true)
|
||||||
.lifetime(20 + rand.nextInt(10)).gravity(true).spawn(world);
|
.time(20 + rand.nextInt(10)).gravity(true).spawn(world);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Parameters for sound: sound event name, volume, pitch.
|
// Parameters for sound: sound event name, volume, pitch.
|
||||||
|
|||||||
@@ -32,6 +32,12 @@ public class EntityLightningArrow extends EntityMagicArrow {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.playSound(WizardrySounds.SPELL_SPARK, 1.0F, 1.0F);
|
this.playSound(WizardrySounds.SPELL_SPARK, 1.0F, 1.0F);
|
||||||
|
@Override
|
||||||
|
public void onBlockHit(RayTraceResult hit){
|
||||||
|
if(this.world.isRemote){
|
||||||
|
Vec3d vec = hit.hitVec.add(new Vec3d(hit.sideHit.getDirectionVec()).scale(WizardryUtilities.ANTI_Z_FIGHTING_OFFSET));
|
||||||
|
ParticleBuilder.create(Type.SCORCH).pos(vec).face(hit.sideHit).clr(0.4f, 0.8f, 1).scale(0.6f).spawn(world);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -201,8 +201,10 @@ public abstract class EntityMagicArrow extends Entity implements IProjectile, IE
|
|||||||
/** Called when the projectile hits an entity. Override to add potion effects and such like. */
|
/** Called when the projectile hits an entity. Override to add potion effects and such like. */
|
||||||
protected void onEntityHit(EntityLivingBase entityHit){}
|
protected void onEntityHit(EntityLivingBase entityHit){}
|
||||||
|
|
||||||
/** Called when the projectile hits a block. Override to add sound effects and such like. */
|
/** Called when the projectile hits a block. Override to add sound effects and such like.
|
||||||
protected void onBlockHit(){}
|
* @param hit A vector representing the exact coordinates of the hit; use this to centre particle effects, for
|
||||||
|
* example. */
|
||||||
|
protected void onBlockHit(RayTraceResult hit){}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onUpdate(){
|
public void onUpdate(){
|
||||||
@@ -390,7 +392,7 @@ public abstract class EntityMagicArrow extends Entity implements IProjectile, IE
|
|||||||
this.inGround = true;
|
this.inGround = true;
|
||||||
this.arrowShake = 7;
|
this.arrowShake = 7;
|
||||||
|
|
||||||
this.onBlockHit();
|
this.onBlockHit(raytraceresult);
|
||||||
|
|
||||||
if(this.stuckInBlock.getMaterial() != Material.AIR){
|
if(this.stuckInBlock.getMaterial() != Material.AIR){
|
||||||
this.stuckInBlock.getBlock().onEntityCollidedWithBlock(this.world, raytraceresult.getBlockPos(),
|
this.stuckInBlock.getBlock().onEntityCollidedWithBlock(this.world, raytraceresult.getBlockPos(),
|
||||||
|
|||||||
@@ -4,9 +4,14 @@ import electroblob.wizardry.util.ParticleBuilder;
|
|||||||
import electroblob.wizardry.util.ParticleBuilder.Type;
|
import electroblob.wizardry.util.ParticleBuilder.Type;
|
||||||
import net.minecraft.entity.EntityLivingBase;
|
import net.minecraft.entity.EntityLivingBase;
|
||||||
import net.minecraft.init.SoundEvents;
|
import net.minecraft.init.SoundEvents;
|
||||||
|
import net.minecraft.util.math.RayTraceResult;
|
||||||
|
import net.minecraft.util.math.Vec3d;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
public class EntityMagicMissile extends EntityMagicArrow {
|
public class EntityMagicMissile extends EntityMagicArrow {
|
||||||
|
|
||||||
|
/** The number of ticks the magic missile flies for before vanishing; effectively determines its range. */
|
||||||
|
private static final int LIFETIME = 12;
|
||||||
|
|
||||||
/** Creates a new magic missile in the given world. */
|
/** Creates a new magic missile in the given world. */
|
||||||
public EntityMagicMissile(World world){
|
public EntityMagicMissile(World world){
|
||||||
@@ -26,25 +31,32 @@ public class EntityMagicMissile extends EntityMagicArrow {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onBlockHit(){
|
public void onBlockHit(RayTraceResult hit){
|
||||||
if(this.world.isRemote) spawnImpactParticles();
|
if(this.world.isRemote){
|
||||||
}
|
// Gets a position slightly away from the block hit so the particle doesn't get cut in half by the block face
|
||||||
|
Vec3d vec = hit.hitVec.add(new Vec3d(hit.sideHit.getDirectionVec()).scale(0.15));
|
||||||
private void spawnImpactParticles(){
|
ParticleBuilder.create(Type.FLASH).pos(vec).clr(1, 1, 0.65f).fade(0.85f, 0.5f, 0.8f).spawn(world);
|
||||||
ParticleBuilder.create(Type.FLASH).pos(posX, posY, posZ).colour(0.5f + rand.nextFloat()/2, 0.5f + rand.nextFloat()/2,
|
}
|
||||||
0.5f + rand.nextFloat()/2).spawn(world);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void tickInAir(){
|
public void tickInAir(){
|
||||||
|
|
||||||
if(this.ticksExisted > 20){
|
if(this.ticksExisted > LIFETIME){
|
||||||
this.setDead();
|
this.setDead();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(this.world.isRemote){
|
if(this.world.isRemote){
|
||||||
ParticleBuilder.create(Type.SPARKLE).pos(this.posX, this.posY, this.posZ).lifetime(20 + rand.nextInt(10))
|
ParticleBuilder.create(Type.SPARKLE, rand, posX, posY, posZ, 0.03, true).clr(1, 1, 0.65f).fade(0.7f, 0, 1)
|
||||||
.colour(0.5f + (rand.nextFloat() / 2), 0.5f + (rand.nextFloat() / 2), 0.5f + (rand.nextFloat() / 2)).spawn(world);
|
.time(20 + rand.nextInt(10)).spawn(world);
|
||||||
|
|
||||||
|
if(this.ticksExisted > 1){ // Don't spawn particles behind where it started!
|
||||||
|
double x = posX - motionX/2;
|
||||||
|
double y = posY - motionY/2;
|
||||||
|
double z = posZ - motionZ/2;
|
||||||
|
ParticleBuilder.create(Type.SPARKLE, rand, x, y, z, 0.03, true).clr(1, 1, 0.65f).fade(0.7f, 0, 1)
|
||||||
|
.time(20 + rand.nextInt(10)).spawn(world);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -41,13 +41,17 @@ public class EntityPoisonBomb extends EntityBomb {
|
|||||||
|
|
||||||
// Particle effect
|
// Particle effect
|
||||||
if(world.isRemote){
|
if(world.isRemote){
|
||||||
|
|
||||||
|
ParticleBuilder.create(Type.FLASH).pos(this.getPositionVector()).scale(5 * blastMultiplier)
|
||||||
|
.clr(0.2f + rand.nextFloat() * 0.3f, 0.6f, 0.0f).spawn(world);
|
||||||
|
|
||||||
for(int i = 0; i < 60 * blastMultiplier; i++){
|
for(int i = 0; i < 60 * blastMultiplier; i++){
|
||||||
|
|
||||||
ParticleBuilder.create(Type.SPARKLE, rand, posX, posY, posZ, 2*blastMultiplier, false).lifetime(35)
|
ParticleBuilder.create(Type.SPARKLE, rand, posX, posY, posZ, 2*blastMultiplier, false).time(35)
|
||||||
.colour(0.2f + rand.nextFloat() * 0.3f, 0.6f, 0.0f).spawn(world);
|
.clr(0.2f + rand.nextFloat() * 0.3f, 0.6f, 0.0f).spawn(world);
|
||||||
|
|
||||||
ParticleBuilder.create(Type.DARK_MAGIC, rand, posX, posY, posZ, 2*blastMultiplier, false)
|
ParticleBuilder.create(Type.DARK_MAGIC, rand, posX, posY, posZ, 2*blastMultiplier, false)
|
||||||
.colour(0.2f + rand.nextFloat() * 0.2f, 0.8f, 0.0f).spawn(world);
|
.clr(0.2f + rand.nextFloat() * 0.2f, 0.8f, 0.0f).spawn(world);
|
||||||
}
|
}
|
||||||
// Spawning this after the other particles fixes the rendering colour bug. It's a bit of a cheat, but it
|
// Spawning this after the other particles fixes the rendering colour bug. It's a bit of a cheat, but it
|
||||||
// works pretty well.
|
// works pretty well.
|
||||||
|
|||||||
@@ -27,7 +27,11 @@ public class EntitySmokeBomb extends EntityBomb {
|
|||||||
|
|
||||||
// Particle effect
|
// Particle effect
|
||||||
if(world.isRemote){
|
if(world.isRemote){
|
||||||
|
|
||||||
|
ParticleBuilder.create(Type.FLASH).pos(this.getPositionVector()).scale(5 * blastMultiplier).clr(0, 0, 0).spawn(world);
|
||||||
|
|
||||||
this.world.spawnParticle(EnumParticleTypes.EXPLOSION_LARGE, this.posX, this.posY, this.posZ, 0, 0, 0);
|
this.world.spawnParticle(EnumParticleTypes.EXPLOSION_LARGE, this.posX, this.posY, this.posZ, 0, 0, 0);
|
||||||
|
|
||||||
for(int i = 0; i < 60 * blastMultiplier; i++){
|
for(int i = 0; i < 60 * blastMultiplier; i++){
|
||||||
|
|
||||||
this.world.spawnParticle(EnumParticleTypes.SMOKE_LARGE,
|
this.world.spawnParticle(EnumParticleTypes.SMOKE_LARGE,
|
||||||
@@ -37,7 +41,7 @@ public class EntitySmokeBomb extends EntityBomb {
|
|||||||
|
|
||||||
float brightness = rand.nextFloat() * 0.3f;
|
float brightness = rand.nextFloat() * 0.3f;
|
||||||
ParticleBuilder.create(Type.DARK_MAGIC, rand, posX, posY, posZ, 2*blastMultiplier, false)
|
ParticleBuilder.create(Type.DARK_MAGIC, rand, posX, posY, posZ, 2*blastMultiplier, false)
|
||||||
.colour(brightness, brightness, brightness).spawn(world);
|
.clr(brightness, brightness, brightness).spawn(world);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,11 +2,11 @@ package electroblob.wizardry.entity.projectile;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import electroblob.wizardry.entity.EntityArc;
|
|
||||||
import electroblob.wizardry.registry.WizardrySounds;
|
import electroblob.wizardry.registry.WizardrySounds;
|
||||||
import electroblob.wizardry.util.MagicDamage;
|
import electroblob.wizardry.util.MagicDamage;
|
||||||
import electroblob.wizardry.util.MagicDamage.DamageType;
|
import electroblob.wizardry.util.MagicDamage.DamageType;
|
||||||
import electroblob.wizardry.util.ParticleBuilder;
|
import electroblob.wizardry.util.ParticleBuilder;
|
||||||
|
import electroblob.wizardry.util.ParticleBuilder.Type;
|
||||||
import electroblob.wizardry.util.WizardryUtilities;
|
import electroblob.wizardry.util.WizardryUtilities;
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.entity.EntityLivingBase;
|
import net.minecraft.entity.EntityLivingBase;
|
||||||
@@ -65,19 +65,14 @@ public class EntitySparkBomb extends EntityBomb {
|
|||||||
|
|
||||||
if(!this.world.isRemote){
|
if(!this.world.isRemote){
|
||||||
|
|
||||||
EntityArc arc = new EntityArc(this.world);
|
target.playSound(WizardrySounds.ENTITY_SPARK_BOMB_CHAIN, 1.0F, rand.nextFloat() * 0.4F + 1.5F);
|
||||||
arc.setEndpointCoords(this.posX, this.posY, this.posZ, target.posX, target.posY + target.height / 2,
|
|
||||||
target.posZ);
|
|
||||||
this.world.spawnEntity(arc);
|
|
||||||
|
|
||||||
target.playSound(WizardrySounds.SPELL_SPARK, 1.0F, rand.nextFloat() * 0.4F + 1.5F);
|
|
||||||
|
|
||||||
target.attackEntityFrom(
|
target.attackEntityFrom(
|
||||||
MagicDamage.causeIndirectMagicDamage(this, this.getThrower(), DamageType.SHOCK),
|
MagicDamage.causeIndirectMagicDamage(this, this.getThrower(), DamageType.SHOCK),
|
||||||
5.0f * damageMultiplier);
|
5.0f * damageMultiplier);
|
||||||
|
|
||||||
}else{
|
}else{
|
||||||
// Particle effect
|
ParticleBuilder.create(Type.LIGHTNING).pos(this.getPositionVector()).target(target).spawn(world);
|
||||||
ParticleBuilder.spawnShockParticles(world, target.posX, target.getEntityBoundingBox().minY + target.height/2, target.posZ);
|
ParticleBuilder.spawnShockParticles(world, target.posX, target.getEntityBoundingBox().minY + target.height/2, target.posZ);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,7 +40,6 @@ public class PotionFrost extends Potion implements ICustomPotionParticles {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void spawnCustomParticle(World world, double x, double y, double z){
|
public void spawnCustomParticle(World world, double x, double y, double z){
|
||||||
ParticleBuilder.create(Type.SNOW).pos(x, y, z).lifetime(15 + world.rand.nextInt(5)).spawn(world);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -55,6 +54,7 @@ public class PotionFrost extends Potion implements ICustomPotionParticles {
|
|||||||
public void renderHUDEffect(int x, int y, PotionEffect effect, net.minecraft.client.Minecraft mc, float alpha){
|
public void renderHUDEffect(int x, int y, PotionEffect effect, net.minecraft.client.Minecraft mc, float alpha){
|
||||||
mc.renderEngine.bindTexture(ICON);
|
mc.renderEngine.bindTexture(ICON);
|
||||||
WizardryUtilities.drawTexturedRect(x + 3, y + 3, 0, 0, 18, 18, 18, 18);
|
WizardryUtilities.drawTexturedRect(x + 3, y + 3, 0, 0, 18, 18, 18, 18);
|
||||||
|
ParticleBuilder.create(Type.SNOW).pos(x, y, z).time(15 + world.rand.nextInt(5)).spawn(world);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
|
|||||||
@@ -30,11 +30,10 @@ public class Arc extends SpellRay {
|
|||||||
|
|
||||||
if(WizardryUtilities.isLiving(target)){
|
if(WizardryUtilities.isLiving(target)){
|
||||||
|
|
||||||
if(!world.isRemote){
|
if(world.isRemote){
|
||||||
EntityArc arc = new EntityArc(world);
|
// Rather neatly, the entity can be set here and if it's null nothing will happen.
|
||||||
arc.setEndpointCoords(caster.posX, caster.posY + 1, caster.posZ, target.posX, target.posY + target.height / 2, target.posZ);
|
ParticleBuilder.create(Type.LIGHTNING).entity(caster)
|
||||||
world.spawnEntity(arc);
|
.pos(caster != null ? origin.subtract(caster.getPositionVector()) : origin).target(target).spawn(world);
|
||||||
}else{
|
|
||||||
ParticleBuilder.spawnShockParticles(world, target.posX, target.getEntityBoundingBox().minY + target.height/2, target.posZ);
|
ParticleBuilder.spawnShockParticles(world, target.posX, target.getEntityBoundingBox().minY + target.height/2, target.posZ);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ public class ArcaneJammer extends SpellRay {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void spawnParticle(World world, double x, double y, double z, double vx, double vy, double vz){
|
protected void spawnParticle(World world, double x, double y, double z, double vx, double vy, double vz){
|
||||||
ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).lifetime(12 + world.rand.nextInt(8)).colour(0.9f, 0.3f, 0.7f)
|
ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).time(12 + world.rand.nextInt(8)).clr(0.9f, 0.3f, 0.7f)
|
||||||
.spawn(world);
|
.spawn(world);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -89,7 +89,7 @@ public class Banish extends SpellRay {
|
|||||||
@Override
|
@Override
|
||||||
protected void spawnParticle(World world, double x, double y, double z, double vx, double vy, double vz){
|
protected void spawnParticle(World world, double x, double y, double z, double vx, double vy, double vz){
|
||||||
world.spawnParticle(EnumParticleTypes.PORTAL, x, y - 0.5, z, 0, 0, 0);
|
world.spawnParticle(EnumParticleTypes.PORTAL, x, y - 0.5, z, 0, 0, 0);
|
||||||
ParticleBuilder.create(Type.DARK_MAGIC).pos(x, y, z).colour(0.2f, 0, 0.2f).spawn(world);
|
ParticleBuilder.create(Type.DARK_MAGIC).pos(x, y, z).clr(0.2f, 0, 0.2f).spawn(world);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -102,12 +102,11 @@ public class ChainLightning extends SpellRay {
|
|||||||
target.attackEntityFrom(MagicDamage.causeDirectMagicDamage(caster, DamageType.SHOCK), damage);
|
target.attackEntityFrom(MagicDamage.causeDirectMagicDamage(caster, DamageType.SHOCK), damage);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!world.isRemote){
|
if(world.isRemote){
|
||||||
EntityArc arc = new EntityArc(world);
|
|
||||||
arc.setEndpointCoords(caster.posX, caster.getEntityBoundingBox().minY + caster.height / 2, caster.posZ,
|
ParticleBuilder.create(Type.LIGHTNING).entity(caster)
|
||||||
target.posX, target.getEntityBoundingBox().minY + target.height / 2, target.posZ);
|
.pos(caster != null ? origin.subtract(caster.getPositionVector()) : origin).target(target).spawn(world);
|
||||||
world.spawnEntity(arc);
|
|
||||||
}else{
|
|
||||||
ParticleBuilder.spawnShockParticles(world, target.posX, target.getEntityBoundingBox().minY + target.height/2, target.posZ);
|
ParticleBuilder.spawnShockParticles(world, target.posX, target.getEntityBoundingBox().minY + target.height/2, target.posZ);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -127,7 +127,7 @@ public class Clairvoyance extends Spell {
|
|||||||
(nextPoint.x - point.x) / (float)PARTICLE_MOVEMENT_INTERVAL,
|
(nextPoint.x - point.x) / (float)PARTICLE_MOVEMENT_INTERVAL,
|
||||||
(nextPoint.y - point.y) / (float)PARTICLE_MOVEMENT_INTERVAL,
|
(nextPoint.y - point.y) / (float)PARTICLE_MOVEMENT_INTERVAL,
|
||||||
(nextPoint.z - point.z) / (float)PARTICLE_MOVEMENT_INTERVAL)
|
(nextPoint.z - point.z) / (float)PARTICLE_MOVEMENT_INTERVAL)
|
||||||
.lifetime((int)(1800 * durationMultiplier)).colour(0, 1, 0.3f).spawn(world);
|
.time((int)(1800 * durationMultiplier)).clr(0, 1, 0.3f).spawn(world);
|
||||||
|
|
||||||
path.incrementPathIndex();
|
path.incrementPathIndex();
|
||||||
path.incrementPathIndex();
|
path.incrementPathIndex();
|
||||||
@@ -136,7 +136,7 @@ public class Clairvoyance extends Spell {
|
|||||||
point = path.getFinalPathPoint();
|
point = path.getFinalPathPoint();
|
||||||
|
|
||||||
ParticleBuilder.create(Type.PATH).pos(point.x + 0.5, point.y + 0.5, point.z + 0.5)
|
ParticleBuilder.create(Type.PATH).pos(point.x + 0.5, point.y + 0.5, point.z + 0.5)
|
||||||
.lifetime((int)(1800 * durationMultiplier)).colour(1, 1, 1).spawn(world);
|
.time((int)(1800 * durationMultiplier)).clr(1, 1, 1).spawn(world);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
|
|||||||
@@ -54,9 +54,9 @@ public class CurseOfSoulbinding extends SpellRay {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void spawnParticle(World world, double x, double y, double z, double vx, double vy, double vz){
|
protected void spawnParticle(World world, double x, double y, double z, double vx, double vy, double vz){
|
||||||
ParticleBuilder.create(Type.DARK_MAGIC).pos(x, y, z).colour(0.4f, 0, 0).spawn(world);
|
ParticleBuilder.create(Type.DARK_MAGIC).pos(x, y, z).clr(0.4f, 0, 0).spawn(world);
|
||||||
ParticleBuilder.create(Type.DARK_MAGIC).pos(x, y, z).colour(0.1f, 0, 0).spawn(world);
|
ParticleBuilder.create(Type.DARK_MAGIC).pos(x, y, z).clr(0.1f, 0, 0).spawn(world);
|
||||||
ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).lifetime(12 + world.rand.nextInt(8)).colour(1, 0.8f, 1).spawn(world);
|
ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).time(12 + world.rand.nextInt(8)).clr(1, 0.8f, 1).spawn(world);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ public class Entrapment extends SpellRay {
|
|||||||
@Override
|
@Override
|
||||||
protected void spawnParticle(World world, double x, double y, double z, double vx, double vy, double vz){
|
protected void spawnParticle(World world, double x, double y, double z, double vx, double vy, double vz){
|
||||||
world.spawnParticle(EnumParticleTypes.PORTAL, x, y - 0.5, z, 0, 0, 0);
|
world.spawnParticle(EnumParticleTypes.PORTAL, x, y - 0.5, z, 0, 0, 0);
|
||||||
ParticleBuilder.create(Type.DARK_MAGIC).pos(x, y, z).colour(0.1f, 0, 0).spawn(world);
|
ParticleBuilder.create(Type.DARK_MAGIC).pos(x, y, z).clr(0.1f, 0, 0).spawn(world);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ public class FlamingWeapon extends Spell {
|
|||||||
double x = caster.posX + world.rand.nextDouble() * 2 - 1;
|
double x = caster.posX + world.rand.nextDouble() * 2 - 1;
|
||||||
double y = caster.getEntityBoundingBox().minY + caster.getEyeHeight() - 0.5 + world.rand.nextDouble();
|
double y = caster.getEntityBoundingBox().minY + caster.getEyeHeight() - 0.5 + world.rand.nextDouble();
|
||||||
double z = caster.posZ + world.rand.nextDouble() * 2 - 1;
|
double z = caster.posZ + world.rand.nextDouble() * 2 - 1;
|
||||||
ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).vel(0, 0.1, 0).colour(0.9f, 0.7f, 1).spawn(world);
|
ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).vel(0, 0.1, 0).clr(0.9f, 0.7f, 1).spawn(world);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -41,11 +41,11 @@ public class Flight extends Spell {
|
|||||||
double x = caster.posX - 1 + world.rand.nextDouble() * 2;
|
double x = caster.posX - 1 + world.rand.nextDouble() * 2;
|
||||||
double y = caster.getEntityBoundingBox().minY + caster.getEyeHeight() - 0.5 + world.rand.nextDouble();
|
double y = caster.getEntityBoundingBox().minY + caster.getEyeHeight() - 0.5 + world.rand.nextDouble();
|
||||||
double z = caster.posZ - 1 + world.rand.nextDouble() * 2;
|
double z = caster.posZ - 1 + world.rand.nextDouble() * 2;
|
||||||
ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).vel(0, -0.1, 0).lifetime(15).colour(0.8f, 1, 0.5f).spawn(world);
|
ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).vel(0, -0.1, 0).time(15).clr(0.8f, 1, 0.5f).spawn(world);
|
||||||
x = caster.posX - 1 + world.rand.nextDouble() * 2;
|
x = caster.posX - 1 + world.rand.nextDouble() * 2;
|
||||||
y = caster.getEntityBoundingBox().minY + caster.getEyeHeight() - 0.5 + world.rand.nextDouble();
|
y = caster.getEntityBoundingBox().minY + caster.getEyeHeight() - 0.5 + world.rand.nextDouble();
|
||||||
z = caster.posZ - 1 + world.rand.nextDouble() * 2;
|
z = caster.posZ - 1 + world.rand.nextDouble() * 2;
|
||||||
ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).vel(0, -0.1, 0).lifetime(15).colour(1, 1, 1).spawn(world);
|
ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).vel(0, -0.1, 0).time(15).clr(1, 1, 1).spawn(world);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ticksInUse % 24 == 0){
|
if(ticksInUse % 24 == 0){
|
||||||
|
|||||||
@@ -52,8 +52,8 @@ public class FontOfMana extends Spell {
|
|||||||
double y = caster.getEntityBoundingBox().minY;
|
double y = caster.getEntityBoundingBox().minY;
|
||||||
double z = caster.posZ + radius * Math.sin(angle);
|
double z = caster.posZ + radius * Math.sin(angle);
|
||||||
|
|
||||||
ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).vel(0, 0.03, 0).lifetime(50)
|
ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).vel(0, 0.03, 0).time(50)
|
||||||
.colour(1, 1 - hue, 0.6f + hue).spawn(world);
|
.clr(1, 1 - hue, 0.6f + hue).spawn(world);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -50,13 +50,13 @@ public class ForestsCurse extends SpellAreaEffect {
|
|||||||
|
|
||||||
float brightness = world.rand.nextFloat() / 4;
|
float brightness = world.rand.nextFloat() / 4;
|
||||||
ParticleBuilder.create(Type.DARK_MAGIC).pos(x, y, z).vel(0, -0.2, 0)
|
ParticleBuilder.create(Type.DARK_MAGIC).pos(x, y, z).vel(0, -0.2, 0)
|
||||||
.colour(0.05f + brightness, 0.2f + brightness, 0).spawn(world);
|
.clr(0.05f + brightness, 0.2f + brightness, 0).spawn(world);
|
||||||
|
|
||||||
brightness = world.rand.nextFloat() / 4;
|
brightness = world.rand.nextFloat() / 4;
|
||||||
ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).vel(0, -0.05, 0).lifetime(50)
|
ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).vel(0, -0.05, 0).time(50)
|
||||||
.colour(0.1f + brightness, 0.2f + brightness, 0).spawn(world);
|
.clr(0.1f + brightness, 0.2f + brightness, 0).spawn(world);
|
||||||
|
|
||||||
ParticleBuilder.create(Type.LEAF).pos(x, y, z).vel(0, -0.01, 0).lifetime(40 + world.rand.nextInt(12)).spawn(world);
|
ParticleBuilder.create(Type.LEAF).pos(x, y, z).vel(0, -0.01, 0).time(40 + world.rand.nextInt(12)).spawn(world);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -87,8 +87,8 @@ public class Freeze extends SpellRay {
|
|||||||
@Override
|
@Override
|
||||||
protected void spawnParticle(World world, double x, double y, double z, double vx, double vy, double vz){
|
protected void spawnParticle(World world, double x, double y, double z, double vx, double vy, double vz){
|
||||||
float brightness = 0.5f + (world.rand.nextFloat() / 2);
|
float brightness = 0.5f + (world.rand.nextFloat() / 2);
|
||||||
ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).lifetime(12 + world.rand.nextInt(8))
|
ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).time(12 + world.rand.nextInt(8))
|
||||||
.colour(brightness, brightness + 0.1f, 1).spawn(world);
|
.clr(brightness, brightness + 0.1f, 1).spawn(world);
|
||||||
ParticleBuilder.create(Type.SNOW).pos(x, y, z).spawn(world);
|
ParticleBuilder.create(Type.SNOW).pos(x, y, z).spawn(world);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ public class FreezingWeapon extends Spell {
|
|||||||
double x = caster.posX + world.rand.nextDouble() * 2 - 1;
|
double x = caster.posX + world.rand.nextDouble() * 2 - 1;
|
||||||
double y = caster.getEntityBoundingBox().minY + caster.getEyeHeight() - 0.5 + world.rand.nextDouble();
|
double y = caster.getEntityBoundingBox().minY + caster.getEyeHeight() - 0.5 + world.rand.nextDouble();
|
||||||
double z = caster.posZ + world.rand.nextDouble() * 2 - 1;
|
double z = caster.posZ + world.rand.nextDouble() * 2 - 1;
|
||||||
ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).vel(0, 0.1, 0).colour(0.9f, 0.7f, 1).spawn(world);
|
ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).vel(0, 0.1, 0).clr(0.9f, 0.7f, 1).spawn(world);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -104,9 +104,9 @@ public class FrostRay extends SpellRay {
|
|||||||
@Override
|
@Override
|
||||||
protected void spawnParticle(World world, double x, double y, double z, double vx, double vy, double vz){
|
protected void spawnParticle(World world, double x, double y, double z, double vx, double vy, double vz){
|
||||||
float brightness = world.rand.nextFloat();
|
float brightness = world.rand.nextFloat();
|
||||||
ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).vel(vx, vy, vz).lifetime(8 + world.rand.nextInt(12))
|
ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).vel(vx, vy, vz).time(8 + world.rand.nextInt(12))
|
||||||
.colour(0.4f + 0.6f * brightness, 0.6f + 0.4f*brightness, 1).spawn(world);
|
.clr(0.4f + 0.6f * brightness, 0.6f + 0.4f*brightness, 1).spawn(world);
|
||||||
ParticleBuilder.create(Type.SNOW).pos(x, y, z).vel(vx, vy, vz).lifetime(8 + world.rand.nextInt(12)).spawn(world);
|
ParticleBuilder.create(Type.SNOW).pos(x, y, z).vel(vx, vy, vz).time(8 + world.rand.nextInt(12)).spawn(world);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,11 +35,11 @@ public class Glide extends Spell {
|
|||||||
double x = caster.posX - 0.25 + world.rand.nextDouble() / 2;
|
double x = caster.posX - 0.25 + world.rand.nextDouble() / 2;
|
||||||
double y = caster.getEntityBoundingBox().minY + world.rand.nextDouble();
|
double y = caster.getEntityBoundingBox().minY + world.rand.nextDouble();
|
||||||
double z = caster.posZ - 0.25 + world.rand.nextDouble() / 2;
|
double z = caster.posZ - 0.25 + world.rand.nextDouble() / 2;
|
||||||
ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).vel(0, -0.1, 0).lifetime(15).colour(1, 1, 1).spawn(world);
|
ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).vel(0, -0.1, 0).time(15).clr(1, 1, 1).spawn(world);
|
||||||
x = caster.posX - 0.25 + world.rand.nextDouble() / 2;
|
x = caster.posX - 0.25 + world.rand.nextDouble() / 2;
|
||||||
y = caster.getEntityBoundingBox().minY + world.rand.nextDouble();
|
y = caster.getEntityBoundingBox().minY + world.rand.nextDouble();
|
||||||
z = caster.posZ - 0.25 + world.rand.nextDouble() / 2;
|
z = caster.posZ - 0.25 + world.rand.nextDouble() / 2;
|
||||||
ParticleBuilder.create(Type.LEAF).pos(x, y, z).lifetime(20).spawn(world);
|
ParticleBuilder.create(Type.LEAF).pos(x, y, z).time(20).spawn(world);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ticksInUse % 24 == 0){
|
if(ticksInUse % 24 == 0){
|
||||||
|
|||||||
@@ -9,8 +9,8 @@ import electroblob.wizardry.constants.Tier;
|
|||||||
import electroblob.wizardry.entity.living.ISummonedCreature;
|
import electroblob.wizardry.entity.living.ISummonedCreature;
|
||||||
import electroblob.wizardry.registry.WizardryItems;
|
import electroblob.wizardry.registry.WizardryItems;
|
||||||
import electroblob.wizardry.registry.WizardrySounds;
|
import electroblob.wizardry.registry.WizardrySounds;
|
||||||
import electroblob.wizardry.util.ParticleBuilder.Type;
|
|
||||||
import electroblob.wizardry.util.ParticleBuilder;
|
import electroblob.wizardry.util.ParticleBuilder;
|
||||||
|
import electroblob.wizardry.util.ParticleBuilder.Type;
|
||||||
import electroblob.wizardry.util.SpellModifiers;
|
import electroblob.wizardry.util.SpellModifiers;
|
||||||
import electroblob.wizardry.util.WizardryUtilities;
|
import electroblob.wizardry.util.WizardryUtilities;
|
||||||
import net.minecraft.entity.EntityLivingBase;
|
import net.minecraft.entity.EntityLivingBase;
|
||||||
@@ -49,10 +49,10 @@ public class GroupHeal extends Spell {
|
|||||||
double x = caster.posX + world.rand.nextDouble() * 2 - 1;
|
double x = caster.posX + world.rand.nextDouble() * 2 - 1;
|
||||||
double y = caster.getEntityBoundingBox().minY + caster.getEyeHeight() - 0.5 + world.rand.nextDouble();
|
double y = caster.getEntityBoundingBox().minY + caster.getEyeHeight() - 0.5 + world.rand.nextDouble();
|
||||||
double z = caster.posZ + world.rand.nextDouble() * 2 - 1;
|
double z = caster.posZ + world.rand.nextDouble() * 2 - 1;
|
||||||
ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).vel(0, 0.1, 0).colour(1, 1, 0.3f).spawn(world);
|
ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).vel(0, 0.1, 0).clr(1, 1, 0.3f).spawn(world);
|
||||||
}
|
}
|
||||||
|
|
||||||
Wizardry.proxy.spawnEntityParticle(world, caster, 15, 1, 1, 0.3f);
|
ParticleBuilder.create(Type.BUFF).entity(caster).clr(1, 1, 0.3f).spawn(world);
|
||||||
}
|
}
|
||||||
|
|
||||||
WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_HEAL, 0.7F,
|
WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_HEAL, 0.7F,
|
||||||
@@ -78,10 +78,10 @@ public class GroupHeal extends Spell {
|
|||||||
double x = caster.posX + world.rand.nextDouble() * 2 - 1;
|
double x = caster.posX + world.rand.nextDouble() * 2 - 1;
|
||||||
double y = caster.getEntityBoundingBox().minY + caster.getEyeHeight() - 0.5 + world.rand.nextDouble();
|
double y = caster.getEntityBoundingBox().minY + caster.getEyeHeight() - 0.5 + world.rand.nextDouble();
|
||||||
double z = caster.posZ + world.rand.nextDouble() * 2 - 1;
|
double z = caster.posZ + world.rand.nextDouble() * 2 - 1;
|
||||||
ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).vel(0, 0.1, 0).colour(1, 1, 0.3f).spawn(world);
|
ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).vel(0, 0.1, 0).clr(1, 1, 0.3f).spawn(world);
|
||||||
}
|
}
|
||||||
|
|
||||||
Wizardry.proxy.spawnEntityParticle(world, caster, 15, 1, 1, 0.3f);
|
ParticleBuilder.create(Type.BUFF).entity(caster).clr(1, 1, 0.3f).spawn(world);
|
||||||
}
|
}
|
||||||
|
|
||||||
WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_HEAL, 0.7F,
|
WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_HEAL, 0.7F,
|
||||||
|
|||||||
@@ -41,10 +41,10 @@ public class HealAlly extends SpellRay {
|
|||||||
double x1 = (double)((float)entity.posX + world.rand.nextFloat() * 2 - 1.0f);
|
double x1 = (double)((float)entity.posX + world.rand.nextFloat() * 2 - 1.0f);
|
||||||
double y1 = (double)((float)entity.getEntityBoundingBox().minY + entity.getEyeHeight() - 0.5f + world.rand.nextFloat());
|
double y1 = (double)((float)entity.getEntityBoundingBox().minY + entity.getEyeHeight() - 0.5f + world.rand.nextFloat());
|
||||||
double z1 = (double)((float)entity.posZ + world.rand.nextFloat() * 2 - 1.0f);
|
double z1 = (double)((float)entity.posZ + world.rand.nextFloat() * 2 - 1.0f);
|
||||||
ParticleBuilder.create(Type.SPARKLE).pos(x1, y1, z1).vel(0, 0.1F, 0).colour(r, g, b).spawn(world);
|
ParticleBuilder.create(Type.SPARKLE).pos(x1, y1, z1).vel(0, 0.1F, 0).clr(r, g, b).spawn(world);
|
||||||
}
|
}
|
||||||
|
|
||||||
Wizardry.proxy.spawnEntityParticle(world, entity, 15, r, g, b);
|
ParticleBuilder.create(Type.BUFF).entity(caster).clr(r, g, b).spawn(world);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -55,9 +55,9 @@ public class IceStatue extends SpellRay {
|
|||||||
@Override
|
@Override
|
||||||
protected void spawnParticle(World world, double x, double y, double z, double vx, double vy, double vz){
|
protected void spawnParticle(World world, double x, double y, double z, double vx, double vy, double vz){
|
||||||
float brightness = 0.5f + world.rand.nextFloat() * 0.5f;
|
float brightness = 0.5f + world.rand.nextFloat() * 0.5f;
|
||||||
ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).lifetime(12 + world.rand.nextInt(8))
|
ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).time(12 + world.rand.nextInt(8))
|
||||||
.colour(brightness, brightness + 0.1f, 1.0f).spawn(world);
|
.clr(brightness, brightness + 0.1f, 1.0f).spawn(world);
|
||||||
ParticleBuilder.create(Type.SNOW).pos(x, y, z).lifetime(20 + world.rand.nextInt(10)).spawn(world);
|
ParticleBuilder.create(Type.SNOW).pos(x, y, z).time(20 + world.rand.nextInt(10)).spawn(world);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ public class ImbueWeapon extends Spell {
|
|||||||
double x = caster.posX + world.rand.nextDouble() * 2 - 1;
|
double x = caster.posX + world.rand.nextDouble() * 2 - 1;
|
||||||
double y = caster.getEntityBoundingBox().minY + caster.getEyeHeight() - 0.5 + world.rand.nextDouble();
|
double y = caster.getEntityBoundingBox().minY + caster.getEyeHeight() - 0.5 + world.rand.nextDouble();
|
||||||
double z = caster.posZ + world.rand.nextDouble() * 2 - 1;
|
double z = caster.posZ + world.rand.nextDouble() * 2 - 1;
|
||||||
ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).vel(0, 0.1, 0).colour(0.9f, 0.7f, 1).spawn(world);
|
ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).vel(0, 0.1, 0).clr(0.9f, 0.7f, 1).spawn(world);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ public class Intimidate extends Spell {
|
|||||||
double x = caster.posX - 1 + world.rand.nextDouble() * 2;
|
double x = caster.posX - 1 + world.rand.nextDouble() * 2;
|
||||||
double y = caster.getEntityBoundingBox().minY + 1.5 + world.rand.nextDouble() * 0.5;
|
double y = caster.getEntityBoundingBox().minY + 1.5 + world.rand.nextDouble() * 0.5;
|
||||||
double z = caster.posZ - 1 + world.rand.nextDouble() * 2;
|
double z = caster.posZ - 1 + world.rand.nextDouble() * 2;
|
||||||
ParticleBuilder.create(Type.DARK_MAGIC).pos(x, y, z).colour(0.9f, 0.1f, 0).spawn(world);
|
ParticleBuilder.create(Type.DARK_MAGIC).pos(x, y, z).clr(0.9f, 0.1f, 0).spawn(world);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
WizardryUtilities.playSoundAtPlayer(caster, SoundEvents.ENTITY_ENDERDRAGON_GROWL, 1.0f, 1.0f);
|
WizardryUtilities.playSoundAtPlayer(caster, SoundEvents.ENTITY_ENDERDRAGON_GROWL, 1.0f, 1.0f);
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ public class InvigoratingPresence extends Spell {
|
|||||||
double y = caster.getEntityBoundingBox().minY;
|
double y = caster.getEntityBoundingBox().minY;
|
||||||
double z = caster.posZ + radius * Math.sin(angle);
|
double z = caster.posZ + radius * Math.sin(angle);
|
||||||
|
|
||||||
ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).vel(0, 0.03, 0).lifetime(50).colour(1, 0.2f, 0.2f).spawn(world);
|
ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).vel(0, 0.03, 0).time(50).clr(1, 0.2f, 0.2f).spawn(world);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ public class InvokeWeather extends Spell {
|
|||||||
double x = caster.posX + world.rand.nextDouble() * 2 - 1;
|
double x = caster.posX + world.rand.nextDouble() * 2 - 1;
|
||||||
double y = caster.getEntityBoundingBox().minY + caster.getEyeHeight() - 0.5 + world.rand.nextDouble();
|
double y = caster.getEntityBoundingBox().minY + caster.getEyeHeight() - 0.5 + world.rand.nextDouble();
|
||||||
double z = caster.posZ + world.rand.nextDouble() * 2 - 1;
|
double z = caster.posZ + world.rand.nextDouble() * 2 - 1;
|
||||||
ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).vel(0, 0.1, 0).colour(0.5f, 0.7f, 1).spawn(world);
|
ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).vel(0, 0.1, 0).clr(0.5f, 0.7f, 1).spawn(world);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ public class Levitation extends Spell {
|
|||||||
double x = caster.posX - 0.25 + world.rand.nextDouble() * 0.5;
|
double x = caster.posX - 0.25 + world.rand.nextDouble() * 0.5;
|
||||||
double y = caster.getEntityBoundingBox().minY;
|
double y = caster.getEntityBoundingBox().minY;
|
||||||
double z = caster.posZ - 0.25 + world.rand.nextDouble() * 0.5;
|
double z = caster.posZ - 0.25 + world.rand.nextDouble() * 0.5;
|
||||||
ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).vel(0, -0.1, 0).lifetime(15).colour(0.5f, 1, 0.7f).spawn(world);
|
ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).vel(0, -0.1, 0).time(15).clr(0.5f, 1, 0.7f).spawn(world);
|
||||||
}
|
}
|
||||||
if(ticksInUse % 24 == 0 && world.isRemote){
|
if(ticksInUse % 24 == 0 && world.isRemote){
|
||||||
Wizardry.proxy.playMovingSound(caster, WizardrySounds.SPELL_LOOP_SPARKLE, 0.5f, 1, false);
|
Wizardry.proxy.playMovingSound(caster, WizardrySounds.SPELL_LOOP_SPARKLE, 0.5f, 1, false);
|
||||||
|
|||||||
@@ -89,10 +89,10 @@ public class LifeDrain extends SpellRay {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void spawnParticle(World world, double x, double y, double z, double vx, double vy, double vz){
|
protected void spawnParticle(World world, double x, double y, double z, double vx, double vy, double vz){
|
||||||
if(world.rand.nextInt(5) == 0) ParticleBuilder.create(Type.DARK_MAGIC).pos(x, y, z).colour(0.1f, 0, 0).spawn(world);
|
if(world.rand.nextInt(5) == 0) ParticleBuilder.create(Type.DARK_MAGIC).pos(x, y, z).clr(0.1f, 0, 0).spawn(world);
|
||||||
// This used to multiply the velocity by the distance from the caster
|
// This used to multiply the velocity by the distance from the caster
|
||||||
ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).vel(vx, vy, vz).lifetime(8 + world.rand.nextInt(6))
|
ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).vel(vx, vy, vz).time(8 + world.rand.nextInt(6))
|
||||||
.colour(0.5f, 0, 0).spawn(world);
|
.clr(0.5f, 0, 0).spawn(world);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,11 +5,12 @@ import java.util.List;
|
|||||||
import electroblob.wizardry.constants.Element;
|
import electroblob.wizardry.constants.Element;
|
||||||
import electroblob.wizardry.constants.SpellType;
|
import electroblob.wizardry.constants.SpellType;
|
||||||
import electroblob.wizardry.constants.Tier;
|
import electroblob.wizardry.constants.Tier;
|
||||||
import electroblob.wizardry.entity.construct.EntityLightningPulse;
|
|
||||||
import electroblob.wizardry.registry.WizardryItems;
|
import electroblob.wizardry.registry.WizardryItems;
|
||||||
import electroblob.wizardry.registry.WizardrySounds;
|
import electroblob.wizardry.registry.WizardrySounds;
|
||||||
import electroblob.wizardry.util.MagicDamage;
|
import electroblob.wizardry.util.MagicDamage;
|
||||||
import electroblob.wizardry.util.MagicDamage.DamageType;
|
import electroblob.wizardry.util.MagicDamage.DamageType;
|
||||||
|
import electroblob.wizardry.util.ParticleBuilder;
|
||||||
|
import electroblob.wizardry.util.ParticleBuilder.Type;
|
||||||
import electroblob.wizardry.util.SpellModifiers;
|
import electroblob.wizardry.util.SpellModifiers;
|
||||||
import electroblob.wizardry.util.WizardryUtilities;
|
import electroblob.wizardry.util.WizardryUtilities;
|
||||||
import net.minecraft.entity.EntityLivingBase;
|
import net.minecraft.entity.EntityLivingBase;
|
||||||
@@ -72,14 +73,10 @@ public class LightningPulse extends Spell {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!world.isRemote){
|
if(world.isRemote){
|
||||||
// Surely neither of the commented lines would have done anything?
|
ParticleBuilder.create(Type.LIGHTNING_PULSE).pos(caster.posX, caster.getEntityBoundingBox().minY
|
||||||
EntityLightningPulse lightningpulse = new EntityLightningPulse(world);
|
+ WizardryUtilities.ANTI_Z_FIGHTING_OFFSET, caster.posZ)
|
||||||
lightningpulse.setPosition(caster.posX, caster.getEntityBoundingBox().minY, caster.posZ);
|
.scale(modifiers.get(WizardryItems.blast_upgrade)).spawn(world);
|
||||||
//lightningpulse.setCaster(caster);
|
|
||||||
lightningpulse.lifetime = 7;
|
|
||||||
//lightningpulse.damageMultiplier = modifiers.get(SpellModifiers.POTENCY);
|
|
||||||
world.spawnEntity(lightningpulse);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
caster.swingArm(hand);
|
caster.swingArm(hand);
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package electroblob.wizardry.spell;
|
|||||||
import electroblob.wizardry.constants.Element;
|
import electroblob.wizardry.constants.Element;
|
||||||
import electroblob.wizardry.constants.SpellType;
|
import electroblob.wizardry.constants.SpellType;
|
||||||
import electroblob.wizardry.constants.Tier;
|
import electroblob.wizardry.constants.Tier;
|
||||||
import electroblob.wizardry.entity.EntityArc;
|
|
||||||
import electroblob.wizardry.registry.WizardrySounds;
|
import electroblob.wizardry.registry.WizardrySounds;
|
||||||
import electroblob.wizardry.util.MagicDamage;
|
import electroblob.wizardry.util.MagicDamage;
|
||||||
import electroblob.wizardry.util.MagicDamage.DamageType;
|
import electroblob.wizardry.util.MagicDamage.DamageType;
|
||||||
@@ -18,6 +17,7 @@ import net.minecraft.entity.player.EntityPlayer;
|
|||||||
import net.minecraft.util.EnumFacing;
|
import net.minecraft.util.EnumFacing;
|
||||||
import net.minecraft.util.EnumHand;
|
import net.minecraft.util.EnumHand;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.Vec3d;
|
||||||
import net.minecraft.util.text.TextComponentTranslation;
|
import net.minecraft.util.text.TextComponentTranslation;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
@@ -71,23 +71,18 @@ public class LightningRay extends SpellRay {
|
|||||||
BASE_DAMAGE * modifiers.get(SpellModifiers.POTENCY));
|
BASE_DAMAGE * modifiers.get(SpellModifiers.POTENCY));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!world.isRemote){
|
if(world.isRemote){
|
||||||
|
|
||||||
|
if(ticksInUse % 3 == 0) ParticleBuilder.create(Type.LIGHTNING).entity(caster)
|
||||||
|
.pos(caster != null ? origin.subtract(caster.getPositionVector()) : origin).target(target).spawn(world);
|
||||||
|
|
||||||
if(ticksInUse % 2 == 0){
|
|
||||||
|
|
||||||
EntityArc arc = new EntityArc(world);
|
|
||||||
arc.setEndpointCoords(caster.posX, caster.posY + 1.2, caster.posZ, target.posX,
|
|
||||||
target.posY + target.height / 2, target.posZ);
|
|
||||||
arc.lifetime = 1;
|
|
||||||
world.spawnEntity(arc);
|
|
||||||
}
|
|
||||||
|
|
||||||
}else{
|
|
||||||
// Particle effect
|
// Particle effect
|
||||||
for(int i=0; i<5; i++){
|
for(int i=0; i<5; i++){
|
||||||
ParticleBuilder.create(Type.SPARK, target).spawn(world);
|
ParticleBuilder.create(Type.SPARK, target).spawn(world);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@@ -101,21 +96,15 @@ public class LightningRay extends SpellRay {
|
|||||||
@Override
|
@Override
|
||||||
protected boolean onMiss(World world, EntityLivingBase caster, int ticksInUse, SpellModifiers modifiers){
|
protected boolean onMiss(World world, EntityLivingBase caster, int ticksInUse, SpellModifiers modifiers){
|
||||||
// This is a nice example of when onMiss is used for more than just returning a boolean
|
// This is a nice example of when onMiss is used for more than just returning a boolean
|
||||||
if(!world.isRemote){
|
if(world.isRemote && ticksInUse % 4 == 0){
|
||||||
|
|
||||||
if(ticksInUse % 2 == 0){
|
if(caster != null) origin = origin.subtract(0, Y_OFFSET, 0);
|
||||||
|
|
||||||
double freeRange = 0.8 * baseRange; // The arc does not reach full range when it has a free end
|
double freeRange = 0.8 * baseRange; // The arc does not reach full range when it has a free end
|
||||||
|
Vec3d endpoint = origin.add(direction.scale(freeRange));
|
||||||
EntityArc arc = new EntityArc(world);
|
|
||||||
arc.setEndpointCoords(caster.posX, caster.posY + 1.2, caster.posZ,
|
ParticleBuilder.create(Type.LIGHTNING).entity(caster)
|
||||||
caster.posX + caster.getLookVec().x * freeRange,
|
.pos(caster != null ? origin.subtract(caster.getPositionVector()) : origin).target(endpoint).spawn(world);
|
||||||
caster.posY + caster.getEyeHeight() + caster.getLookVec().y * freeRange,
|
|
||||||
caster.posZ + caster.getLookVec().z * freeRange);
|
|
||||||
arc.lifetime = 1;
|
|
||||||
world.spawnEntity(arc);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import java.util.List;
|
|||||||
import electroblob.wizardry.constants.Element;
|
import electroblob.wizardry.constants.Element;
|
||||||
import electroblob.wizardry.constants.SpellType;
|
import electroblob.wizardry.constants.SpellType;
|
||||||
import electroblob.wizardry.constants.Tier;
|
import electroblob.wizardry.constants.Tier;
|
||||||
import electroblob.wizardry.entity.EntityArc;
|
|
||||||
import electroblob.wizardry.registry.WizardrySounds;
|
import electroblob.wizardry.registry.WizardrySounds;
|
||||||
import electroblob.wizardry.util.MagicDamage;
|
import electroblob.wizardry.util.MagicDamage;
|
||||||
import electroblob.wizardry.util.MagicDamage.DamageType;
|
import electroblob.wizardry.util.MagicDamage.DamageType;
|
||||||
@@ -20,6 +19,7 @@ import net.minecraft.entity.player.EntityPlayer;
|
|||||||
import net.minecraft.util.EnumFacing;
|
import net.minecraft.util.EnumFacing;
|
||||||
import net.minecraft.util.EnumHand;
|
import net.minecraft.util.EnumHand;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.Vec3d;
|
||||||
import net.minecraft.util.text.TextComponentTranslation;
|
import net.minecraft.util.text.TextComponentTranslation;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
@@ -119,19 +119,20 @@ public class LightningWeb extends SpellRay {
|
|||||||
@Override
|
@Override
|
||||||
protected boolean onMiss(World world, EntityLivingBase caster, int ticksInUse, SpellModifiers modifiers){
|
protected boolean onMiss(World world, EntityLivingBase caster, int ticksInUse, SpellModifiers modifiers){
|
||||||
// This is a nice example of when onMiss is used for more than just returning a boolean
|
// This is a nice example of when onMiss is used for more than just returning a boolean
|
||||||
if(!world.isRemote){
|
if(world.isRemote){
|
||||||
|
|
||||||
|
if(caster != null) origin = origin.subtract(0, Y_OFFSET, 0);
|
||||||
|
|
||||||
|
double freeRange = 0.8 * baseRange; // The arc does not reach full range when it has a free end
|
||||||
|
Vec3d endpoint = origin.add(direction.scale(freeRange));
|
||||||
|
|
||||||
|
ParticleBuilder.create(Type.BEAM).entity(caster).clr(0.2f, 0.6f, 1)
|
||||||
|
.pos(caster != null ? origin.subtract(caster.getPositionVector()) : origin).target(endpoint).spawn(world);
|
||||||
|
|
||||||
if(ticksInUse % 2 == 0){
|
if(ticksInUse % 2 == 0){
|
||||||
|
|
||||||
double freeRange = 0.8 * baseRange; // The arc does not reach full range when it has a free end
|
|
||||||
|
|
||||||
EntityArc arc = new EntityArc(world);
|
ParticleBuilder.create(Type.LIGHTNING).entity(caster)
|
||||||
arc.setEndpointCoords(caster.posX, caster.posY + 1.2, caster.posZ,
|
.pos(caster != null ? origin.subtract(caster.getPositionVector()) : origin).target(endpoint).spawn(world);
|
||||||
caster.posX + caster.getLookVec().x * freeRange,
|
|
||||||
caster.posY + caster.getEyeHeight() + caster.getLookVec().y * freeRange,
|
|
||||||
caster.posZ + caster.getLookVec().z * freeRange);
|
|
||||||
arc.lifetime = 1;
|
|
||||||
world.spawnEntity(arc);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -150,17 +151,16 @@ public class LightningWeb extends SpellRay {
|
|||||||
MagicDamage.causeDirectMagicDamage(caster, DamageType.SHOCK), damage);
|
MagicDamage.causeDirectMagicDamage(caster, DamageType.SHOCK), damage);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!world.isRemote){
|
if(world.isRemote){
|
||||||
// Arc entity spawning
|
|
||||||
if(ticksInUse % 2 == 0){
|
|
||||||
EntityArc arc = new EntityArc(world);
|
|
||||||
arc.setEndpointCoords(origin.posX, origin.posY + 1.2, origin.posZ, target.posX,
|
|
||||||
target.posY + target.height / 2, target.posZ);
|
|
||||||
arc.lifetime = 1;
|
|
||||||
world.spawnEntity(arc);
|
|
||||||
}
|
|
||||||
|
|
||||||
}else{
|
ParticleBuilder.create(Type.BEAM).entity(caster).clr(0.2f, 0.6f, 1)
|
||||||
|
.pos(caster != null ? origin.subtract(caster.getPositionVector()) : origin).target(target).spawn(world);
|
||||||
|
|
||||||
|
if(ticksInUse % 3 == 0){
|
||||||
|
ParticleBuilder.create(Type.LIGHTNING).entity(caster)
|
||||||
|
.pos(caster != null ? origin.subtract(caster.getPositionVector()) : origin).target(target).spawn(world);
|
||||||
|
}
|
||||||
|
|
||||||
// Particle effect
|
// Particle effect
|
||||||
for(int i=0; i<5; i++){
|
for(int i=0; i<5; i++){
|
||||||
ParticleBuilder.create(Type.SPARK, target).spawn(world);
|
ParticleBuilder.create(Type.SPARK, target).spawn(world);
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ import net.minecraft.entity.passive.EntityPig;
|
|||||||
import net.minecraft.nbt.NBTTagCompound;
|
import net.minecraft.nbt.NBTTagCompound;
|
||||||
import net.minecraft.util.EnumFacing;
|
import net.minecraft.util.EnumFacing;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.Vec3d;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
public class Metamorphosis extends SpellRay {
|
public class Metamorphosis extends SpellRay {
|
||||||
@@ -111,7 +112,7 @@ public class Metamorphosis extends SpellRay {
|
|||||||
|
|
||||||
}else{
|
}else{
|
||||||
for(int i=0; i<5; i++){
|
for(int i=0; i<5; i++){
|
||||||
ParticleBuilder.create(Type.DARK_MAGIC).pos(xPos, yPos, zPos).colour(0.1f, 0, 0).spawn(world);
|
ParticleBuilder.create(Type.DARK_MAGIC).pos(xPos, yPos, zPos).clr(0.1f, 0, 0).spawn(world);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -76,10 +76,10 @@ public class MindControl extends SpellRay {
|
|||||||
for(int i=0; i<10; i++){
|
for(int i=0; i<10; i++){
|
||||||
ParticleBuilder.create(Type.DARK_MAGIC, world.rand, target.posX,
|
ParticleBuilder.create(Type.DARK_MAGIC, world.rand, target.posX,
|
||||||
target.getEntityBoundingBox().minY + target.getEyeHeight(), target.posZ, 0.25, false)
|
target.getEntityBoundingBox().minY + target.getEyeHeight(), target.posZ, 0.25, false)
|
||||||
.colour(0.8f, 0.2f, 1.0f).spawn(world);
|
.clr(0.8f, 0.2f, 1.0f).spawn(world);
|
||||||
ParticleBuilder.create(Type.DARK_MAGIC, world.rand, target.posX,
|
ParticleBuilder.create(Type.DARK_MAGIC, world.rand, target.posX,
|
||||||
target.getEntityBoundingBox().minY + target.getEyeHeight(), target.posZ, 0.25, false)
|
target.getEntityBoundingBox().minY + target.getEyeHeight(), target.posZ, 0.25, false)
|
||||||
.colour(0.2f, 0.04f, 0.25f).spawn(world);
|
.clr(0.2f, 0.04f, 0.25f).spawn(world);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ public class MindTrick extends SpellRay {
|
|||||||
for(int i=0; i<10; i++){
|
for(int i=0; i<10; i++){
|
||||||
ParticleBuilder.create(Type.DARK_MAGIC, world.rand, target.posX,
|
ParticleBuilder.create(Type.DARK_MAGIC, world.rand, target.posX,
|
||||||
target.getEntityBoundingBox().minY + target.getEyeHeight(), target.posZ, 0.25, false)
|
target.getEntityBoundingBox().minY + target.getEyeHeight(), target.posZ, 0.25, false)
|
||||||
.colour(0.8f, 0.2f, 1.0f).spawn(world);
|
.clr(0.8f, 0.2f, 1.0f).spawn(world);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -53,8 +53,8 @@ public class Petrify extends SpellRay {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void spawnParticle(World world, double x, double y, double z, double vx, double vy, double vz){
|
protected void spawnParticle(World world, double x, double y, double z, double vx, double vy, double vz){
|
||||||
ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).lifetime(12 + world.rand.nextInt(8)).colour(0.2f, 0.2f, 0.2f).spawn(world);
|
ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).time(12 + world.rand.nextInt(8)).clr(0.2f, 0.2f, 0.2f).spawn(world);
|
||||||
ParticleBuilder.create(Type.DARK_MAGIC).pos(x, y, z).colour(0.1f, 0.1f, 0.1f).spawn(world);
|
ParticleBuilder.create(Type.DARK_MAGIC).pos(x, y, z).clr(0.1f, 0.1f, 0.1f).spawn(world);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,12 +58,12 @@ public class PlagueOfDarkness extends Spell {
|
|||||||
particleX = caster.posX - 1.0d + 2 * world.rand.nextDouble();
|
particleX = caster.posX - 1.0d + 2 * world.rand.nextDouble();
|
||||||
particleZ = caster.posZ - 1.0d + 2 * world.rand.nextDouble();
|
particleZ = caster.posZ - 1.0d + 2 * world.rand.nextDouble();
|
||||||
ParticleBuilder.create(Type.DARK_MAGIC).pos(particleX, caster.getEntityBoundingBox().minY, particleZ)
|
ParticleBuilder.create(Type.DARK_MAGIC).pos(particleX, caster.getEntityBoundingBox().minY, particleZ)
|
||||||
.vel(particleX - caster.posX, 0, particleZ - caster.posZ).colour(0.1f, 0, 0).spawn(world);
|
.vel(particleX - caster.posX, 0, particleZ - caster.posZ).clr(0.1f, 0, 0).spawn(world);
|
||||||
|
|
||||||
particleX = caster.posX - 1.0d + 2 * world.rand.nextDouble();
|
particleX = caster.posX - 1.0d + 2 * world.rand.nextDouble();
|
||||||
particleZ = caster.posZ - 1.0d + 2 * world.rand.nextDouble();
|
particleZ = caster.posZ - 1.0d + 2 * world.rand.nextDouble();
|
||||||
ParticleBuilder.create(Type.SPARKLE).pos(particleX, caster.getEntityBoundingBox().minY, particleZ)
|
ParticleBuilder.create(Type.SPARKLE).pos(particleX, caster.getEntityBoundingBox().minY, particleZ)
|
||||||
.vel(particleX - caster.posX, 0, particleZ - caster.posZ).lifetime(30).colour(0.1f, 0, 0.05f).spawn(world);
|
.vel(particleX - caster.posX, 0, particleZ - caster.posZ).time(30).clr(0.1f, 0, 0.05f).spawn(world);
|
||||||
|
|
||||||
particleX = caster.posX - 1.0d + 2 * world.rand.nextDouble();
|
particleX = caster.posX - 1.0d + 2 * world.rand.nextDouble();
|
||||||
particleZ = caster.posZ - 1.0d + 2 * world.rand.nextDouble();
|
particleZ = caster.posZ - 1.0d + 2 * world.rand.nextDouble();
|
||||||
|
|||||||
@@ -68,8 +68,8 @@ public class Poison extends SpellRay {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void spawnParticle(World world, double x, double y, double z, double vx, double vy, double vz){
|
protected void spawnParticle(World world, double x, double y, double z, double vx, double vy, double vz){
|
||||||
ParticleBuilder.create(Type.DARK_MAGIC).pos(x, y, z).colour(0.3f, 0.7f, 0).spawn(world);
|
ParticleBuilder.create(Type.DARK_MAGIC).pos(x, y, z).clr(0.3f, 0.7f, 0).spawn(world);
|
||||||
ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).lifetime(12 + world.rand.nextInt(8)).colour(0.1f, 0.4f, 0).spawn(world);
|
ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).time(12 + world.rand.nextInt(8)).clr(0.1f, 0.4f, 0).spawn(world);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -78,12 +78,12 @@ public class Shockwave extends Spell {
|
|||||||
particleX = caster.posX - 1.0d + 2 * world.rand.nextDouble();
|
particleX = caster.posX - 1.0d + 2 * world.rand.nextDouble();
|
||||||
particleZ = caster.posZ - 1.0d + 2 * world.rand.nextDouble();
|
particleZ = caster.posZ - 1.0d + 2 * world.rand.nextDouble();
|
||||||
ParticleBuilder.create(Type.SPARKLE).pos(particleX, caster.getEntityBoundingBox().minY, particleZ)
|
ParticleBuilder.create(Type.SPARKLE).pos(particleX, caster.getEntityBoundingBox().minY, particleZ)
|
||||||
.vel(particleX - caster.posX, 0, particleZ - caster.posZ).lifetime(30).colour(0.8f, 0.8f, 1).spawn(world);
|
.vel(particleX - caster.posX, 0, particleZ - caster.posZ).time(30).clr(0.8f, 0.8f, 1).spawn(world);
|
||||||
|
|
||||||
particleX = caster.posX - 1.0d + 2 * world.rand.nextDouble();
|
particleX = caster.posX - 1.0d + 2 * world.rand.nextDouble();
|
||||||
particleZ = caster.posZ - 1.0d + 2 * world.rand.nextDouble();
|
particleZ = caster.posZ - 1.0d + 2 * world.rand.nextDouble();
|
||||||
ParticleBuilder.create(Type.SPARKLE).pos(particleX, caster.getEntityBoundingBox().minY, particleZ)
|
ParticleBuilder.create(Type.SPARKLE).pos(particleX, caster.getEntityBoundingBox().minY, particleZ)
|
||||||
.vel(particleX - caster.posX, 0, particleZ - caster.posZ).lifetime(30).colour(0.9f, 0.9f, 0.9f).spawn(world);
|
.vel(particleX - caster.posX, 0, particleZ - caster.posZ).time(30).clr(0.9f, 0.9f, 0.9f).spawn(world);
|
||||||
|
|
||||||
particleX = caster.posX - 1.0d + 2 * world.rand.nextDouble();
|
particleX = caster.posX - 1.0d + 2 * world.rand.nextDouble();
|
||||||
particleZ = caster.posZ - 1.0d + 2 * world.rand.nextDouble();
|
particleZ = caster.posZ - 1.0d + 2 * world.rand.nextDouble();
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ public class Slime extends SpellRay {
|
|||||||
@Override
|
@Override
|
||||||
protected void spawnParticle(World world, double x, double y, double z, double vx, double vy, double vz){
|
protected void spawnParticle(World world, double x, double y, double z, double vx, double vy, double vz){
|
||||||
world.spawnParticle(EnumParticleTypes.SLIME, x, y, z, 0, 0, 0);
|
world.spawnParticle(EnumParticleTypes.SLIME, x, y, z, 0, 0, 0);
|
||||||
ParticleBuilder.create(Type.DARK_MAGIC).pos(x, y, z).colour(0.2f, 0.8f, 0.1f).spawn(world);
|
ParticleBuilder.create(Type.DARK_MAGIC).pos(x, y, z).clr(0.2f, 0.8f, 0.1f).spawn(world);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,9 +54,9 @@ public class Snare extends SpellRay {
|
|||||||
@Override
|
@Override
|
||||||
protected void spawnParticle(World world, double x, double y, double z, double vx, double vy, double vz){
|
protected void spawnParticle(World world, double x, double y, double z, double vx, double vy, double vz){
|
||||||
float brightness = world.rand.nextFloat() * 0.25f;
|
float brightness = world.rand.nextFloat() * 0.25f;
|
||||||
ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).lifetime(20 + world.rand.nextInt(8))
|
ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).time(20 + world.rand.nextInt(8))
|
||||||
.colour(brightness, brightness + 0.1f, 0).spawn(world);
|
.clr(brightness, brightness + 0.1f, 0).spawn(world);
|
||||||
ParticleBuilder.create(Type.LEAF).pos(x, y, z).vel(0, -0.01, 0).lifetime(40 + world.rand.nextInt(10)).spawn(world);
|
ParticleBuilder.create(Type.LEAF).pos(x, y, z).vel(0, -0.01, 0).time(40 + world.rand.nextInt(10)).spawn(world);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user