package de.slikey.effectlib.effect;
import de.slikey.effectlib.Effect;
import de.slikey.effectlib.EffectManager;
import de.slikey.effectlib.EffectType;
import de.slikey.effectlib.math.EquationTransform;
import de.slikey.effectlib.util.ParticleEffect;
import de.slikey.effectlib.util.VectorUtils;
import org.bukkit.Location;
import org.bukkit.util.Vector;
public class EquationEffect extends Effect {
/**
* ParticleType of spawned particle
*/
public ParticleEffect particle = ParticleEffect.REDSTONE;
/**
* Equations defining the X,Y,Z coordinates over
* iteration t
*
* These equations can make use of most common math functions,
* including randomized numbers. Some examples:
*
* 4*sin(t)
* cos(t * rand(-4,5) + 32
* tan(t)
*/
public String xEquation = "t";
public String yEquation = "0";
public String zEquation = "0";
/**
* The variable name used in equations to represent major ticks
*/
public String variable = "t";
/**
* How many steps to take per iteration
*/
public int particles = 1;
/**
* A set of equations that, if set, will be performed in a sub-iteration
* for each major iteration.
*/
public String x2Equation = null;
public String y2Equation = null;
public String z2Equation = null;
/**
* The variable name used in sub-equations to represent minor ticks
*/
public String variable2 = "t2";
/**
* How many steps to take per sub-iteration
*/
public int particles2 = 0;
/**
* Whether or not to orient the effect in the direction
* of the source Location
*
* If this is set to true, the X axis will represent "forward".
*/
public boolean orient = true;
/**
* Similar to orient, however this is specific to pitch.
*/
public boolean orientPitch = true;
/**
* These is the limit for the steps until it starts over.
*/
public int maxSteps = 0;
/**
* If this is true, after cycling the inner equation, it'll be set to 0.
* Set this to false if you want the miniStep to be saved between major steps.
*/
public boolean cycleMiniStep = true;
private EquationTransform xTransform;
private EquationTransform yTransform;
private EquationTransform zTransform;
private EquationTransform x2Transform;
private EquationTransform y2Transform;
private EquationTransform z2Transform;
private int step = 0;
private int miniStep = 0;
public EquationEffect(EffectManager effectManager) {
super(effectManager);
type = EffectType.REPEATING;
period = 1;
iterations = 100;
}
@Override
public void reset() {
this.step = 0;
this.miniStep = 0;
}
@Override
public void onRun() {
if (xTransform == null) {
xTransform = new EquationTransform(xEquation, variable);
yTransform = new EquationTransform(yEquation, variable);
zTransform = new EquationTransform(zEquation, variable);
if (x2Equation != null && y2Equation != null && z2Equation != null && particles2 > 0) {
x2Transform = new EquationTransform(x2Equation, variable, variable2);
y2Transform = new EquationTransform(y2Equation, variable, variable2);
z2Transform = new EquationTransform(z2Equation, variable, variable2);
}
}
Location location = getLocation();
boolean hasInnerEquation = (x2Transform != null && y2Transform != null && z2Transform != null);
for (int i = 0; i < particles; i++) {
Double xValue = xTransform.get(step);
Double yValue = yTransform.get(step);
Double zValue = zTransform.get(step);
Vector result = new Vector(xValue, yValue, zValue);
if (orient && orientPitch) {
result = VectorUtils.rotateVector(result, location);
} else if (orient) {
result = VectorUtils.rotateVector(result, location.getYaw(), 0);
}
Location targetLocation = location.clone();
targetLocation.add(result);
if (!hasInnerEquation) {
display(particle, targetLocation);
} else {
for (int j = 0; j < particles2; j++) {
Double x2Value = x2Transform.get(step, miniStep);
Double y2Value = y2Transform.get(step, miniStep);
Double z2Value = z2Transform.get(step, miniStep);
Vector result2 = new Vector(x2Value, y2Value, z2Value);
if (orient && orientPitch) {
result2 = VectorUtils.rotateVector(result2, location);
} else if (orient) {
result2 = VectorUtils.rotateVector(result2, location.getYaw(), 0);
}
Location target2Location = targetLocation.clone().add(result2);
display(particle, target2Location);
miniStep++;
}
if (cycleMiniStep) {
miniStep = 0;
}
}
if (maxSteps != 0 && step > maxSteps) {
step = 0;
break;
} else {
step++;
}
}
}
}