nwn-lib 0.3.6 → 0.4.0

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/BINARIES CHANGED
@@ -1,45 +1,40 @@
1
- == nwn-gff-print
2
-
3
- Usage: nwn-gff-print [options] file/- [file, file, ..]
4
- -y, --yaml Dump as yaml
5
- -k, --kivinen Dump as kivinens dump format (like the perl tools)
6
- --kivinen-full-path Print the full path (implies -k)
7
- -b, --print-basename Prefix the file basename to the output
8
- -f, --print-filename Prefix the full filename to the output
9
- -t, --print-types Print types as well
10
- -m, --marshal Native ruby marshalling. Warning: raw bytes
11
- --postfix P Write output to file postfixed with P instead of stdout
12
- --float_rounding F Round floating point numbers to the specified number of righthand digits
13
- --type filetype Override the file type (implies --struct 0xffffffff)
14
- --struct id Override struct id (as hex, please)
15
- -p, --path path Only print the given path
16
- -v, --verbose Be verbose
17
-
18
- This prints out the given file(s) (or stdin, if -) as the specified format (-y, -k, -m)
19
- [-k] is the same as gffprint.pl
20
- [-kt] is the same as gffprint.pl -t
21
- [-m] is the native ruby marshal format (see Marshal.dump(obj))
22
- [-y] is standard YAML
23
- [--postfix] will write out each processed file to the same directory as the infile, with the given postfix appended
24
- [--float_rounding] can be used to truncate FPs to the given precision.
25
- [-p] will print out a given path within the GFF data (for example <tt>/ItemList[2]</tt>)
26
-
27
- == nwn-gff-import
28
-
29
- Usage: nwn-gff-import [options] file/- [file, file, file]
30
- -y, --yaml Import as yaml
31
- -m, --marshal Import as native ruby marshal data
32
- -o, --outfile F Write to outfile instead of stdout
33
- --postfix P Strip the given postfix from file and write to that instead of stdout (overrides -o)
34
-
35
- This is the equivalent to gffencode.pl. This can be used to transform marshalled gff data back into gff binary data.
36
-
37
- Example (save to run on a shell, prints out hex data):
38
-
39
- nwn-gff-print -y my_item.uti | nwn-gff-import.rb -y - - | xxd
40
-
41
- == nwn-gff-irb
42
-
43
- Usage: nwn-gff-irb file
44
-
45
- nwn-gff-irb allows interactive editing of gff files. There are some examples on the CHEATSHEET.
1
+ == nwn-gff
2
+
3
+ A generic converter that can be used for converting gff files to and fro from various
4
+ file formats and presentations, and transform them with custom script filters.
5
+
6
+ Type
7
+ nwn-gff -h
8
+ for help, it should be self-explanatory.
9
+
10
+ There are some usage examples on the CHEATSHEET.
11
+
12
+ == nwn-irb
13
+
14
+ nwn-irb is a interactive shell preloading all relevant libs, and optionally
15
+ loading a gff file.
16
+
17
+ There are some usage examples on the CHEATSHEET.
18
+
19
+ == nwn-dsl
20
+
21
+ A standalone script interpreter. See the example scripts in the gem distribution
22
+ under scripts/.
23
+
24
+ == Things under tools/
25
+
26
+ These are not added to PATH, you'll have to specify their path explicitly; you can
27
+ find them in your gem repository (/usr/lib/ruby/1.8/gems/ or similar).
28
+
29
+ === migrate_03x_to_04x.sh
30
+
31
+ This can be used to migrate old YAML dumps made with version 0.3.x to the new,
32
+ compacter format of 0.4.x.
33
+
34
+ Usage is simple: just pass all old .yml files to the script, it will convert them
35
+ in-place (read: make a backup!).
36
+
37
+ This uses nwn-gff-convert and nwn-gff, so all environment variables are taken into
38
+ consideration. You will want to point NWN_LIB_INFER_DATA_FILE to something useful.
39
+
40
+ Backup and testing is ADVISED!
data/CHANGELOG CHANGED
@@ -105,3 +105,7 @@ Bernhard Stoeckner <elven@swordcoast.net> (5):
105
105
 
