@@ -123,7 +123,7 @@ def non_charlock_chest(self):
123
123
chest = chest + 1 if (chest > 23 ) else chest
124
124
return chest
125
125
126
- def randomize_attack_patterns (self ):
126
+ def randomize_attack_patterns (self , ultra = False ):
127
127
"""
128
128
Randomizes attack patterns of enemies (whether or not they use spells/fire
129
129
breath).
@@ -135,18 +135,21 @@ def randomize_attack_patterns(self):
135
135
if random .randint (0 ,1 ): # 50/50 chance
136
136
resist = random .randint (0 ,round (i / 5 ))
137
137
new_ss_resist [i ] &= (0xf0 | resist )
138
- if i <= 20 :
139
- # heal, sleep, stopspell, hurt
140
- new_patterns .append ((random .randint (0 ,11 ) << 4 ) | random .randint (0 ,3 ))
141
- elif i < 30 :
142
- # healmore, heal, sleep, stopspell, fire breath, hurtmore
143
- new_patterns .append ((random .randint (0 ,15 ) << 4 ) | random .randint (4 , 11 ))
138
+ if ultra :
139
+ new_patterns .append ((random .randint (0 ,255 )))
144
140
else :
145
- # healmore, sleep, stopspell, strong fire breath, fire breath, hurtmore
146
- #we'll be nice and not give Axe Knight Dragonlord's breath.
147
- slot2 = random .randint (4 , 11 ) if i == 33 else random .randint (4 , 15 )
148
- new_patterns .append ((random .choice ((0 , 1 , 3 )) << 6 ) |
149
- (random .randint (0 , 3 ) << 4 ) | slot2 )
141
+ if i <= 20 :
142
+ # heal, sleep, stopspell, hurt
143
+ new_patterns .append ((random .randint (0 ,11 ) << 4 ) | random .randint (0 ,3 ))
144
+ elif i < 30 :
145
+ # healmore, heal, sleep, stopspell, fire breath, hurtmore
146
+ new_patterns .append ((random .randint (0 ,15 ) << 4 ) | random .randint (4 , 11 ))
147
+ else :
148
+ # healmore, sleep, stopspell, strong fire breath, fire breath, hurtmore
149
+ #we'll be nice and not give Axe Knight Dragonlord's breath.
150
+ slot2 = random .randint (4 , 11 ) if i == 33 else random .randint (4 , 15 )
151
+ new_patterns .append ((random .choice ((0 , 1 , 3 )) << 6 ) |
152
+ (random .randint (0 , 3 ) << 4 ) | slot2 )
150
153
else :
151
154
new_patterns .append (0 )
152
155
new_patterns .append (87 ) #Dragonlord form 1
@@ -170,7 +173,8 @@ def shuffle_towns(self):
170
173
# this could happen if it ends up in southern shrine position or
171
174
# behind a locked door when rimuldar is in it's normal location.
172
175
while (caves [3 ][0 ] == 21 or
173
- (towns [3 ][0 ] == 11 and 21 in (caves [5 ][0 ], caves [6 ][0 ]))):
176
+ (towns [3 ][0 ] == 11 and 21 in (caves [5 ][0 ], caves [6 ][0 ])) or
177
+ (towns [3 ][0 ] == 9 and caves [6 ][0 ] == 21 )):
174
178
random .shuffle (caves )
175
179
warp_data [153 :156 ] = towns [0 ]
176
180
warp_data [159 :162 ] = towns [1 ]
@@ -191,39 +195,46 @@ def shuffle_towns(self):
191
195
warp_data [174 :177 ],warp_data [189 :192 ] = warp_data [189 :192 ],warp_data [174 :177 ]
192
196
self .rom_data [self .warps_slice ] = warp_data
193
197
194
- def randomize_zones (self ):
198
+ def randomize_zones (self , ultra = False ):
195
199
"""
196
200
Randomizes which enemies are present in each zone.
197
201
"""
198
202
new_zones = list ()
199
- #zone 0
200
- for j in range (5 ):
201
- new_zones .append (int (random .randint (0 , 4 )/ 2 ))
202
-
203
- # zones 1-13 (overworld)
204
- for i in range (1 , 14 ):
205
- for j in range (5 ):
206
- enemy = random .randint (max (0 , i * 2 - 2 ), (max (2 ,round (i * 2.5 ))))
207
- while enemy == 24 : # don't add golem
208
- enemy = random .randint (i * 2 - 2 , round (i * 2.5 ))
209
- new_zones .append (enemy )
210
-
211
- #zone 14 - garin's grave?
212
- for j in range (5 ):
213
- new_zones .append (random .randint (7 , 17 ))
214
-
215
- #zone 15 - lower garin's grave
216
- for j in range (5 ):
217
- new_zones .append (random .randint (15 , 23 ))
218
-
219
- # zone 16-18 - Charlock
220
- for i in range (16 , 19 ):
203
+ if ultra :
204
+ #zone 0-1
205
+ for i in range (0 ,10 ):
206
+ new_zones .append (random .randint (0 , 6 ))
207
+ for i in range (0 ,90 ):
208
+ new_zones .append (random .randint (0 , 37 ))
209
+ else :
210
+ #zones 2-19
211
+ for j in range (5 ):
212
+ new_zones .append (int (random .randint (0 , 6 )/ 2 ))
213
+
214
+ # zones 1-13 (Overworld)
215
+ for i in range (1 , 14 ):
216
+ for j in range (5 ):
217
+ enemy = random .randint (i * 2 - 2 , min (37 ,round (i * 3 )))
218
+ while enemy == 24 : # don't add golem
219
+ enemy = random .randint (i * 2 - 2 , min (37 ,round (i * 3 )))
220
+ new_zones .append (enemy )
221
+
222
+ #zone 14 - Garin's Grave?
223
+ for j in range (5 ):
224
+ new_zones .append (random .randint (7 , 17 ))
225
+
226
+ #zone 15 - Lower Garin's Grave
227
+ for j in range (5 ):
228
+ new_zones .append (random .randint (15 , 23 ))
229
+
230
+ # zone 16-18 - Charlock
231
+ for i in range (16 , 19 ):
232
+ for j in range (5 ):
233
+ new_zones .append (random .randint (13 + i , 37 ))
234
+
235
+ # zone 19 - Rimuldar Tunnel
221
236
for j in range (5 ):
222
- new_zones .append (random .randint (13 + i , 37 ))
223
-
224
- # zone 19 rimuldar tunnel
225
- for j in range (5 ):
226
- new_zones .append (random .randint (3 , 11 ))
237
+ new_zones .append (random .randint (3 , 11 ))
227
238
self .rom_data [self .zones_slice ] = new_zones
228
239
229
240
def randomize_shops (self ):
@@ -269,22 +280,32 @@ def shuffle_searchables(self):
269
280
self .rom_data [self .flute_slice ] = searchables [1 ]
270
281
self .rom_data [self .armor_slice ] = searchables [2 ]
271
282
272
- def randomize_growth (self ):
283
+ def randomize_growth (self , ultra = False ):
273
284
player_stat_data = self .rom_data [self .player_stats_slice ]
274
285
275
286
player_str = list (player_stat_data [0 :180 :6 ])
276
287
player_agi = list (player_stat_data [1 :180 :6 ])
277
288
player_hp = list (player_stat_data [2 :180 :6 ])
278
289
player_mp = list (player_stat_data [3 :180 :6 ])
279
290
280
- for i in range (len (player_str )):
281
- player_str [i ] = round (player_str [i ] * random .uniform (0.8 , 1.2 ))
282
- for i in range (len (player_agi )):
283
- player_agi [i ] = round (player_agi [i ] * random .uniform (0.8 , 1.2 ))
284
- for i in range (len (player_hp )):
285
- player_hp [i ] = round (player_hp [i ] * random .uniform (0.8 , 1.2 ))
286
- for i in range (len (player_mp )):
287
- player_mp [i ] = round (player_mp [i ] * random .uniform (0.8 , 1.2 ))
291
+ if ultra :
292
+ for i in range (len (player_str )):
293
+ player_str [i ] = round (player_str [i ] * random .uniform (0.8 , 1.2 ))
294
+ for i in range (len (player_agi )):
295
+ player_agi [i ] = round (player_agi [i ] * random .uniform (0.8 , 1.2 ))
296
+ for i in range (len (player_hp )):
297
+ player_hp [i ] = round (player_hp [i ] * random .uniform (0.8 , 1.2 ))
298
+ for i in range (len (player_mp )):
299
+ player_mp [i ] = round (player_mp [i ] * random .uniform (0.8 , 1.2 ))
300
+ else :
301
+ for i in range (len (player_str )):
302
+ player_str [i ] = random .randint (4 ,200 )
303
+ for i in range (len (player_agi )):
304
+ player_agi [i ] = random .randint (4 ,200 )
305
+ for i in range (len (player_hp )):
306
+ player_hp [i ] = random .randint (10 ,255 )
307
+ for i in range (len (player_mp )):
308
+ player_mp [i ] = random .randint (0 ,255 )
288
309
289
310
player_str .sort ()
290
311
player_agi .sort ()
@@ -297,14 +318,18 @@ def randomize_growth(self):
297
318
player_stat_data [3 :180 :6 ] = player_mp
298
319
self .rom_data [self .player_stats_slice ] = player_stat_data
299
320
300
- def randomize_spell_learning (self ):
321
+ def randomize_spell_learning (self , ultra = False ):
301
322
self .move_repel () # in case this hasn't been called yet.
302
323
levels = self .rom_data [self .new_spell_slice ]
303
324
player_mp = self .rom_data [self .player_mp_slice ]
304
325
new_masks = []
305
326
# choose the levels for new spells
306
- for i in range (len (levels )):
307
- levels [i ] = levels [i ] + random .randint (- 2 , 2 )
327
+ if ultra :
328
+ for i in range (len (levels )):
329
+ levels [i ] = random .randint (0 , 20 )
330
+ else :
331
+ for i in range (len (levels )):
332
+ levels [i ] = levels [i ] + random .randint (- 2 , 2 )
308
333
#adjust the spell masks to fit the new levels
309
334
for i in range (30 ):
310
335
mask = 0
@@ -342,12 +367,15 @@ def update_drops(self):
342
367
enemy_stats [7 ::16 ] = bytearray (remake_gold )
343
368
self .rom_data [self .enemy_stats_slice ] = enemy_stats
344
369
345
- def update_mp_reqs (self ):
370
+ def update_mp_reqs (self , ultra = False ):
346
371
"""
347
372
Lowers the MP requirements of spells to that of the remake
348
373
"""
349
374
#magic required for each spell, in order
350
375
remake_mp = [3 , 2 , 2 , 2 , 2 , 6 , 8 , 2 , 8 , 5 ]
376
+ if ultra :
377
+ for i in range (10 ):
378
+ remake_mp [i ] = random .randint (1 , 8 )
351
379
self .rom_data [self .mp_req_slice ] = remake_mp
352
380
353
381
def update_enemy_hp (self ):
@@ -411,26 +439,36 @@ def main():
411
439
parser .add_argument ("-f" ,"--force" , action = "store_false" ,
412
440
help = "Skip checksums and force randomization. This may produce an invalid"
413
441
" ROM if the incorrect file is used." )
414
- parser .add_argument ("-e" ,"--enemies" , action = "store_false" ,
415
- help = "Do not randomize enemy zones." )
416
442
parser .add_argument ("-i" ,"--searchitems" , action = "store_false" ,
417
443
help = "Do not randomize the locations of searchable items (Fairy Flute, "
418
444
"Erdrick's Armor, Erdrick's Token)." )
419
445
parser .add_argument ("-g" ,"--growth" , action = "store_false" ,
420
446
help = "Do not randomize player stat growth." )
447
+ parser .add_argument ("-G" ,"--ultra-growth" , action = "store_true" ,
448
+ help = "Enable ultra randomization of player stat growth." )
421
449
parser .add_argument ("-l" ,"--repel" , action = "store_false" ,
422
450
help = "Do not move repel to level 8." )
423
451
parser .add_argument ("-m" ,"--spells" , action = "store_false" ,
424
452
help = "Do not randomize the level spells are learned." )
453
+ parser .add_argument ("-M" ,"--ultra-spells" , action = "store_true" ,
454
+ help = "Enable ultra randomization of the level spells are learned." )
425
455
parser .add_argument ("-p" ,"--patterns" , action = "store_false" ,
426
456
help = "Do not randomize enemy attack patterns." )
457
+ parser .add_argument ("-P" ,"--ultra-patterns" , action = "store_true" ,
458
+ help = "Enable ultra randomization of enemy attack patterns." )
427
459
parser .add_argument ("-s" ,"--seed" , type = int ,
428
460
help = "Specify a seed to be used for randomization." )
429
461
parser .add_argument ("-t" ,"--towns" , action = "store_false" ,
430
462
help = "Do not randomize towns." )
431
463
parser .add_argument ("-w" ,"--shops" , action = "store_false" ,
432
464
help = "Do not randomize weapon shops." )
465
+ parser .add_argument ("-U" ,"--ultra" , action = "store_true" ,
466
+ help = "Enable all '--ultra' options." )
433
467
# parser.add_argument('--version', action='version', version='%(prog) %s'%VERSION)
468
+ parser .add_argument ("-z" ,"--zones" , action = "store_false" ,
469
+ help = "Do not randomize enemy zones." )
470
+ parser .add_argument ("-Z" ,"--ultra-zones" , action = "store_true" ,
471
+ help = "Enable ultra randomization of enemy zones." )
434
472
parser .add_argument ("filename" , help = "The rom file to use for input" )
435
473
args = parser .parse_args ()
436
474
randomize (args )
@@ -442,7 +480,7 @@ def randomize(args):
442
480
print ("Randomizing %s using random seed %d..." % (args .filename , args .seed ))
443
481
random .seed (args .seed )
444
482
flags = ""
445
- prg = "PRG_ "
483
+ prg = ""
446
484
447
485
rom = Rom (args .filename )
448
486
@@ -455,7 +493,7 @@ def randomize(args):
455
493
sys .exit (- 1 )
456
494
else :
457
495
print ("Processing Dragon Warrior PRG%d ROM..." % result )
458
- prg = "PRG%d" % result
496
+ prg = "PRG%d. " % result
459
497
460
498
else :
461
499
print ("Skipping checksum..." )
@@ -484,25 +522,40 @@ def randomize(args):
484
522
flags += "t"
485
523
rom .shuffle_towns ()
486
524
487
- if args .enemies :
488
- print ("Randomizing enemy zones..." )
489
- flags += "e"
490
- rom .randomize_zones ()
525
+ if args .zones :
526
+ if args .ultra or args .ultra_zones :
527
+ print ("Ultra randomizing enemy zones..." )
528
+ flags += "Z"
529
+ rom .randomize_zones (True )
530
+ else :
531
+ print ("Randomizing enemy zones..." )
532
+ flags += "z"
533
+ rom .randomize_zones ()
491
534
492
535
if args .patterns :
493
- print ("Randomizing enemy attack patterns..." )
494
- flags += "p"
495
- rom .randomize_attack_patterns ()
536
+ if args .ultra or args .ultra_patterns :
537
+ print ("Ultra randomizing enemy attack patterns..." )
538
+ flags += "P"
539
+ rom .randomize_attack_patterns (True )
540
+ else :
541
+ print ("Randomizing enemy attack patterns..." )
542
+ flags += "p"
543
+ rom .randomize_attack_patterns ()
496
544
497
545
if args .shops :
498
546
print ("Randomizing weapon shops..." )
499
547
flags += "w"
500
548
rom .randomize_shops ()
501
549
502
550
if args .growth :
503
- print ("Randomizing player stat growth..." )
504
- flags += "g"
505
- rom .randomize_growth ()
551
+ if args .ultra or args .ultra_growth :
552
+ print ("Ultra randomizing player stat growth..." )
553
+ flags += "G"
554
+ rom .randomize_growth (True )
555
+ else :
556
+ print ("Randomizing player stat growth..." )
557
+ flags += "g"
558
+ rom .randomize_growth ()
506
559
507
560
if args .remake :
508
561
print ("Increasing XP/Gold drops to remake levels..." )
@@ -519,11 +572,16 @@ def randomize(args):
519
572
rom .move_repel ()
520
573
521
574
if args .spells :
522
- print ("Randomizing level spells are learned..." )
523
- flags += "m"
524
- rom .randomize_spell_learning ()
575
+ if args .ultra or args .ultra_spells :
576
+ print ("Ultra randomizing level spells are learned..." )
577
+ flags += "M"
578
+ rom .randomize_spell_learning (True )
579
+ else :
580
+ print ("Randomizing level spells are learned..." )
581
+ flags += "m"
582
+ rom .randomize_spell_learning ()
525
583
526
- output_filename = "DWRandomizer.%d.% s.%s.nes " % (args .seed , flags , prg )
584
+ output_filename = "DWRando.% s.%d.%snes " % (flags , args .seed , prg )
527
585
print ("Writing output file %s..." % output_filename )
528
586
rom .write (output_filename )
529
587
print ("New ROM Checksum: %s" % rom .sha1 ())
0 commit comments