nwn-lib 0.4.6 → 0.4.7
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +35 -0
- data/Rakefile +1 -1
- data/bin/nwn-erf +22 -14
- data/bin/nwn-gff +3 -3
- data/bin/nwn-irb +1 -2
- data/lib/nwn/all.rb +0 -1
- data/lib/nwn/erf.rb +62 -14
- data/lib/nwn/gff.rb +1 -1
- data/lib/nwn/gff/reader.rb +43 -16
- data/lib/nwn/gff/writer.rb +18 -9
- data/lib/nwn/res.rb +6 -4
- data/lib/nwn/scripting.rb +2 -2
- data/lib/nwn/settings.rb +12 -0
- data/lib/nwn/twoda.rb +7 -10
- data/scripts/extract_all_items.rb +1 -1
- data/scripts/reformat_2da +1 -1
- data/spec/bin_dsl_spec.rb +36 -0
- data/spec/bin_erf_spec.rb +118 -0
- data/spec/bin_gff_spec.rb +90 -0
- data/spec/erf_spec.rb +63 -46
- data/spec/gff_spec.rb +46 -3
- data/spec/spec_helper.rb +174 -0
- data/spec/struct_spec.rb +21 -0
- data/spec/tlk_spec.rb +0 -17
- data/spec/twoda_spec.rb +0 -68
- data/spec/{wellformed_gff.binary → wellformed_gff.bic} +0 -0
- metadata +6 -4
- data/lib/nwn/helpers.rb +0 -153
data/spec/gff_spec.rb
CHANGED
@@ -1,11 +1,38 @@
|
|
1
1
|
require File.join(File.dirname(__FILE__), 'spec_helper')
|
2
2
|
|
3
|
-
|
3
|
+
describe "Gff.read/write API" do
|
4
|
+
it "reads correctly" do
|
5
|
+
i = StringIO.new WELLFORMED_GFF
|
6
|
+
g = Gff.read(i, :gff)
|
7
|
+
end
|
8
|
+
|
9
|
+
it "writes correctly" do
|
10
|
+
i = StringIO.new WELLFORMED_GFF
|
11
|
+
gff = Gff.read(i, :gff)
|
12
|
+
|
13
|
+
out = StringIO.new
|
14
|
+
ret = Gff.write(out, :gff, gff)
|
15
|
+
ret.should == out.size
|
16
|
+
end
|
17
|
+
|
18
|
+
{
|
19
|
+
:gff => %w{utc utd ute uti utm utp uts utt utw git are gic mod ifo fac ssf dlg itp bic},
|
20
|
+
:yaml => %w{yml yaml},
|
21
|
+
:kivinen => %w{k kivinen},
|
22
|
+
:marshal => %w{marshal}
|
23
|
+
}.each {|expect, arr|
|
24
|
+
arr.each {|ext|
|
25
|
+
it "guesses the file format #{expect} for extension #{ext} correctly" do
|
26
|
+
Gff.guess_file_format("xxy.#{ext}").should == expect
|
27
|
+
end
|
28
|
+
}
|
29
|
+
}
|
30
|
+
end
|
4
31
|
|
5
32
|
describe "Gff::*" do
|
6
33
|
|
7
34
|
def wellformed_verify binary
|
8
|
-
t = Gff::Reader.read(binary)
|
35
|
+
t = Gff::Reader.read(StringIO.new binary)
|
9
36
|
end
|
10
37
|
|
11
38
|
it "reads wellformed GFF data" do
|
@@ -13,10 +40,26 @@ describe "Gff::*" do
|
|
13
40
|
end
|
14
41
|
|
15
42
|
it "reproduces correct GFF binary data" do
|
16
|
-
t = Gff::Reader.read(WELLFORMED_GFF)
|
43
|
+
t = Gff::Reader.read(StringIO.new WELLFORMED_GFF)
|
17
44
|
v = Gff::Writer.dump(t)
|
18
45
|
t2 = wellformed_verify v
|
19
46
|
t2.should == t
|
20
47
|
end
|
21
48
|
|
49
|
+
it "writes to io and returns the number of written bytes" do
|
50
|
+
t = Gff::Reader.read(StringIO.new WELLFORMED_GFF)
|
51
|
+
out = StringIO.new
|
52
|
+
v = Gff::Writer.dump(t, out)
|
53
|
+
v.should == out.size
|
54
|
+
out.seek(0)
|
55
|
+
v = out.read(v)
|
56
|
+
t2 = wellformed_verify v
|
57
|
+
t2.should == t
|
58
|
+
end
|
59
|
+
|
60
|
+
it "fails on not enough data" do
|
61
|
+
proc {wellformed_verify WELLFORMED_GFF[0 .. -2] }.should
|
62
|
+
raise_error IOError, "cannot read list_indices"
|
63
|
+
end
|
64
|
+
|
22
65
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,4 +1,6 @@
|
|
1
1
|
require 'rubygems'
|
2
|
+
require 'tempfile'
|
3
|
+
require 'open3'
|
2
4
|
|
3
5
|
Thread.abort_on_exception = true
|
4
6
|
|
@@ -22,3 +24,175 @@ GffFieldValidations = {
|
|
22
24
|
:short => [[-0x8000, 0x7fff], [-0x8001, 0x7fff + 1]],
|
23
25
|
:word => [[0, 0xffff], [-1, 0xffff + 1]],
|
24
26
|
}.freeze
|
27
|
+
|
28
|
+
WELLFORMED_GFF_PATH = File.join(File.expand_path(File.dirname(__FILE__)), "wellformed_gff.bic").freeze
|
29
|
+
WELLFORMED_GFF = IO.read(WELLFORMED_GFF_PATH).freeze
|
30
|
+
|
31
|
+
WELLFORMED_ERF = ([
|
32
|
+
"HAK", "V1.0",
|
33
|
+
locstr_count = 1, locstr_size = 14,
|
34
|
+
entry_count = 3,
|
35
|
+
offset_to_locstr = 160,
|
36
|
+
offset_to_keys = offset_to_locstr + locstr_size,
|
37
|
+
offset_to_res = offset_to_locstr + locstr_size + entry_count * (16 + 4 + 2 + 2),
|
38
|
+
|
39
|
+
100, 126, # year, dayofyear
|
40
|
+
0xdeadbeef, "" #description strref, 116 bytes 0-padding
|
41
|
+
].pack("A4 A4 VV VV VV VV V a116") + [
|
42
|
+
0, 6, "abcdef" # one locstr
|
43
|
+
].pack("V V a*") + [
|
44
|
+
"resref", 0, 10, 0, # keylist: resref.txt, id = 0
|
45
|
+
"help", 1, 1, 0, # keylist: help.bmp, id = 1
|
46
|
+
"yegods", 2, 4, 0, # keylist: yegods.wav, id = 2
|
47
|
+
].pack("a16 V v v" * entry_count) + [
|
48
|
+
offset_to_res + entry_count * 8, 6, # offset, size
|
49
|
+
offset_to_res + entry_count * 8 + 6, 4, # offset, size
|
50
|
+
offset_to_res + entry_count * 8 + 6 + 4, 6, # offset, size
|
51
|
+
].pack("II" * entry_count) + [
|
52
|
+
"resref", "help", "yegods"
|
53
|
+
].pack("a* a* a*")).freeze
|
54
|
+
|
55
|
+
WELLFORMED_ERF_11 = ([
|
56
|
+
"HAK", "V1.1",
|
57
|
+
locstr_count = 1, locstr_size = 14,
|
58
|
+
entry_count = 3,
|
59
|
+
offset_to_locstr = 160,
|
60
|
+
offset_to_keys = offset_to_locstr + locstr_size,
|
61
|
+
offset_to_res = offset_to_locstr + locstr_size + entry_count * (32 + 4 + 2 + 2),
|
62
|
+
|
63
|
+
100, 126, # year, dayofyear
|
64
|
+
0xdeadbeef, "" #description strref, 116 bytes 0-padding
|
65
|
+
].pack("A4 A4 VV VV VV VV V a116") + [
|
66
|
+
0, 6, "abcdef" # one locstr
|
67
|
+
].pack("V V a*") + [
|
68
|
+
"resref", 0, 10, 0, # keylist: resref.txt, id = 0
|
69
|
+
"help", 1, 1, 0, # keylist: help.bmp, id = 1
|
70
|
+
"yegods", 2, 4, 0, # keylist: yegods.wav, id = 2
|
71
|
+
].pack("a32 V v v" * entry_count) + [
|
72
|
+
offset_to_res + entry_count * 8, 6, # offset, size
|
73
|
+
offset_to_res + entry_count * 8 + 6, 4, # offset, size
|
74
|
+
offset_to_res + entry_count * 8 + 6 + 4, 6, # offset, size
|
75
|
+
].pack("II" * entry_count) + [
|
76
|
+
"resref", "help", "yegods"
|
77
|
+
].pack("a* a* a*")).freeze
|
78
|
+
|
79
|
+
WELLFORMED_TLK = ([
|
80
|
+
"TLK", "V3.0",
|
81
|
+
language_id = 0,
|
82
|
+
string_count = 5,
|
83
|
+
offset_to_str = 21,
|
84
|
+
].pack("a4 a4 I I I") + [ # string data table
|
85
|
+
# flags, soundresref, volvariance, pitchvariance, offset_to_str, sz, soundlen
|
86
|
+
0x1, "", 0, 0, -1 + 40 * string_count, 1, 0.0,
|
87
|
+
0x3, "textsnd", 0, 0, -1 + 40 * string_count + 1, 2, 0.0,
|
88
|
+
0x7, "textsndlen", 0, 0, -1 + 40 * string_count + 3, 3, 2.0,
|
89
|
+
0x1, "", 0, 0, -1 + 40 * string_count + 6, 4, 0.0,
|
90
|
+
0x2, "justsnd", 0, 0, -1 + 40 * string_count + 10, 0, 0.0,
|
91
|
+
].pack("I A16 I I I I f" * string_count) + [
|
92
|
+
"1", "22", "333", "4444"
|
93
|
+
].join("")).freeze
|
94
|
+
|
95
|
+
TWODA_WELLFORMED = <<-EOT
|
96
|
+
2DA V2.0
|
97
|
+
|
98
|
+
Col1 Col2
|
99
|
+
0 a b
|
100
|
+
1 c d
|
101
|
+
EOT
|
102
|
+
|
103
|
+
TWODA_MISALIGNED = <<-EOT
|
104
|
+
2DA V2.0
|
105
|
+
|
106
|
+
Col1
|
107
|
+
0 a
|
108
|
+
1 b
|
109
|
+
2 c
|
110
|
+
3 d
|
111
|
+
4 e
|
112
|
+
6 f
|
113
|
+
2 g
|
114
|
+
7 h
|
115
|
+
EOT
|
116
|
+
|
117
|
+
TWODA_WHITESPACE = <<-EOT
|
118
|
+
2DA V2.0
|
119
|
+
|
120
|
+
|
121
|
+
Col1
|
122
|
+
0 4
|
123
|
+
EOT
|
124
|
+
|
125
|
+
TWODA_MISSING_COLUMN = <<-EOT
|
126
|
+
2DA V2.0
|
127
|
+
|
128
|
+
Col1 Col2 Col3
|
129
|
+
0 a1 b1 c1
|
130
|
+
1 a2 b2
|
131
|
+
EOT
|
132
|
+
|
133
|
+
TWODA_TOO_MANY_CELLS = <<-EOT
|
134
|
+
2DA V2.0
|
135
|
+
|
136
|
+
Col1
|
137
|
+
0 a1 b1 c1
|
138
|
+
1 a2 b2
|
139
|
+
2 "a2 b2 c1"
|
140
|
+
EOT
|
141
|
+
|
142
|
+
|
143
|
+
TWODA_EMPTY_AND_QUOTES = <<-EOT
|
144
|
+
2DA V2.0
|
145
|
+
|
146
|
+
Col1 Col2
|
147
|
+
0 **** b
|
148
|
+
1 c d
|
149
|
+
2 "" f
|
150
|
+
3 "g g" h
|
151
|
+
EOT
|
152
|
+
|
153
|
+
TWODA_MISSING_ID = <<-EOT
|
154
|
+
2DA V2.0
|
155
|
+
|
156
|
+
Col1
|
157
|
+
a
|
158
|
+
0 b
|
159
|
+
1 c
|
160
|
+
2 d
|
161
|
+
EOT
|
162
|
+
|
163
|
+
describe "bin helper", :shared => true do
|
164
|
+
before do
|
165
|
+
@tmp = Dir.tmpdir
|
166
|
+
end
|
167
|
+
|
168
|
+
def run_bin *va
|
169
|
+
binary = File.join(File.expand_path(File.dirname(__FILE__)), "..", "bin", subject.to_s)
|
170
|
+
incl = File.join(File.expand_path(File.dirname(__FILE__)), "..", "lib")
|
171
|
+
old = Dir.pwd
|
172
|
+
begin
|
173
|
+
Dir.chdir(@tmp)
|
174
|
+
Open3.popen3(
|
175
|
+
"ruby", "-I#{incl}",
|
176
|
+
binary,
|
177
|
+
*va
|
178
|
+
) do |i,o,e|
|
179
|
+
yield i, o, e
|
180
|
+
end
|
181
|
+
ensure
|
182
|
+
Dir.chdir(old)
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
def run *va
|
187
|
+
run_bin *va do |i, o, e|
|
188
|
+
e = e.read
|
189
|
+
e.should == ""
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
def run_fail *va
|
194
|
+
run_bin *va do |i, o, e|
|
195
|
+
e.read.size.should > 0
|
196
|
+
end
|
197
|
+
end
|
198
|
+
end
|
data/spec/struct_spec.rb
CHANGED
@@ -58,4 +58,25 @@ describe "Gff::Struct" do
|
|
58
58
|
end
|
59
59
|
}
|
60
60
|
|
61
|
+
it "returns proper fields" do
|
62
|
+
t = Gff::Reader.read(StringIO.new WELLFORMED_GFF)
|
63
|
+
t['Plot'].should respond_to :t
|
64
|
+
t['Plot'].should respond_to :l
|
65
|
+
t['Plot'].should respond_to :v
|
66
|
+
t['Plot'].l.should == "Plot"
|
67
|
+
t['Plot'].t.should == :byte
|
68
|
+
end
|
69
|
+
|
70
|
+
it "yields all and correct values in each_by_flat_path" do
|
71
|
+
t = Gff::Reader.read(StringIO.new WELLFORMED_GFF)
|
72
|
+
t.each_by_flat_path do |k,v|
|
73
|
+
k.class.should == String
|
74
|
+
k.should =~ %r{^/}
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
it "responds_to to_gff" do
|
79
|
+
t = Gff::Reader.read(StringIO.new WELLFORMED_GFF)
|
80
|
+
Gff::Reader.read(StringIO.new t.to_gff).should == t
|
81
|
+
end
|
61
82
|
end
|
data/spec/tlk_spec.rb
CHANGED
@@ -1,22 +1,5 @@
|
|
1
1
|
require File.join(File.dirname(__FILE__), 'spec_helper')
|
2
2
|
|
3
|
-
WELLFORMED_TLK = ([
|
4
|
-
"TLK", "V3.0",
|
5
|
-
language_id = 0,
|
6
|
-
string_count = 5,
|
7
|
-
offset_to_str = 21,
|
8
|
-
].pack("a4 a4 I I I") + [ # string data table
|
9
|
-
# flags, soundresref, volvariance, pitchvariance, offset_to_str, sz, soundlen
|
10
|
-
0x1, "", 0, 0, -1 + 40 * string_count, 1, 0.0,
|
11
|
-
0x3, "textsnd", 0, 0, -1 + 40 * string_count + 1, 2, 0.0,
|
12
|
-
0x7, "textsndlen", 0, 0, -1 + 40 * string_count + 3, 3, 2.0,
|
13
|
-
0x1, "", 0, 0, -1 + 40 * string_count + 6, 4, 0.0,
|
14
|
-
0x2, "justsnd", 0, 0, -1 + 40 * string_count + 10, 0, 0.0,
|
15
|
-
].pack("I A16 I I I I f" * string_count) + [
|
16
|
-
"1", "22", "333", "4444"
|
17
|
-
].join("")).freeze
|
18
|
-
|
19
|
-
|
20
3
|
describe "Tlk::Tlk" do
|
21
4
|
|
22
5
|
def wellformed_verify binary
|
data/spec/twoda_spec.rb
CHANGED
@@ -1,73 +1,5 @@
|
|
1
1
|
require File.join(File.dirname(__FILE__), 'spec_helper')
|
2
2
|
|
3
|
-
TWODA_WELLFORMED = <<-EOT
|
4
|
-
2DA V2.0
|
5
|
-
|
6
|
-
Col1 Col2
|
7
|
-
0 a b
|
8
|
-
1 c d
|
9
|
-
EOT
|
10
|
-
|
11
|
-
TWODA_MISALIGNED = <<-EOT
|
12
|
-
2DA V2.0
|
13
|
-
|
14
|
-
Col1
|
15
|
-
0 a
|
16
|
-
1 b
|
17
|
-
2 c
|
18
|
-
3 d
|
19
|
-
4 e
|
20
|
-
6 f
|
21
|
-
2 g
|
22
|
-
7 h
|
23
|
-
EOT
|
24
|
-
|
25
|
-
TWODA_WHITESPACE = <<-EOT
|
26
|
-
2DA V2.0
|
27
|
-
|
28
|
-
|
29
|
-
Col1
|
30
|
-
0 4
|
31
|
-
EOT
|
32
|
-
|
33
|
-
TWODA_MISSING_COLUMN = <<-EOT
|
34
|
-
2DA V2.0
|
35
|
-
|
36
|
-
Col1 Col2 Col3
|
37
|
-
0 a1 b1 c1
|
38
|
-
1 a2 b2
|
39
|
-
EOT
|
40
|
-
|
41
|
-
TWODA_TOO_MANY_CELLS = <<-EOT
|
42
|
-
2DA V2.0
|
43
|
-
|
44
|
-
Col1
|
45
|
-
0 a1 b1 c1
|
46
|
-
1 a2 b2
|
47
|
-
2 "a2 b2 c1"
|
48
|
-
EOT
|
49
|
-
|
50
|
-
|
51
|
-
TWODA_EMPTY_AND_QUOTES = <<-EOT
|
52
|
-
2DA V2.0
|
53
|
-
|
54
|
-
Col1 Col2
|
55
|
-
0 **** b
|
56
|
-
1 c d
|
57
|
-
2 "" f
|
58
|
-
3 "g g" h
|
59
|
-
EOT
|
60
|
-
|
61
|
-
TWODA_MISSING_ID = <<-EOT
|
62
|
-
2DA V2.0
|
63
|
-
|
64
|
-
Col1
|
65
|
-
a
|
66
|
-
0 b
|
67
|
-
1 c
|
68
|
-
2 d
|
69
|
-
EOT
|
70
|
-
|
71
3
|
describe TwoDA::Table do
|
72
4
|
|
73
5
|
it "parses wellformed files" do
|
File without changes
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: nwn-lib
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bernhard Stoeckner
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-05-
|
12
|
+
date: 2009-05-26 00:00:00 +02:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
@@ -39,9 +39,9 @@ files:
|
|
39
39
|
- bin/nwn-gff
|
40
40
|
- bin/nwn-irb
|
41
41
|
- bin/nwn-erf
|
42
|
+
- spec/wellformed_gff.bic
|
42
43
|
- spec/gff_spec.rb
|
43
44
|
- spec/res_spec.rb
|
44
|
-
- spec/wellformed_gff.binary
|
45
45
|
- spec/spec.opts
|
46
46
|
- spec/erf_spec.rb
|
47
47
|
- spec/field_spec.rb
|
@@ -49,7 +49,10 @@ files:
|
|
49
49
|
- spec/struct_spec.rb
|
50
50
|
- spec/spec_helper.rb
|
51
51
|
- spec/tlk_spec.rb
|
52
|
+
- spec/bin_dsl_spec.rb
|
53
|
+
- spec/bin_gff_spec.rb
|
52
54
|
- spec/rcov.opts
|
55
|
+
- spec/bin_erf_spec.rb
|
53
56
|
- spec/twoda_spec.rb
|
54
57
|
- lib/nwn
|
55
58
|
- lib/nwn/scripting.rb
|
@@ -62,7 +65,6 @@ files:
|
|
62
65
|
- lib/nwn/res.rb
|
63
66
|
- lib/nwn/kivinen.rb
|
64
67
|
- lib/nwn/all.rb
|
65
|
-
- lib/nwn/helpers.rb
|
66
68
|
- lib/nwn/gff
|
67
69
|
- lib/nwn/gff/field.rb
|
68
70
|
- lib/nwn/gff/reader.rb
|
data/lib/nwn/helpers.rb
DELETED
@@ -1,153 +0,0 @@
|
|
1
|
-
require 'nwn/gff'
|
2
|
-
require 'nwn/twoda'
|
3
|
-
|
4
|
-
module NWN
|
5
|
-
module Gff
|
6
|
-
|
7
|
-
module Helpers
|
8
|
-
# This sets up the IPRP cache. Used internally; no need to call this yourself.
|
9
|
-
def self._ip_cache_setup #:nodoc:
|
10
|
-
return if defined? @costtables
|
11
|
-
@costtables = {}
|
12
|
-
@paramtables = {}
|
13
|
-
@costtable_index = NWN::TwoDA::Cache.get('iprp_costtable')
|
14
|
-
@paramtable_index = NWN::TwoDA::Cache.get('iprp_paramtable')
|
15
|
-
@costtable_index.by_col('Name').each_with_index {|p,idx|
|
16
|
-
next if @costtables[p.downcase]
|
17
|
-
@costtables[p.downcase] = @costtables[idx] = NWN::TwoDA::Cache.get(p.downcase)
|
18
|
-
}
|
19
|
-
@paramtable_index.by_col('TableResRef').each_with_index {|p,idx|
|
20
|
-
next if @paramtables[p.downcase]
|
21
|
-
@paramtables[p.downcase] = @paramtables[idx] = NWN::TwoDA::Cache.get(p.downcase)
|
22
|
-
}
|
23
|
-
@properties = NWN::TwoDA::Cache.get('itemprops')
|
24
|
-
@propdef = NWN::TwoDA::Cache.get('itempropdef')
|
25
|
-
@subtypes = []
|
26
|
-
@propdef.by_col('SubTypeResRef').each_with_index {|st, idx|
|
27
|
-
@subtypes[idx] = NWN::TwoDA::Cache.get(st.downcase) if st != "****"
|
28
|
-
}
|
29
|
-
@prop_id_to_costtable = []
|
30
|
-
@propdef.by_col('CostTableResRef').each_with_index {|st, idx|
|
31
|
-
@prop_id_to_costtable[idx] = st.to_i if st != "****"
|
32
|
-
}
|
33
|
-
@prop_id_to_param1 = []
|
34
|
-
@propdef.by_col('Param1ResRef').each_with_index {|st, idx|
|
35
|
-
@prop_id_to_param1[idx] = st.to_i if st != "****"
|
36
|
-
}
|
37
|
-
end
|
38
|
-
|
39
|
-
def self.resolve_or_match_partial name_spec, list #:nodoc:
|
40
|
-
name_spec = name_spec.downcase
|
41
|
-
|
42
|
-
raise ArgumentError, "?-expand: #{list.inspect}" if name_spec == '?'
|
43
|
-
|
44
|
-
list.each {|l|
|
45
|
-
return l if l.downcase == name_spec
|
46
|
-
}
|
47
|
-
|
48
|
-
substrings = list.select {|l| l.downcase.index(name_spec) }
|
49
|
-
if substrings.size == 1
|
50
|
-
return substrings[0]
|
51
|
-
elsif substrings.size > 1
|
52
|
-
raise ArgumentError, "Cannot resolve #{name_spec}. Partial matches: #{substrings.inspect}."
|
53
|
-
end
|
54
|
-
|
55
|
-
raise ArgumentError, "Cannot resolve #{name_spec}."
|
56
|
-
end
|
57
|
-
|
58
|
-
# This creates a NWN::Gff::Struct describing the item property in question.
|
59
|
-
#
|
60
|
-
# [+name+] The iprp name to resolve, for example <tt>Damage_Bonus_vs_Racial_Group</tt>
|
61
|
-
# [+subtype+] The iprp subtype, for example <tt>Elf</tt>
|
62
|
-
# [+value+] The iprp value, for example <tt>2d12</tt>
|
63
|
-
# [+param+] The iprp param1, for example <tt>Acid</tt>
|
64
|
-
# [+chance+] The iprp appearance chance (whats this?)
|
65
|
-
#
|
66
|
-
# Depends on the 2da cache set up correctly.
|
67
|
-
#
|
68
|
-
# Note that the given arguments can be resolved with partial matches as well, as long
|
69
|
-
# as they are unique. (<tt>Fir -> Fire</tt>)
|
70
|
-
#
|
71
|
-
# Arguments are case-insensitive.
|
72
|
-
def self.item_property name, subtype = nil, value = nil, param1 = nil, chance_appear = 100
|
73
|
-
self._ip_cache_setup
|
74
|
-
|
75
|
-
struct = NWN::Gff::Struct.new
|
76
|
-
|
77
|
-
name = resolve_or_match_partial name, @properties.by_col('Label')
|
78
|
-
index = @properties.by_col('Label').index(name)
|
79
|
-
raise ArgumentError, "Cannot find property #{name}" unless index
|
80
|
-
|
81
|
-
raise ArgumentError, "Property #{name} needs subtype of type #{NWN::TwoDA::Cache.get('itempropdef').by_col('SubTypeResRef', index)}, but none given." if
|
82
|
-
@subtypes[index] && !subtype
|
83
|
-
raise ArgumentError, "Property #{name} does not need subtype, but subtype given." if
|
84
|
-
!@subtypes[index] && subtype
|
85
|
-
|
86
|
-
subindex = 255
|
87
|
-
|
88
|
-
if subtype
|
89
|
-
subtype = resolve_or_match_partial subtype, @subtypes[index].by_col('Label')
|
90
|
-
|
91
|
-
subindex = @subtypes[index].by_col('Label').index(subtype)
|
92
|
-
raise ArgumentError, "Cannot find subtype #{subtype} for property #{name}" unless
|
93
|
-
subindex
|
94
|
-
|
95
|
-
raise ArgumentError, "Property #{name} requires a cost value of type #{@costtable_index.by_row(@prop_id_to_costtable[index], 'Name')}, but none given" if
|
96
|
-
!value && @prop_id_to_costtable[index]
|
97
|
-
raise ArgumentError, "Property #{name} does not require a cost value, but value given" if
|
98
|
-
value && !@prop_id_to_costtable[index]
|
99
|
-
end
|
100
|
-
|
101
|
-
_cost = 255
|
102
|
-
_cost_value = 0
|
103
|
-
|
104
|
-
if value
|
105
|
-
ct = @prop_id_to_costtable[index]
|
106
|
-
value = resolve_or_match_partial value, @costtables[ct.to_i].by_col('Label')
|
107
|
-
|
108
|
-
costvalue = @costtables[ct.to_i].by_col('Label').index(value)
|
109
|
-
raise ArgumentError, "Cannot find CostValue for #{value}" unless costvalue
|
110
|
-
_cost = ct
|
111
|
-
_cost_value = costvalue
|
112
|
-
end
|
113
|
-
struct.merge!({
|
114
|
-
'CostTable' => Element.new('CostTable', :byte, _cost),
|
115
|
-
'CostValue' => Element.new('CostValue', :word, _cost_value)
|
116
|
-
})
|
117
|
-
|
118
|
-
|
119
|
-
raise ArgumentError, "Property #{name} requires a param1 value of type #{@paramtable_index.by_row(@prop_id_to_param1[index], 'TableResRef')}, but none given" if
|
120
|
-
!param1 && @prop_id_to_param1[index]
|
121
|
-
raise ArgumentError, "Property #{name} does not require a param1 value, but value given" if
|
122
|
-
param1 && !@prop_id_to_param1[index]
|
123
|
-
|
124
|
-
_param1 = 255
|
125
|
-
_param1_value = 0
|
126
|
-
|
127
|
-
if param1
|
128
|
-
pt = @prop_id_to_param1[index]
|
129
|
-
param1 = resolve_or_match_partial param1, @paramtables[pt.to_i].by_col('Label')
|
130
|
-
|
131
|
-
param1value = @paramtables[pt.to_i].by_col('Label').index(param1)
|
132
|
-
raise ArgumentError, "Cannot find Param1 for #{param1}" unless param1value
|
133
|
-
_param1 = pt
|
134
|
-
_param1_value = param1value
|
135
|
-
end
|
136
|
-
struct.merge!({
|
137
|
-
'Param1' => Element.new('Param1', :byte, _param1),
|
138
|
-
'Param1Value' => Element.new('Param1Value', :byte, _param1_value)
|
139
|
-
})
|
140
|
-
|
141
|
-
struct.merge!({
|
142
|
-
'PropertyName' => Element.new('PropertyName', :word, index),
|
143
|
-
'Subtype' => Element.new('Subtype', :word, subindex),
|
144
|
-
'ChanceAppear' => Element.new('ChanceAppear', :byte, chance_appear)
|
145
|
-
})
|
146
|
-
|
147
|
-
struct.struct_id = 0
|
148
|
-
struct
|
149
|
-
end
|
150
|
-
|
151
|
-
end
|
152
|
-
end
|
153
|
-
end
|