Re-rip Gen III contest effects

Gen III contest effects were part of the initial data import from brown
veekun and so have probably never gotten a proper rip.

This commit re-rips contest effect stats, types, combos, and the mapping
between contest effects and moves.

None of the stats changed (jam & appeal); a few moves got assigned
different contest effects (specifically: smokescreen, flash, spite, and
shadow ball); and several combos changed.

For example, Hail was listed as comboing into the following moves
(this is also what Bulbapedia says):

    Ice Beam, Blizzard, Aurora Beam, Haze, Powder Snow, Icy Wind,
    Ice Ball, Weather Ball, Sheer Cold, Icicle Spear

However, the actual list is much shorter:

    Blizzard, Powder Snow, Weather Ball

I verified on my Ruby cart that Hail->Ice Beam and Hail->Icy Wind are
not real combos, and that Hail->Blizzard is.

n.b. There are a bunch of unused contest effects in the game: out of 48
effects, 15 are not used by any move. The pokedex doesn't currently
include these. I elected not to add them, partly because i didn't want
to have to rip flavor text for them, but mostly because if i were going
to go that route i would probably reassign contest_effects.id to match
their internal ids, which would have made for uglier diffs.

Fixes #280
This commit is contained in:
Andrew Ekstedt 2020-03-01 19:24:57 -08:00
parent cc2ad50752
commit 9c1d1828c9
3 changed files with 123 additions and 21 deletions

View file

@ -1,6 +1,6 @@
first_move_id,second_move_id
1,3
1,29
1,21
1,185
7,8
7,9
@ -37,7 +37,6 @@ first_move_id,second_move_id
74,22
74,71
74,72
74,73
74,75
74,76
74,80
@ -45,6 +44,7 @@ first_move_id,second_move_id
74,331
74,338
74,345
81,169
82,225
82,337
82,349
@ -77,8 +77,8 @@ first_move_id,second_move_id
111,205
116,2
116,5
116,21
116,25
116,29
116,36
116,38
116,167
@ -108,8 +108,6 @@ first_move_id,second_move_id
170,66
170,136
170,223
170,276
170,329
174,180
174,194
174,212
@ -132,10 +130,8 @@ first_move_id,second_move_id
199,276
201,28
201,189
201,300
201,311
201,328
201,341
203,175
203,179
203,194
@ -155,17 +151,18 @@ first_move_id,second_move_id
230,77
230,78
230,79
240,3
240,55
240,56
240,57
240,61
240,87
240,110
240,127
240,128
240,145
240,152
240,190
240,250
240,291
240,308
240,311
@ -174,7 +171,6 @@ first_move_id,second_move_id
240,346
240,352
241,7
241,27
241,52
241,53
241,76
@ -186,6 +182,7 @@ first_move_id,second_move_id
241,235
241,236
241,257
241,261
241,284
241,299
241,307
@ -198,22 +195,14 @@ first_move_id,second_move_id
252,292
254,255
254,256
258,58
258,59
258,62
258,114
258,181
258,196
258,301
258,311
258,329
258,333
268,9
268,84
268,85
268,86
268,87
268,192
268,209
268,344
268,351

1 first_move_id second_move_id
2 1 3
3 1 29 21
4 1 185
5 7 8
6 7 9
37 74 22
38 74 71
39 74 72
74 73
40 74 75
41 74 76
42 74 80
44 74 331
45 74 338
46 74 345
47 81 169
48 82 225
49 82 337
50 82 349
77 111 205
78 116 2
79 116 5
116 21
80 116 25
81 116 29
82 116 36
83 116 38
84 116 167
108 170 66
109 170 136
110 170 223
170 276
170 329
111 174 180
112 174 194
113 174 212
130 199 276
131 201 28
132 201 189
201 300
133 201 311
134 201 328
201 341
135 203 175
136 203 179
137 203 194
151 230 77
152 230 78
153 230 79
240 3
154 240 55
155 240 56
156 240 57
157 240 61
158 240 87
159 240 110
160 240 127
161 240 128
162 240 145
163 240 152
164 240 190
165 240 250
166 240 291
167 240 308
168 240 311
171 240 346
172 240 352
173 241 7
241 27
174 241 52
175 241 53
176 241 76
182 241 235
183 241 236
184 241 257
185 241 261
186 241 284
187 241 299
188 241 307
195 252 292
196 254 255
197 254 256
258 58
198 258 59
258 62
258 114
199 258 181
258 196
258 301
200 258 311
258 329
258 333
201 268 9
202 268 84
203 268 85
204 268 86
205 268 87
268 192
206 268 209
207 268 344
208 268 351

