package ru.vagrant_ai.questionmarkgame.obj;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Image;
import org.newdawn.slick.Input;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.geom.Circle;
import org.newdawn.slick.geom.Point;
import org.newdawn.slick.geom.Vector2f;
import ru.vagrant_ai.questionmarkgame.main.GameplayState;
import ru.vagrant_ai.questionmarkgame.obj.proj.Bullet;
import ru.vagrant_ai.questionmarkgame.obj.proj.LightningProjectile;
import ru.vagrant_ai.questionmarkgame.obj.proj.Projectile;
import ru.vagrant_ai.questionmarkgame.obj.proj.ShotgunProjectile;
import ru.vagrant_ai.questionmarkgame.util.Particle;
import ru.vagrant_ai.questionmarkgame.util.Util;
import ru.vagrant_ai.questionmarkgame.util.list.ITEM;
import ru.vagrant_ai.questionmarkgame.util.list.PT;
public class Gun {
public Image gun = null;
public Image gun_f;
private Circle exception_circle;
private Circle exception_circle_f;
private Vector2f vector_gun;
private Vector2f vector_mouse = new Vector2f(Util.MouseX(), Util.MouseY());
public Point gun_point;
private final byte gun_dist = 25; //distance between center of rotation and gun's barrel
public byte opt_shoot_delay = 28; //[28..5] - [0..1]
public byte opt_shoot_delay_add = 0;
public final byte opt_shoot_delay_min = 28;
public final byte opt_shoot_delay_max = 5;
public final byte opt_shoot_delay_add_max = 1;
public float opt_spreading = 5; //[5..0.5] - [0..0.3]
public float opt_spreading_add = 0;
public final float opt_spreading_min = 5f;
public final float opt_spreading_max = 0.5f;
public final float opt_spreading_add_max = 0.3f;
public byte opt_chamber = 6; //[6..36]
public final byte opt_max_chamber = 36;
public byte opt_power = 38; //[38..100] + [0..7]
public byte opt_power_add = 0;
public final byte opt_power_min = 38;
public final byte opt_power_max = 100;
public final byte opt_power_add_max = 7;
public float opt_reload_speed = 20; //[20..5] - [0..2]
public float opt_reload_speed_add = 0;
public final float opt_reload_speed_min = 20;
public final float opt_reload_speed_max = 5;
public final float opt_reload_speed_add_max = 2;
public boolean opt_auto = false;
public boolean opt_poison = false;
public byte opt_pierce = 0;
public boolean opt_shotgun_mode = false;
public boolean opt_lightning_mode = false;
public boolean opt_distance_is_power = false;
public boolean opt_crit_up = false;
public byte util_chamber = opt_chamber; //current chamber
private byte util_shoot_delay = opt_shoot_delay;
private float util_reload_speed = opt_reload_speed;
public byte util_reload_chamber = opt_chamber; //current chamber when reloading
private List<Projectile> bullet_array = new ArrayList<Projectile>();
public Gun()
{
exception_circle = new Circle(GameplayState.player.getX()-17, GameplayState.player.getY()-13, 28);
exception_circle_f = new Circle(GameplayState.player.getX()-10, GameplayState.player.getY()-13, 28);
gun = Util.loadImage("player/gun.png");
gun_f = gun.getFlippedCopy(true, false);
gun.setCenterOfRotation(2, 2); //do not move gun to gun and gun_f to gun_f
gun_f.setCenterOfRotation(24, 2);
/*strange bug:
* center of rotation to gun wouldn't set cause image wouldn't be loaded in time
*/
gun_point = new Point(GameplayState.player.getX(), GameplayState.player.getY()+5);
}
/**
* Scans list of bullets and update every bullet
* @throws SlickException
*/
public void render(Graphics g)
{
exception_circle.setLocation(GameplayState.player.getX()-17, GameplayState.player.getY()-13);
exception_circle_f.setLocation(GameplayState.player.getX()-10, GameplayState.player.getY()-13);
if (GameplayState.player.util_facing == true)
{
gun.rotate((float) vector_mouse.getTheta());
gun.draw(GameplayState.player.getX()+7, GameplayState.player.getY()+11);
gun.rotate((float) -vector_mouse.getTheta());
}
else
{
gun_f.rotate((float) vector_mouse.getTheta()+180);
gun_f.draw(GameplayState.player.getX()-8, GameplayState.player.getY()+11);
gun_f.rotate((float) -vector_mouse.getTheta()+180);
}
for (int i = 0; i < bullet_array.size(); ++i)
{
Projectile bullet = bullet_array.get(i);
bullet.update();
if (!bullet.checkActive())
{
bullet_array.remove(i);
i--;
}
bullet.render(g);
}
}
public void update(GameContainer gc)
{
/* GUN ROTATION UPDATE */
boolean b = GameplayState.player.util_facing; //get player facing
vector_gun = new Vector2f(GameplayState.player.getX()+((b)?9:16),
GameplayState.player.getY()+13); //get vector of gun
vector_mouse = new Vector2f(Util.MouseX(), Util.MouseY()); //get vector of mouse
vector_mouse.sub(vector_gun);
vector_mouse.normalise(); //subtract and normalise
gun_point.setLocation(GameplayState.player.getX()+((b)?9:16)+gun_dist*vector_mouse.x,
GameplayState.player.getY()+13+gun_dist*vector_mouse.y); //sets the location of gun point
/* SHOOTING UPDATE */
Input inp = gc.getInput();
if (inp.isKeyDown(Input.KEY_R) && util_chamber != 0 && util_chamber != opt_chamber)
{
util_reload_chamber = opt_chamber;
util_chamber = 0;
}
if (util_chamber == 0)
update_reload();
else if (util_shoot_delay > 0)
util_shoot_delay--;
if (util_shoot_delay == 0
&& (GameplayState.player.pl_ground_level == GameplayState.ground_level //check for player current level
|| GameplayState.player.pl_ground_level == GameplayState.ramp_level)
&& GameplayState.player.util_x_movement_lock == false //check for playing changing location
&& util_chamber > 0 //check for empty chamber
&& ((!exception_circle.contains(Util.MouseX(), Util.MouseY()) && GameplayState.player.util_facing)
|| (!exception_circle_f.contains(Util.MouseX(), Util.MouseY()) && !GameplayState.player.util_facing)
) //check for mouse inside exception circles
)
{
if (Util.MousePressed(1) || (opt_auto && Util.MouseIsPressed(1)))
{
if (new Random().nextInt(100) > Elements.extractLevel(ITEM.P_GUN_CHAMBER)*8) //chance to save ammo when get_chamber upgraded
util_chamber--;
util_shoot_delay = (byte) (opt_shoot_delay-opt_shoot_delay_add);
if (opt_shotgun_mode)
{
ShotgunProjectile shotgun_shot = new ShotgunProjectile(gun_point);
bullet_array.add(shotgun_shot);
}
else if (opt_lightning_mode)
{
LightningProjectile lightning_shot = new LightningProjectile(gun_point);
bullet_array.add(lightning_shot);
}
else
{
Bullet bullet = new Bullet(gun_point);
bullet_array.add(bullet);
}
Particle.addNew(PT.GUNSMOKE, (int)vector_mouse.getTheta(), gun_point.getX(), gun_point.getY()-3);
}
}
}
public void update_reload()
{
util_reload_speed--;
if (util_reload_speed < 1)
{
util_reload_chamber--;
util_reload_speed = opt_reload_speed-opt_reload_speed_add;
if (util_reload_chamber == 0)
{
util_chamber = opt_chamber;
util_reload_chamber = opt_chamber;
}
}
}
public int getChamber() //for GUI purposes
{
if (util_chamber == 0)
return opt_chamber-util_reload_chamber;
else
return util_chamber;
}
}