package com.shade.crash;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedList;
import org.newdawn.slick.state.StateBasedGame;
import com.crash.Body;
import com.crash.Grid;
import com.crash.Response;
import com.shade.base.Entity;
import com.shade.base.Level;
import com.shade.lighting.LuminousEntity;
/**
* Concrete instance of the Level interface which has a grid underlying it for
* collision detection.
*
* Note that all entities added to this level must extend the com.crash.Body
* class or a class cast exception will occur.
*
* @author Alexander Schearer <aschearer@gmail.com>
*/
public class CrashLevel implements Level<LuminousEntity> {
private Grid grid;
private LinkedList<LuminousEntity> entities;
public CrashLevel(int w, int h, int c) {
entities = new LinkedList<LuminousEntity>();
grid = new Grid(w, h, c);
grid.setResponse(new Response() {
public void respond(Body one, Body two) {
Entity e1 = (Entity) one;
Entity e2 = (Entity) two;
e1.onCollision(e2);
e2.onCollision(e1);
}
});
}
public void add(LuminousEntity e) {
e.addToLevel(this);
entities.add(e);
grid.add((Body) e);
}
public void remove(LuminousEntity e) {
e.removeFromLevel(this);
entities.remove(e);
grid.remove((Body) e);
}
public Object[] getEntitiesByRole(int role) {
LinkedList<LuminousEntity> players = new LinkedList<LuminousEntity>();
for (LuminousEntity e : entities) {
if (e.getRole() == role) {
players.add(e);
}
}
return players.toArray();
}
public void clear() {
for (Entity e : entities) {
e.removeFromLevel(this);
}
entities.clear();
grid.clear();
}
public void update(StateBasedGame game, int delta) {
grid.update();
for (int i = 0; i < entities.size(); i++) {
entities.get(i).update(game, delta);
}
}
public LuminousEntity[] toArray(LuminousEntity[] a) {
return entities.toArray(a);
}
public LuminousEntity[] toArray() {
return entities.toArray(new LuminousEntity[0]);
}
public boolean lineOfSight(Entity one, Entity two, Body... exceptions) {
return grid.ray((Body) one, (Body) two, exceptions);
}
public LuminousEntity[] nearbyEntities(final Entity subject, int threshold) {
int threshold2 = threshold * threshold;
LinkedList<LuminousEntity> neighbors = new LinkedList<LuminousEntity>();
for (LuminousEntity e : entities) {
if (CrashGeom.distance2((Body) subject, (Body) e) < threshold2) {
neighbors.add(e);
}
}
Collections.sort(neighbors, new Comparator<LuminousEntity>() {
public int compare(LuminousEntity e1, LuminousEntity e2) {
float d1 = CrashGeom.distance2((Body) subject, (Body) e1);
float d2 = CrashGeom.distance2((Body) subject, (Body) e2);
return (int) (d1 - d2);
}
});
return neighbors.toArray(new LuminousEntity[0]);
}
}