god_of_thunder_save 0.1.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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 74bde38607234354dc3556e6dba0713cde6060e56afc2d2df8e1eccbdabd86ce
4
+ data.tar.gz: 4f67dc2960aa4cb95d8d4ba42dd7b56f012bb44d447291a2f71eb33833d550f4
5
+ SHA512:
6
+ metadata.gz: 496d5f044edcc720b8d8495c01e1c18b549aa4eebe8a5d59ee327086352b834c16aabb2cffe90ba0ed7b02bb7d6daf9b3290f56d845170dc1a36ffd9d5272c2b
7
+ data.tar.gz: 35b930b2f840f901c10939c9a46fdd7f3820eef6b6688526330afed785bd3cda5f6fa46851f91facfdf5c3202a6f5adca6f1159a15d2dea44b216088f209e436
@@ -0,0 +1,33 @@
1
+ class GodOfThunderSave
2
+ class BitmaskValue
3
+ attr_reader :pos, :bitmask
4
+
5
+ def initialize(pos:, bitmask:)
6
+ @pos = pos
7
+ @bitmask = bitmask
8
+ end
9
+
10
+ def read(file)
11
+ file.seek(pos)
12
+ byte = file.readbyte
13
+
14
+ byte & bitmask > 0
15
+ end
16
+
17
+ def write(file, data)
18
+ file.seek(pos)
19
+ byte = file.readbyte
20
+
21
+ byte &= inverted_bitmask
22
+ byte += bitmask if data
23
+ byte = [byte].pack("C")
24
+
25
+ file.seek(pos)
26
+ file.write(byte)
27
+ end
28
+
29
+ def inverted_bitmask
30
+ @inverted_bitmask ||= bitmask ^ 0xff
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,36 @@
1
+ class GodOfThunderSave
2
+ class IntegerValue
3
+ INTEGER_DIRECTIVES = {
4
+ 1 => "C",
5
+ 2 => "v",
6
+ 4 => "V"
7
+ }.freeze
8
+
9
+ attr_reader :pos, :bytes
10
+
11
+ def initialize(pos:, bytes:)
12
+ @pos = pos
13
+ @bytes = bytes
14
+ end
15
+
16
+ def read(file)
17
+ file.seek(pos)
18
+
19
+ bytes_read = file.read(bytes)
20
+ bytes_read.unpack(integer_directive).first
21
+ end
22
+
23
+ def write(file, data)
24
+ bytes_write = [data].pack(integer_directive)
25
+
26
+ file.seek(pos)
27
+ file.write(bytes_write)
28
+ end
29
+
30
+ private
31
+
32
+ def integer_directive
33
+ @integer_directive ||= INTEGER_DIRECTIVES.fetch(bytes)
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,30 @@
1
+ class GodOfThunderSave
2
+ class StringValue
3
+ attr_reader :pos, :length
4
+
5
+ def initialize(pos:, length:)
6
+ @pos = pos
7
+ @length = length
8
+ end
9
+
10
+ def read(file)
11
+ file.seek(pos)
12
+ string = file.read(length)
13
+
14
+ string.strip
15
+ end
16
+
17
+ def write(file, string)
18
+ formatted_string = pad_and_truncate(string)
19
+
20
+ file.seek(pos)
21
+ file.write(formatted_string)
22
+ end
23
+
24
+ private
25
+
26
+ def pad_and_truncate(string)
27
+ string[0..length - 1].ljust(length, "\0")
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,57 @@
1
+ require "god_of_thunder_save/bitmask_value"
2
+ require "god_of_thunder_save/integer_value"
3
+ require "god_of_thunder_save/string_value"
4
+
5
+ class GodOfThunderSave
6
+ ENTRIES = {
7
+ name: StringValue.new(pos: 0, length: 22),
8
+ health: IntegerValue.new(pos: 0x63, bytes: 1),
9
+ magic: IntegerValue.new(pos: 0x64, bytes: 1),
10
+ jewels: IntegerValue.new(pos: 0x65, bytes: 2),
11
+ keys: IntegerValue.new(pos: 0x67, bytes: 1),
12
+ score: IntegerValue.new(pos: 0x70, bytes: 4),
13
+ enchanted_apple: BitmaskValue.new(pos: 0x69, bitmask: 0x01),
14
+ lightning_power: BitmaskValue.new(pos: 0x69, bitmask: 0x02),
15
+ winged_boots: BitmaskValue.new(pos: 0x69, bitmask: 0x04),
16
+ wind_power: BitmaskValue.new(pos: 0x69, bitmask: 0x08),
17
+ amulet_of_protection: BitmaskValue.new(pos: 0x69, bitmask: 0x10),
18
+ thunder_power: BitmaskValue.new(pos: 0x69, bitmask: 0x20)
19
+ }.freeze
20
+
21
+ attr_reader :path
22
+ ENTRIES.keys.each { |entry| attr_accessor entry }
23
+
24
+ def initialize(path)
25
+ @path = path
26
+
27
+ read!
28
+ end
29
+
30
+ def attributes
31
+ ENTRIES.keys.each_with_object({}) do |entry_name, hash|
32
+ hash[entry_name] = instance_variable_get(:"@#{entry_name}")
33
+ end
34
+ end
35
+
36
+ def write!
37
+ File.open(path, File::RDWR) do |file|
38
+ ENTRIES.each do |entry_name, entry|
39
+ memory_value = instance_variable_get(:"@#{entry_name}")
40
+ entry.write(file, memory_value)
41
+ end
42
+ end
43
+
44
+ self
45
+ end
46
+
47
+ def read!
48
+ File.open(path) do |file|
49
+ ENTRIES.each do |entry_name, entry|
50
+ file_value = entry.read(file)
51
+ instance_variable_set(:"@#{entry_name}", file_value)
52
+ end
53
+ end
54
+
55
+ self
56
+ end
57
+ end
metadata ADDED
@@ -0,0 +1,46 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: god_of_thunder_save
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Maxwell Pray
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2022-08-13 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Read and write to God of Thunder saved games as models
14
+ email: synthead@gmail.com
15
+ executables: []
16
+ extensions: []
17
+ extra_rdoc_files: []
18
+ files:
19
+ - lib/god_of_thunder_save.rb
20
+ - lib/god_of_thunder_save/bitmask_value.rb
21
+ - lib/god_of_thunder_save/integer_value.rb
22
+ - lib/god_of_thunder_save/string_value.rb
23
+ homepage: https://github.com/synthead/god_of_thunder_save
24
+ licenses:
25
+ - MIT
26
+ metadata: {}
27
+ post_install_message:
28
+ rdoc_options: []
29
+ require_paths:
30
+ - lib
31
+ required_ruby_version: !ruby/object:Gem::Requirement
32
+ requirements:
33
+ - - ">="
34
+ - !ruby/object:Gem::Version
35
+ version: '0'
36
+ required_rubygems_version: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ requirements: []
42
+ rubygems_version: 3.3.7
43
+ signing_key:
44
+ specification_version: 4
45
+ summary: God of Thunder saved game editor
46
+ test_files: []