nwn-lib 0.4.4 → 0.4.5
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
|