Support trolls
This commit is contained in:
@@ -35,7 +35,7 @@ def adjust(args):
|
||||
args.sprite, args.ow_palettes, args.uw_palettes, args.reduce_flashing, args.shuffle_sfx,
|
||||
args.msu_resume)
|
||||
|
||||
output_path.cached_path = args.outputpath
|
||||
# output_path.cached_path = args.outputpath
|
||||
rom.write_to_file(output_path('%s.sfc' % outfilebase))
|
||||
|
||||
logger.info('Done. Enjoy.')
|
||||
|
||||
@@ -105,6 +105,7 @@ class World(object):
|
||||
self.sanc_portal = {}
|
||||
self.fish = BabelFish()
|
||||
self.pot_contents = {}
|
||||
self.trolls = {}
|
||||
|
||||
for player in range(1, players + 1):
|
||||
def set_player_attr(attr, val):
|
||||
@@ -177,6 +178,7 @@ class World(object):
|
||||
|
||||
set_player_attr('exp_cache', defaultdict(dict))
|
||||
set_player_attr('enabled_entrances', {})
|
||||
set_player_attr('trolls', False)
|
||||
|
||||
def finish_init(self):
|
||||
for player in range(1, self.players + 1):
|
||||
@@ -184,6 +186,8 @@ class World(object):
|
||||
self.mode[player] = 'open'
|
||||
if self.goal[player] == 'completionist':
|
||||
self.accessibility[player] = 'locations'
|
||||
if self.trolls[player]:
|
||||
self.can_take_damage[player] = False
|
||||
|
||||
def get_name_string_for_object(self, obj):
|
||||
return obj.name if self.players == 1 else f'{obj.name} ({self.get_player_names(obj.player)})'
|
||||
@@ -352,7 +356,7 @@ class World(object):
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
def check_for_door(self, doorname, player):
|
||||
if isinstance(doorname, Door):
|
||||
return doorname
|
||||
|
||||
12
Bosses.py
12
Bosses.py
@@ -38,6 +38,8 @@ def LanmolasDefeatRule(state, player):
|
||||
state.has_special_weapon_level(player, 1)))
|
||||
|
||||
def MoldormDefeatRule(state, player):
|
||||
if state.world.trolls[player] and not (state.has('Blue Boomerang', player) or state.has('Red Boomerang', player) or state.has('Hookshot', player)):
|
||||
return False
|
||||
return (state.special_weapon_check(player, 1) and
|
||||
(state.has_blunt_weapon(player) or state.has_special_weapon_level(player, 1)))
|
||||
|
||||
@@ -74,6 +76,8 @@ def MothulaDefeatRule(state, player):
|
||||
state.has_special_weapon_level(player, 1)))
|
||||
|
||||
def BlindDefeatRule(state, player):
|
||||
if state.world.trolls[player]:
|
||||
return state.has('Shovel', player)
|
||||
return (state.special_weapon_check(player, 1) and
|
||||
(state.has_blunt_weapon(player) or state.has('Cane of Somaria', player) or
|
||||
state.has('Cane of Byrna', player) or state.has_special_weapon_level(player, 1)))
|
||||
@@ -107,6 +111,14 @@ def VitreousDefeatRule(state, player):
|
||||
state.has_special_weapon_level(player, 2)))
|
||||
|
||||
def TrinexxDefeatRule(state, player):
|
||||
if state.world.trolls[player]:
|
||||
if not (state.has('Bombos', player) and state.has('Ether', player)):
|
||||
return False
|
||||
return (state.has('Hammer', player) or
|
||||
state.has_real_sword(player, 3) or
|
||||
state.has_special_weapon_level(player, 4) or
|
||||
((state.has_real_sword(player, 2) or state.has_special_weapon_level(player, 3))
|
||||
and state.can_extend_magic(player, 24)))
|
||||
if not (state.has('Fire Rod', player) and state.has('Ice Rod', player)):
|
||||
return False
|
||||
if not state.special_weapon_check(player, 2):
|
||||
|
||||
5
CLI.py
5
CLI.py
@@ -147,7 +147,7 @@ def parse_cli(argv, no_defaults=False):
|
||||
'heartbeep', 'remote_items', 'shopsanity', 'dropshuffle', 'pottery', 'keydropshuffle',
|
||||
'mixed_travel', 'standardize_palettes', 'code', 'reduce_flashing', 'shuffle_sfx',
|
||||
'msu_resume', 'collection_rate', 'colorizepots', 'decoupledoors', 'door_type_mode',
|
||||
'bonk_drops', 'trap_door_mode', 'key_logic_algorithm']:
|
||||
'bonk_drops', 'trap_door_mode', 'key_logic_algorithm', 'trolls']:
|
||||
value = getattr(defaults, name) if getattr(playerargs, name) is None else getattr(playerargs, name)
|
||||
if player == 1:
|
||||
setattr(ret, name, {1: value})
|
||||
@@ -360,7 +360,8 @@ def parse_settings():
|
||||
"outputpath": os.path.join("."),
|
||||
"saveonexit": "ask",
|
||||
"outputname": "",
|
||||
"startinventoryarray": {}
|
||||
"startinventoryarray": {},
|
||||
"trolls": False,
|
||||
}
|
||||
|
||||
if sys.platform.lower().find("windows"):
|
||||
|
||||
@@ -1126,6 +1126,10 @@ def get_pool_core(world, player, progressive, shuffle, difficulty, treasure_hunt
|
||||
pool.remove('Piece of Heart')
|
||||
pool.extend(['Rupees (20)'] * 12)
|
||||
|
||||
if world.trolls[player]:
|
||||
pool.remove('Rupees (20)')
|
||||
pool.extend(['Magic Upgrade (1/2)'])
|
||||
|
||||
if bombbag:
|
||||
pool = [item.replace('Bomb Upgrade (+5)','Rupees (5)') for item in pool]
|
||||
pool = [item.replace('Bomb Upgrade (+10)','Rupees (5)') for item in pool]
|
||||
|
||||
40
Rom.py
40
Rom.py
@@ -2715,6 +2715,46 @@ def write_strings(rom, world, player, team):
|
||||
rom.write_byte(0x04a529, 0x19) # x tile shifted right a few tiles
|
||||
rom.write_byte(0x04a52e, 0x06) # follower set to blind maiden
|
||||
|
||||
if world.trolls[player]:
|
||||
tt['telepathic_tile_eastern_palace'] = "Health will not help you against the Armos Knights."
|
||||
tt['telepathic_tile_desert_bonk_torch_room'] = "Who ever saw lanmolas fly so fast?"
|
||||
tt['telepathic_tile_tower_of_hera_entrance'] = "Please stop tickling my tail. It makes me freeze up and lower my defenses.\n\n - Moldorm"
|
||||
tt['telepathic_tile_tower_of_hera_floor_4'] = "Hookshots and boomerangs are forbidden in my tower.\n\n - Moldorm"
|
||||
tt['telepathic_tile_spectacle_rock'] = "With greater health and armor come shorter periods of refuge from damage."
|
||||
tt['telepathic_tile_castle_tower'] = "Agahnim does not care for your foolish mortal patterns."
|
||||
tt['telepathic_tile_palace_of_darkness'] = "Who weakened my mask?\n\n - Helmasaur King"
|
||||
tt['telepathic_tile_swamp_entrance'] = "Please take your boots off before entering my room.\n\n - Arrghus"
|
||||
tt['telepathic_tile_thieves_town_upstairs'] = "Secret power is said to be in the shovel."
|
||||
tt['blind_by_the_light'] = "I'd really dig it if you didn't bring a shovel."
|
||||
tt['telepathic_tile_ice_entrace'] = "Kholdstare's hypnotic eyes can be confusing..."
|
||||
tt['telepathic_tile_ice_stalfos_knights_room'] = "Bomb fuses may be shorter or longer than they appear."
|
||||
tt['telepathic_tile_ice_large_room'] = "Does your sword feel heavier than usual?"
|
||||
tt['telepathic_tile_misery_mire'] = "Vitreous' small eyes require explosives to defeat."
|
||||
tt['telepathic_tile_turtle_rock'] = "Trinexx has upped her defenses, requiring more powerful spells to defeat her. Consider whether you have enough magic reserves."
|
||||
|
||||
ganon_mock = 'Can you keep up with my changing weaknesses?';
|
||||
tt['ganon_phase_3_no_bow'] = ganon_mock
|
||||
tt['ganon_phase_3_no_silvers'] = ganon_mock
|
||||
tt['ganon_phase_3_no_silvers_alt'] = ganon_mock
|
||||
tt['ganon_phase_3_silvers'] = ganon_mock
|
||||
|
||||
tt.insertText('ganon_fall_in_mushroom', "I smell a mushroom!")
|
||||
tt.insertText('ganon_phase_3_mushroom', "Your mushroom grants me invulnerability!")
|
||||
tt.insertText('ganon_phase_4_silvers', "\n SILVER ARROWS ")
|
||||
tt.insertText('ganon_phase_4_boomerang', "\n BOOMERANG ")
|
||||
tt.insertText('ganon_phase_4_hookshot', "\n HOOKSHOT ")
|
||||
tt.insertText('ganon_phase_4_bomb', "\n BOMB ")
|
||||
tt.insertText('ganon_phase_4_powder', "\n POWDER ")
|
||||
tt.insertText('ganon_phase_4_fire_rod', "\n FIRE ROD ")
|
||||
tt.insertText('ganon_phase_4_ice_rod', "\n ICE ROD ")
|
||||
tt.insertText('ganon_phase_4_bombos', "\n BOMBOS ")
|
||||
tt.insertText('ganon_phase_4_ether', "\n ETHER ")
|
||||
tt.insertText('ganon_phase_4_quake', "\n QUAKE ")
|
||||
tt.insertText('ganon_phase_4_hammer', "\n HAMMER ")
|
||||
tt.insertText('ganon_phase_4_bee', "\n BEE ")
|
||||
tt.insertText('ganon_phase_4_somaria', "\n SOMARIA ")
|
||||
tt.insertText('ganon_phase_4_byrna', "\n BYRNA ")
|
||||
|
||||
# inverted spawn menu changes
|
||||
if world.mode[player] == 'inverted':
|
||||
tt['menu_start_2'] = "{MENU}\n{SPEED0}\n≥@'s House\n Dark Chapel\n{CHOICE3}"
|
||||
|
||||
10
Text.py
10
Text.py
@@ -1390,6 +1390,16 @@ class TextTable(object):
|
||||
return data.ljust(self.SIZE, b'\xff')
|
||||
return data
|
||||
|
||||
def insertText(self, key, value):
|
||||
if key in self._text:
|
||||
raise KeyError(key)
|
||||
if isinstance(value, str):
|
||||
self._text[key] = CompressedTextMapper.convert(value)
|
||||
else:
|
||||
self._text[key] = value
|
||||
self._text.move_to_end('end_pad_data')
|
||||
self._text.move_to_end('terminator')
|
||||
|
||||
def removeUnwantedText(self):
|
||||
nomessage = bytes(CompressedTextMapper.convert("{NOTEXT}", False))
|
||||
messages_to_zero = [
|
||||
|
||||
@@ -603,5 +603,9 @@
|
||||
]
|
||||
},
|
||||
"outputname": {},
|
||||
"code": {}
|
||||
"code": {},
|
||||
"trolls": {
|
||||
"action": "store_true",
|
||||
"type": "bool"
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user