View file

@ -106,7 +106,7 @@ id,identifier,generation_id,type_id,power,pp,accuracy,priority,target_id,damage_
105,recover,1,1,,10,,0,7,1,33,,4,23,8
106,harden,1,1,,30,,0,7,1,12,,5,16,13
107,minimize,1,1,,10,,0,7,1,109,,3,16,13
108,smokescreen,1,1,,20,100,0,10,1,24,,4,21,10
108,smokescreen,1,1,,20,100,0,10,1,24,,4,22,10
109,confuse-ray,1,8,,10,100,0,10,1,50,,4,21,10
110,withdraw,1,11,,40,,0,7,1,12,,3,15,13
111,defense-curl,1,1,,40,,0,7,1,157,,3,16,13
@ -146,7 +146,7 @@ id,identifier,generation_id,type_id,power,pp,accuracy,priority,target_id,damage_
145,bubble,1,11,40,30,100,0,11,3,71,10,3,8,2
146,dizzy-punch,1,1,70,10,100,0,10,2,77,20,1,4,16
147,spore,1,12,,15,100,0,10,1,2,,2,5,10
148,flash,1,1,,20,100,0,10,1,24,,2,21,10
148,flash,1,1,,20,100,0,10,1,24,,2,22,10
149,psywave,1,14,,15,100,0,10,3,89,,4,14,5
150,splash,1,1,,40,,0,7,1,86,,3,28,16
151,acid-armor,1,4,,20,,0,7,1,52,,5,32,11
@ -178,7 +178,7 @@ id,identifier,generation_id,type_id,power,pp,accuracy,priority,target_id,damage_
177,aeroblast,2,3,100,5,95,0,10,3,44,,1,2,22
178,cotton-spore,2,12,,40,100,0,11,1,61,,2,10,1
179,reversal,2,2,,15,100,0,10,2,100,,1,28,15
180,spite,2,8,,10,100,0,10,1,101,,5,28,19
180,spite,2,8,,10,100,0,10,1,101,,5,26,19
181,powder-snow,2,15,40,25,100,0,11,3,6,10,2,1,5
182,protect,2,1,,10,,4,7,1,112,,3,15,16
183,mach-punch,2,2,40,30,100,1,10,2,104,,1,30,1
@ -245,7 +245,7 @@ id,identifier,generation_id,type_id,power,pp,accuracy,priority,target_id,damage_
244,psych-up,2,1,,10,,0,10,1,144,,4,12,11
245,extreme-speed,2,1,80,5,100,2,10,2,104,,1,30,1
246,ancient-power,2,6,60,5,100,0,10,3,141,10,5,32,18
247,shadow-ball,2,8,80,15,100,0,10,3,73,20,4,21,17
247,shadow-ball,2,8,80,15,100,0,10,3,73,20,4,22,17
248,future-sight,2,14,120,10,100,0,10,3,149,,4,24,17
249,rock-smash,2,2,40,15,100,0,10,2,70,50,5,29,18
250,whirlpool,2,11,35,15,85,0,10,3,262,100,2,24,21

