ballistics-ng 0.1.0.1 → 0.1.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +106 -6
- data/Rakefile +25 -13
- data/ext/ballistics/ext.c +1 -1
- data/ext/ballistics/{gnu_ballistics.h → include/gnu_ballistics.h} +0 -0
- data/lib/ballistics/cartridge.rb +73 -36
- data/lib/ballistics/cartridges/300_blk.yaml +1 -1
- data/lib/ballistics/gun.rb +6 -25
- data/lib/ballistics/problem.rb +1 -5
- data/lib/ballistics/projectile.rb +8 -12
- data/lib/ballistics/yaml.rb +26 -0
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 03d24f50b7132229db03bb1eb7873a7828ed8858
|
4
|
+
data.tar.gz: 43cd6e8398d7f346ed6f0226b304a1dd000f014a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2d13c3f18c4798d23088eadd755ce1685e2301f52449e7ae3a3f8b05acc2b5a0272006c2e3a6ac80c68e4b1f3a9e972a6efc27602987923469405c780b491a50
|
7
|
+
data.tar.gz: 58d7e56498841d05dc2129c2a128b753690f7e722c302b96dfa1d51a985320e433f143d35184bb687af25b82099947870049c49a4b988d19291eabe5c9ad07d8
|
data/README.md
CHANGED
@@ -1,12 +1,112 @@
|
|
1
|
+
[![Build Status](https://travis-ci.org/rickhull/ballistics.svg)](https://travis-ci.org/rickhull/ballistics)
|
2
|
+
[![Gem Version](https://badge.fury.io/rb/ballistics-ng.svg)](http://badge.fury.io/rb/ballistics-ng)
|
3
|
+
[![Dependency Status](https://gemnasium.com/rickhull/ballistics.svg)](https://gemnasium.com/rickhull/ballistics)
|
4
|
+
[![Security Status](https://hakiri.io/github/rickhull/ballistics/master.svg)](https://hakiri.io/github/rickhull/ballistics/master)
|
5
|
+
|
6
|
+
# Ballistics-NG (next gen)
|
7
|
+
|
8
|
+
This gem consists of a C extension which wraps the "GNU Ballistics" C library
|
9
|
+
(which is not an official GNU project as far as I can tell) and some
|
10
|
+
additional Ruby code for managing input data.
|
11
|
+
|
12
|
+
Feed in projectile and atmospheric specifics in order to retrieve trajectory
|
13
|
+
information at range.
|
14
|
+
|
15
|
+
This project is originally based on the **ballistics** gem, which has been
|
16
|
+
abandoned since 2013. It is anticipated that this gem will take over the
|
17
|
+
**ballistics** name, but until then, this gem is known as **ballistics-ng**
|
18
|
+
|
1
19
|
# Install
|
2
20
|
|
3
21
|
```
|
4
|
-
|
5
|
-
|
22
|
+
$ gem install ballistics-ng
|
23
|
+
```
|
24
|
+
|
25
|
+
# Usage
|
26
|
+
|
27
|
+
```ruby
|
28
|
+
require 'ballistics/problem'
|
6
29
|
|
7
|
-
|
30
|
+
prob = Ballistics::Problem.simple(gun_family: 'rifles',
|
31
|
+
gun_id: 'ar15_300_blk',
|
32
|
+
cart_id: 'barnes_110_vor_tx')
|
8
33
|
|
9
|
-
|
10
|
-
|
11
|
-
|
34
|
+
puts prob.report
|
35
|
+
puts
|
36
|
+
puts
|
37
|
+
puts prob.table
|
12
38
|
```
|
39
|
+
|
40
|
+
```
|
41
|
+
$ ruby -Ilib examples/table.rb
|
42
|
+
|
43
|
+
GUN: AR-15 with 10.5 inch barrel (300 BLK)
|
44
|
+
===
|
45
|
+
Chamber: 300 BLK
|
46
|
+
Barrel length: 10.5
|
47
|
+
Sight height: 2.6
|
48
|
+
Zero Range: 50
|
49
|
+
|
50
|
+
CARTRIDGE: Barnes 300 BLK 110gr VOR-TX
|
51
|
+
=========
|
52
|
+
Case: 300 BLK
|
53
|
+
MV @ 10: 2180
|
54
|
+
MV @ 16: 2350
|
55
|
+
Desc: Hunting round for penetration and expansion
|
56
|
+
|
57
|
+
PROJECTILE: Barnes 110gr TAC-TX 300 BLK
|
58
|
+
==========
|
59
|
+
Caliber: 0.308
|
60
|
+
Grains: 110
|
61
|
+
BC (G1): 0.289
|
62
|
+
Desc: Black polymer tip, copper bullet
|
63
|
+
|
64
|
+
|
65
|
+
Range Time FPS Path
|
66
|
+
0 0.000 2180.0 -2.6
|
67
|
+
50 0.072 2043.1 -0.0
|
68
|
+
100 0.147 1911.8 0.5
|
69
|
+
150 0.229 1786.0 -1.4
|
70
|
+
200 0.316 1666.5 -6.0
|
71
|
+
250 0.409 1553.7 -13.7
|
72
|
+
300 0.509 1448.3 -25.1
|
73
|
+
350 0.616 1351.2 -40.6
|
74
|
+
400 0.731 1263.9 -60.9
|
75
|
+
450 0.854 1187.7 -86.6
|
76
|
+
500 0.983 1123.6 -118.5
|
77
|
+
```
|
78
|
+
|
79
|
+
# Features
|
80
|
+
|
81
|
+
## `Ballistics::Problem`
|
82
|
+
|
83
|
+
* specify a gun and cartridge (etc) for meaningful results
|
84
|
+
|
85
|
+
## `Ballistics::Atmosphere`
|
86
|
+
|
87
|
+
* specify altitude, humidity, pressure, and temp
|
88
|
+
* Army and ICAO atmospheres included at no charge
|
89
|
+
|
90
|
+
## `Ballistics::Gun`
|
91
|
+
|
92
|
+
* determines sight height, zero angle, chamber,
|
93
|
+
muzzle velocity per barrel length
|
94
|
+
* determines the cartridge by chamber
|
95
|
+
|
96
|
+
## `Ballistics::Cartridge`
|
97
|
+
|
98
|
+
* organized by chamber (e.g. *300 BLK*)
|
99
|
+
* *projectile* (see below)
|
100
|
+
* *case* (determines the chamber)
|
101
|
+
* optionally: *powder charge* (and *primer*) details
|
102
|
+
|
103
|
+
## `Ballistics::Projectile`
|
104
|
+
|
105
|
+
* organized by chamber
|
106
|
+
* determines caliber, grains, ballistic coefficient, and drag function
|
107
|
+
|
108
|
+
## Built In YAML Components
|
109
|
+
|
110
|
+
* [guns](https://github.com/rickhull/ballistics/tree/master/lib/ballistics/guns)
|
111
|
+
* [cartridges](https://github.com/rickhull/ballistics/tree/master/lib/ballistics/cartridges)
|
112
|
+
* [projectiles](https://github.com/rickhull/ballistics/tree/master/lib/ballistics/projectiles)
|
data/Rakefile
CHANGED
@@ -1,19 +1,26 @@
|
|
1
|
-
|
2
|
-
require "rake/testtask"
|
1
|
+
require "rake/testtask"
|
3
2
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
3
|
+
# add test task
|
4
|
+
Rake::TestTask.new do |t|
|
5
|
+
t.test_files = FileList['test/**/*.rb']
|
6
|
+
end
|
7
|
+
desc "Run minitest tests"
|
8
|
+
|
9
|
+
desc "Run example scripts"
|
10
|
+
task :examples do
|
11
|
+
Dir['examples/**/*.rb'].each { |fn|
|
12
|
+
puts
|
13
|
+
sh "ruby -Ilib #{fn}"
|
14
|
+
puts
|
15
|
+
}
|
16
|
+
end
|
9
17
|
|
10
|
-
|
18
|
+
task default: [:test, :examples]
|
19
|
+
|
20
|
+
#
|
21
|
+
# C EXTENSION
|
22
|
+
#
|
11
23
|
|
12
|
-
@test_task = true
|
13
|
-
rescue Exception => e
|
14
|
-
warn "testtask error: #{e}"
|
15
|
-
@test_task = false
|
16
|
-
end
|
17
24
|
|
18
25
|
begin
|
19
26
|
gem "rake-compiler"
|
@@ -37,6 +44,11 @@ rescue Exception => e
|
|
37
44
|
warn "rake-compiler error: #{e}"
|
38
45
|
end
|
39
46
|
|
47
|
+
#
|
48
|
+
# GEM BUILD / PUBLISH
|
49
|
+
#
|
50
|
+
|
51
|
+
|
40
52
|
begin
|
41
53
|
require 'buildar'
|
42
54
|
|
data/ext/ballistics/ext.c
CHANGED
File without changes
|
data/lib/ballistics/cartridge.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
require 'ballistics/yaml'
|
2
2
|
|
3
3
|
class Ballistics::Cartridge
|
4
|
+
YAML_DIR = 'cartridges'
|
5
|
+
|
4
6
|
MANDATORY = {
|
5
7
|
"name" => :string,
|
6
8
|
"case" => :string,
|
@@ -20,20 +22,14 @@ class Ballistics::Cartridge
|
|
20
22
|
'.308' => 24,
|
21
23
|
}
|
22
24
|
|
25
|
+
# 1% FPS gain/loss per inch of barrel length
|
26
|
+
FPS_INCH_FACTOR = 0.01
|
27
|
+
|
23
28
|
# Load a built-in YAML file and instantiate cartridge objects
|
24
29
|
# Return a hash of cartridge objects keyed by the cartridge id as in the YAML
|
25
30
|
#
|
26
|
-
def self.find(
|
27
|
-
|
28
|
-
Ballistics::YAML.load_built_in('cartridges', short_name).each { |id, hsh|
|
29
|
-
obj = self.new(hsh)
|
30
|
-
if block_given?
|
31
|
-
objects[id] = obj if yield obj
|
32
|
-
else
|
33
|
-
objects[id] = obj
|
34
|
-
end
|
35
|
-
}
|
36
|
-
objects
|
31
|
+
def self.find(file: nil, id: nil)
|
32
|
+
Ballistics::YAML.find(klass: self, file: file, id: id)
|
37
33
|
end
|
38
34
|
|
39
35
|
# This is a helper method to perform loading of cartridges and projectiles
|
@@ -43,9 +39,8 @@ class Ballistics::Cartridge
|
|
43
39
|
#
|
44
40
|
def self.find_with_projectiles(chamber)
|
45
41
|
require 'ballistics/projectile'
|
46
|
-
|
47
|
-
|
48
|
-
projectiles = Ballistics::Projectile.find(chamber)
|
42
|
+
cartridges = self.find(file: chamber)
|
43
|
+
projectiles = Ballistics::Projectile.find(file: chamber)
|
49
44
|
self.cross_ref(cartridges, projectiles)
|
50
45
|
cartridges
|
51
46
|
end
|
@@ -82,15 +77,70 @@ class Ballistics::Cartridge
|
|
82
77
|
# and a known burn length
|
83
78
|
# Guess a muzzle velocity for an unknown length
|
84
79
|
#
|
85
|
-
def self.guess_mv(known_length, known_mv,
|
86
|
-
inch_diff = known_length -
|
87
|
-
|
88
|
-
|
89
|
-
# assume 1% FPS per inch; adjust for burn_length and take the average
|
90
|
-
fps_per_inch = known_mv * (known_bf + unknown_bf) / 2 / 100
|
80
|
+
def self.guess_mv(known_length, known_mv, barrel_length, burn_length = nil)
|
81
|
+
inch_diff = known_length - barrel_length
|
82
|
+
burn_factor = self.burn_factor(burn_length, known_length, barrel_length)
|
83
|
+
fps_per_inch = known_mv * burn_factor * FPS_INCH_FACTOR
|
91
84
|
known_mv - inch_diff * fps_per_inch
|
92
85
|
end
|
93
86
|
|
87
|
+
# Given at least two data points (barrel_length, muzzle_velocity)
|
88
|
+
# Estimate a muzzle velocity for an unknown length assuming the relationship
|
89
|
+
# between barrel length and muzzle velocity is linear
|
90
|
+
def self.estimate_mv(known_mvs, barrel_length, burn_length = nil)
|
91
|
+
if !known_mvs.is_a?(Hash) or known_mvs.empty?
|
92
|
+
raise(TypeError, "populated Hash expected")
|
93
|
+
end
|
94
|
+
if known_mvs.length == 1
|
95
|
+
return self.guess_mv(known_mvs.keys.first,
|
96
|
+
known_mvs.values.first,
|
97
|
+
burn_length,
|
98
|
+
barrel_length)
|
99
|
+
end
|
100
|
+
known_lengths = known_mvs.keys.sort
|
101
|
+
lb = known_lengths.first
|
102
|
+
ub = known_lengths.last
|
103
|
+
if lb < barrel_length and barrel_length < ub
|
104
|
+
# we can interpolate
|
105
|
+
known_lengths.each { |len|
|
106
|
+
if barrel_length < len
|
107
|
+
ub = len
|
108
|
+
break
|
109
|
+
end
|
110
|
+
lb = len
|
111
|
+
}
|
112
|
+
else
|
113
|
+
# we must extrapolate
|
114
|
+
if barrel_length < lb
|
115
|
+
lb, ub = known_lengths[0], known_lengths[1]
|
116
|
+
else
|
117
|
+
lb, ub = known_lengths[-2], known_lengths[-1]
|
118
|
+
end
|
119
|
+
end
|
120
|
+
lv, uv = known_mvs.fetch(lb), known_mvs.fetch(ub)
|
121
|
+
|
122
|
+
# TODO: consider adjusting m by burn_factor()
|
123
|
+
m, b = self.linear_coefficients(lb, ub, lv, uv)
|
124
|
+
m * barrel_length + b
|
125
|
+
end
|
126
|
+
|
127
|
+
# muzzle velocity curve is steeper below burn length and shallower above it
|
128
|
+
# the burn_factor can correct a linear prediction if we know the burn length
|
129
|
+
# take the average of the known and unknown
|
130
|
+
def self.burn_factor(burn_length, known_length, barrel_length)
|
131
|
+
return 1 unless burn_length
|
132
|
+
(burn_length.to_f / known_length + burn_length.to_f / barrel_length) / 2
|
133
|
+
end
|
134
|
+
|
135
|
+
# Assume: y = mx + b
|
136
|
+
# Given 2 points, return m and b
|
137
|
+
#
|
138
|
+
def self.linear_coefficients(x1, x2, y1, y2)
|
139
|
+
m = (y1 - y2) / (x1 - x2)
|
140
|
+
b = y1 - m * x1
|
141
|
+
[m, b]
|
142
|
+
end
|
143
|
+
|
94
144
|
# Match and extract e.g. "16" from "16_inch_fps"
|
95
145
|
BARREL_LENGTH_REGEX = /([0-9]+)_inch_fps/i
|
96
146
|
|
@@ -103,6 +153,7 @@ class Ballistics::Cartridge
|
|
103
153
|
@yaml_data = hsh
|
104
154
|
MANDATORY.each { |field, type|
|
105
155
|
val = hsh.fetch(field)
|
156
|
+
val = val.to_s if field == "case" and type == :string
|
106
157
|
Ballistics::YAML.check_type!(val, type)
|
107
158
|
self.instance_variable_set("@#{field}", val)
|
108
159
|
}
|
@@ -138,26 +189,12 @@ class Ballistics::Cartridge
|
|
138
189
|
|
139
190
|
# estimate muzzle velocity for a given barrel length
|
140
191
|
def mv(barrel_length, burn_length = nil)
|
192
|
+
# is MV already known?
|
141
193
|
[barrel_length, barrel_length.floor, barrel_length.ceil].each { |candidate|
|
142
194
|
mv = @muzzle_velocity[candidate]
|
143
195
|
return mv if mv
|
144
196
|
}
|
145
|
-
|
146
|
-
known_lengths = @muzzle_velocity.keys
|
147
|
-
|
148
|
-
case known_lengths.length
|
149
|
-
when 0
|
150
|
-
raise "no muzzle velocities available"
|
151
|
-
when 1
|
152
|
-
known_length = known_lengths.first
|
153
|
-
self.class.guess_mv(known_length,
|
154
|
-
@muzzle_velocity[known_length],
|
155
|
-
burn_length,
|
156
|
-
barrel_length)
|
157
|
-
else
|
158
|
-
# ok, now we need to interpolate if we can
|
159
|
-
raise "not implemented yet"
|
160
|
-
end
|
197
|
+
self.class.estimate_mv(@muzzle_velocity, barrel_length, BURN_LENGTH[@case])
|
161
198
|
end
|
162
199
|
|
163
200
|
def multiline
|
data/lib/ballistics/gun.rb
CHANGED
@@ -3,6 +3,8 @@ require 'ballistics/yaml'
|
|
3
3
|
class Ballistics::Gun
|
4
4
|
class ChamberNotFound < KeyError; end
|
5
5
|
|
6
|
+
YAML_DIR = 'guns'
|
7
|
+
|
6
8
|
MANDATORY = {
|
7
9
|
"name" => :string,
|
8
10
|
"chamber" => :string,
|
@@ -25,29 +27,8 @@ class Ballistics::Gun
|
|
25
27
|
# Load a built-in YAML file and instantiate gun objects
|
26
28
|
# Return a hash of gun objects keyed by gun id (per the YAML)
|
27
29
|
#
|
28
|
-
def self.find(
|
29
|
-
|
30
|
-
Ballistics::YAML.load_built_in('guns', short_name).each { |id, hsh|
|
31
|
-
obj = self.new(hsh)
|
32
|
-
if block_given?
|
33
|
-
objects[id] = obj if yield obj
|
34
|
-
else
|
35
|
-
objects[id] = obj
|
36
|
-
end
|
37
|
-
}
|
38
|
-
objects
|
39
|
-
end
|
40
|
-
|
41
|
-
def self.find_id(id)
|
42
|
-
Ballistics::YAML::BUILT_IN.fetch('guns').each { |short_name|
|
43
|
-
object = self.find(short_name)[id]
|
44
|
-
return object if object
|
45
|
-
}
|
46
|
-
nil
|
47
|
-
end
|
48
|
-
|
49
|
-
def self.fetch_id(id)
|
50
|
-
self.find_id(id) or raise("id #{id} not found")
|
30
|
+
def self.find(file: nil, id: nil)
|
31
|
+
Ballistics::YAML.find(klass: self, file: file, id: id)
|
51
32
|
end
|
52
33
|
|
53
34
|
attr_reader(*MANDATORY.keys)
|
@@ -76,11 +57,11 @@ class Ballistics::Gun
|
|
76
57
|
(hsh.keys - MANDATORY.keys - OPTIONAL.keys).each { |k|
|
77
58
|
@extra[k] = hsh[k]
|
78
59
|
}
|
79
|
-
@cartridges =
|
60
|
+
@cartridges = {}
|
80
61
|
end
|
81
62
|
|
82
63
|
def chamber=(new_chamber)
|
83
|
-
@cartridges =
|
64
|
+
@cartridges = {}
|
84
65
|
@chamber = new_chamber
|
85
66
|
end
|
86
67
|
|
data/lib/ballistics/problem.rb
CHANGED
@@ -15,11 +15,7 @@ class Ballistics::Problem
|
|
15
15
|
}
|
16
16
|
|
17
17
|
def self.simple(gun_id:, cart_id:, gun_family: nil)
|
18
|
-
|
19
|
-
gun = Ballistics::Gun.find(gun_family).fetch(gun_id)
|
20
|
-
else
|
21
|
-
gun = Ballistics::Gun.fetch_id(gun_id)
|
22
|
-
end
|
18
|
+
gun = Ballistics::Gun.find(file: gun_family, id: gun_id)
|
23
19
|
cart = gun.cartridges.fetch(cart_id)
|
24
20
|
self.new(projectile: cart.projectile,
|
25
21
|
cartridge: cart,
|
@@ -1,6 +1,8 @@
|
|
1
1
|
require 'ballistics/yaml'
|
2
2
|
|
3
3
|
class Ballistics::Projectile
|
4
|
+
YAML_DIR = 'projectiles'
|
5
|
+
|
4
6
|
MANDATORY = {
|
5
7
|
"name" => :string,
|
6
8
|
"cal" => :float,
|
@@ -29,17 +31,8 @@ class Ballistics::Projectile
|
|
29
31
|
# Load a built-in YAML file and instantiate projectile objects
|
30
32
|
# Return a hash of projectile objects keyed by projectile id (per the YAML)
|
31
33
|
#
|
32
|
-
def self.find(
|
33
|
-
|
34
|
-
Ballistics::YAML.load_built_in('projectiles', short_name).each { |id, hsh|
|
35
|
-
obj = self.new(hsh)
|
36
|
-
if block_given?
|
37
|
-
objects[id] = obj if yield obj
|
38
|
-
else
|
39
|
-
objects[id] = obj
|
40
|
-
end
|
41
|
-
}
|
42
|
-
objects
|
34
|
+
def self.find(file: nil, id: nil)
|
35
|
+
Ballistics::YAML.find(klass: self, file: file, id: id)
|
43
36
|
end
|
44
37
|
|
45
38
|
# Normalize common flat-base and boat-tail terms to flat or boat
|
@@ -82,7 +75,9 @@ class Ballistics::Projectile
|
|
82
75
|
BALLISTIC_COEFFICIENT.each { |field, type|
|
83
76
|
if hsh.key?(field)
|
84
77
|
val = hsh[field]
|
85
|
-
Ballistics::YAML.check_type
|
78
|
+
if !Ballistics::YAML.check_type?(val, type)
|
79
|
+
raise(TypeError, "#{val} (#{field}) is not #{type}")
|
80
|
+
end
|
86
81
|
self.instance_variable_set("@#{field}", val)
|
87
82
|
@ballistic_coefficient[field] = val
|
88
83
|
end
|
@@ -92,6 +87,7 @@ class Ballistics::Projectile
|
|
92
87
|
OPTIONAL.each { |field, type|
|
93
88
|
if hsh.key?(field)
|
94
89
|
val = hsh[field]
|
90
|
+
val = val.to_s if field == "intended" and type == :string
|
95
91
|
Ballistics::YAML.check_type!(val, type)
|
96
92
|
if field == "base"
|
97
93
|
@base = self.class.base(val)
|
data/lib/ballistics/yaml.rb
CHANGED
@@ -34,6 +34,32 @@ module Ballistics::YAML
|
|
34
34
|
end
|
35
35
|
end
|
36
36
|
|
37
|
+
def self.find(klass:, file: nil, id: nil)
|
38
|
+
candidates = {}
|
39
|
+
objects = {}
|
40
|
+
yd = klass::YAML_DIR or raise("no YAML_DIR for #{klass}")
|
41
|
+
if file
|
42
|
+
candidates = self.load_built_in(yd, file)
|
43
|
+
else
|
44
|
+
BUILT_IN.fetch(yd).each { |f|
|
45
|
+
candidates.merge!(self.load_built_in(yd, f))
|
46
|
+
}
|
47
|
+
end
|
48
|
+
if id
|
49
|
+
klass.new candidates.fetch id
|
50
|
+
else
|
51
|
+
candidates.each { |cid, hsh|
|
52
|
+
obj = klass.new hsh
|
53
|
+
if block_given?
|
54
|
+
objects[cid] = obj if yield obj
|
55
|
+
else
|
56
|
+
objects[cid] = obj
|
57
|
+
end
|
58
|
+
}
|
59
|
+
objects
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
37
63
|
def self.check_type?(val, type)
|
38
64
|
case type
|
39
65
|
when :string, :reference
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ballistics-ng
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rick Hull
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-10-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: buildar
|
@@ -54,7 +54,7 @@ files:
|
|
54
54
|
- examples/table.rb
|
55
55
|
- ext/ballistics/ext.c
|
56
56
|
- ext/ballistics/extconf.rb
|
57
|
-
- ext/ballistics/gnu_ballistics.h
|
57
|
+
- ext/ballistics/include/gnu_ballistics.h
|
58
58
|
- lib/ballistics.rb
|
59
59
|
- lib/ballistics/atmosphere.rb
|
60
60
|
- lib/ballistics/cartridge.rb
|