package rts.core.engine.layers.entities;
import java.awt.Point;
import java.util.ArrayList;
import org.newdawn.slick.Color;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.SlickException;
import rts.core.engine.Engine;
import rts.core.engine.Utils;
import rts.core.network.ig_udp_containers.EntityState;
import rts.utils.Timer;
public abstract class ActiveEntity extends BasicEntity implements INetworkEntity {
public static final int TEC_LEVEL_1 = 0;
public static final int TEC_LEVEL_2 = 1;
public static final int TEC_LEVEL_3 = 2;
public static final int TEC_LEVEL_4 = 3;
private static final int TIME_BEFORE_MOUSEOVER = 1000;
private static final Color TRANS_GREEN = new Color(0, 255, 0, 100);
private static final Color TRANS_RED = new Color(255, 0, 0, 100);
private static final Color TRANS_YELLOW = new Color(255, 255, 0, 100);
private static final Color TRANS_BLACK = new Color(255, 255, 255, 100);
private static final Color TRANS_CYAN = new Color(51, 51, 102, 200);
protected int type;
protected int maxLife;
protected int life;
protected int playerId;
protected int teamId;
protected int networkId;
protected int direction;
protected int view;
protected int minTecLevel;
protected boolean selected;
protected boolean mouseOver;
protected boolean weak;
protected boolean dying;
protected boolean visible;
protected EntityState state;
protected Color color;
protected ArrayList<Point> viewLimit;
private String name;
private Timer mouseOverTimer;
private boolean remove;
private int diX;
private int diY;
public ActiveEntity(Engine engine, int minTecLevel, int layer, int type, int maxLife, int view, int playerId, int teamId, int networkId) {
super(engine, layer);
this.minTecLevel = minTecLevel;
this.type = type;
this.maxLife = maxLife;
this.life = maxLife;
this.playerId = playerId;
this.teamId = teamId;
this.networkId = networkId;
this.state = new EntityState();
this.state.life = life;
this.state.networkId = networkId;
this.view = view;
this.visible = true;
this.viewLimit = new ArrayList<Point>();
this.mouseOverTimer = new Timer(TIME_BEFORE_MOUSEOVER);
this.diX = -1;
this.diY = -1;
this.name = EData.NAMES[type];
this.color = Color.white;
}
public ActiveEntity(Engine engine, int minTecLevel, int layer, int type, int maxLife, int view, int networkId) {
this(engine, minTecLevel, layer, type, maxLife, view, -1, -1, networkId);
}
public abstract void renderEntity(GameContainer container, Graphics g) throws SlickException;
public abstract void updateEntity(GameContainer container, int delta) throws SlickException;
public abstract void remove();
public abstract void target(ActiveEntity target, int mx, int my);
public abstract int getTargetCursor(ActiveEntity target, int mx, int my);
public abstract boolean fogOnUnit();
public abstract void renderOnMiniMap(Graphics g, float x, float y, float tw, float th);
public boolean mouseOver() {
return engine.getMouseX() > x && engine.getMouseX() < x + width && engine.getMouseY() > y && engine.getMouseY() < y + height;
}
private void findViewDistance(Point p, int view) {
boolean contain = false;
for (int i = 0; i < viewLimit.size(); i++) {
if (viewLimit.get(i).equals(p)) {
contain = true;
break;
}
}
if (!contain) {
viewLimit.add(p);
}
for (int i = 0; i < Utils.AXES.length; i++) {
Point np = new Point(p.x + Utils.AXES[i][0], p.y + Utils.AXES[i][1]);
int v = view - 1;
if (v > 0)
findViewDistance(np, v);
}
}
protected void calcViewLimit(int sx, int sy) {
if (engine.getMap().isEnableFow()) {
if (view > 0)
findViewDistance(new Point(sx, sy), view);
}
}
public void checkFowFromView() {
if (engine.getMap().isEnableFow()) {
if (teamId == engine.getPlayer().getTeamId() && view != 0) {
for (int i = 0; i < viewLimit.size(); i++) {
engine.getMap().showFow(viewLimit.get(i).x + (int) (x / engine.getTileW()), viewLimit.get(i).y + (int) (y / engine.getTileH()));
}
}
}
}
@Override
public void render(GameContainer container, Graphics g) throws SlickException {
if (visible && !fogOnUnit()) {
renderEntity(container, g);
}
}
public void renderInfos(Graphics g) {
if (visible && !fogOnUnit()) {
mouseOver = mouseOver();
if (isAlive()) {
if (selected) {
g.setColor(Color.white);
g.drawRect(x, y - 1, width, height + 1);
if (dying) {
g.setColor(Color.red);
} else {
if (weak)
g.setColor(Color.yellow);
else
g.setColor(Color.green);
}
if (y < 6) {
g.fillRect(x, y + height + 1, (life * width) / maxLife, 4);
g.setColor(Color.black);
g.drawRect(x, y + height + 1, width, 4);
} else {
g.fillRect(x, y - 6, (life * width) / maxLife, 4);
g.setColor(Color.black);
g.drawRect(x, y - 6, width, 4);
}
} else {
if (mouseOver) {
if (dying) {
g.setColor(TRANS_RED);
} else {
if (weak)
g.setColor(TRANS_YELLOW);
else
g.setColor(TRANS_GREEN);
}
if (y < 6) {
g.fillRect(x, y + height + 1, (life * width) / maxLife, 4);
g.setColor(TRANS_BLACK);
g.drawRect(x, y + height + 1, width, 4);
} else {
g.fillRect(x, y - 6, (life * width) / maxLife, 4);
g.setColor(TRANS_BLACK);
g.drawRect(x, y - 6, width, 4);
}
}
}
}
if (mouseOver && mouseOverTimer.isTimeComplete()) {
if (diX == -1 && diY == -1) {
diX = engine.getMouseX();
diY = engine.getMouseY();
}
g.setColor(TRANS_CYAN);
g.fillRect(diX, diY, name.length() * 10, 20);
g.setColor(Color.black);
g.drawRect(diX, diY, name.length() * 10, 20);
g.setColor(color);
g.drawString(name, diX + 2, diY);
}
}
}
@Override
public void update(GameContainer container, int delta) throws SlickException {
if (visible) {
updateEntity(container, delta);
if (mouseOver) {
mouseOverTimer.update(delta);
} else {
diX = -1;
diY = -1;
mouseOverTimer.resetTime();
}
}
}
@Override
public int getNetworkID() {
return networkId;
}
@Override
public EntityState getState() {
state.layer = layer;
state.life = life;
state.x = x;
state.y = y;
state.visible = visible;
state.weak = weak;
state.dying = dying;
state.direction = direction;
return state;
}
@Override
public void setState(EntityState state) {
this.layer = state.layer;
this.life = state.life;
this.x = state.x;
this.y = state.y;
this.visible = state.visible;
this.weak = state.weak;
this.dying = state.dying;
this.direction = state.direction;
}
public void addLife(int bonus) {
life = (life + bonus <= maxLife) ? life + bonus : maxLife;
if ((float) life / (float) maxLife > 0.5f) {
weak = false;
dying = false;
} else {
if ((float) life / (float) maxLife > 0.2f) {
dying = false;
}
}
remove = false;
}
public void removeLife(int damage) {
life -= damage;
if (life <= 0) {
if (!remove) {
remove();
remove = true;
}
life = 0;
} else {
if ((float) life / (float) maxLife <= 0.2f) {
dying = true;
} else {
if ((float) life / (float) maxLife < 0.5f) {
weak = true;
}
}
}
}
public boolean isAlive() {
return life > 0;
}
public void selected() {
if (visible)
this.selected = true;
else
selected = false;
}
public void deselected() {
selected = false;
}
public int getPlayerId() {
return playerId;
}
public void setPlayerId(int playerId) {
this.playerId = playerId;
}
public int getTeamId() {
return teamId;
}
public void setTeamId(int teamId) {
this.teamId = teamId;
}
public boolean isSelected() {
return selected;
}
public int getType() {
return type;
}
public int getDirection() {
return direction;
}
public void setDirection(int direction) {
this.direction = direction;
}
public int getLife() {
return life;
}
public int getMaxLife() {
return maxLife;
}
public void setLife(int life) {
this.life = life;
}
public int getTecLevel() {
return minTecLevel;
}
public boolean isVisible() {
return visible;
}
public void setColor(Color color) {
this.color = color;
}
}