nwn-lib 0.6.0 → 0.6.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +6 -0
- data/bin/nwn-erf +17 -6
- data/lib/nwn/erf.rb +9 -7
- data/lib/nwn/gff.rb +1 -1
- data/lib/nwn/gff/field.rb +2 -2
- data/lib/nwn/key.rb +3 -3
- data/lib/nwn/res.rb +31 -12
- data/lib/nwn/scripting.rb +4 -4
- data/lib/nwn/tlk.rb +29 -26
- data/lib/nwn/twoda.rb +13 -7
- data/nwn-lib.gemspec +2 -1
- data/spec/res_spec.rb +6 -1
- data/spec/spec_helper.rb +10 -4
- data/spec/tlk_spec.rb +1 -1
- data/spec/twoda_spec.rb +15 -1
- metadata +10 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2a2d93809edde689509fb37cdfaf410acc03ea31
|
4
|
+
data.tar.gz: 57caf59003fb680ec38e3f91034d95d027967ab5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6bd0bca589892c6036d41ff70b5dd08c65f91dce64673f9051cbc57325bca2a2fb74e927e560b6bf0a84fe464b67bd44f30764f09b0328f5e70f02423a92c696
|
7
|
+
data.tar.gz: 3da9bcb5475aa8cb696b4f776dd66663a3ef0e50f48edba223909925cd2fc87c081cdd2eddba9c6bf5ec19cd53b73fa3b6c188a464200585255dd10278f8bb5e
|
data/.travis.yml
ADDED
data/bin/nwn-erf
CHANGED
@@ -7,6 +7,8 @@ $action = nil
|
|
7
7
|
$verbose = false
|
8
8
|
$type = 'ERF'
|
9
9
|
$allow_duplicates = false
|
10
|
+
$day_of_year = nil
|
11
|
+
$year = nil
|
10
12
|
$descriptions = {}
|
11
13
|
$version = "V1.0"
|
12
14
|
$file = nil
|
@@ -33,7 +35,7 @@ begin OptionParser.new do |o|
|
|
33
35
|
o.on "-x", "--extract", "Extract FILEs (or all) to current directory." do
|
34
36
|
$action = :x
|
35
37
|
end
|
36
|
-
o.on "-a", "--add", "Add files to the given archive.",
|
38
|
+
o.on "-a", "--add", "Add (or replace) files to the given archive.",
|
37
39
|
"This is an expensive operation, a full archive rebuild is required." do
|
38
40
|
$action = :a
|
39
41
|
end
|
@@ -71,6 +73,12 @@ begin OptionParser.new do |o|
|
|
71
73
|
o.on "-1", "Create (only -c) V1.1 ERF, 32 byte resrefs. (NWN2)." do
|
72
74
|
$version = "V1.1"
|
73
75
|
end
|
76
|
+
o.on "--day DAY", "Set the day_of_year header field when doing write operations" do |x|
|
77
|
+
$day_of_year = x
|
78
|
+
end
|
79
|
+
o.on "--year YEAR", "Set the year header field when doing write operations" do |x|
|
80
|
+
$year = x
|
81
|
+
end
|
74
82
|
|
75
83
|
o.separator " "
|
76
84
|
o.separator "Hacks:"
|
@@ -155,6 +163,8 @@ case $action
|
|
155
163
|
erf = NWN::Erf::Erf.new
|
156
164
|
erf.file_type = $type if $type
|
157
165
|
erf.file_version = $version
|
166
|
+
erf.year = $year if $year
|
167
|
+
erf.day_of_year = $day_of_year if $day_of_year
|
158
168
|
|
159
169
|
if $descriptions
|
160
170
|
erf.localized_strings.merge! $descriptions
|
@@ -171,22 +181,23 @@ case $action
|
|
171
181
|
when :a, :r
|
172
182
|
input do |infile|
|
173
183
|
erf = NWN::Erf::Erf.new(infile)
|
184
|
+
erf.year = $year if $year
|
185
|
+
erf.day_of_year = $day_of_year if $day_of_year
|
174
186
|
|
175
187
|
if $descriptions
|
176
188
|
erf.localized_strings.merge! $descriptions
|
177
189
|
end
|
178
190
|
|
179
191
|
ARGV.each {|arg|
|
192
|
+
# Remove all (old) files.
|
193
|
+
erf.remove_file(arg) if erf.has?(arg)
|
194
|
+
|
180
195
|
case $action
|
181
196
|
when :a
|
182
|
-
raise ArgumentError, "#{File.basename(arg)} already present in erf." if
|
183
|
-
!$allow_duplicates && erf.has?(arg)
|
184
197
|
erf.add_file File.basename(arg), File.open(arg, "r")
|
185
198
|
|
186
199
|
when :r
|
187
|
-
|
188
|
-
con.filename.downcase == arg.downcase
|
189
|
-
}
|
200
|
+
# Nothing to do.
|
190
201
|
end
|
191
202
|
}
|
192
203
|
|
data/lib/nwn/erf.rb
CHANGED
@@ -105,19 +105,21 @@ module NWN
|
|
105
105
|
@io.seek(offset_to_keys)
|
106
106
|
keylist = @io.e_read(keylist_entry_size * entry_count, "keylist")
|
107
107
|
keylist = keylist.unpack("A#{fnlen} V v v" * entry_count)
|
108
|
-
keylist.each_slice(4) {|resref, res_id, res_type, unused|
|
109
|
-
@content << NWN::Resources::ContentObject.new(resref, res_type, @io)
|
110
|
-
}
|
111
108
|
|
112
109
|
resourcelist_entry_size = 4 + 4
|
113
110
|
@io.seek(offset_to_res)
|
114
111
|
resourcelist = @io.e_read(resourcelist_entry_size * entry_count, "reslist")
|
115
112
|
resourcelist = resourcelist.unpack("I I" * entry_count)
|
116
|
-
|
117
|
-
|
113
|
+
|
114
|
+
_index = 0
|
115
|
+
keylist.each_slice(4) {|resref, res_id, res_type, unused|
|
116
|
+
co = NWN::Resources::ContentObject.new(resref, res_type, @io)
|
117
|
+
offset, size = resourcelist[_index * 2], resourcelist[_index * 2 + 1]
|
118
|
+
co.offset = offset
|
119
|
+
co.size_override = size
|
120
|
+
add co
|
121
|
+
|
118
122
|
_index += 1
|
119
|
-
@content[_index].offset = offset
|
120
|
-
@content[_index].size_override = size
|
121
123
|
}
|
122
124
|
end
|
123
125
|
|
data/lib/nwn/gff.rb
CHANGED
@@ -116,7 +116,7 @@ module NWN
|
|
116
116
|
OutputFormats = {}
|
117
117
|
FileFormatGuesses = {}
|
118
118
|
|
119
|
-
Handler.register :gff, /^(ut[cdeimpstw]|git|are|gic|mod|ifo|fac|ssf|dlg|itp|bic)$/, NWN::Gff::Handler::Gff
|
119
|
+
Handler.register :gff, /^(ut[cdeimpstw]|git|are|gic|mod|ifo|fac|ssf|dlg|itp|bic|jrl)$/, NWN::Gff::Handler::Gff
|
120
120
|
Handler.register :marshal, /^marshal$/, NWN::Gff::Handler::Marshal
|
121
121
|
Handler.register :pretty, /^$/, NWN::Gff::Handler::Pretty, false, true
|
122
122
|
|
data/lib/nwn/gff/field.rb
CHANGED
@@ -150,7 +150,7 @@ module NWN::Gff::Field
|
|
150
150
|
value.is_a?(Integer) && value >= 0 && value <= 0xffffffffffffffff
|
151
151
|
|
152
152
|
when :float, :double
|
153
|
-
value.is_a?(Float)
|
153
|
+
value.is_a?(Float) || value.is_a?(Integer)
|
154
154
|
|
155
155
|
when :resref
|
156
156
|
if !NWN.setting(:resref32) && value.is_a?(String) && value.size > 16
|
@@ -169,7 +169,7 @@ module NWN::Gff::Field
|
|
169
169
|
|
170
170
|
when :cexolocstr
|
171
171
|
value.is_a?(Hash) &&
|
172
|
-
value.keys.reject {|x| x.is_a?(
|
172
|
+
value.keys.reject {|x| x.is_a?(Integer) && x >= 0 }.size == 0 &&
|
173
173
|
value.values.reject {|x| x.is_a?(String) }.size == 0
|
174
174
|
|
175
175
|
when :struct
|
data/lib/nwn/key.rb
CHANGED
@@ -116,11 +116,11 @@ module NWN
|
|
116
116
|
o = NWN::Resources::ContentObject.new(resref, res_type, bif.io, ofs, sz)
|
117
117
|
if @fn_to_co[o.filename] && @fn_to_co[o.filename][2] < bif_index
|
118
118
|
oo, biff = @fn_to_co[o.filename]
|
119
|
-
NWN.log_debug "#{o.filename} in #{biff.io.inspect} shadowed by file of same name in #{bif.io.inspect}"
|
120
|
-
|
119
|
+
# NWN.log_debug "#{o.filename} in #{biff.io.inspect} shadowed by file of same name in #{bif.io.inspect}"
|
120
|
+
remove oo
|
121
121
|
end
|
122
122
|
@fn_to_co[o.filename] = [o, bif, bif_index]
|
123
|
-
|
123
|
+
add o
|
124
124
|
}
|
125
125
|
end
|
126
126
|
end
|
data/lib/nwn/res.rb
CHANGED
@@ -33,7 +33,7 @@ module NWN
|
|
33
33
|
|
34
34
|
# Get the size in bytes of this object.
|
35
35
|
def size
|
36
|
-
@size_override || (@io.is_a?(IO) ? @io.stat.size : File.stat(@io).size)
|
36
|
+
@size ||= (@size_override || (@io.is_a?(IO) ? @io.stat.size : File.stat(@io).size))
|
37
37
|
end
|
38
38
|
|
39
39
|
# Get the contents of this object. This is a costly operation, loading
|
@@ -50,12 +50,12 @@ module NWN
|
|
50
50
|
|
51
51
|
# Get the canonical filename of this object.
|
52
52
|
def filename
|
53
|
-
@resref + "." + (self.extension || "unknown-#{@res_type}")
|
53
|
+
@filename ||= (@resref + "." + (self.extension || "unknown-#{@res_type}"))
|
54
54
|
end
|
55
55
|
|
56
56
|
# Get the extension of this object.
|
57
57
|
def extension
|
58
|
-
NWN::Resources::Extensions.key(@res_type)
|
58
|
+
@extension ||= NWN::Resources::Extensions.key(@res_type)
|
59
59
|
end
|
60
60
|
end
|
61
61
|
|
@@ -63,43 +63,62 @@ module NWN
|
|
63
63
|
class Container
|
64
64
|
|
65
65
|
# An array of all ContentObjects indexed by this Container.
|
66
|
+
# Do not modify, use add/remove instead.
|
66
67
|
attr_reader :content
|
67
68
|
|
69
|
+
# A hash containing filename.downcase => ContentObject.
|
70
|
+
# Do not modify, use add/remove instead.
|
71
|
+
attr_reader :content_by_filename
|
72
|
+
|
68
73
|
def initialize
|
69
74
|
@content = []
|
75
|
+
@content_by_filename = {}
|
70
76
|
end
|
71
77
|
|
72
78
|
# Returns true if the given filename is contained herein.
|
73
79
|
# Case-insensitive.
|
74
80
|
def has?(filename)
|
75
|
-
|
81
|
+
@content_by_filename[filename.downcase] != nil
|
76
82
|
end
|
77
83
|
|
78
84
|
# Add a content object giving a +filename+ and a optional
|
79
85
|
# +io+.
|
80
86
|
def add_file filename, io = nil
|
81
|
-
|
87
|
+
add ContentObject.new_from(filename, io)
|
82
88
|
end
|
83
89
|
|
84
90
|
# Add a content object giving the ContentObject
|
85
91
|
def add o
|
86
92
|
@content << o
|
93
|
+
@content_by_filename[o.filename.downcase] = o
|
94
|
+
@filenames = nil
|
95
|
+
end
|
96
|
+
|
97
|
+
# Removes a content object by filename.
|
98
|
+
# Raises ENOENT if no object by that name is contained.
|
99
|
+
def remove_file filename
|
100
|
+
@content_by_filename[filename.downcase] or raise Errno::ENOENT,
|
101
|
+
"No ContentObject with the given filename #{filename.inspect} found."
|
102
|
+
|
103
|
+
remove @content_by_filename[filename.downcase]
|
104
|
+
end
|
105
|
+
|
106
|
+
def remove o
|
107
|
+
@content.delete(o)
|
108
|
+
@content_by_filename.delete(o.filename)
|
109
|
+
@filenames = nil
|
87
110
|
end
|
88
111
|
|
89
112
|
# Returns a list of filenames, all lowercase.
|
90
113
|
def filenames
|
91
|
-
@
|
114
|
+
@filenames ||= @content_by_filename.keys
|
92
115
|
end
|
93
116
|
|
94
117
|
# Get the ContentObject pointing to the given filename.
|
95
118
|
# Raises ENOENT if not mapped.
|
96
119
|
def get_content_object filename
|
97
|
-
filename
|
98
|
-
|
99
|
-
raise Errno::ENOENT,
|
100
|
-
"No ContentObject with the given filename #{filename.inspect} found." if
|
101
|
-
ret.size == 0
|
102
|
-
ret[0]
|
120
|
+
@content_by_filename[filename.downcase] or raise Errno::ENOENT,
|
121
|
+
"No ContentObject with the given filename #{filename.inspect} found."
|
103
122
|
end
|
104
123
|
|
105
124
|
# Get the contents of the given filename.
|
data/lib/nwn/scripting.rb
CHANGED
@@ -70,7 +70,7 @@ module NWN::Gff::Scripting
|
|
70
70
|
end
|
71
71
|
$stop_output = true
|
72
72
|
end
|
73
|
-
|
73
|
+
|
74
74
|
def will_output?
|
75
75
|
!$stop_output
|
76
76
|
end
|
@@ -177,7 +177,7 @@ module NWN::Gff::Scripting
|
|
177
177
|
when Array
|
178
178
|
i = 0 ; Hash[match.map {|x| [i+=1, x]}]
|
179
179
|
|
180
|
-
when Hash, Regexp,
|
180
|
+
when Hash, Regexp, Integer, Float
|
181
181
|
match
|
182
182
|
|
183
183
|
else
|
@@ -201,7 +201,7 @@ module NWN::Gff::Scripting
|
|
201
201
|
end
|
202
202
|
when Regexp
|
203
203
|
ret =~ match
|
204
|
-
when
|
204
|
+
when Integer
|
205
205
|
ret =~ /^\d+$/
|
206
206
|
when Float
|
207
207
|
ret =~ /^\d+(.\d+)?$/
|
@@ -210,7 +210,7 @@ module NWN::Gff::Scripting
|
|
210
210
|
|
211
211
|
case match
|
212
212
|
when Float; ret.to_f
|
213
|
-
when
|
213
|
+
when Integer; ret.to_i
|
214
214
|
else; ret
|
215
215
|
end
|
216
216
|
end
|
data/lib/nwn/tlk.rb
CHANGED
@@ -21,7 +21,7 @@ module NWN
|
|
21
21
|
DATA_ELEMENT_SIZE = 4 + 16 + 4 + 4 + 4 + 4 + 4
|
22
22
|
|
23
23
|
# The number of strings this Tlk holds.
|
24
|
-
|
24
|
+
attr_reader :size
|
25
25
|
|
26
26
|
# The language_id of this Tlk.
|
27
27
|
attr_reader :language
|
@@ -59,7 +59,7 @@ module NWN
|
|
59
59
|
|
60
60
|
return @cache[id] if @cache[id]
|
61
61
|
|
62
|
-
raise ArgumentError, "No such string ID: #{id.inspect}" if id > self.
|
62
|
+
raise ArgumentError, "No such string ID: #{id.inspect} (size: #{@size})" if id > (self.size-1) || id < 0
|
63
63
|
seek_to = HEADER_SIZE + (id) * DATA_ELEMENT_SIZE
|
64
64
|
@io.seek(seek_to)
|
65
65
|
data = @io.e_read(DATA_ELEMENT_SIZE, "tlk entry = #{id}")
|
@@ -84,55 +84,58 @@ module NWN
|
|
84
84
|
# Add a new entry to this Tlk and return the strref given to it.
|
85
85
|
# To override existing entries, use tlk[][:text] = ".."
|
86
86
|
def add text, sound = "", sound_length = 0.0, v_variance = 0, p_variance = 0
|
87
|
-
next_id = self.
|
87
|
+
next_id = self.size + 1
|
88
88
|
$stderr.puts "put in cache: #{next_id}"
|
89
89
|
@cache[next_id] = {:text => text, :sound => sound, :sound_length => 0.0, :volume_variance => v_variance, :pitch_variance => p_variance}
|
90
|
+
@size += 1
|
90
91
|
next_id
|
91
92
|
end
|
92
93
|
|
93
|
-
# Return the highest ID in this Tlk table.
|
94
|
-
def highest_id
|
95
|
-
highest_cached = @cache.keys.sort[-1] || 0
|
96
|
-
@size - 1 > highest_cached ? @size - 1 : highest_cached
|
97
|
-
end
|
98
|
-
|
99
94
|
# Write this Tlk to +io+.
|
100
95
|
# Take care not to write it to the same IO object you are reading from.
|
101
96
|
def write_to io
|
102
|
-
|
97
|
+
header = [
|
98
|
+
@file_type,
|
99
|
+
@file_version,
|
100
|
+
@language,
|
101
|
+
self.size,
|
102
|
+
HEADER_SIZE + (self.size) * DATA_ELEMENT_SIZE
|
103
|
+
].pack("A4 A4 I I I")
|
104
|
+
io.write(header)
|
105
|
+
|
103
106
|
offsets = []
|
104
107
|
offset = 0
|
105
|
-
for i in 0
|
108
|
+
for i in 0...@size do
|
106
109
|
entry = self[i]
|
107
110
|
offsets[i] = offset
|
108
|
-
text_block << entry[:text]
|
109
111
|
offset += entry[:text].size
|
110
112
|
end
|
111
|
-
text_block = text_block.join("")
|
112
|
-
|
113
|
-
header = [
|
114
|
-
@file_type, @file_version,
|
115
|
-
@language,
|
116
|
-
self.highest_id + 1, HEADER_SIZE + (self.highest_id + 1) * DATA_ELEMENT_SIZE
|
117
|
-
].pack("A4 A4 I I I")
|
118
113
|
|
119
114
|
entries = []
|
120
|
-
for i in 0
|
115
|
+
for i in 0...@size do
|
121
116
|
entry = self[i]
|
122
117
|
text, sound, sound_length = entry[:text], entry[:sound], entry[:sound_length]
|
123
118
|
flags = 0
|
124
119
|
flags |= 0x01 if text.size > 0
|
125
120
|
flags |= 0x02 if sound.size > 0
|
126
121
|
flags |= 0x04 if sound_length > 0.0
|
127
|
-
|
128
|
-
|
122
|
+
|
123
|
+
ev_s = [
|
124
|
+
flags,
|
125
|
+
sound, #resref
|
126
|
+
entry[:volume_variance],
|
127
|
+
entry[:pitch_variance],
|
128
|
+
offsets[i],
|
129
|
+
text.size,
|
130
|
+
sound_length
|
129
131
|
].pack("I a16 I I I I f")
|
132
|
+
|
133
|
+
io.write(ev_s)
|
130
134
|
end
|
131
|
-
entries = entries.join("")
|
132
135
|
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
+
for i in 0...@size do
|
137
|
+
io.write(self[i][:text])
|
138
|
+
end
|
136
139
|
end
|
137
140
|
end
|
138
141
|
|
data/lib/nwn/twoda.rb
CHANGED
@@ -47,8 +47,7 @@ module NWN
|
|
47
47
|
false
|
48
48
|
end
|
49
49
|
|
50
|
-
if idx = @table.
|
51
|
-
idx = @table.columns.index(col)
|
50
|
+
if idx = @table.column_name_to_id(col)
|
52
51
|
if assignment
|
53
52
|
self[idx] = args.shift or raise ArgumentError,
|
54
53
|
"Need a paramenter for assignments .."
|
@@ -65,7 +64,11 @@ module NWN
|
|
65
64
|
CELL_PAD_SPACES = 4
|
66
65
|
|
67
66
|
# An array of all column names present in this 2da table.
|
68
|
-
|
67
|
+
def columns; @columns; end
|
68
|
+
def columns=(c)
|
69
|
+
@columns = c
|
70
|
+
@columns_lookup = @columns.map(&:downcase)
|
71
|
+
end
|
69
72
|
|
70
73
|
# An array of row arrays, without headers.
|
71
74
|
attr_accessor :rows
|
@@ -82,6 +85,7 @@ module NWN
|
|
82
85
|
# Create a new, empty 2da table.
|
83
86
|
def initialize
|
84
87
|
@columns = []
|
88
|
+
@columns_lookup = []
|
85
89
|
@rows = []
|
86
90
|
@newline = "\r\n"
|
87
91
|
end
|
@@ -180,7 +184,7 @@ module NWN
|
|
180
184
|
k_row.pop while k_row.size > header.size
|
181
185
|
}
|
182
186
|
|
183
|
-
|
187
|
+
self.columns = header
|
184
188
|
@rows = new_row_data
|
185
189
|
end
|
186
190
|
|
@@ -242,9 +246,10 @@ module NWN
|
|
242
246
|
# or the column cannot be resolved.
|
243
247
|
def column_name_to_id column
|
244
248
|
case column
|
245
|
-
when String
|
246
|
-
@
|
247
|
-
|
249
|
+
when String, Symbol
|
250
|
+
@columns_lookup.index(column.to_s.downcase) or raise ArgumentError,
|
251
|
+
"Not a valid column name: #{column}"
|
252
|
+
when Integer
|
248
253
|
column
|
249
254
|
when NilClass
|
250
255
|
nil
|
@@ -282,6 +287,7 @@ module NWN
|
|
282
287
|
rv = []
|
283
288
|
rv << row_idx.to_s + " " * (id_cell_size - row_idx.to_s.size)
|
284
289
|
row.each_with_index {|cell, column_idx|
|
290
|
+
cell = cell ? 1 : 0 if cell.is_a?(TrueClass) || cell.is_a?(FalseClass)
|
285
291
|
cell = "****" if cell == ""
|
286
292
|
cell = '"%s"' % cell if cell =~ /\s/
|
287
293
|
cell = cell.to_s
|
data/nwn-lib.gemspec
CHANGED
@@ -12,6 +12,7 @@ Gem::Specification.new do |gem|
|
|
12
12
|
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
13
13
|
gem.name = "nwn-lib"
|
14
14
|
gem.require_paths = ["lib"]
|
15
|
-
gem.version = "0.6.
|
15
|
+
gem.version = "0.6.1"
|
16
16
|
gem.required_ruby_version = '>= 1.9.3'
|
17
|
+
gem.license = 'MIT'
|
17
18
|
end
|
data/spec/res_spec.rb
CHANGED
@@ -5,7 +5,7 @@ class StubContainer < Resources::Container
|
|
5
5
|
super()
|
6
6
|
files.each {|fn, content|
|
7
7
|
io = StringIO.new(content)
|
8
|
-
|
8
|
+
self.add_file fn, io
|
9
9
|
}
|
10
10
|
end
|
11
11
|
end
|
@@ -34,6 +34,11 @@ describe "Resources::Container" do
|
|
34
34
|
subject.get('CASE.txt').should == "case"
|
35
35
|
subject.get('CASE.tXt').should == "case"
|
36
36
|
end
|
37
|
+
|
38
|
+
it "returns proper values for has?" do
|
39
|
+
subject.has?('case.txt').should == true
|
40
|
+
subject.has?('invalid').should == false
|
41
|
+
end
|
37
42
|
end
|
38
43
|
|
39
44
|
describe Resources::Manager do
|
data/spec/spec_helper.rb
CHANGED
@@ -1,5 +1,11 @@
|
|
1
1
|
Bundler.setup(:default, :test)
|
2
2
|
|
3
|
+
RSpec.configure do |config|
|
4
|
+
config.expect_with :rspec do |c|
|
5
|
+
c.syntax = [:should, :expect]
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
3
9
|
require 'tempfile'
|
4
10
|
require 'fileutils'
|
5
11
|
require 'open3'
|
@@ -21,10 +27,10 @@ GffFieldValidations = {
|
|
21
27
|
:byte => [[0, 255], [256, -1]],
|
22
28
|
:char => [[0, 255], [256, -1]],
|
23
29
|
:resref => [["", "a" * 16], ["a" * 17]],
|
24
|
-
:double => [[0.0], ["x"]],
|
30
|
+
:double => [[0.0, 0], ["x"]],
|
25
31
|
:dword => [[0, 0xffffffff], [-1, 0xffffffff + 1]],
|
26
32
|
:dword64 => [[0, 0xffffffffffffffff], [-1, 0xffffffffffffffff + 1]],
|
27
|
-
:float => [[0.0], ["x"]],
|
33
|
+
:float => [[0.0, 0], ["x"]],
|
28
34
|
:int => [[-0x80000000, 0x7fffffff], [0x80000001, 0x7fffffff + 1]],
|
29
35
|
:int64 => [[-0x8000000000000000, 0x7fffffffffffffff], [-0x8000000000000000 - 1, 0x7fffffffffffffff + 1]],
|
30
36
|
:short => [[-0x8000, 0x7fff], [-0x8001, 0x7fff + 1]],
|
@@ -219,11 +225,11 @@ module BinHelper
|
|
219
225
|
|
220
226
|
def run *va
|
221
227
|
stdout_str, ret = run_bin *va
|
222
|
-
|
228
|
+
raise "Error running command #{va.inspect}: #{stdout_str}" if ret != 0
|
223
229
|
end
|
224
230
|
|
225
231
|
def run_fail *va
|
226
232
|
stdout_str, ret = run_bin *va
|
227
|
-
|
233
|
+
raise "No error running command #{va.inspect} (expected failure): #{stdout_str}" if ret == 0
|
228
234
|
end
|
229
235
|
end
|
data/spec/tlk_spec.rb
CHANGED
@@ -6,7 +6,7 @@ describe "Tlk::Tlk" do
|
|
6
6
|
t = Tlk::Tlk.new(StringIO.new binary)
|
7
7
|
|
8
8
|
t.language.should == 0
|
9
|
-
t.
|
9
|
+
t.size.should == 5
|
10
10
|
t[0].should == {:pitch_variance=>0, :text=>"1", :sound=>"", :sound_length=>0.0, :volume_variance=>0}
|
11
11
|
t[1].should == {:pitch_variance=>0, :text=>"22", :sound=>"textsnd", :sound_length=>0.0, :volume_variance=>0}
|
12
12
|
t[2].should == {:pitch_variance=>0, :text=>"333", :sound=>"textsndlen", :sound_length=>2.0, :volume_variance=>0}
|
data/spec/twoda_spec.rb
CHANGED
@@ -2,7 +2,7 @@ require File.join(File.dirname(__FILE__), 'spec_helper')
|
|
2
2
|
|
3
3
|
describe TwoDA::Table do
|
4
4
|
it "parses wellformed files" do
|
5
|
-
proc { subject.parse(TWODA_WELLFORMED) }.should_not raise_error
|
5
|
+
proc { subject.parse(TWODA_WELLFORMED) }.should_not raise_error
|
6
6
|
end
|
7
7
|
|
8
8
|
it "parses misnumbered IDs as NWN does" do
|
@@ -74,4 +74,18 @@ describe TwoDA::Table do
|
|
74
74
|
ENV['NWN_LIB_2DA_NEWLINE'] = "2"
|
75
75
|
subject.to_2da.should =~ /^2DA V2.0\r\r +C/
|
76
76
|
end
|
77
|
+
|
78
|
+
it "should treat columns case-insensitive" do
|
79
|
+
subject.parse(TWODA_WELLFORMED)
|
80
|
+
subject[0].Col1.should == subject[0].col1
|
81
|
+
subject.column_name_to_id("Col2").should == 1
|
82
|
+
subject.column_name_to_id("Col1").should == 0
|
83
|
+
subject.column_name_to_id("COL2").should == 1
|
84
|
+
subject.column_name_to_id("COL1").should == 0
|
85
|
+
end
|
86
|
+
|
87
|
+
it "should allow column lookups with symbols" do
|
88
|
+
subject.parse(TWODA_WELLFORMED)
|
89
|
+
subject.column_name_to_id(:Col2).should == 1
|
90
|
+
end
|
77
91
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: nwn-lib
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.6.
|
4
|
+
version: 0.6.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bernhard Stoeckner
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2017-05-06 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Neverwinter Nights 1/2 file formats ruby library
|
14
14
|
email:
|
@@ -21,8 +21,9 @@ executables:
|
|
21
21
|
extensions: []
|
22
22
|
extra_rdoc_files: []
|
23
23
|
files:
|
24
|
-
- .gitignore
|
25
|
-
- .
|
24
|
+
- ".gitignore"
|
25
|
+
- ".travis.yml"
|
26
|
+
- ".yardopts"
|
26
27
|
- BINARIES.rdoc
|
27
28
|
- CHEATSHEET.rdoc
|
28
29
|
- Gemfile
|
@@ -85,7 +86,8 @@ files:
|
|
85
86
|
- tools/migrate_03x_to_04x.sh
|
86
87
|
- tools/verify.sh
|
87
88
|
homepage: https://github.com/niv/nwn-lib
|
88
|
-
licenses:
|
89
|
+
licenses:
|
90
|
+
- MIT
|
89
91
|
metadata: {}
|
90
92
|
post_install_message:
|
91
93
|
rdoc_options: []
|
@@ -93,17 +95,17 @@ require_paths:
|
|
93
95
|
- lib
|
94
96
|
required_ruby_version: !ruby/object:Gem::Requirement
|
95
97
|
requirements:
|
96
|
-
- -
|
98
|
+
- - ">="
|
97
99
|
- !ruby/object:Gem::Version
|
98
100
|
version: 1.9.3
|
99
101
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
100
102
|
requirements:
|
101
|
-
- -
|
103
|
+
- - ">="
|
102
104
|
- !ruby/object:Gem::Version
|
103
105
|
version: '0'
|
104
106
|
requirements: []
|
105
107
|
rubyforge_project:
|
106
|
-
rubygems_version: 2.
|
108
|
+
rubygems_version: 2.6.12
|
107
109
|
signing_key:
|
108
110
|
specification_version: 4
|
109
111
|
summary: Neverwinter Nights 1/2 file formats ruby library
|
@@ -128,4 +130,3 @@ test_files:
|
|
128
130
|
- spec/tlk_spec.rb
|
129
131
|
- spec/twoda_spec.rb
|
130
132
|
- spec/wellformed_gff.bic
|
131
|
-
has_rdoc:
|