1 id identifier generation_id type_id power pp accuracy priority target_id damage_class_id effect_id effect_chance contest_type_id contest_effect_id super_contest_effect_id
106 105 recover 1 1 10 0 7 1 33 4 23 8
107 106 harden 1 1 30 0 7 1 12 5 16 13
108 107 minimize 1 1 10 0 7 1 109 3 16 13
109 108 smokescreen 1 1 20 100 0 10 1 24 4 21 22 10
110 109 confuse-ray 1 8 10 100 0 10 1 50 4 21 10
111 110 withdraw 1 11 40 0 7 1 12 3 15 13
112 111 defense-curl 1 1 40 0 7 1 157 3 16 13
146 145 bubble 1 11 40 30 100 0 11 3 71 10 3 8 2
147 146 dizzy-punch 1 1 70 10 100 0 10 2 77 20 1 4 16
148 147 spore 1 12 15 100 0 10 1 2 2 5 10
149 148 flash 1 1 20 100 0 10 1 24 2 21 22 10
150 149 psywave 1 14 15 100 0 10 3 89 4 14 5
151 150 splash 1 1 40 0 7 1 86 3 28 16
152 151 acid-armor 1 4 20 0 7 1 52 5 32 11
178 177 aeroblast 2 3 100 5 95 0 10 3 44 1 2 22
179 178 cotton-spore 2 12 40 100 0 11 1 61 2 10 1
180 179 reversal 2 2 15 100 0 10 2 100 1 28 15
181 180 spite 2 8 10 100 0 10 1 101 5 28 26 19
182 181 powder-snow 2 15 40 25 100 0 11 3 6 10 2 1 5
183 182 protect 2 1 10 4 7 1 112 3 15 16
184 183 mach-punch 2 2 40 30 100 1 10 2 104 1 30 1
245 244 psych-up 2 1 10 0 10 1 144 4 12 11
246 245 extreme-speed 2 1 80 5 100 2 10 2 104 1 30 1
247 246 ancient-power 2 6 60 5 100 0 10 3 141 10 5 32 18
248 247 shadow-ball 2 8 80 15 100 0 10 3 73 20 4 21 22 17
249 248 future-sight 2 14 120 10 100 0 10 3 149 4 24 17
250 249 rock-smash 2 2 40 15 100 0 10 2 70 50 5 29 18
251 250 whirlpool 2 11 35 15 85 0 10 3 262 100 2 24 21

View file

