package robombs.game.view;
import robombs.game.util.*;
import com.threed.jpct.*;
import java.awt.*;
/**
* A particle is a client only object for doing special effects like impacts, trails...
*/
public class Particle extends Object3D {
static final private long serialVersionUID=1L;
private final static float NO_MAX_Y=9999999999999999f;
private static Object3D PLANE=null;
private static final SimpleVector GRAV=new SimpleVector(0, 0.01, 0);
private SimpleVector vel=new SimpleVector();
private SimpleVector grav=null;
private String texture="";
private long time=0;
private long maxTime=-1;
private float maxY=NO_MAX_Y;
private int checkCount=0;
private long lastMoved=0;
private boolean water=false;
private boolean remote=false;
/**
* static initializer to create a PLANE-blueprint.
*/
static {
if (!Config.saveMemory) {
Logger.log("jPCT isn't running in save memory mode!", Logger.WARNING);
}
PLANE=new Object3D(1);
PLANE.addTriangle(new SimpleVector(-1, -1, 0), 0, 0, new SimpleVector(1, -1, 0), 1, 0,
new SimpleVector(1, 1, 0), 1, 1);
PLANE.setTexture("particle");
PLANE.rotateZ((float)Math.PI/4f);
PLANE.rotateMesh();
PLANE.getRotationMatrix().setIdentity();
PLANE.getMesh().compress();
PLANE.build();
}
/**
* Creates a new particle. The texture will be "particle" and to exists in the TextureManager.
*/
public Particle() {
super(PLANE);
grav=new SimpleVector(GRAV);
rotateZ((float)Math.random()*6f);
rotateMesh();
getRotationMatrix().setIdentity();
setBillboarding(Object3D.BILLBOARDING_ENABLED);
setVisibility(Object3D.OBJ_VISIBLE);
setCulling(Object3D.CULLING_DISABLED);
setTransparency(10);
setAdditionalColor(Color.white);
setLighting(Object3D.LIGHTING_NO_LIGHTS);
enableLazyTransformations();
reset();
setScale(0.8f);
texture="particle";
}
/**
* Sets the texture. This overrides setTexture in Object3D to keep an internal reference to the texture's name.
* @param texture String the texture's name like the TextureManager knows it.
*/
public void setTexture(String texture) {
if (!this.texture.equals(texture)) {
super.setTexture(texture);
this.texture=texture;
}
}
/**
* Sets the time in ms this particle should live.
* @param time long the time
*/
public void setLifeTime(long time) {
this.maxTime=time;
}
public boolean isWater() {
return water;
}
public void setWater(boolean isWater) {
water=isWater;
}
public boolean isRemote() {
return remote;
}
public void setColor(Color col) {
setAdditionalColor(col);
}
public void setAsRemote(boolean remote) {
this.remote=remote;
}
/**
* Sets the y-limit, i.e. how deep the particle may fall before being discarded.
* @param limit float the y-limit
*/
public void setYLimit(float limit) {
this.maxY=limit;
}
/**
* Sets the velocity for the particle.
* @param vel SimpleVector
*/
public void setVelocity(SimpleVector vel) {
this.vel.set(vel);
}
/**
* Resets the particle.
*/
public void reset() {
time=Ticker.getTime();
getTranslationMatrix().setIdentity();
checkCount=0;
}
/**
* Determines is the particle is "old". This has nothing to do with the life time. The time after
* that a particle is considered to be old is hard-wired to 20 sec. here.
* @return boolean is it old?
*/
public boolean isOld() {
return (Ticker.hasPassed(lastMoved, 20000));
}
/**
* Move the particle according to it's velocity and such. If it exceed its life time or its y-limit,
* the particle will be set to invisible.
* @param ticks long the number of ticks passed since the last call
*/
public void move(long ticks) {
if (getVisibility()) {
ticks<<=1; // Former version of the game had a nasty bug...move was called twice. But all particles
// were designed to match that behaviour, so after correcting it, the timing was wrong. To avoid changing
// all particle emitters, ticks is taken *2 here...not nice, but at least commented!
for (int i=0; i<ticks; i++) {
vel.add(grav);
translate(vel);
}
checkCount+=ticks;
lastMoved=Ticker.getTime();
if ((maxTime!=-1 && lastMoved-time>maxTime)||
(checkCount>10 && maxY!=NO_MAX_Y && getTranslation().y>=maxY)) {
reset();
setVisibility(Object3D.OBJ_INVISIBLE);
}
}
}
}