package ru.vagrant_ai.questionmarkgame.obj.proj;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import org.newdawn.slick.Color;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.geom.Line;
import org.newdawn.slick.geom.Point;
import org.newdawn.slick.geom.Vector2f;
import ru.vagrant_ai.questionmarkgame.main.Game;
import ru.vagrant_ai.questionmarkgame.main.GameplayState;
import ru.vagrant_ai.questionmarkgame.obj.Elements;
import ru.vagrant_ai.questionmarkgame.obj.mob.Monster;
import ru.vagrant_ai.questionmarkgame.util.MonsterHandler;
import ru.vagrant_ai.questionmarkgame.util.Util;
import ru.vagrant_ai.questionmarkgame.util.list.ITEM;
import ru.vagrant_ai.questionmarkgame.util.list.MS;
public class Bullet extends Projectile {
private Line bullet;
private Color col;
private float alpha = 0;
private float x;
private float y;
private float curr_x;
private float curr_y;
private float fire_x;
private float fire_y;
private float n_x;
private float n_y;
private short power = (short) (GameplayState.player.gun.opt_power + GameplayState.player.gun.opt_power_add);
private boolean original_line_render;
private Vector2f vector_pl;
private Vector2f vector_mouse;
private byte pierce = GameplayState.player.gun.opt_pierce;
private List<Monster> pierced = new ArrayList<Monster>();
private float power_add = 0;
public Bullet(Point gun_point)
{
this.x = (short) gun_point.getX();
this.y = (short) gun_point.getY();
curr_x = this.x;
curr_y = this.y;
if (curr_x == 0 && curr_y == 0) //game freeze prevention
{
curr_x = 1;
curr_y = 1;
}
bullet_iter = 12;
if (GameplayState.player.gun.opt_distance_is_power)
power_add = -10;
/* Searching for player-mouse line angle and setting bullet fly vector */
vector_pl = new Vector2f(this.x, this.y);
vector_mouse = new Vector2f(Util.MouseX(), Util.MouseY());
vector_mouse.sub(vector_pl);
vector_mouse.normalise();
float spread = GameplayState.player.gun.opt_spreading-GameplayState.player.gun.opt_spreading_add;
float rand = new Random().nextFloat()*6-3; //[-3..3]
vector_mouse.setTheta(vector_mouse.getTheta()+rand/5*spread); //rand/spread_max*(spread-spread_add)
n_x = vector_mouse.x;
n_y = vector_mouse.y;
bullet = new Line(this.x, this.y, curr_x, curr_y);
while(true) //set 2nd gradient line
{
curr_x += n_x; curr_y += n_y;
if (GameplayState.player.gun.opt_distance_is_power)
power_add += 0.1f+Elements.extractLevel(ITEM.P_GUN_DISTANCE_IS_POWER)*0.035f;
drawLine();
if (checkCollision() == 0)
{
float length = bullet.length();
if (length > 220)
{
length = 220;
original_line_render = true;
}
else
original_line_render = false;
fire_x = this.x;
fire_y = this.y;
while(new Line(x, y, fire_x, fire_y).length() <= length)
{
fire_x += n_x;
fire_y += n_y;
}
break;
}
}
col = new Color(190, 190, 190, 0);
render(Game.app.getGraphics());
}
private void drawLine()
{
bullet.set(x, y, curr_x, curr_y);
}
public void render(Graphics g)
{
col.a = alpha;
g.setLineWidth(1);
g.setColor(col);
if (original_line_render)
g.drawLine(x, y, curr_x, curr_y);
if (GameplayState.player.gun.opt_poison)
g.drawGradientLine(x, y, 1f/255f*159f, 1f, 1f/255f*163f, alpha, fire_x, fire_y, 1f/255f*190f, 1f/255*190f, 1f/255f*190f, alpha);
else
g.drawGradientLine(x, y, 1f, 1f/255f*125f, 0, alpha, fire_x, fire_y, 1f/255f*190f, 1f/255f*190f, 1f/255f*190f, alpha);
}
public void update()
{
bullet_iter--;
if (bullet_iter > 0)
alpha = 1f/12f*(float)bullet_iter;
}
private int checkCollision()
{
if (bullet.intersects(GameplayState.border))
return 0;
boolean crit = false;
for (int i = 0; i < MonsterHandler.monster_array.size(); ++i)
{
Monster monster = MonsterHandler.monster_array.get(i);
if (monster.state != MS.NULL && monster.state != MS.DEAD && mobNotPierced(monster))
{
if (bullet.intersects(monster.hitbox) || bullet.intersects(monster.hitbox_crit))
{
if (bullet.intersects(monster.hitbox_crit))
crit = true;
if (GameplayState.player.gun.opt_poison)
monster.addPoison((byte) ((crit?7:5)+Elements.extractLevel(ITEM.P_GUN_POISON_BULLET)*(crit?2:1)), (byte) (power/((crit?1.12f:0.9f)+Elements.extractLevel(ITEM.P_GUN_POISON_BULLET)*(0.15f+(crit?0.1f:0)))));
int damage = (int) (power + power_add); //calculate damage
damage = (short) (power * ((crit?2.4f:1) + (GameplayState.player.gun.opt_crit_up && crit?0.5f+Elements.extractLevel(ITEM.P_GUN_CRIT_UP)*0.24f:0)));
damage /= (pierced.size()>0?pierced.size()+1-Elements.extractLevel(ITEM.P_GUN_PIERCE)*0.65f:1);
monster.onDamage(damage, true);
if (pierce > 0)
{
pierce--;
pierced.add(monster);
return 1;
}
else if (pierce == 0)
return 0;
}
}
}
return 1;
}
private boolean mobNotPierced(Monster mob)
{
if (GameplayState.player.gun.opt_pierce == 0)
return true;
for (int i = 0; i < pierced.size(); ++i)
{
if (mob == pierced.get(i))
return false;
}
return true;
}
}