package com.weem.epicinventor.projectile;
import com.weem.epicinventor.*;
import com.weem.epicinventor.actor.*;
import com.weem.epicinventor.network.*;
import com.weem.epicinventor.utility.*;
import java.awt.*;
import java.awt.image.*;
import java.awt.Rectangle.*;
import java.awt.geom.AffineTransform;
import java.util.*;
public class Projectile {
protected ProjectileManager projectileManager;
protected Registry registry;
protected String id = "";
protected String name = "";
protected int mapX, mapY;
protected int width, height;
protected int speed;
protected BufferedImage image;
protected BufferedImage[] images;
protected Rectangle spriteRect;
protected boolean isDirty;
protected Point start;
protected Point end;
protected Point finalPoint;
protected Point last;
protected double slope;
protected Direction direction;
protected boolean friendly;
protected boolean placeable;
protected boolean disregardTerrain;
protected int damage;
protected static final long MAX_DISTANCE = 1600;
protected Actor source;
protected int count = 0;
protected boolean returning = false;
protected int numAnimationFrames;
protected int currentAnimationFrame;
protected boolean isSpinning = false;
transient protected SoundClip soundClip;
protected enum Direction {
RIGHT,
LEFT
}
public Projectile(ProjectileManager pm, Registry rg, Actor as, String im, int sp, Point s, Point e, boolean f, boolean p, boolean dt, int d) {
projectileManager = pm;
registry = rg;
source = as;
id = UUID.randomUUID().toString();
start = s;
end = e;
finalPoint = s;
last = new Point();
last.x = mapX = start.x;
last.y = mapY = start.y;
setSlope(start, end);
count = 0;
speed = sp;
friendly = f;
placeable = p;
disregardTerrain = dt;
damage = d;
if (end.x > start.x) {
direction = Direction.RIGHT;
} else {
direction = Direction.LEFT;
}
name = im;
images = new BufferedImage[8];
setImage("Projectiles/" + im);
spriteRect = new Rectangle();
SoundClip cl = new SoundClip(registry, "Projectile/" + im, getCenterPoint());
}
public Projectile(String i, ProjectileManager pm, Registry rg, Actor as, String im, int sp, Point s, Point e, boolean f, boolean p, int d) {
projectileManager = pm;
registry = rg;
source = as;
id = i;
start = s;
end = e;
last = new Point();
last.x = mapX = start.x;
last.y = mapY = start.y;
setSlope(start, end);
count = 0;
speed = sp;
friendly = f;
placeable = p;
damage = d;
if (end.x > start.x) {
direction = Direction.RIGHT;
} else {
direction = Direction.LEFT;
}
name = im;
images = new BufferedImage[8];
setImage("Projectiles/" + im);
spriteRect = new Rectangle();
SoundClip cl = new SoundClip(registry, "Projectile/" + im, getCenterPoint());
}
public String getId() {
return id;
}
public String getName() {
return name;
}
public void setSound(String s, boolean l) {
stopSound();
soundClip = new SoundClip(s);
if (l) {
soundClip.setLooping(true);
}
}
public void stopSound() {
if (soundClip != null) {
soundClip.setLooping(false);
}
}
public Rectangle getRect() {
return new Rectangle(mapX, mapY, width, height);
}
protected double getAngleFromSlope() {
double angle = 0.0f;
angle = Math.atan(slope);
if (direction == Direction.LEFT) {
angle += Math.PI;
}
return angle;
}
public void setIsDirty(boolean d) {
isDirty = d;
}
protected void setSlope(Point s, Point e) {
slope = 0.0f;
if ((double) last.x - (double) end.x != 0.0f) {
slope = ((double) last.y - (double) end.y) / ((double) last.x - (double) end.x);
} else if (last.y > end.y) {
slope = 9999999.0f;
} else if (last.y < end.y) {
slope = -9999999.0f;
}
}
public boolean isDirty() {
return isDirty;
}
private int getMapY(int x) {
double y = slope * (double) (x - start.x) + (double) start.y;
return (int) y;
}
public int getDamage() {
return damage;
}
public Actor getSource() {
return source;
}
public Point getCenterPoint() {
Point p = new Point(mapX + (width / 2), mapY + (height / 2));
return p;
}
private void setImage(String name) {
BufferedImage im = registry.getImageLoader().getImage(name);
if (im != null) {
AffineTransform tx = null;
AffineTransformOp op = null;
if (direction == Direction.LEFT) {
//rotate the image based on where you're shooting
tx = new AffineTransform();
tx.rotate(Math.atan(slope), im.getWidth() / 2, im.getHeight() / 2);
op = new AffineTransformOp(tx, AffineTransformOp.TYPE_BILINEAR);
image = op.filter(im, null);
width = im.getWidth();
height = im.getHeight();
//flip horizontally
tx = new AffineTransform();
tx = AffineTransform.getScaleInstance(-1, 1);
tx.translate(-width, 0);
op = new AffineTransformOp(tx, AffineTransformOp.TYPE_BILINEAR);
image = op.filter(image, null);
} else {
//rotate the image based on where you're shooting
tx = new AffineTransform();
tx.rotate(-Math.atan(slope), im.getWidth() / 2, im.getHeight() / 2);
op = new AffineTransformOp(tx, AffineTransformOp.TYPE_BILINEAR);
image = op.filter(im, null);
width = im.getWidth();
height = im.getHeight();
}
}
}
public void setSpinning(String name) {
numAnimationFrames = 8;
BufferedImage im = registry.getImageLoader().getImage("Projectiles/" + name);
if (im != null) {
for (int i = 0; i < numAnimationFrames; i++) {
AffineTransform tx = null;
AffineTransformOp op = null;
//rotate the image based on where you're shooting
tx = new AffineTransform();
tx.rotate(Math.toRadians(i * 45), im.getWidth() / 2, im.getHeight() / 2);
op = new AffineTransformOp(tx, AffineTransformOp.TYPE_BILINEAR);
images[i] = op.filter(im, null);
}
width = im.getWidth();
height = im.getHeight();
}
isSpinning = true;
currentAnimationFrame = 0;
}
public void destroy() {
stopSound();
isDirty = true;
}
public boolean isFromPlaceable() {
return placeable;
}
public void update() {
Point ePoint = null;
if (numAnimationFrames > 0) {
currentAnimationFrame++;
if (currentAnimationFrame >= numAnimationFrames) {
currentAnimationFrame = 0;
}
image = images[currentAnimationFrame];
}
//do movement
if (count >= 0) {
count++;
}
if (last.distance(end) > 150) {
if (count % 5 == 0) {
last.x = mapX;
last.y = mapY;
setSlope(start, end);
}
} else if (count >= 0) {
count = -1;
}
mapX += (int) (speed * Math.cos(getAngleFromSlope()));
mapY += (int) (speed * Math.sin(getAngleFromSlope()));
if (registry.getGameController().multiplayerMode != registry.getGameController().multiplayerMode.CLIENT) {
ePoint = new Point(mapX, mapY);
//make sure it hasn't been going on for a long time
if (start.distance(ePoint) > MAX_DISTANCE) {
stopSound();
isDirty = true;
return;
}
//check for hitting an actor
if (friendly) {
//check to see if it hit any monsters
if (projectileManager.checkMobProjectileHit(this)) {
stopSound();
isDirty = true;
}
} else {
//hit player?
if (projectileManager.checkPlayerProjectileHit(this)) {
stopSound();
isDirty = true;
} else if (projectileManager.checkPlaceableProjectileHit(this)) {
stopSound();
isDirty = true;
}
}
//check for hitting a block
if (!disregardTerrain) {
if (projectileManager.checkForBlock(getCenterPoint()) != 0) {
stopSound();
isDirty = true;
}
}
if (isDirty) {
stopSound();
if (registry.getGameController().multiplayerMode == registry.getGameController().multiplayerMode.SERVER && registry.getNetworkThread() != null) {
if (registry.getNetworkThread().readyForUpdates()) {
UpdateProjectile up = new UpdateProjectile();
up.id = this.getId();
up.action = "Destroy";
registry.getNetworkThread().sendData(up);
}
}
if (source != null) {
source.projectileReturned();
}
}
}
}
public void render(Graphics g) {
if (image != null && !isDirty) {
int xPos = projectileManager.mapToPanelX(mapX);
int yPos = projectileManager.mapToPanelY(mapY);
//flip the yPos since drawing happens top down versus bottom up
yPos = projectileManager.getPHeight() - yPos;
//subtract the block height since points are bottom left and drawing starts from top left
yPos -= height;
xPos -= (image.getHeight() / 2);
yPos += (image.getHeight() / 2);
g.drawImage(image, xPos, yPos, null);
/*
* xPos = projectileManager.mapToPanelX(start.x); yPos =
* projectileManager.mapToPanelY(start.y); yPos =
* projectileManager.getPHeight() - yPos;
*
* int xPos2 = projectileManager.mapToPanelX(end.x); int yPos2 =
* projectileManager.mapToPanelY(end.y); yPos2 =
* projectileManager.getPHeight() - yPos2;
*
*
* g.setColor(Color.red); g.drawLine(xPos, yPos, xPos2, yPos2);
*/
/*
* xPos = projectileManager.mapToPanelX(start.x); yPos =
* projectileManager.mapToPanelY(start.y);
*
* //flip the yPos since drawing happens top down versus bottom up
* yPos = projectileManager.getPHeight() - yPos;
*
* //subtract the block height since points are bottom left and
* drawing starts from top left yPos -= height;
* g.setColor(Color.yellow); g.drawRect(xPos - 1, yPos - 1, 2, 2);
*
*
* xPos = projectileManager.mapToPanelX(end.x); yPos =
* projectileManager.mapToPanelY(end.y);
*
* //flip the yPos since drawing happens top down versus bottom up
* yPos = projectileManager.getPHeight() - yPos;
*
* //subtract the block height since points are bottom left and
* drawing starts from top left yPos -= height;
* g.setColor(Color.red); g.drawRect(xPos - 1, yPos - 1, 2, 2);
*/
}
}
public void cleanUp() {
}
}