forked from OoTRandomizer/OoT-Randomizer
-
Notifications
You must be signed in to change notification settings - Fork 5
/
Dungeon.py
142 lines (116 loc) · 5.79 KB
/
Dungeon.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
from __future__ import annotations
from collections.abc import Iterator
from typing import TYPE_CHECKING, Optional, Any
if TYPE_CHECKING:
from Hints import HintArea
from Item import Item
from Region import Region
from World import World
class Dungeon:
def __init__(self, world: World, name: str, hint: HintArea, regions: Optional[list[Region]] = None) -> None:
self.world: World = world
self.name: str = name
self.hint: HintArea = hint
self.regions: list[Region] = regions if regions is not None else []
self.boss_key: list[Item] = []
self.small_keys: list[Item] = []
self.dungeon_items: list[Item] = []
self.silver_rupees: list[Item] = []
self.reward: list[Item] = []
if regions is None:
for region in world.regions:
if region.dungeon_name != self.name:
continue
region.dungeon = self
self.regions.append(region)
def copy(self) -> Dungeon:
new_dungeon = Dungeon(world=self.world, name=self.name, hint=self.hint, regions=[])
new_dungeon.regions = [region for region in self.regions]
new_dungeon.boss_key = [item for item in self.boss_key]
new_dungeon.small_keys = [item for item in self.small_keys]
new_dungeon.dungeon_items = [item for item in self.dungeon_items]
new_dungeon.silver_rupees = [item for item in self.silver_rupees]
new_dungeon.reward = [item for item in self.reward]
return new_dungeon
@staticmethod
def from_vanilla_reward(item: Item) -> Dungeon:
dungeons = [dungeon for dungeon in item.world.dungeons if dungeon.vanilla_reward == item.name]
if dungeons:
return dungeons[0]
@property
def shuffle_mapcompass(self) -> str:
return self.world.settings.shuffle_mapcompass
@property
def shuffle_smallkeys(self) -> str:
return self.world.settings.shuffle_smallkeys
@property
def shuffle_bosskeys(self) -> str:
return self.world.settings.shuffle_bosskeys if self.name != 'Ganons Castle' else self.world.settings.shuffle_ganon_bosskey
@property
def shuffle_silver_rupees(self) -> str:
return self.world.settings.shuffle_silver_rupees
@property
def shuffle_dungeon_rewards(self) -> str:
return self.world.settings.shuffle_dungeon_rewards
@property
def empty(self) -> bool:
return self.world.empty_dungeons[self.name].empty
@property
def keys(self) -> list[Item]:
return self.small_keys + self.boss_key
@property
def all_items(self) -> list[Item]:
return self.dungeon_items + self.keys + self.silver_rupees + self.reward
@property
def vanilla_boss_name(self) -> Optional[str]:
return {
'Deku Tree': 'Queen Gohma',
'Dodongos Cavern': 'King Dodongo',
'Jabu Jabus Belly': 'Barinade',
'Forest Temple': 'Phantom Ganon',
'Fire Temple': 'Volvagia',
'Water Temple': 'Morpha',
'Shadow Temple': 'Bongo Bongo',
'Spirit Temple': 'Twinrova',
}.get(self.name)
@property
def vanilla_reward(self) -> Optional[str]:
if self.vanilla_boss_name is not None:
return self.world.get_location(self.vanilla_boss_name).vanilla_item
def item_name(self, text: str) -> str:
return f"{text} ({self.name})"
def get_silver_rupee_names(self) -> set[str]:
from Item import ItemInfo
return {name for name, item in ItemInfo.items.items() if item.type == 'SilverRupee' and self.name in name}
def get_item_names(self) -> set[str]:
return (self.get_silver_rupee_names() |
{self.item_name(name) for name in ["Map", "Compass", "Small Key", "Boss Key", "Small Key Ring"]})
def is_dungeon_item(self, item: Item) -> bool:
return item.name in [dungeon_item.name for dungeon_item in self.all_items]
def get_restricted_dungeon_items(self) -> Iterator[Item]:
if self.shuffle_mapcompass == 'dungeon' or (self.empty and self.shuffle_mapcompass in ['any_dungeon', 'overworld', 'keysanity', 'regional']):
yield from self.dungeon_items
if self.shuffle_smallkeys == 'dungeon' or (self.empty and self.shuffle_smallkeys in ['any_dungeon', 'overworld', 'keysanity', 'regional']):
yield from self.small_keys
if self.shuffle_bosskeys == 'dungeon' or (self.empty and self.shuffle_bosskeys in ['any_dungeon', 'overworld', 'keysanity', 'regional']):
yield from self.boss_key
if self.shuffle_silver_rupees == 'dungeon' or (self.empty and self.shuffle_silver_rupees in ['any_dungeon', 'overworld', 'anywhere', 'regional']):
yield from self.silver_rupees
if self.shuffle_dungeon_rewards in ('vanilla', 'dungeon'): # we don't lock rewards inside pre-completed dungeons since they're still useful outside
yield from self.reward
# get a list of items that don't have to be in their proper dungeon
def get_unrestricted_dungeon_items(self) -> Iterator[Item]:
if self.empty:
return
if self.shuffle_mapcompass in ['any_dungeon', 'overworld', 'keysanity', 'regional']:
yield from self.dungeon_items
if self.shuffle_smallkeys in ['any_dungeon', 'overworld', 'keysanity', 'regional']:
yield from self.small_keys
if self.shuffle_bosskeys in ['any_dungeon', 'overworld', 'keysanity', 'regional']:
yield from self.boss_key
if self.shuffle_silver_rupees in ['any_dungeon', 'overworld', 'anywhere', 'regional']:
yield from self.silver_rupees
if self.shuffle_dungeon_rewards in ('any_dungeon', 'overworld', 'anywhere', 'regional'):
yield from self.reward
def __str__(self) -> str:
return self.name