package robombs.game.view;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import robombs.clientserver.NetLogger;
import robombs.game.Globals;
import robombs.game.util.Ticker;
import com.threed.jpct.Object3D;
import com.threed.jpct.SimpleVector;
import com.threed.jpct.World;
/**
* A simple manager for smoke.
*/
public class SmokeCloudManager {
private SmokeCloud[] parts = null;
private World level = null;
private long lastCleanup = 0;
private int cnt = 100;
private Set<SmokeEmitter> emitters = new HashSet<SmokeEmitter>();
/**
* Creates a new manager with a default number of particles (100).
*
* @param level
* World the world
*/
public SmokeCloudManager(World level) {
this.level = level;
init();
}
/**
* Creates a new manager for a number of particles.
*
* @param level
* World the world
* @param max
* int the number of particles
*/
public SmokeCloudManager(World level, int max) {
cnt = max;
this.level = level;
init();
}
public void addSmokeEmitter(SimpleVector pos) {
int freq = 5;
int size = 15;
if (Globals.enhancedGraphics) {
freq = 3;
size = 22;
}
SmokeEmitter emitter = new SmokeEmitter(pos, 500, freq, size);
emitters.add(emitter);
}
/**
* Moves all clouds managed by this manager.
*
* @param ticks
* long the number of ticks passed since the last call
*/
public void move(long ticks) {
for (Iterator<SmokeEmitter> itty = emitters.iterator(); itty.hasNext();) {
SmokeEmitter emitter = itty.next();
if (emitter.isOld()) {
itty.remove();
} else {
emitter.smoke(ticks, this);
}
}
for (int i = 0; i < cnt; i++) {
SmokeCloud pp = parts[i];
if (pp != null && pp.getVisibility()) {
pp.move(ticks);
}
}
doCleanup();
}
/**
* Adds a new particle to the manager. If the maximum number of active,
* visible particles have been reached, nothing happens.
*
* @param pos
* SimpleVector the position
* @param vel
* SimpleVector the velocity
* @param time
* long the time-limit
* @param texture
* String the texture's name
*/
public void addSmokeCloud(SimpleVector pos, SimpleVector vel, long time, String texture, float scale) {
SmokeCloud p = getSmokeCloud();
if (p != null) {
p.setScale(scale);
p.setOrigin(pos);
p.setVelocity(vel);
p.setLifeTime(time);
p.setTexture(texture);
p.setTransparencyMode(Object3D.TRANSPARENCY_MODE_ADD);
p.reset();
}
}
/**
* Initializes the manager
*/
private void init() {
parts = new SmokeCloud[cnt];
lastCleanup = Ticker.getTime();
}
/**
* Every 30 secs, the managers checks for old clouds that can be cleaned up.
*/
private void doCleanup() {
long time = Ticker.getTime() - lastCleanup;
if (time > 30000 || time < 0) {
int counter = 0;
for (int i = cnt - 1; i >= 0; i--) {
SmokeCloud pp = parts[i];
if (pp != null && pp.isOld()) {
level.removeObject(pp);
parts[i] = null;
counter++;
}
}
if (counter != 0) {
NetLogger.log("Smoke cloud system cleanup performed: " + counter + " clouds removed!");
}
lastCleanup = Ticker.getTime();
}
}
/**
* Gets a particle from the manager's pool. If the pool if full of
* particles, null will be returned.
*
* @return Particle a fresh particle or null
*/
private SmokeCloud getSmokeCloud() {
int np = -1;
for (int i = 0; i < cnt; i++) {
SmokeCloud pp = parts[i];
if (pp != null && !pp.getVisibility()) {
pp.setVisibility(Object3D.OBJ_VISIBLE);
return pp;
}
if (pp == null && np == -1) {
np = i;
}
}
SmokeCloud p = null;
int s = 0;
if (np != -1) {
s = np;
}
for (int i = s; i < cnt; i++) {
if (parts[i] == null) {
p = new SmokeCloud();
level.addObject(p);
parts[i] = p;
break;
}
}
return p;
}
}