gen3_pokeedit 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 76cb20ee1ee5ea208ecacae5246c35b69403fb3c
4
+ data.tar.gz: 5f5915df7e49134065dcfcfbbec015594fe90dbf
5
+ SHA512:
6
+ metadata.gz: b3194a78ff66da10e7bd34e86a881190eae6bd386250e505d1984ed99b2cff80caa937bebc71857d7b89e4729278af6973fc451a2e4f23cbeaeb0e19ae3594d2
7
+ data.tar.gz: 4343f0d4ad5ad0b79f376b913b904fea0fecd9603f23da832aab86365dc2e9375f3c78fc48c3a7b8d27fd965c86a295419cf7a80ec2d32ff2c14c1a6c5883670
data/.Gemfile.swp ADDED
Binary file
Binary file
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/.travis.yml ADDED
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.2.1
4
+ before_install: gem install bundler -v 1.10.6
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in gen3_pokeedit.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015 RainbowReich
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,41 @@
1
+ # Gen3Pokeedit
2
+
3
+ Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/gen3_pokeedit`. To experiment with that code, run `bin/console` for an interactive prompt.
4
+
5
+ TODO: Delete this and the text above, and describe your gem
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'gen3_pokeedit'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install gen3_pokeedit
22
+
23
+ ## Usage
24
+
25
+ TODO: Write usage instructions here
26
+
27
+ ## Development
28
+
29
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake false` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
30
+
31
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
32
+
33
+ ## Contributing
34
+
35
+ Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/gen3_pokeedit.
36
+
37
+
38
+ ## License
39
+
40
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
41
+
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "gen3_pokeedit"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
data/bin/setup ADDED
@@ -0,0 +1,7 @@
1
+ #!/bin/bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+
5
+ bundle install
6
+
7
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,29 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'gen3_pokeedit/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "gen3_pokeedit"
8
+ spec.version = Gen3PokeEdit::VERSION
9
+ spec.authors = ["RainbowReich"]
10
+ spec.email = ["rainbowryke@gmail.com"]
11
+
12
+ spec.summary = %q{Gen3PokeEdit is a gem for viewing and editing save files from Pokemon Ruby, Sapphire, Emerald, Firered, and Leafgreen versions.}
13
+ spec.license = "MIT"
14
+
15
+ # Prevent pushing this gem to RubyGems.org by setting 'allowed_push_host', or
16
+ # delete this section to allow pushing this gem to any host.
17
+ if spec.respond_to?(:metadata)
18
+ else
19
+ raise "RubyGems 2.0 or newer is required to protect against public gem pushes."
20
+ end
21
+
22
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
23
+ spec.bindir = "exe"
24
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
25
+ spec.require_paths = ["lib"]
26
+
27
+ spec.add_development_dependency "bundler", "~> 1.10"
28
+ spec.add_development_dependency "rake", "~> 10.0"
29
+ end
Binary file
@@ -0,0 +1,4 @@
1
+ require "gen3_pokeedit/version"
2
+
3
+ require "gen3_pokeedit/Gen3PokemonStruct"
4
+ require "gen3_pokeedit/Gen3PokemonSaveLoader"
Binary file
@@ -0,0 +1,27 @@
1
+ module ByteCompiler
2
+ def compile_bytes(*dat)
3
+ total_value = 0
4
+ dat = dat[0]
5
+ dat.each_index do |i|
6
+ total_value += dat[i] << (8*i)
7
+ end
8
+ return total_value
9
+ end
10
+
11
+ def decompile_bytes(value, num_bytes)
12
+ total_array = Array.new
13
+ num_bytes.times do |i|
14
+ total_array << ((value & (0xFF << 8*i)) >> 8*i)
15
+ end
16
+ return total_array
17
+ end
18
+
19
+ def set_bit(value, bit)
20
+ value = value | (1 << bit)
21
+ end
22
+
23
+ def unset_bit(value, bit)
24
+ value = value & !(1 << bit)
25
+ end
26
+
27
+ end
@@ -0,0 +1,150 @@
1
+ require_relative "Gen3PokemonStruct"
2
+ require_relative "ByteCompiler"
3
+
4
+ class Gen3PokemonSaveLoader
5
+
6
+ include ByteCompiler
7
+
8
+ def initialize(file = nil)
9
+ @game = nil
10
+ return if file.nil?
11
+ load_save(file)
12
+ detect_game_version
13
+ end
14
+
15
+ def load_save(file)
16
+ @save = File.new(file,"r+b")
17
+ end
18
+
19
+ def close
20
+ @save.close
21
+ end
22
+
23
+ def get_section_loc(id)
24
+ raise "Save file not loaded" if game.nil?
25
+ case id
26
+ when 0
27
+ if @game == :rs
28
+ return 0
29
+ elsif @game == :frlg
30
+ return 0
31
+ elsif @game == :e
32
+ return 0
33
+ end
34
+ when 1
35
+ if @game == :rs
36
+ return 0x234
37
+ elsif @game == :frlg
38
+ return 0x234
39
+ elsif @game == :e
40
+ return 0x34
41
+ end
42
+ end
43
+ end
44
+
45
+ def calculate_section_checksum(id)
46
+ num_data = 0
47
+ case id
48
+ when 0
49
+ num_data = 3884
50
+ when 1
51
+ num_data = 3968
52
+ end
53
+ @save.pos = find_section(id)
54
+ calc_checksum = 0
55
+ num_data.times do |i|
56
+ if i%4==0
57
+ calc_checksum += compile_bytes([@save.readbyte,@save.readbyte,@save.readbyte,@save.readbyte])
58
+ end
59
+ end
60
+ calc_checksum = (((calc_checksum&0xFFFF0000)>>16) + (calc_checksum&0xFFFF)) & 0xFFFF
61
+ @save.pos = find_section(id) + 0xFF6
62
+ @save.pos = find_section(id) + 0xFF6
63
+ @save.putc (calc_checksum&0xFF)
64
+ @save.putc ((calc_checksum&0xFF00)>>8)
65
+ end
66
+
67
+ def get_team_size
68
+ @save.pos = find_section(1)
69
+ return @save.readbyte
70
+ end
71
+
72
+ def set_team_size(val)
73
+ @save.pos = find_section(1)
74
+ @save.putc (val&7)
75
+ end
76
+
77
+ def get_team_pokemon(id)
78
+ @save.pos = find_section(1) + get_section_loc(1) + 4 + ((id-1)*100)
79
+ temp_pks = Gen3PokemonStruct.new
80
+ 100.times do |i|
81
+ temp_pks.pdata[i] = @save.readbyte
82
+ end
83
+ return temp_pks
84
+ end
85
+
86
+ def put_team_pokemon(id, pks)
87
+ @save.pos = find_section(1) + get_section_loc(1) + 4 + ((id-1)*100)
88
+ 100.times do |i|
89
+ if pks.pdata[i] != nil
90
+ @save.putc pks.pdata[i]
91
+ else
92
+ @save.pos = @save.pos + 1
93
+ end
94
+ end
95
+ calculate_section_checksum(1)
96
+ end
97
+
98
+ def find_section(id)
99
+ cur_id = 255
100
+ @save.pos = find_recent_save + 0xFF4
101
+ while cur_id != id
102
+ cur_id = @save.readbyte
103
+ @save.pos += 0x1000 - 1
104
+ end
105
+ return @save.pos - 0x1000 - 0xFF4
106
+ end
107
+
108
+ def find_recent_save
109
+ @save.pos = 0xFFC
110
+ game_a = 0
111
+ game_b = 0
112
+ 4.times do |i|
113
+ game_a += (@save.readbyte << 8*i)
114
+ end
115
+ @save.pos = 0xEFFC
116
+ 4.times do |i|
117
+ game_b += (@save.readbyte << 8*i)
118
+ end
119
+ game_a == 0xFFFFFFFF ? game_a = 0 : game_b == 0xFFFFFFFF ? game_b = 0 : 0
120
+ if game_a > game_b
121
+ return 0
122
+ else
123
+ return 0xE000
124
+ end
125
+ end
126
+
127
+ def detect_game_version
128
+ @save.pos = find_section(0) + 0xAC
129
+ tempdata = 0
130
+ 4.times do
131
+ tempdata << 8
132
+ tempdata | @save.readbyte
133
+ end
134
+
135
+ puts tempdata
136
+ case tempdata
137
+ when 0
138
+ @game = :rs
139
+ when 1
140
+ @game = :frlg
141
+ else
142
+ @game = :e
143
+ end
144
+ puts @game.to_s
145
+ return tempdata
146
+ end
147
+
148
+ end
149
+
150
+
@@ -0,0 +1,504 @@
1
+ require_relative 'ByteCompiler'
2
+ require_relative 'TextConverter'
3
+
4
+ class Gen3PokemonStruct
5
+
6
+ include ByteCompiler
7
+
8
+ def initialize
9
+ @pdata = Array.new(100,0)
10
+ @block_g = 32; @block_a = 44; @block_e = 56; @block_m = 68
11
+ end
12
+
13
+ def pdata
14
+ return @pdata
15
+ end
16
+
17
+ def generate_block_order #Call this after changing the PID of a Gen3PokemonStruct
18
+ g = @pdata[@block_g,12]
19
+ a = @pdata[@block_a,12]
20
+ m = @pdata[@block_m,12]
21
+ e = @pdata[@block_e,12]
22
+ calculate_block_order
23
+ @pdata[@block_g,12] = g
24
+ @pdata[@block_a,12] = a
25
+ @pdata[@block_m,12] = m
26
+ @pdata[@block_e,12] = e
27
+ return self
28
+ end
29
+
30
+ def calculate_block_order #Call this before editing any properties of a Gen3PokemonStruct
31
+ case (pid % 24)
32
+ when 0
33
+ @block_g = 32; @block_a = 44; @block_e = 56; @block_m = 68
34
+ when 1
35
+ @block_g = 32; @block_a = 44; @block_e = 68; @block_m = 56
36
+ when 2
37
+ @block_g = 32; @block_a = 56; @block_e = 44; @block_m = 68
38
+ when 3
39
+ @block_g = 32; @block_a = 68; @block_e = 44; @block_m = 56
40
+ when 4
41
+ @block_g = 32; @block_a = 56; @block_e = 68; @block_m = 44
42
+ when 5
43
+ @block_g = 32; @block_a = 68; @block_e = 56; @block_m = 44
44
+ when 6
45
+ @block_g = 44; @block_a = 32; @block_e = 56; @block_m = 68
46
+ when 7
47
+ @block_g = 44; @block_a = 32; @block_e = 68; @block_m = 56
48
+ when 8
49
+ @block_g = 56; @block_a = 32; @block_e = 44; @block_m = 68
50
+ when 9
51
+ @block_g = 68; @block_a = 32; @block_e = 44; @block_m = 56
52
+ when 10
53
+ @block_g = 44; @block_a = 32; @block_e = 68; @block_m = 44
54
+ when 11
55
+ @block_g = 68; @block_a = 32; @block_e = 56; @block_m = 44
56
+ when 12
57
+ @block_g = 44; @block_a = 56; @block_e = 32; @block_m = 68
58
+ when 13
59
+ @block_g = 44; @block_a = 68; @block_e = 32; @block_m = 56
60
+ when 14
61
+ @block_g = 56; @block_a = 44; @block_e = 32; @block_m = 68
62
+ when 15
63
+ @block_g = 68; @block_a = 44; @block_e = 32; @block_m = 56
64
+ when 16
65
+ @block_g = 56; @block_a = 68; @block_e = 32; @block_m = 44
66
+ when 17
67
+ @block_g = 68; @block_a = 56; @block_e = 32; @block_m = 44
68
+ when 18
69
+ @block_g = 44; @block_a = 56; @block_e = 68; @block_m = 32
70
+ when 19
71
+ @block_g = 44; @block_a = 68; @block_e = 56; @block_m = 32
72
+ when 20
73
+ @block_g = 56; @block_a = 44; @block_e = 68; @block_m = 32
74
+ when 21
75
+ @block_g = 68; @block_a = 44; @block_e = 56; @block_m = 32
76
+ when 22
77
+ @block_g = 56; @block_a = 68; @block_e = 44; @block_m = 32
78
+ when 23
79
+ @block_g = 68; @block_a = 56; @block_e = 44; @block_m = 32
80
+ end
81
+ return self
82
+ end
83
+
84
+ def pid
85
+ return compile_bytes(@pdata[0,4])
86
+ end
87
+
88
+ def pid=(value)
89
+ @pdata[0,4] = decompile_bytes(value, 4)
90
+ end
91
+
92
+ def otid
93
+ return compile_bytes(@pdata[4,2])
94
+ end
95
+
96
+ def secretid
97
+ return compile_bytes(@pdata[6,2])
98
+ end
99
+
100
+ def secretid=(value)
101
+ @pdata[6,2] = decompile_bytes(value,2)
102
+ end
103
+
104
+ def shiny?
105
+ return (((((otid) ^ secretid) ^ (pid & 0xFFFF0000)>>16) ^ pid & 0xFFFF) < 8)
106
+ end
107
+
108
+ def wurmple_evolution? #true for Silcoon and false for Cascoon
109
+ ((pid & 0xFFFF) ^ 10) < 5 ? true : false
110
+ end
111
+
112
+ def otid=(value)
113
+ @pdata[4,2] = decompile_bytes(value, 2)
114
+ end
115
+
116
+ def egg
117
+ if @pdata[@block_m+3]&64==64
118
+ return true
119
+ else
120
+ return false
121
+ end
122
+ end
123
+
124
+ def egg=(value)
125
+ if value
126
+ set_bit(@pdata[@block_m+3],7)
127
+ else
128
+ unset_bit(@pdata[@block_m+3],7)
129
+ end
130
+ end
131
+
132
+ def happiness
133
+ return @pdata[@block_g+9]
134
+ end
135
+
136
+ def happiness=(value)
137
+ @pdata[@block_g+9] = value
138
+ end
139
+
140
+ def ability
141
+ if @pdata[@block_m+3]&128==128
142
+ return true
143
+ else
144
+ return false
145
+ end
146
+ end
147
+
148
+ def species
149
+ return (compile_bytes(@pdata[@block_g,2]))
150
+ end
151
+
152
+ def nature
153
+ return pid % 25
154
+ end
155
+
156
+ def nature_name
157
+ case nature
158
+ when 0
159
+ return "Hardy"
160
+ when 1
161
+ return "Lonely"
162
+ when 2
163
+ return "Brave"
164
+ when 3
165
+ return "Adamant"
166
+ when 4
167
+ return "Naughty"
168
+ when 5
169
+ return "Bold"
170
+ when 6
171
+ return "Docile"
172
+ when 7
173
+ return "Relaxed"
174
+ when 8
175
+ return "Impish"
176
+ when 9
177
+ return "Lax"
178
+ when 10
179
+ return "Timid"
180
+ when 11
181
+ return "Hasty"
182
+ when 12
183
+ return "Serious"
184
+ when 13
185
+ return "Jolly"
186
+ when 14
187
+ return "Naive"
188
+ when 15
189
+ return "Modest"
190
+ when 16
191
+ return "Mild"
192
+ when 17
193
+ return "Quiet"
194
+ when 18
195
+ return "Bashful"
196
+ when 19
197
+ return "Rash"
198
+ when 20
199
+ return "Calm"
200
+ when 21
201
+ return "Gentle"
202
+ when 22
203
+ return "Sassy"
204
+ when 23
205
+ return "Careful"
206
+ when 24
207
+ return "Quirky"
208
+ end
209
+ end
210
+
211
+ def pokedex_species
212
+ return species if species <= 251
213
+ return species - 25 if species > 251
214
+ end
215
+
216
+ def species=(val)
217
+ @pdata[@block_g,2] = decompile_bytes(val,2)
218
+ end
219
+
220
+ def exp
221
+ return compile_bytes(@pdata[@block_g+4,4])
222
+ end
223
+
224
+ def exp=(val)
225
+ @pdata[@block_g+4,4] = decompile_bytes(val,4)
226
+ end
227
+
228
+ def nickname
229
+ tmpar = @pdata[8,10]
230
+ return "" if tmpar.uniq.count == 1 && tmpar.uniq[0] == 0
231
+ tmpar.slice!(tmpar.find_index(0xFF)..tmpar.length-1) if tmpar.find_index(0xFF) != nil
232
+ tmpar.each_index do |i|
233
+ tmpar[i] = tmpar[i].chr
234
+ end
235
+ return TextConverter.convert_text_to_ascii(tmpar.join, {gen: 3}).encode('UTF-8')
236
+ end
237
+
238
+ def nickname=(value)
239
+ if value != ""
240
+ newname = TextConverter.convert_text_to_game(value, {gen: 3})
241
+ newray = Array.new(10)
242
+ newname.each_char.with_index do |char, i|
243
+ newray[i] = char.ord
244
+ end
245
+ newray.each_index do |i|
246
+ if i>=newname.length
247
+ newray[i] = 0xFF unless newname.length >= 10
248
+ end
249
+ end
250
+ puts newray
251
+ @pdata[8,10] = newray[0,10]
252
+ end
253
+ end
254
+
255
+ def change_to_shiny
256
+
257
+ end
258
+
259
+ def language
260
+ return compile_bytes(@pdata[18,2])
261
+ end
262
+
263
+ def language_name
264
+ case language
265
+ when 0x201
266
+ return "Japanese"
267
+ when 0x202
268
+ return "English"
269
+ when 0x203
270
+ return "French"
271
+ when 0x204
272
+ return "Italian"
273
+ when 0x205
274
+ return "German"
275
+ when 0x206
276
+ return "Korean"
277
+ when 0x207
278
+ return "Spanish"
279
+ end
280
+ end
281
+
282
+ def language=(value)
283
+ @pdata[18,2] = decompile_bytes(value,2)
284
+ end
285
+
286
+ def marking
287
+ tmpmark = @pdata[27]
288
+ mark = {}
289
+ mark[:circle] = true if tmpmark & 1 == 1
290
+ mark[:square] = true if tmpmark & 2 == 2
291
+ mark[:triangle] = true if tmpmark & 4 == 4
292
+ mark[:heart] = true if tmpmark & 8 == 8
293
+ return mark
294
+ end
295
+
296
+ def marking=(mark)
297
+ @pdata[27] = value & 0xFF
298
+ mark[:circle] ? set_bit(@pdata[27],0) : unset_bit(@pdata[27],0)
299
+ mark[:square] ? set_bit(@pdata[27],1) : unset_bit(@pdata[27],1)
300
+ mark[:triangle] ? set_bit(@pdata[27],2) : unset_bit(@pdata[27],2)
301
+ mark[:heart] ? set_bit(@pdata[27],3) : unset_bit(@pdata[27],3)
302
+ end
303
+
304
+ def checksum
305
+ return compile_bytes(@pdata[28,2])
306
+ end
307
+
308
+ def checksum=(value)
309
+ @pdata[28,2] = decompile_bytes(value,2)
310
+ end
311
+
312
+ def status
313
+ return compile_bytes(@pdata[80,4])
314
+ end
315
+
316
+ def status=(value)
317
+ @pdata[80,4] = decompile_bytes(value, 4)
318
+ end
319
+
320
+ def level
321
+ return @pdata[84]
322
+ end
323
+
324
+ def level=(value)
325
+ @pdata[84] = value & 0xFF
326
+ end
327
+
328
+ def pokerus
329
+ return @pdata[85]
330
+ end
331
+
332
+ def pokerus=(value)
333
+ @pdata[85] = value & 0xFF
334
+ end
335
+
336
+ def curhp
337
+ return compile_bytes(@pdata[86,2])
338
+ end
339
+
340
+ def curhp=(value)
341
+ @pdata[86,2] = decompile_bytes(value,2)
342
+ end
343
+
344
+ def maxhp
345
+ return compile_bytes(@pdata[88,2])
346
+ end
347
+
348
+ def maxhp=(value)
349
+ @pdata[88,2] = decompile_bytes(value,2)
350
+ end
351
+
352
+ def attack
353
+ return compile_bytes(@pdata[90,2])
354
+ end
355
+
356
+ def attack=(value)
357
+ @pdata[90,2] = decompile_bytes(value,2)
358
+ end
359
+
360
+ def defense
361
+ return compile_bytes(@pdata[92,2])
362
+ end
363
+
364
+ def defense=(value)
365
+ @pdata[92,2] = decompile_bytes(value,2)
366
+ end
367
+
368
+ def speed
369
+ return compile_bytes(@pdata[94,2])
370
+ end
371
+
372
+ def speed=(value)
373
+ @pdata[94,2] = decompile_bytes(value,2)
374
+ end
375
+
376
+ def special_attack
377
+ return compile_bytes(@pdata[96,2])
378
+ end
379
+
380
+ def special_attack=(value)
381
+ @pdata[96,2] = decompile_bytes(value,2)
382
+ end
383
+
384
+ def special_defense
385
+ return compile_bytes(@pdata[98,2])
386
+ end
387
+
388
+ def special_defense=(value)
389
+ @pdata[98,2] = decompile_bytes(value,2)
390
+ end
391
+
392
+ def iv(options = {hp: true})
393
+ iv_total = compile_bytes(@pdata[@block_m+4,4])
394
+ if options[:hp]
395
+ return (iv_total & 0x1F)
396
+ elsif options[:attack]
397
+ return ((iv_total & 0x3E0)>>5)
398
+ elsif options[:defense]
399
+ return ((iv_total & 0x7C00)>>10)
400
+ elsif options[:speed]
401
+ return ((iv_total & 0xF8000)>>15)
402
+ elsif options[:special_attack]
403
+ return ((iv_total & 0x1F00000)>>20)
404
+ elsif options[:special_defense]
405
+ return ((iv_total & 0x3E000000)>>25)
406
+ end
407
+ end
408
+
409
+ def ivs
410
+ iv_total = compile_bytes(@pdata[@block_m+4,4])
411
+ return {hp: iv_total & 0x1F, attack: ((iv_total & 0x3E0)>>5), defense: ((iv_total & 0x7C00)>>10), speed: ((iv_total & 0xF8000)>>15), special_attack: ((iv_total & 0x1F00000)>>20), special_defense: ((iv_total & 0x3E000000)>>25)}
412
+ end
413
+
414
+ def ivs=(val)
415
+ iv_total = (val[:hp].to_i&0x1F) | ((val[:attack].to_i&0x1F)<<5) | ((val[:defense].to_i&0x1F)<<10) | ((val[:speed].to_i&0x1F)<<15) | ((val[:special_attack].to_i&0x1F)<<20) | ((val[:special_defense].to_i&0x1F)<<25)
416
+ @pdata[@block_m+4,4] = decompile_bytes(iv_total,4)
417
+ end
418
+
419
+ def evs
420
+ return {hp: @pdata[@block_e].to_i, attack: @pdata[@block_e+1].to_i, defense: @pdata[@block_e+2].to_i, speed: @pdata[@block_e+3].to_i, special_attack: @pdata[@block_e+4].to_i, special_defense: @pdata[@block_e+5].to_i}
421
+ end
422
+
423
+ def evs=(val)
424
+ @pdata[@block_e] = val[:hp]
425
+ @pdata[@block_e+1] = val[:attack]
426
+ @pdata[@block_e+2] = val[:defense]
427
+ @pdata[@block_e+3] = val[:speed]
428
+ @pdata[@block_e+4] = val[:special_attack]
429
+ @pdata[@block_e+5] = val[:special_defense]
430
+ end
431
+
432
+ def ev(options = {hp: true})
433
+ if options[:hp]
434
+ return @pdata[@block_e]
435
+ elsif options[:attack]
436
+ return @pdata[@block_e+1]
437
+ elsif options[:defense]
438
+ return @pdata[@block_e+2]
439
+ elsif options[:speed]
440
+ return @pdata[@block_e+3]
441
+ elsif options[:special_attack]
442
+ return @pdata[@block_e+4]
443
+ elsif options[:special_defense]
444
+ return @pdata[@block_e+5]
445
+ end
446
+ end
447
+
448
+ def ball_caught_with
449
+ return ((compile_bytes(@pdata[@block_m+2,2]) & 0x7800)>>11)
450
+ end
451
+
452
+ def moves
453
+ return {1=>compile_bytes(@pdata[@block_a,2]), 2=>compile_bytes(@pdata[@block_a+2,2]), 3=>compile_bytes(@pdata[@block_a+4,2]), 4=>compile_bytes(@pdata[@block_a+6,2]) }
454
+ end
455
+
456
+ def moves=(val)
457
+ @pdata[@block_a,2] = decompile_bytes(val[1],2)
458
+ @pdata[@block_a+2,2] = decompile_bytes(val[2],2)
459
+ @pdata[@block_a+4,2] = decompile_bytes(val[3],2)
460
+ @pdata[@block_a+6,2] = decompile_bytes(val[4],2)
461
+ end
462
+
463
+ def decrypt
464
+ temp_pks = self.dup
465
+ decrypt_key = pid ^ (((secretid&0xFFFF)<<16) | (otid&0xFFFF))
466
+ calc_checksum = 0
467
+ pdata[32,48].each_index do |i|
468
+ i+=32
469
+ if i%4==0
470
+ temp_pks.pdata[i,4] = decompile_bytes(decrypt_key ^ compile_bytes(@pdata[i,4]),4)
471
+ end
472
+ end
473
+ pdata[32,48].each_index do |i|
474
+ i+=32
475
+ if i%2==0
476
+ calc_checksum += compile_bytes(temp_pks.pdata[i,2])
477
+ end
478
+ end
479
+ puts "0x" + checksum.to_s(16) + ": Invalid Checksum!!! (Should be 0x" + (calc_checksum&0xFFFF).to_s(16).upcase + ")" if (calc_checksum&0xFFFF) != checksum
480
+ return temp_pks
481
+ end
482
+
483
+ def encrypt
484
+ temp_pks = self.dup
485
+ decrypt_key = pid ^ (((secretid&0xFFFF)<<16) | (otid&0xFFFF))
486
+ calc_checksum = 0
487
+
488
+ pdata[32,48].each_index do |i|
489
+ i+=32
490
+ if i%2==0
491
+ calc_checksum += compile_bytes(temp_pks.pdata[i,2])
492
+ end
493
+ end
494
+
495
+ pdata[32,48].each_index do |i|
496
+ i+=32
497
+ temp_pks.pdata[i] = pdata[i] ^ ((decrypt_key & (0xFF << (i%4)*8)) >> ((i%4)*8))
498
+ end
499
+
500
+ temp_pks.checksum = calc_checksum
501
+ return temp_pks
502
+ end
503
+
504
+ end