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 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.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
@@ -13,10 +13,10 @@ end.parse!
13
13
 
14
14
  fail "Not enough arguments (try -h)." unless ARGV.size > 0
15
15
 
16
- $base_script = ARGV.shift
16
+ $SCRIPT = ARGV.shift
17
17
 
18
18
  begin
19
- NWN::Gff::Scripting.run_script(IO.read($base_script), nil, ARGV)
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
@@ -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
- $base_script = File.basename($script)
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)
@@ -6,7 +6,7 @@ require 'irb'
6
6
  require 'irb/completion'
7
7
 
8
8
  OptionParser.new do |o|
9
- o.banner = "Usage: nwn-gff-irb [file]"
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::Gff
42
- include NWN::TwoDA
41
+ include NWN
43
42
 
44
43
  if $file
45
44
  read($file)
@@ -72,7 +72,7 @@ module NWN
72
72
  }
73
73
 
74
74
  def self.guess_file_format(filename)
75
- extension = File.extname(filename)[1..-1]
75
+ extension = File.extname(filename.downcase)[1..-1]
76
76
  FileFormatGuesses[FileFormatGuesses.keys.select {|key| extension =~ key}[0]]
77
77
  end
78
78
 
@@ -82,4 +82,8 @@ module NWN::Gff::Struct
82
82
 
83
83
  super
84
84
  end
85
+
86
+ def to_s
87
+ "<NWN::Gff::Struct #{self.data_type}/#{self.data_version}, #{self.keys.size} fields>"
88
+ end
85
89
  end
@@ -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 "#{$base_script}: not emitting any data."
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 [$base_script, " on ", $options[:infile], ": ", *args].join("")
158
+ $stderr.puts [$SCRIPT, perc, " on ", $options[:infile], ": ", *args].join("")
128
159
  else
129
- $stderr.puts [$base_script, ": ", *args].join("")
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($base_script) + ": " + question + " "
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
@@ -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
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-09 00:00:00 +01:00
12
+ date: 2009-03-16 00:00:00 +01:00
13
13
  default_executable:
14
14
  dependencies: []
15
15