106
106
  Stuart Coyle <stuart.coyle@gmail.com> (1):
107
107
  TwoDA: use four spaces for field separation instead of tabs, indent columns
108
+
109
+ ==== 0.4.0
110
+ Bernhard Stoeckner <elven@swordcoast.net>:
111
+ too many to sanely list, see README for migration information
data/CHEATSHEET CHANGED
@@ -1,75 +1,9 @@
1
- ==== Extract item from creature inventory
1
+ ==== Convert all item files in the current directory to yaml and back
2
2
 
3
- nwn-gff-print --type UTI -kt -p 'ItemList[12]' creature.bic | gffencode.pl -o item.uti
3
+ for x in *.uti; do
4
+ nwn-gff-convert -i"$x" -o"$x.yml" -lg -ky
5
+ done
4
6
 
5
- ==== Convert all item files in the current directory to yaml
6
-
7
- nwn-gff-print -v -y --postfix .yml *.uti
8
-
9
- ==== Convert all yaml item files back to their gff counterpart
10
-
11
- nwn-gff-import -y --postfix .yml *.uti.yml
12
-
13
- ==== Makefile rules for building resources from yml files
14
-
15
- postfix := uti
16
-
17
- objects := $(basename $(wildcard *.$(postfix).yml))
18
-
19
- all: $(objects)
20
-
21
- $(objects) : %.$(postfix) : %.$(postfix).yml
22
- nwn-gff-import -y -o $@ $<
23
-
24
- clean:
25
- -@rm $(objects)
26
-
27
- This ruleset will automatically rebuild changed ymls to their respective .uti counterparts.
28
- This only serves as an example on how to do it; it does not constitute a complete build environment.
29
-
30
- ==== Quick-edit a item
31
-
32
- your/prompt$ nwn-gff-irb my_item.uti
33
- Your GFF file is in `GFF' (type: "UTI ").
34
- Type `save' to save to the filename it came from (make a backup!), `exit' (or Ctrl+D) to exit (without saving).
35
- To save to a different location, type `save "path/to/new/location.ext"'.
36
-
37
- irb(main):001:0> GFF.root_struct.keys
38
- => ["ModelPart2", "Cursed", "ModelPart3", "Cost", "StackSize", "Charges", "Comment", "PaletteID", "BaseItem", "Tag", "DescIdentified", "Identified", "Plot", "TemplateResRef", "PropertiesList", "AddCost", "Stolen", "Description", "LocalizedName", "ModelPart1"]
39
-
40
- irb(main):002:0> GFF['LocalizedName/4']
41
- => "Mundane Feuerpfeile (aus Eibe)"
42
-
43
- irb(main):003:0> GFF['LocalizedName/4'] = 'New Name'
44
- => "New Name"
45
-
46
- irb(main):004:0> GFF['LocalizedName']
47
- => #<NWN::Gff::Element:0xb790641c @type=:cexolocstr, @value=[#<struct NWN::Gff::CExoLocString language=4, text="New Name">, #<struct NWN::Gff::CExoLocString language=0, text="Pfeil">], @_str_ref=1517, @label="LocalizedName">
48
-
49
- irb(main):005:0> save
50
- Saving to `/home/elven/code/nwn/nwn-lib.git/my_item.uti' ..
51
- saved.
52
- => nil
53
-
54
- irb(main):006:0> exit
55
-
56
- ==== Add a item property, the semi-human way
57
-
58
- irb(main):001:0> Helpers.item_property('Cast_Spell')
59
- ArgumentError: Property Cast_Spell needs subtype of type IPRP_SPELLS, but none given.
60
- from /var/lib/gems/1.8/gems/nwn-lib-0.2.3/lib/nwn/helpers.rb:108:in `item_property'
61
- from (irb):1
62
-
63
- irb(main):002:0> Helpers.item_property('Cast_Spell', 'Invisib')
64
- ArgumentError: Cannot resolve invisib. Partial matches: ["Improved_Invisibility", "Invisibility", "Invisibility_Purge", "Invisibility_Sphere", "See_Invisibility"].
65
- from /var/lib/gems/1.8/gems/nwn-lib-0.2.3/lib/nwn/helpers.rb:79:in `resolve_or_match_partial'
66
- from /var/lib/gems/1.8/gems/nwn-lib-0.2.3/lib/nwn/helpers.rb:116:in `item_property'
67
- from (irb):2
68
-
69
- irb(main):003:0> Helpers.item_property('Cast_Spell', 'Invisibility')
70
- ArgumentError: Property Cast_Spell requires a cost value of type IPRP_CHARGECOST, but none given
71
- from /var/lib/gems/1.8/gems/nwn-lib-0.2.3/lib/nwn/helpers.rb:122:in `item_property'
72
- from (irb):3
73
-
74
- irb(main):004:0> Helpers.item_property('Cast_Spell', 'Invisibility', 'Unlimi')
75
- => {"PropertyName"=>#<NWN::Gff::Element:0xb75f4e68 ..
7
+ for x in *.uti.yml; do
8
+ nwn-gff-convert -i"$x" -o"$(basename $x .yml)" -ly -kg
9
+ done
data/COPYING CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (C) 2008 Bernhard Stoeckner <elven@swordcoast.net>
1
+ Copyright (C) 2008 Bernhard Stoeckner <elven@swordcoast.net> and contributors
2
2
 
3
3
  This program is free software; you can redistribute it and/or modify
4
4
  it under the terms of the GNU General Public License as published by
@@ -0,0 +1,50 @@
1
+ == Internal data representation
2
+
3
+ All data is representend internally as simple hashes or arrays. On load,
4
+ each structure will be extended by a representing module containing
5
+ the API and some application logic.
6
+
7
+ * Structs are normal hashes extended by NWN::Gff::Struct
8
+ * Lists are arrays extended by NWN::Gff::List
9
+ * Fields are normal hashes extended by NWN::Gff::Field
10
+ * CExoLocStrings are normal hashes extended by NWN::Gff::CExoLocString
11
+
12
+
13
+ === Struct
14
+
15
+ Example:
16
+ "/AddCost" => {"value" => 5, "label" => "AddCost", "type" => :dword}
17
+
18
+ Also, a NWN::Gff::Struct also has these accessors:
19
+
20
+ * data_type: A string describing the data type of this struct. (see Data Type)
21
+ * data_version: A string describing the version (usually "V3.2")
22
+ * struct_id: the struct Id of this struct.
23
+ * element: The NWN::Gff::Field which this struct contains. This is nil
24
+ for root structs.
25
+
26
+
27
+ === Field
28
+
29
+ Each field is a hash containing two keys:
30
+ "value": The data contained in this field, depending on
31
+ "type": The data type. For known data types, see NWN::Gff::Gff.
32
+
33
+ Additionally, "label" is a key set by the Readers saying its' label name.
34
+ This key, however, will not be written out to YAML (since it would be
35
+ redundant).
36
+
37
+ Also, each field has a .parent, which is a simple accessor set by
38
+ the various readers pointing to the struct it is member of.
39
+
40
+
41
+ === Data Type
42
+
43
+ Each Struct has a data_type, which describes the type of data the struct contains.
44
+ For top-level structs, this equals the data type written to the GFF file ("UTI",
45
+ for example); for sub structures, this is usually the top-level data type + the
46
+ field label ("UTI/PropertiesList", for example). This is used by various loaders/writers
47
+ to infer field types and default values.
48
+
49
+ This also means that inventory items in /ItemList/ structs have a type of "UTI" and
50
+ thus could be exported to item files, or re-attached somewhere else with minimum scripting.
data/README CHANGED
@@ -4,55 +4,45 @@ This package provides a library for reading, changing, and writing common file f
4
4
 
5
5
  They should work with NWN2 just as well, since the file format specifications did not change.
6
6
 
7
- There are various things included in this distribution:
8
- * some binaries under bin/ (see BINARIES)
9
- * the actual library under lib/nwn
7
+ === Upgrade from 0.3.6 to 0.4.x
10
8
 
11
- == Attention Unicode/UTF-users
9
+ 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.
10
+ I can't help you with your API bindings, but for your YAML dumps, a converter script has been provided (see BINARIES).
12
11
 
13
- ruby 1.8 does not support character sets natively, and as such nwn-gff-irb will <b>FAIL</b> to encode non-standard characters properly on non-latin1 shells.
14
- This will be worked around in a future release until the release of ruby 1.9, which will provide native charset support.
15
-
16
- == Quickstart
12
+ === A word on version numbers
17
13
 
18
- It is easiest to just use the gem, which is available through rubyforge (<tt>sudo gem install nwn-lib</tt>).
14
+ Please consider all version releases below 1.0.0 to be unstable, even though the code is fully functional - further API changes may not be avoidable between major revisions - such as is the case with 0.3 -> 0.4.
19
15
 
20
- As an alternative, fetch the latest development files with git[http://git.swordcoast.net/?p=nwn/nwn-lib.git;a=summary].
21
-
22
- require 'rubygems'
23
- require 'nwn/gff'
16
+ === Features of nwn-lib
24
17
 
25
- # Read a GFF file
26
- o = NWN::Gff::Reader.read(IO.read('/tmp/test-creature.gff'))
18
+ * a feature-complete parser and generator of valid GFF V3.2 data
19
+ * shell scripts and tools to simplify your life (see BINARIES)
20
+ * kivinen-style ("gffprint.pl") presentation of data
21
+ * yaml presentation of data
22
+ * ruby-native marshalling of gff data
23
+ * extensive developer API
24
+ * a powerful get-out-of-my-way scripting system for data transformation (see SCRIPTING)
25
+ * guessing of field-types and -values for shorter plaintext data dumps (see TYPE_AND_VALUE_INFERRING)
27
26
 
28
- # Do some modifications to it
29
- o['/Tag'] = 'testtag'
27
+ Also in the box:
30
28
 
31
- # And write it somewhere else
32
- bytes = NWN::Gff::Writer.dump(o)
29
+ * a CHEATSHEET showing off some cool tricks
30
+ * some gadgetry for working with 2da files
33
31
 
34
- File.open('/tmp/test-creature-2.gff', 'w') {|f| f.write(bytes) }
32
+ === Attention Unicode/UTF-users
35
33
 
36
- Modification API is fairly limited, for now, but will improve soon.
37
-
38
- == GFF data structures: Quick Intro
34
+ ruby 1.8 does not support character sets natively, and as such nwn-gff-irb will <b>FAIL</b> to encode non-standard characters properly on non-latin1 shells.
35
+ This will be worked around in a future release until the release of ruby 1.9, which will provide native charset support.
39
36
 
40
- Ruby GFF data structures are nearly a 1:1 wrapper around the known format.
37
+ === Quickstart
41
38
 
42
- Each GFF object has a root structure with a +struct_id+ of 0.
39
+ To use it, simply install the gem (available on rubyforge):
43
40
 
44
- === Label
45
- A Label is a string of up to 16 bytes, and occurs as keys in Structs.
41
+ gem1.8 install nwn-lib
46
42
 
47
- === Struct
48
- A struct is a hash. It is a unordered collection of key => value pairs.
49
- Keys are Labels, values are either:
50
- * Structs
51
- * Lists
52
- * Elements
43
+ And do the following in a script of your own devising:
53
44
 
54
- === List
55
- A list is an *ordered* array of Structs.
45
+ require 'rubygems'
46
+ require 'nwn/all'
56
47
 
57
- === Element
58
- A Element is a distinct value of a given type. For all possible types, see the +Types+ hash in the NWN::Gff module.
48
+ For nwn-lib scripts, see SCRIPTING.
data/Rakefile CHANGED
@@ -9,16 +9,18 @@ include FileUtils
9
9
  # Configuration
10
10
  ##############################################################################
11
11
  NAME = "nwn-lib"
12
- VERS = "0.3.6"
12
+ VERS = "0.4.0"
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', \
16
16
  '--main', 'README']
17
17
 
18
+ DOCS = ["README", "BINARIES", "DATA_STRUCTURES", "SCRIPTING", "SETTINGS", "TYPE_VALUE_INFERRING", "CHEATSHEET", "CHANGELOG", "COPYING"]
19
+
18
20
  Rake::RDocTask.new do |rdoc|
19
21
  rdoc.rdoc_dir = "rdoc"
20
22
  rdoc.options += RDOC_OPTS
21
- rdoc.rdoc_files.add ["README", "BINARIES", "CHEATSHEET", "CHANGELOG", "COPYING", "doc/*.rdoc", "lib/**/*.rb"]
23
+ rdoc.rdoc_files.add DOCS + ["doc/*.rdoc", "lib/**/*.rb"]
22
24
  end
23
25
 
24
26
  desc "Packages up nwn-lib"
@@ -30,16 +32,16 @@ spec = Gem::Specification.new do |s|
30
32
  s.version = VERS
31
33
  s.platform = Gem::Platform::RUBY
32
34
  s.has_rdoc = true
33
- s.extra_rdoc_files = ["README", "BINARIES", "CHEATSHEET", "CHANGELOG", "COPYING"] + Dir["doc/*.rdoc"]
35
+ s.extra_rdoc_files = DOCS + Dir["doc/*.rdoc"]
34
36
  s.rdoc_options += RDOC_OPTS + ["--exclude", "^(examples|extras)\/"]
35
37
  s.summary = "a ruby library for accessing Neverwinter Nights resource files"
36
38
  s.description = s.summary
37
39
  s.author = "Bernhard Stoeckner"
38
40
  s.email = "elven@swordcoast.net"
39
41
  s.homepage = "http://nwn-lib.elv.es"
40
- s.executables = ["nwn-gff-print", "nwn-gff-irb", "nwn-gff-import"]
42
+ s.executables = ["nwn-gff", "nwn-dsl", "nwn-irb"]
41
43
  s.required_ruby_version = ">= 1.8.4"
42
- s.files = %w(COPYING CHANGELOG README Rakefile) + Dir.glob("{bin,doc,spec,lib}/**/*")
44
+ s.files = %w(COPYING CHANGELOG README Rakefile) + Dir.glob("{bin,doc,spec,lib,tools,scripts,data}/**/*")
43
45
  s.require_path = "lib"
44
46
  s.bindir = "bin"
45
47
  end
@@ -0,0 +1,44 @@
1
+ To help you manage your NWN data more efficiently, nwn-lib supports
2
+ user-written, small (or large) scripts that follow the unix principle
3
+ of piping.
4
+
5
+ === Filter Scripts
6
+
7
+ Filter Scripts act as an argument to nwn-gff, and will be invoked
8
+ as a pass-through for data filtering and transformation.
9
+ Filters always depend on self being a Gff element.
10
+
11
+ An example of a filter script would be a snippet, that truncates
12
+ all floating points to a fixed size before outputting them to yaml.
13
+
14
+ Filter scripts are usually not executable by themself.
15
+
16
+ === Standalone Scripts
17
+
18
+ Standalone scripts are shell scripts invokable from command line,
19
+ and do not operate on specific files; instead, they get invoked
20
+ with their own (optional) parameters and act independently of
21
+ data sources.
22
+
23
+ An example for a standalone script would be a script, that asks
24
+ the user for a name and then generates a random item from that.
25
+
26
+ You can create standalone scripts by prefixing them with the proper
27
+ shebang:
28
+
29
+ #!/usr/bin/env nwn-dsl
30
+
31
+ If you are on systems which do not support executable scripts this
32
+ way, simply call them with nwn-dsl.
33
+
34
+ DSL stands for domain-specific-language by the way, and this is quite
35
+ a stretch, considering your scripts will be written in plain old ruby.
36
+
37
+ === API
38
+
39
+ There are various helpers available to scripts. See NWN::Gff::Scripting
40
+ for a list of helper methods; additionally you can use all other API
41
+ functions, of course.
42
+
43
+ There are some examples packaged together with nwn-lib, check the scripts/
44
+ directory with the distribution.
@@ -0,0 +1,80 @@
1
+ There are various environment variables you can configure to adjust various parts of nwn-lib.
2
+
3
+ <b>All of them are optional!</b>
4
+
5
+ Under linux, just add them to your shell environment (usually .bashrc), like so:
6
+
7
+ export NWN_LIB_INFER_DATA_FILE=/usr/lib/ruby/gems/1.8/gems/nwn-lib-0.4.0/data/gff-common-nwn1.yaml
8
+
9
+
10
+ == NWN_LIB_INFER_DATA_FILE
11
+
12
+ The path to the type/value inferring data file. See TYPE_VALUE_INFERRING for a definition.
13
+
14
+ Please be advised that inferring support for YAML is <b>EXPERIMENTAL</b> and may result in
15
+ <b>module and gff file corruption</b>.
16
+
17
+ == NWN_LIB_DONT_COMPACT_FIELDS
18
+
19
+ Set to non-nil ("1" will do) to prevent nwn-lib from compacting scalar fields into a more-readable
20
+ (but still fully parseable) format, if type inferring data is available.
21
+
22
+ === Without compacting
23
+ ItemList:
24
+ value:
25
+ - !nwn-lib.elv.es,2008-12/struct
26
+ __data_type: UTC/ItemList
27
+ __struct_id: 0
28
+ InventoryRes: {value: herb053}
29
+ PaletteID: {value: 6}
30
+ SkillList: [{value: 0}, {value: 0}, {value: 0}, {value: 0}, ...
31
+
32
+ === With compacting
33
+ ItemList:
34
+ - !nwn-lib.elv.es,2008-12/struct
35
+ __data_type: UTC/ItemList
36
+ InventoryRes: herb053
37
+ PaletteID: 6
38
+ SkillList: [0, 0, 0, 0, 0, 0, 2, 0, 0, 0 ...
39
+
40
+
41
+ == NWN_LIB_DONT_COMPACT_LIST_STRUCTS
42
+
43
+ Setting this to non-nil ("1" will do) will prevent nwn-lib from compacting lists that contain
44
+ structs, if type inferring data is available.
45
+
46
+ === Without compacting
47
+ SkillList:
48
+ - !nwn-lib.elv.es,2008-12/struct {__data_type: UTC/SkillList, Rank: 0}
49
+ - !nwn-lib.elv.es,2008-12/struct {__data_type: UTC/SkillList, Rank: 0}
50
+ - !nwn-lib.elv.es,2008-12/struct {__data_type: UTC/SkillList, Rank: 0}
51
+ - !nwn-lib.elv.es,2008-12/struct {__data_type: UTC/SkillList, Rank: 0}
52
+ - !nwn-lib.elv.es,2008-12/struct {__data_type: UTC/SkillList, Rank: 0}
53
+ - !nwn-lib.elv.es,2008-12/struct {__data_type: UTC/SkillList, Rank: 0}
54
+ - !nwn-lib.elv.es,2008-12/struct {__data_type: UTC/SkillList, Rank: 2}
55
+ - !nwn-lib.elv.es,2008-12/struct {__data_type: UTC/SkillList, Rank: 0}
56
+ ...
57
+
58
+ === With compacting
59
+ SkillList: [0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, ...
60
+
61
+
62
+ == NWN_LIB_CLEAR_KNOWN_VALUES
63
+
64
+ Set to non-nil ("1" will do) to make nwn-lib omit fields that resolve to default values
65
+ as configured in $NWN_LIB_INFER_DATA_FILE.
66
+
67
+ The default is to not omit known-value data fields.
68
+
69
+ == NWN_LIB_FILTER_EMPTY_EXOLOCSTR
70
+
71
+ Set to non-nil ("1" will do) to make nwn-lib filter out empty exolocstr fields from
72
+ input files on reading.
73
+
74
+ The default is to keep them as-is.
75
+
76
+ == NWN_LIB_2DA_LOCATION
77
+
78
+ Set to a path containing all 2da files to initialize the 2da cache. This is needed for
79
+ most interactive helpers and a few type infer gizmos.
80
+