nwn-lib 0.4.4 → 0.4.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +18 -0
- data/Rakefile +1 -1
- data/SCRIPTING +3 -0
- data/bin/nwn-dsl +2 -2
- data/bin/nwn-gff +3 -3
- data/bin/nwn-irb +2 -3
- data/lib/nwn/gff.rb +1 -1
- data/lib/nwn/gff/struct.rb +4 -0
- data/lib/nwn/scripting.rb +42 -7
- data/lib/nwn/twoda.rb +52 -0
- metadata +2 -2
data/CHANGELOG
CHANGED
@@ -147,3 +147,21 @@ Bernhard Stoeckner (7):
|
|
147
147
|
bin/nwn-erf: -vt: move column type before filename
|
148
148
|
erf: fix loctable reading breaking on more than one locstr
|
149
149
|
0.4.4-rel
|
150
|
+
|
151
|
+
=== 0.4.5
|
152
|
+
Bernhard Stoeckner (14):
|
153
|
+
bin/nwn-irb: fix help scriptname
|
154
|
+
nwn-dsl: $SCRIPT is the currently-running script
|
155
|
+
TwoDA: add .get alias
|
156
|
+
Scripting/log: provide #progress to indicate progress within scripts
|
157
|
+
guess_file_name: consider non-lowercase extensions
|
158
|
+
nwn-gff: $SCRIPT fix
|
159
|
+
nwn-irb: include NWN namespace
|
160
|
+
Namespace clobbering: Integer provides xp_to_level, level_to_xp
|
161
|
+
Gff::Struct: add #to_s
|
162
|
+
scripting: satisfy: return object as-is when no conditions are given (fix)
|
163
|
+
Scripting: add support to .#save files that were loaded with satisfy/need/want
|
164
|
+
Scripting: ask: fix return value of hash and arrays
|
165
|
+
TwoDA: add disclaimer for Cache references
|
166
|
+
TwoDA: add Table#[], Table#[]=
|
167
|
+
|
data/Rakefile
CHANGED
@@ -9,7 +9,7 @@ include FileUtils
|
|
9
9
|
# Configuration
|
10
10
|
##############################################################################
|
11
11
|
NAME = "nwn-lib"
|
12
|
-
VERS = "0.4.
|
12
|
+
VERS = "0.4.5"
|
13
13
|
CLEAN.include ["**/.*.sw?", "pkg", ".config", "rdoc", "coverage"]
|
14
14
|
RDOC_OPTS = ["--quiet", "--line-numbers", "--inline-source", '--title', \
|
15
15
|
'nwn-lib: a ruby library for accessing NWN resource files', \
|
data/SCRIPTING
CHANGED
@@ -34,6 +34,9 @@ way, simply call them with nwn-dsl.
|
|
34
34
|
DSL stands for domain-specific-language by the way, and this is quite
|
35
35
|
a stretch, considering your scripts will be written in plain old ruby.
|
36
36
|
|
37
|
+
The currently-running script name is in $SCRIPT - you can override this
|
38
|
+
to print a custom name in, for example, +log+.
|
39
|
+
|
37
40
|
=== API
|
38
41
|
|
39
42
|
There are various helpers available to scripts. See NWN::Gff::Scripting
|
data/bin/nwn-dsl
CHANGED
@@ -13,10 +13,10 @@ end.parse!
|
|
13
13
|
|
14
14
|
fail "Not enough arguments (try -h)." unless ARGV.size > 0
|
15
15
|
|
16
|
-
$
|
16
|
+
$SCRIPT = ARGV.shift
|
17
17
|
|
18
18
|
begin
|
19
|
-
NWN::Gff::Scripting.run_script(IO.read($
|
19
|
+
NWN::Gff::Scripting.run_script(IO.read($SCRIPT), nil, ARGV)
|
20
20
|
rescue => e
|
21
21
|
$stderr.puts e.message
|
22
22
|
if $backtrace
|
data/bin/nwn-gff
CHANGED
@@ -102,7 +102,7 @@ $options[:informat] or fail "No input format specified."
|
|
102
102
|
$options[:outformat] or fail "No output format specified."
|
103
103
|
|
104
104
|
if :auto == $options[:informat]
|
105
|
-
$options[:informat] = NWN::Gff.guess_file_format($options[:infile])
|
105
|
+
$options[:informat] = NWN::Gff.guess_file_format($options[:infile].downcase)
|
106
106
|
fail "Cannot guess infile format from filename, specify with -l." unless
|
107
107
|
$options[:informat]
|
108
108
|
end
|
@@ -110,7 +110,7 @@ end
|
|
110
110
|
if $options[:outfile] == "-"
|
111
111
|
$options[:outformat] = $options[:informat] if :in == $options[:outformat]
|
112
112
|
elsif :in == $options[:outformat]
|
113
|
-
$options[:outformat] = NWN::Gff.guess_file_format($options[:outfile])
|
113
|
+
$options[:outformat] = NWN::Gff.guess_file_format($options[:outfile].downcase)
|
114
114
|
fail "Cannot guess outfile format from filename, specify with -k." unless
|
115
115
|
$options[:outformat]
|
116
116
|
end
|
@@ -138,7 +138,7 @@ $options[:run].each {|file|
|
|
138
138
|
vputs "Running script file: #{file}"
|
139
139
|
FileTest.exists?(file) or file = file + ".rb"
|
140
140
|
$script = File.expand_path(file)
|
141
|
-
$
|
141
|
+
$SCRIPT = File.basename($script)
|
142
142
|
include NWN
|
143
143
|
include NWN::Gff::Scripting
|
144
144
|
NWN::Gff::Scripting.run_script(IO.read(file), data_in)
|
data/bin/nwn-irb
CHANGED
@@ -6,7 +6,7 @@ require 'irb'
|
|
6
6
|
require 'irb/completion'
|
7
7
|
|
8
8
|
OptionParser.new do |o|
|
9
|
-
o.banner = "Usage: nwn-
|
9
|
+
o.banner = "Usage: nwn-irb [file]"
|
10
10
|
end.parse!
|
11
11
|
|
12
12
|
$file = ARGV.shift
|
@@ -38,8 +38,7 @@ def read file
|
|
38
38
|
nil
|
39
39
|
end
|
40
40
|
|
41
|
-
include NWN
|
42
|
-
include NWN::TwoDA
|
41
|
+
include NWN
|
43
42
|
|
44
43
|
if $file
|
45
44
|
read($file)
|
data/lib/nwn/gff.rb
CHANGED
data/lib/nwn/gff/struct.rb
CHANGED
data/lib/nwn/scripting.rb
CHANGED
@@ -14,6 +14,7 @@ module NWN::Gff::Scripting
|
|
14
14
|
$code = code
|
15
15
|
$argv = arguments
|
16
16
|
$standalone = run_on.nil?
|
17
|
+
$satisfy_loaded = {}
|
17
18
|
run_on ||= Sandbox.new
|
18
19
|
|
19
20
|
$script_obj_hash = run_on.hash
|
@@ -27,6 +28,24 @@ module NWN::Gff::Scripting
|
|
27
28
|
$script_obj_hash != run_on.hash
|
28
29
|
end
|
29
30
|
|
31
|
+
# Save the given object if it was loaded via want/need
|
32
|
+
def save object
|
33
|
+
fn, hash = $satisfy_loaded[object.object_id]
|
34
|
+
if fn
|
35
|
+
if hash != object.hash
|
36
|
+
File.open(fn, "w") {|f|
|
37
|
+
NWN::Gff.write(f, NWN::Gff.guess_file_format(fn), object)
|
38
|
+
}
|
39
|
+
log "saved #{object.to_s} -> #{fn}"
|
40
|
+
else
|
41
|
+
log "not saving #{fn}: not modified"
|
42
|
+
end
|
43
|
+
else
|
44
|
+
raise ArgumentError,
|
45
|
+
"#save: object #{object.to_s} was not loaded via want/need/satisfy, cannot save"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
30
49
|
# This script only runs for the following conditions (see #satisfy).
|
31
50
|
def want *what
|
32
51
|
obj = satisfy(*what)
|
@@ -47,7 +66,7 @@ module NWN::Gff::Scripting
|
|
47
66
|
if $standalone
|
48
67
|
log "warn: no need to stop_output on standalone scripts"
|
49
68
|
else
|
50
|
-
log "#{$
|
69
|
+
log "#{$SCRIPT}: not emitting any data."
|
51
70
|
end
|
52
71
|
$stop_output = true
|
53
72
|
end
|
@@ -94,12 +113,14 @@ module NWN::Gff::Scripting
|
|
94
113
|
# "object to read from (usually the first script argument)."
|
95
114
|
end
|
96
115
|
obj = NWN::Gff.read(io, NWN::Gff.guess_file_format(fn))
|
116
|
+
log "satisfied #{fn} -> #{obj.to_s}"
|
117
|
+
$satisfy_loaded[obj.object_id] = [fn, obj.hash]
|
118
|
+
|
119
|
+
return obj if what.size == 1
|
97
120
|
else
|
98
121
|
obj = self
|
99
122
|
end
|
100
123
|
|
101
|
-
return obj if what.size == 1
|
102
|
-
|
103
124
|
what.each {|w|
|
104
125
|
case w
|
105
126
|
when Class, Module
|
@@ -118,15 +139,25 @@ module NWN::Gff::Scripting
|
|
118
139
|
return nil
|
119
140
|
end
|
120
141
|
|
142
|
+
# You can call this to provide a progress indicator, if your script is long-running.
|
143
|
+
# the calculated percentage will be prefixed before each log message.
|
144
|
+
#
|
145
|
+
# +position+ The number of items in the work queue finished.
|
146
|
+
# +total_size+ The total size of the work queue, defaults to ARGV.size.
|
147
|
+
def progress position, total_size = nil
|
148
|
+
total_size ||= ARGV.size
|
149
|
+
$PERCENTAGE_DONE = position.to_f / total_size.to_f * 100
|
150
|
+
end
|
121
151
|
|
122
152
|
# Log a friendly message to stderr.
|
123
153
|
# Use this instead of puts, since SAFE levels greater than 0
|
124
154
|
# will prevent you from doing logging yourself.
|
125
155
|
def log *args
|
156
|
+
perc = $PERCENTAGE_DONE.nil? ? "" : " (%d%%)" % [ $PERCENTAGE_DONE.to_i ]
|
126
157
|
if $options
|
127
|
-
$stderr.puts [$
|
158
|
+
$stderr.puts [$SCRIPT, perc, " on ", $options[:infile], ": ", *args].join("")
|
128
159
|
else
|
129
|
-
$stderr.puts [$
|
160
|
+
$stderr.puts [$SCRIPT, perc, ": ", *args].join("")
|
130
161
|
end
|
131
162
|
end
|
132
163
|
|
@@ -150,13 +181,17 @@ module NWN::Gff::Scripting
|
|
150
181
|
ret = nil
|
151
182
|
while true
|
152
183
|
y object
|
153
|
-
$stderr.print File.basename($
|
184
|
+
$stderr.print File.basename($SCRIPT) + ": " + question + " "
|
154
185
|
ret = $stdin.gets
|
155
186
|
ret = ret.rstrip
|
156
187
|
|
157
188
|
break if object.nil? || case object
|
158
189
|
when Hash
|
159
|
-
object.keys.index(ret) || (ret != "" && object.keys.index(ret.to_i))
|
190
|
+
if object.keys.index(ret) || (ret != "" && object.keys.index(ret.to_i))
|
191
|
+
ret = object[ret] || (ret != "" && object[ret.to_i])
|
192
|
+
else
|
193
|
+
nil
|
194
|
+
end
|
160
195
|
when Regexp
|
161
196
|
ret =~ match
|
162
197
|
when Fixnum
|
data/lib/nwn/twoda.rb
CHANGED
@@ -1,5 +1,19 @@
|
|
1
1
|
require 'shellwords'
|
2
2
|
|
3
|
+
class Integer
|
4
|
+
def xp_to_level
|
5
|
+
NWN::TwoDA.get('exptable').rows.each {|row|
|
6
|
+
level, exp = row.Level.to_i, row.XP.to_i
|
7
|
+
return level - 1 if exp > self
|
8
|
+
}
|
9
|
+
return nil
|
10
|
+
end
|
11
|
+
|
12
|
+
def level_to_xp
|
13
|
+
NWN::TwoDA.get('exptable').by_col("XP", self - 1).to_i
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
3
17
|
module NWN
|
4
18
|
module TwoDA
|
5
19
|
|
@@ -156,6 +170,37 @@ module NWN
|
|
156
170
|
column = column_name_to_id column
|
157
171
|
column.nil? ? @rows[row.to_i] : (@rows[row.to_i].nil? ? nil : @rows[row.to_i][column])
|
158
172
|
end
|
173
|
+
alias_method :[], :by_row
|
174
|
+
|
175
|
+
|
176
|
+
# Set a cell or row value.
|
177
|
+
#
|
178
|
+
# [+row+] The row to operate on (starts at 0)
|
179
|
+
# [+column+] Optional column name or index.
|
180
|
+
# [+value+] New value, either a full row, or a single value.
|
181
|
+
#
|
182
|
+
# Examples:
|
183
|
+
# TwoDA.get('portraits')[1, "BaseResRef"] = "hi"
|
184
|
+
# TwoDA.get('portraits')[1] = %w{1 2 3 4 5 6}
|
185
|
+
def []= row, column = nil, value = nil
|
186
|
+
if value.nil?
|
187
|
+
value = column
|
188
|
+
raise ArgumentError, "Expected array for setting a whole row" unless value.is_a?(Array)
|
189
|
+
end
|
190
|
+
|
191
|
+
if value.is_a?(Array)
|
192
|
+
raise ArgumentError, "Given array size does not match table columns (got: #{value.size}, want: #{self.columns.size})" unless value.size == self.columns.size
|
193
|
+
new_row = Row.new
|
194
|
+
new_row.concat(value.map {|x| x.to_s})
|
195
|
+
|
196
|
+
@rows[row] = new_row
|
197
|
+
|
198
|
+
else
|
199
|
+
col = column_name_to_id column
|
200
|
+
@rows[row][col] = value
|
201
|
+
|
202
|
+
end
|
203
|
+
end
|
159
204
|
|
160
205
|
|
161
206
|
# Retrieve data by column.
|
@@ -237,6 +282,11 @@ module NWN
|
|
237
282
|
end
|
238
283
|
end
|
239
284
|
|
285
|
+
# An alias for TwoDA::Cache.get
|
286
|
+
def self.get name
|
287
|
+
NWN::TwoDA::Cache.get(name)
|
288
|
+
end
|
289
|
+
|
240
290
|
# This is a simple 2da cache.
|
241
291
|
module Cache
|
242
292
|
@_cache = {}
|
@@ -250,6 +300,8 @@ module NWN
|
|
250
300
|
end
|
251
301
|
|
252
302
|
# Get the 2da file with the given name. +name+ is without extension.
|
303
|
+
# This being a cache, modifications to the returned Table will be reflected
|
304
|
+
# in further calls to Cache.get.
|
253
305
|
def self.get(name)
|
254
306
|
raise Exception,
|
255
307
|
"You need to set up the cache first through the environment variable NWN_LIB_2DA_LOCATION." unless
|
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.5
|
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-03-
|
12
|
+
date: 2009-03-16 00:00:00 +01:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|