@ -0,0 +1,113 @@
#!/usr/bin/env python3
"""
This is an unmaintained one-shot script, only included in the repo for
reference.
"""
import struct
def main():
NUM_MOVES = 354
with open("pokeruby.gba", 'rb') as f:
f.seek(0x3cf594 )
data = f.read(8 * (NUM_MOVES + 1))
effects = []
combo_id_map = {} # combo_id => move_id
combo_pairs = [] # [(combo starter, move id)]
with open("update_contest_effect_ids.sql", "w") as f:
for i in range(NUM_MOVES+1):
effect, type, combo_id, *combo_prev = struct.unpack("<BBBBBBBx", data[i*8:(i+1)*8])
print(i, idmap[effect], type, combo_id, combo_prev)
if i:
print("UPDATE moves SET contest_effect_id = %d, contest_type_id = %d WHERE id = %d;" % (idmap[effect], type+1, i), file=f)
effects.append(effect)
if combo_id:
combo_id_map.setdefault(combo_id, []).append(i)
for c in combo_prev:
combo_pairs.append((c, i))
move_pairs = []
for combo_id, second_move_id in combo_pairs:
for id1 in combo_id_map.get(combo_id, ()):
move_pairs.append((id1, second_move_id))
move_pairs.sort()
with open("contest_combos.csv", "w") as f:
print("first_move_id,second_move_id", file=f)
for first, second in move_pairs:
print(first, second, sep=",", file=f)
num_effects = max(effects)+1
with open("pokeruby.gba", 'rb') as f:
f.seek(0x3d00ac)
data = f.read(4 * num_effects)
with open("contest_effects.csv", "w") as f:
print("id,effect_type,appeal,jam", file=f)
for i in range(num_effects):
if i not in effects:
continue
effectType, appeal, jam = struct.unpack("<BBBx", data[i*4:(i+1)*4])
#print(idmap[i],effectType, appeal//10, jam//10, sep=",")
print(idmap[i], appeal//10, jam//10, sep=",", file=f)
idmap = {
0: 1, # CONTEST_EFFECT_HIGHLY_APPEALING
1: 3, # CONTEST_EFFECT_USER_MORE_EASILY_STARTLED
2: 7, # CONTEST_EFFECT_GREAT_APPEAL_BUT_NO_MORE_MOVES
3: 17, # CONTEST_EFFECT_REPETITION_NOT_BORING
4: 16, # CONTEST_EFFECT_AVOID_STARTLE_ONCE
5: 15, # CONTEST_EFFECT_AVOID_STARTLE
#6: # CONTEST_EFFECT_AVOID_STARTLE_SLIGHTLY
#7: # CONTEST_EFFECT_USER_LESS_EASILY_STARTLED
#8: # CONTEST_EFFECT_STARTLE_FRONT_MON
#9: # CONTEST_EFFECT_SLIGHTLY_STARTLE_PREV_MONS
10: 9, # CONTEST_EFFECT_STARTLE_PREV_MON
11: 8, # CONTEST_EFFECT_STARTLE_PREV_MONS
12: 4, # CONTEST_EFFECT_BADLY_STARTLE_FRONT_MON
13: 5, # CONTEST_EFFECT_BADLY_STARTLE_PREV_MONS
#14: # CONTEST_EFFECT_STARTLE_PREV_MON_2
#15: # CONTEST_EFFECT_STARTLE_PREV_MONS_2
16: 22, # CONTEST_EFFECT_SHIFT_JUDGE_ATTENTION
17: 10, # CONTEST_EFFECT_STARTLE_MON_WITH_JUDGES_ATTENTION
18: 6, # CONTEST_EFFECT_JAMS_OTHERS_BUT_MISS_ONE_TURN
19: 23, # CONTEST_EFFECT_STARTLE_MONS_SAME_TYPE_APPEAL
#20: 0, # CONTEST_EFFECT_STARTLE_MONS_COOL_APPEAL
#21: 0, # CONTEST_EFFECT_STARTLE_MONS_BEAUTY_APPEAL
#22: 0, # CONTEST_EFFECT_STARTLE_MONS_CUTE_APPEAL
#23: 0, # CONTEST_EFFECT_STARTLE_MONS_SMART_APPEAL
#24: 0, # CONTEST_EFFECT_STARTLE_MONS_TOUGH_APPEAL
#25: # CONTEST_EFFECT_MAKE_FOLLOWING_MON_NERVOUS
26: 18, # CONTEST_EFFECT_MAKE_FOLLOWING_MONS_NERVOUS
27: 33, # CONTEST_EFFECT_WORSEN_CONDITION_OF_PREV_MONS
#28: # CONTEST_EFFECT_BADLY_STARTLES_MONS_IN_GOOD_CONDITION
29: 27, # CONTEST_EFFECT_BETTER_IF_FIRST
30: 28, # CONTEST_EFFECT_BETTER_IF_LAST
31: 20, # CONTEST_EFFECT_APPEAL_AS_GOOD_AS_PREV_ONES
32: 19, # CONTEST_EFFECT_APPEAL_AS_GOOD_AS_PREV_ONE
33: 26, # CONTEST_EFFECT_BETTER_WHEN_LATER
34: 25, # CONTEST_EFFECT_QUALITY_DEPENDS_ON_TIMING
35: 12, # CONTEST_EFFECT_BETTER_IF_SAME_TYPE
#36: # CONTEST_EFFECT_BETTER_IF_DIFF_TYPE
37: 2, # CONTEST_EFFECT_AFFECTED_BY_PREV_APPEAL
38: 32, # CONTEST_EFFECT_IMPROVE_CONDITION_PREVENT_NERVOUSNESS
39: 29, # CONTEST_EFFECT_BETTER_WITH_GOOD_CONDITION
40: 30, # CONTEST_EFFECT_NEXT_APPEAL_EARLIER
41: 31, # CONTEST_EFFECT_NEXT_APPEAL_LATER
#42: # CONTEST_EFFECT_MAKE_SCRAMBLING_TURN_ORDER_EASIER
43: 21, # CONTEST_EFFECT_SCRAMBLE_NEXT_TURN_ORDER
44: 13, # CONTEST_EFFECT_EXCITE_AUDIENCE_IN_ANY_CONTEST
45: 14, # CONTEST_EFFECT_BADLY_STARTLE_MONS_WITH_GOOD_APPEALS
46: 11, # CONTEST_EFFECT_BETTER_WHEN_AUDIENCE_EXCITED
47: 24, # CONTEST_EFFECT_DONT_EXCITE_AUDIENCE
}
from collections import Counter
c = Counter(idmap.values())
print([v for v in c if c[v] > 1])
assert len(idmap) == len(set(idmap.values()))
main()