<commit_before>use std::f32;

use cgmath::Point2;
use gfx;
use specs;
use specs::prelude::{Read, ReadStorage, WriteStorage};

use crate::bullet::bullets::Bullets;
use crate::bullet::collision::Collision;
use crate::character::controls::CharacterInputState;
use crate::game::constants::{ASPECT_RATIO, BULLET_SPEED, VIEW_DISTANCE};
use crate::gfx_app::{ColorFormat, DepthFormat};
use crate::graphics::{camera::CameraInputState, can_move, dimensions::{Dimensions, get_projection, get_view_matrix}};
use crate::graphics::can_move_to_tile;
use crate::graphics::mesh::PlainMesh;
use crate::shaders::{bullet_pipeline, Position, Projection};

pub mod bullets;
pub mod collision;

const SHADER_VERT: &[u8] = include_bytes!("../shaders/bullet.v.glsl");
const SHADER_FRAG: &[u8] = include_bytes!("../shaders/bullet.f.glsl");

#[derive(PartialEq)]
pub struct BulletDrawable {
  projection: Projection,
  pub position: Position,
  previous_position: Position,
  offset_delta: Position,
  pub movement_direction: Point2<f32>,
  pub status: collision::Collision,
}

impl BulletDrawable {
  pub fn new(position: Position, movement_direction: Point2<f32>) -> BulletDrawable {
    let view = get_view_matrix(VIEW_DISTANCE);
    let projection = get_projection(view, ASPECT_RATIO);
    BulletDrawable {
      projection,
      position,
      previous_position: Position::origin(),
      offset_delta: Position::origin(),
      movement_direction,
      status: Collision::Flying,
    }
  }

  pub fn update(&mut self, world_to_clip: &Projection, ci: &CharacterInputState) {
    self.projection = *world_to_clip;

    self.offset_delta =
      if (ci.movement.x() - self.previous_position.x()).abs() > f32::EPSILON ||
        (ci.movement.y() - self.previous_position.y()).abs() > f32::EPSILON {
        ci.movement - self.previous_position
      } else {
        self.offset_delta
      };

    self.previous_position = Position::new(
      ci.movement.x() - (self.movement_direction.x * BULLET_SPEED / (5.0 / 3.0)),
      ci.movement.y() + (self.movement_direction.y * BULLET_SPEED));

    self.position = self.position + self.offset_delta +
      Position::new(self.movement_direction.x * BULLET_SPEED / (5.0 / 3.0), -self.movement_direction.y * BULLET_SPEED);

    let tile_pos = ci.movement - self.position;

    self.status = if !can_move(self.position) {
      Collision::OutOfBounds
    } else if !can_move_to_tile(tile_pos) {
      Collision::Hit
    } else {<commit_msg>Add constant SCALING_FACTOR<commit_after>use std::f32;

use cgmath::Point2;
use gfx;
use specs;
use specs::prelude::{Read, ReadStorage, WriteStorage};

use crate::bullet::bullets::Bullets;
use crate::bullet::collision::Collision;
use crate::character::controls::CharacterInputState;
use crate::game::constants::{ASPECT_RATIO, BULLET_SPEED, VIEW_DISTANCE};
use crate::gfx_app::{ColorFormat, DepthFormat};
use crate::graphics::{camera::CameraInputState, can_move, dimensions::{Dimensions, get_projection, get_view_matrix}};
use crate::graphics::can_move_to_tile;
use crate::graphics::mesh::PlainMesh;
use crate::shaders::{bullet_pipeline, Position, Projection};

pub mod bullets;
pub mod collision;

const SHADER_VERT: &[u8] = include_bytes!("../shaders/bullet.v.glsl");
const SHADER_FRAG: &[u8] = include_bytes!("../shaders/bullet.f.glsl");

const SCALING_FACTOR: f32 = 5.0 / 3.0;

#[derive(PartialEq)]
pub struct BulletDrawable {
  projection: Projection,
  pub position: Position,
  previous_position: Position,
  offset_delta: Position,
  pub movement_direction: Point2<f32>,
  pub status: collision::Collision,
}

impl BulletDrawable {
  pub fn new(position: Position, movement_direction: Point2<f32>) -> BulletDrawable {
    let view = get_view_matrix(VIEW_DISTANCE);
    let projection = get_projection(view, ASPECT_RATIO);
    BulletDrawable {
      projection,
      position,
      previous_position: Position::origin(),
      offset_delta: Position::origin(),
      movement_direction,
      status: Collision::Flying,
    }
  }

  pub fn update(&mut self, world_to_clip: &Projection, ci: &CharacterInputState) {
    self.projection = *world_to_clip;

    self.offset_delta =
      if (ci.movement.x() - self.previous_position.x()).abs() > f32::EPSILON ||
        (ci.movement.y() - self.previous_position.y()).abs() > f32::EPSILON {
        ci.movement - self.previous_position
      } else {
        self.offset_delta
      };

    self.previous_position = Position::new(
      ci.movement.x() - (self.movement_direction.x * BULLET_SPEED / SCALING_FACTOR),
      ci.movement.y() + (self.movement_direction.y * BULLET_SPEED));

    self.position = self.position + self.offset_delta +
      Position::new(self.movement_direction.x * BULLET_SPEED / SCALING_FACTOR, -self.movement_direction.y * BULLET_SPEED);

    let tile_pos = ci.movement - self.position;

    self.status = if !can_move(self.position) {
      Collision::OutOfBounds
    } else if !can_move_to_tile(tile_pos) {
      Collision::Hit
    } else {
{'fraction_non_alphanumeric': 0.13649136892814132, 'fraction_numerical': 0.008831794460056202, 'mean_word_length': 4.561383928571429, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3171517', 'n_tokens_mistral': 1688, 'n_tokens_neox': 1688, 'n_words': 309}