nwn-lib 0.4.12 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +4 -0
- data/.yardopts +1 -0
- data/{BINARIES → BINARIES.rdoc} +0 -0
- data/{CHEATSHEET → CHEATSHEET.rdoc} +0 -0
- data/Gemfile +9 -0
- data/{HOWTO → HOWTO.rdoc} +0 -0
- data/LICENCE +15 -0
- data/{README → README.rdoc} +9 -15
- data/Rakefile +6 -95
- data/{SCRIPTING → SCRIPTING.rdoc} +0 -0
- data/{SETTINGS → SETTINGS.rdoc} +0 -0
- data/bin/nwn-erf +2 -2
- data/lib/nwn/all.rb +1 -0
- data/lib/nwn/erf.rb +4 -4
- data/lib/nwn/gff.rb +1 -1
- data/lib/nwn/gff/field.rb +16 -6
- data/lib/nwn/gff/reader.rb +8 -4
- data/lib/nwn/gff/struct.rb +6 -4
- data/lib/nwn/gff/writer.rb +2 -2
- data/lib/nwn/key.rb +2 -2
- data/lib/nwn/kivinen_support.rb +3 -1
- data/lib/nwn/res.rb +2 -2
- data/lib/nwn/scripting.rb +1 -1
- data/lib/nwn/settings.rb +2 -12
- data/lib/nwn/twoda.rb +46 -8
- data/lib/nwn/version.rb +3 -0
- data/lib/nwn/xml_support.rb +3 -3
- data/lib/nwn/yaml_support.rb +1 -0
- data/nwn-lib.gemspec +18 -0
- data/scripts/reformat_2da +11 -6
- data/spec/bin_dsl_spec.rb +4 -4
- data/spec/bin_erf_spec.rb +17 -22
- data/spec/bin_gff_spec.rb +14 -6
- data/spec/erf_spec.rb +2 -1
- data/spec/field_spec.rb +9 -0
- data/spec/gff_spec.rb +1 -2
- data/spec/key_spec.rb +1 -1
- data/spec/kivinen_spec.rb +1 -1
- data/spec/rcov.opts +0 -0
- data/spec/spec.opts +0 -0
- data/spec/spec_helper.rb +9 -7
- metadata +106 -102
- data/CHANGELOG +0 -354
- data/COPYING +0 -15
data/.gitignore
ADDED
data/.yardopts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--no-private lib/**/*.rb - *.rdoc LICENCE
|
data/{BINARIES → BINARIES.rdoc}
RENAMED
File without changes
|
File without changes
|
data/Gemfile
ADDED
data/{HOWTO → HOWTO.rdoc}
RENAMED
File without changes
|
data/LICENCE
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
Copyright Bernhard Stoeckner <le@e-ix.net> and contributors. All rights reserved.
|
2
|
+
|
3
|
+
Redistribution and use in source and binary forms, with or without modification, are
|
4
|
+
permitted provided that the following conditions are met:
|
5
|
+
|
6
|
+
1. Redistributions of source code must retain the above copyright notice, this list of
|
7
|
+
conditions and the following disclaimer.
|
8
|
+
|
9
|
+
2. Redistributions in binary form must reproduce the above copyright notice, this list
|
10
|
+
of conditions and the following disclaimer in the documentation and/or other materials
|
11
|
+
provided with the distribution.
|
12
|
+
|
13
|
+
THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
|
14
|
+
INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
15
|
+
FOR A PARTICULAR PURPOSE.
|
data/{README → README.rdoc}
RENAMED
@@ -31,15 +31,15 @@ They should work with NWN2 just as well, since the file format specifications di
|
|
31
31
|
|
32
32
|
==== Also in the box:
|
33
33
|
|
34
|
-
* shell scripts and tools to simplify your life (see BINARIES)
|
34
|
+
* shell scripts and tools to simplify your life (see {file:BINARIES})
|
35
35
|
* extensive developer API
|
36
|
-
* a powerful get-out-of-my-way scripting system for data transformation (see SCRIPTING)
|
36
|
+
* a powerful get-out-of-my-way scripting system for data transformation (see {file:SCRIPTING})
|
37
37
|
|
38
38
|
|
39
39
|
=== Upgrade from 0.3.6 to 0.4.x
|
40
40
|
|
41
41
|
With the release of 0.4.0, the API changed significantly. Previous yaml dumps made with 0.3.x are INCOMPATIBLE, and so are all scripts.
|
42
|
-
I can't help you with your API bindings, but for your YAML dumps, a converter script has been provided (see BINARIES).
|
42
|
+
I can't help you with your API bindings, but for your YAML dumps, a converter script has been provided (see {file:BINARIES}).
|
43
43
|
|
44
44
|
|
45
45
|
=== Attention Unicode/UTF-users
|
@@ -50,25 +50,19 @@ This will be worked around in a future release until the release of ruby 1.9, wh
|
|
50
50
|
|
51
51
|
=== Quickstart
|
52
52
|
|
53
|
-
To use it, simply install the gem
|
53
|
+
To use it, simply install the gem:
|
54
54
|
|
55
|
-
|
55
|
+
gem install nwn-lib
|
56
56
|
|
57
|
-
And do the following in a script of your own devising:
|
57
|
+
And do the following in a script of your own devising (or just use bundler):
|
58
58
|
|
59
59
|
require 'rubygems'
|
60
60
|
require 'nwn/all'
|
61
61
|
|
62
|
-
Also, read BINARIES and HOWTO.
|
62
|
+
Also, read {file:BINARIES} and {file:HOWTO}.
|
63
63
|
|
64
|
-
For nwn-lib scripts, see SCRIPTING.
|
64
|
+
For nwn-lib scripts, see {file:SCRIPTING}.
|
65
65
|
|
66
66
|
For using the developer API, I suggest you start reading NWN::Gff::Struct.
|
67
67
|
|
68
|
-
|
69
|
-
|
70
|
-
The latest source is available through git[http://git.swordcoast.net/?p=nwn/nwn-lib.git;a=summary].
|
71
|
-
|
72
|
-
All stable releases are tagged properly.
|
73
|
-
|
74
|
-
You can reach me via email[mailto:elven@swordcoast.net].
|
68
|
+
The latest source is available through git[https://github.com/niv/nwn-lib].
|
data/Rakefile
CHANGED
@@ -1,97 +1,8 @@
|
|
1
|
-
|
2
|
-
require "
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require "fileutils"
|
6
|
-
include FileUtils
|
1
|
+
#!/usr/bin/env rake
|
2
|
+
require "bundler/gem_tasks"
|
3
|
+
require 'rspec/core/rake_task'
|
4
|
+
require 'yard'
|
7
5
|
|
8
|
-
|
9
|
-
# Configuration
|
10
|
-
##############################################################################
|
11
|
-
NAME = "nwn-lib"
|
12
|
-
VERS = "0.4.12"
|
13
|
-
CLEAN.include ["**/.*.sw?", "pkg", ".config", "rdoc", "coverage"]
|
14
|
-
RDOC_OPTS = ["--quiet", "--line-numbers", "--inline-source", '--title', \
|
15
|
-
'nwn-lib: a ruby library for accessing NWN resource files', \
|
16
|
-
'--main', 'README']
|
6
|
+
YARD::Rake::YardocTask.new
|
17
7
|
|
18
|
-
|
19
|
-
|
20
|
-
Rake::RDocTask.new do |rdoc|
|
21
|
-
rdoc.rdoc_dir = "rdoc"
|
22
|
-
rdoc.options += RDOC_OPTS
|
23
|
-
rdoc.rdoc_files.add DOCS + ["doc/*.rdoc", "lib/**/*.rb"]
|
24
|
-
end
|
25
|
-
|
26
|
-
desc "Packages up nwn-lib"
|
27
|
-
task :package => [:clean]
|
28
|
-
|
29
|
-
spec = Gem::Specification.new do |s|
|
30
|
-
s.name = NAME
|
31
|
-
s.rubyforge_project = 'nwn-lib'
|
32
|
-
s.version = VERS
|
33
|
-
s.platform = Gem::Platform::RUBY
|
34
|
-
s.has_rdoc = true
|
35
|
-
s.extra_rdoc_files = DOCS + Dir["doc/*.rdoc"]
|
36
|
-
s.rdoc_options += RDOC_OPTS + ["--exclude", "^(examples|extras)\/"]
|
37
|
-
s.summary = "a ruby library for accessing Neverwinter Nights resource files"
|
38
|
-
s.description = s.summary
|
39
|
-
s.author = "Bernhard Stoeckner"
|
40
|
-
s.email = "elven@swordcoast.net"
|
41
|
-
s.homepage = "http://nwn-lib.elv.es"
|
42
|
-
s.executables = ["nwn-gff", "nwn-erf", "nwn-dsl", "nwn-irb"]
|
43
|
-
s.required_ruby_version = ">= 1.8.4"
|
44
|
-
s.files = %w(COPYING CHANGELOG README Rakefile) + Dir.glob("{bin,doc,spec,lib,tools,scripts,data}/**/*")
|
45
|
-
s.require_path = "lib"
|
46
|
-
s.bindir = "bin"
|
47
|
-
end
|
48
|
-
|
49
|
-
Rake::GemPackageTask.new(spec) do |p|
|
50
|
-
p.need_tar = true
|
51
|
-
p.gem_spec = spec
|
52
|
-
end
|
53
|
-
|
54
|
-
desc "Install nwn-lib gem"
|
55
|
-
task :install do
|
56
|
-
sh %{rake package}
|
57
|
-
sh %{sudo gem1.8 install pkg/#{NAME}-#{VERS}}
|
58
|
-
end
|
59
|
-
|
60
|
-
desc "Install nwn-lib gem without docs"
|
61
|
-
task :install_no_docs do
|
62
|
-
sh %{rake package}
|
63
|
-
sh %{sudo gem1.8 install pkg/#{NAME}-#{VERS} --no-rdoc --no-ri}
|
64
|
-
end
|
65
|
-
|
66
|
-
desc "Uninstall nwn-lib gem"
|
67
|
-
task :uninstall => [:clean] do
|
68
|
-
sh %{sudo gem1.8 uninstall #{NAME}}
|
69
|
-
end
|
70
|
-
|
71
|
-
require "spec/rake/spectask"
|
72
|
-
|
73
|
-
desc "Run specs with coverage"
|
74
|
-
Spec::Rake::SpecTask.new("spec") do |t|
|
75
|
-
t.spec_files = FileList["spec/*_spec.rb"]
|
76
|
-
t.spec_opts = ["--format s"]
|
77
|
-
t.rcov = true
|
78
|
-
end
|
79
|
-
|
80
|
-
desc "Run specs without coverage"
|
81
|
-
task :default => [:spec_no_cov]
|
82
|
-
Spec::Rake::SpecTask.new("spec_no_cov") do |t|
|
83
|
-
t.spec_files = FileList["spec/*_spec.rb"]
|
84
|
-
t.spec_opts = ["--format s"]
|
85
|
-
end
|
86
|
-
|
87
|
-
desc "Run rcov only"
|
88
|
-
Spec::Rake::SpecTask.new("rcov") do |t|
|
89
|
-
t.spec_files = FileList["spec/*_spec.rb"]
|
90
|
-
t.spec_opts = ["--format s"]
|
91
|
-
t.rcov = true
|
92
|
-
end
|
93
|
-
|
94
|
-
desc "check documentation coverage"
|
95
|
-
task :dcov do
|
96
|
-
sh "find lib -name '*.rb' | xargs dcov"
|
97
|
-
end
|
8
|
+
RSpec::Core::RakeTask.new(:spec)
|
File without changes
|
data/{SETTINGS → SETTINGS.rdoc}
RENAMED
File without changes
|
data/bin/nwn-erf
CHANGED
@@ -164,7 +164,7 @@ case $action
|
|
164
164
|
puts File.basename(a) if $verbose
|
165
165
|
raise ArgumentError, "#{File.basename(a)} already present in erf." if
|
166
166
|
!$allow_duplicates && erf.has?(a)
|
167
|
-
erf.add_file a
|
167
|
+
erf.add_file File.basename(a), File.open(a, "r")
|
168
168
|
}
|
169
169
|
output {|f| erf.write_to(f) }
|
170
170
|
|
@@ -181,7 +181,7 @@ case $action
|
|
181
181
|
when :a
|
182
182
|
raise ArgumentError, "#{File.basename(arg)} already present in erf." if
|
183
183
|
!$allow_duplicates && erf.has?(arg)
|
184
|
-
erf.add_file arg
|
184
|
+
erf.add_file File.basename(arg), File.open(arg, "r")
|
185
185
|
|
186
186
|
when :r
|
187
187
|
erf.content.reject! {|con|
|
data/lib/nwn/all.rb
CHANGED
data/lib/nwn/erf.rb
CHANGED
@@ -133,12 +133,12 @@ module NWN
|
|
133
133
|
[c.resref, @content.index(c), c.res_type, 0].pack("a#{fnlen} V v v")
|
134
134
|
}.join("")
|
135
135
|
|
136
|
-
|
136
|
+
offset = 160 + locstr.size + keylist.size + 8 * @content.size
|
137
137
|
|
138
138
|
reslist = @content.map {|c|
|
139
|
-
|
140
|
-
|
141
|
-
|
139
|
+
r = [offset, c.size].pack("V V")
|
140
|
+
offset += c.size
|
141
|
+
r
|
142
142
|
}.join("")
|
143
143
|
|
144
144
|
offset_to_locstr = 160
|
data/lib/nwn/gff.rb
CHANGED
data/lib/nwn/gff/field.rb
CHANGED
@@ -103,10 +103,11 @@ module NWN::Gff::Field
|
|
103
103
|
return if field_type == :struct
|
104
104
|
|
105
105
|
field_klass_name = field_type.to_s.capitalize
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
106
|
+
|
107
|
+
field_klass = NWN::Gff.const_defined?(field_klass_name, false) ?
|
108
|
+
NWN::Gff.const_get(field_klass_name, false) : nil
|
109
|
+
field_value_klass = NWN::Gff.const_defined?(field_klass_name + 'Value', false) ?
|
110
|
+
NWN::Gff.const_get(field_klass_name + 'Value', false) : nil
|
110
111
|
|
111
112
|
self.extend(field_klass) unless field_klass.nil? ||
|
112
113
|
self.is_a?(field_klass)
|
@@ -227,15 +228,24 @@ module NWN::Gff::Field
|
|
227
228
|
element.extend_meta_classes
|
228
229
|
case element.field_type
|
229
230
|
when :cexolocstr
|
231
|
+
mod = {}
|
230
232
|
element.field_value.each {|x,y|
|
231
|
-
|
233
|
+
mod[x] = NWN.iconv_native_to_gff(y)
|
234
|
+
}
|
235
|
+
mod.each {|x,y|
|
236
|
+
element.field_value.delete(x)
|
237
|
+
element.field_value[x.to_i] = y
|
232
238
|
}
|
233
239
|
when :cexostr
|
234
240
|
element.field_value = NWN.iconv_native_to_gff(element.field_value)
|
235
241
|
|
236
242
|
when :list
|
243
|
+
mod = {}
|
237
244
|
element.field_value.each_with_index {|x,idx|
|
238
|
-
|
245
|
+
mod[idx] = NWN::Gff::Struct.unbox!(x, element)
|
246
|
+
}
|
247
|
+
mod.each {|x,y|
|
248
|
+
element.field_value[x] = y
|
239
249
|
}
|
240
250
|
when :struct
|
241
251
|
element.field_value = NWN::Gff::Struct.unbox!(element.field_value, element)
|
data/lib/nwn/gff/reader.rb
CHANGED
@@ -47,6 +47,7 @@ class NWN::Gff::Reader
|
|
47
47
|
@io.seek(label_offset)
|
48
48
|
@labels = @io.e_read(label_len, "labels")
|
49
49
|
@labels = @labels.unpack("A16" * label_count)
|
50
|
+
@labels.map! {|l| l.encode("ASCII") }
|
50
51
|
|
51
52
|
@io.seek(field_data_offset)
|
52
53
|
@field_data = @io.e_read(field_data_count, "field_data")
|
@@ -74,6 +75,9 @@ class NWN::Gff::Reader
|
|
74
75
|
raise GffError, "struct index #{index} outside of struct_array" if
|
75
76
|
index * 3 + 3 > @structs.size + 1
|
76
77
|
|
78
|
+
file_type = file_type.encode('ASCII') if file_type
|
79
|
+
file_version = file_version.encode('ASCII') if file_version
|
80
|
+
|
77
81
|
struct.struct_id = type
|
78
82
|
struct.data_type = file_type
|
79
83
|
struct.data_version = file_version
|
@@ -155,11 +159,11 @@ class NWN::Gff::Reader
|
|
155
159
|
|
156
160
|
when :cexostr
|
157
161
|
len = @field_data[data_or_offset, 4].unpack("V")[0]
|
158
|
-
@field_data[data_or_offset + 4, len]
|
162
|
+
@field_data[data_or_offset + 4, len].encode(NWN.setting :in_encoding)
|
159
163
|
|
160
164
|
when :resref
|
161
165
|
len = @field_data[data_or_offset, 1].unpack("C")[0]
|
162
|
-
@field_data[data_or_offset + 1, len]
|
166
|
+
@field_data[data_or_offset + 1, len].encode(NWN.setting :in_encoding)
|
163
167
|
|
164
168
|
when :cexolocstr
|
165
169
|
exostr = {}
|
@@ -172,7 +176,7 @@ class NWN::Gff::Reader
|
|
172
176
|
|
173
177
|
str_count.times {
|
174
178
|
id, len = all.unpack("VV")
|
175
|
-
str = all[8, len].unpack("a*")[0]
|
179
|
+
str = all[8, len].unpack("a*")[0].encode(NWN.setting :in_encoding)
|
176
180
|
all = all[(8 + len)..-1]
|
177
181
|
exostr[id] = str
|
178
182
|
}
|
@@ -181,7 +185,7 @@ class NWN::Gff::Reader
|
|
181
185
|
|
182
186
|
when :void
|
183
187
|
len = @field_data[data_or_offset, 4].unpack("V")[0]
|
184
|
-
@field_data[data_or_offset + 4, len].unpack("
|
188
|
+
@field_data[data_or_offset + 4, len].unpack("a*")[0]
|
185
189
|
|
186
190
|
when :struct
|
187
191
|
read_struct data_or_offset, nil, field.parent.data_version
|
data/lib/nwn/gff/struct.rb
CHANGED
@@ -19,7 +19,7 @@ module NWN::Gff::Struct
|
|
19
19
|
attr_reader :element
|
20
20
|
|
21
21
|
def path
|
22
|
-
if @element
|
22
|
+
if defined?(@element) && !@element.nil?
|
23
23
|
@element.path
|
24
24
|
else
|
25
25
|
"/"
|
@@ -41,13 +41,15 @@ module NWN::Gff::Struct
|
|
41
41
|
# Overrides the data type (used by the built-in file format readers).
|
42
42
|
def data_type= k
|
43
43
|
k = nil if k == ""
|
44
|
-
NWN.log_debug("Setting explicit data_type for parented element") if k &&
|
44
|
+
NWN.log_debug("Setting explicit data_type for parented element") if k &&
|
45
|
+
defined?(@element) && !@element.nil?
|
45
46
|
@data_type = k
|
46
47
|
end
|
47
48
|
|
48
49
|
def element= e #:nodoc:
|
49
50
|
@element = e
|
50
|
-
NWN.log_debug("Re-parenting a struct with explicit data_type #{@data_type.inspect}") if e &&
|
51
|
+
NWN.log_debug("Re-parenting a struct with explicit data_type #{@data_type.inspect}") if !e.nil? &&
|
52
|
+
defined?(@data_type) && !@data_type.nil?
|
51
53
|
end
|
52
54
|
|
53
55
|
# Dump this struct as GFF binary data.
|
@@ -106,7 +108,7 @@ module NWN::Gff::Struct
|
|
106
108
|
|
107
109
|
def method_missing meth, *av, &block # :nodoc:
|
108
110
|
if meth.to_s =~ /^add_(.+)$/
|
109
|
-
if NWN::Gff::Types.
|
111
|
+
if NWN::Gff::Types.key($1.to_sym)
|
110
112
|
av.size >= 1 || av.size <= 2 or raise(NoMethodError,
|
111
113
|
"undefined method #{meth} (requires two arguments to infer add_any)")
|
112
114
|
t = $1.to_sym
|
data/lib/nwn/gff/writer.rb
CHANGED
@@ -42,7 +42,7 @@ private
|
|
42
42
|
|
43
43
|
def add_data_field type, label, content
|
44
44
|
label_id = get_label_id_for_label label
|
45
|
-
@fields.push Types.
|
45
|
+
@fields.push Types.key(type), label_id, content
|
46
46
|
(@fields.size - 1) / 3
|
47
47
|
end
|
48
48
|
|
@@ -129,7 +129,7 @@ private
|
|
129
129
|
v.field_value % (2**32)
|
130
130
|
].pack("II")
|
131
131
|
when :void
|
132
|
-
[ v.field_value.size
|
132
|
+
[ v.field_value.size, v.field_value ].pack("Va*")
|
133
133
|
else
|
134
134
|
[v.field_value].pack(format)
|
135
135
|
end
|
data/lib/nwn/key.rb
CHANGED
@@ -87,8 +87,8 @@ module NWN
|
|
87
87
|
size, name_offset, name_size, drives = x.unpack("VVvv")
|
88
88
|
io.seek(name_offset)
|
89
89
|
name = io.e_read(name_size, "name table").unpack("A*")[0]
|
90
|
-
name.gsub!("\\",
|
91
|
-
name = File.expand_path(@root +
|
90
|
+
name.gsub!("\\", File::SEPARATOR)
|
91
|
+
name = File.expand_path(@root + File::SEPARATOR + name)
|
92
92
|
|
93
93
|
_io = File.new(name, "r")
|
94
94
|
@bif << Bif.new(self, _io)
|
data/lib/nwn/kivinen_support.rb
CHANGED
@@ -50,6 +50,8 @@ module NWN::Gff::Handler::Kivinen
|
|
50
50
|
yield(path + "/", path)
|
51
51
|
yield(path + "/ ____struct_type", field.field_value.struct_id)
|
52
52
|
when :cexolocstr
|
53
|
+
when :void
|
54
|
+
yield(path, field.field_value.unpack("H*")[0])
|
53
55
|
else
|
54
56
|
yield(path, field.field_value)
|
55
57
|
end
|
@@ -57,7 +59,7 @@ module NWN::Gff::Handler::Kivinen
|
|
57
59
|
yield(path + ". ____string_ref",field.str_ref) if
|
58
60
|
field.has_str_ref? || field.field_type == :cexolocstr
|
59
61
|
|
60
|
-
yield(path + ". ____type", NWN::Gff::Types.
|
62
|
+
yield(path + ". ____type", NWN::Gff::Types.key(field.field_type)) if
|
61
63
|
types_too
|
62
64
|
|
63
65
|
end
|
data/lib/nwn/res.rb
CHANGED
@@ -55,7 +55,7 @@ module NWN
|
|
55
55
|
|
56
56
|
# Get the extension of this object.
|
57
57
|
def extension
|
58
|
-
NWN::Resources::Extensions.
|
58
|
+
NWN::Resources::Extensions.key(@res_type)
|
59
59
|
end
|
60
60
|
end
|
61
61
|
|
@@ -115,7 +115,7 @@ module NWN
|
|
115
115
|
def initialize path
|
116
116
|
super()
|
117
117
|
@path = path
|
118
|
-
Dir[path + "
|
118
|
+
Dir[path + File::SEPARATOR + "*.*"].each {|x|
|
119
119
|
begin add_file x
|
120
120
|
rescue ArgumentError => e
|
121
121
|
NWN.log_debug e.to_s
|