71
worlds/ff1/Items.py
Normal file
71
worlds/ff1/Items.py
Normal file
@@ -0,0 +1,71 @@
|
||||
import json
|
||||
from pathlib import Path
|
||||
from typing import Dict, Set, NamedTuple, List
|
||||
|
||||
from BaseClasses import Item
|
||||
|
||||
|
||||
class ItemData(NamedTuple):
|
||||
name: str
|
||||
code: int
|
||||
item_type: str
|
||||
progression: bool
|
||||
|
||||
|
||||
FF1_BRIDGE = 'Bridge'
|
||||
|
||||
|
||||
FF1_STARTER_ITEMS = [
|
||||
"Ship"
|
||||
]
|
||||
|
||||
FF1_PROGRESSION_LIST = [
|
||||
"Rod", "Cube", "Lute", "Key", "Chime", "Oxyale",
|
||||
"Ship", "Canoe", "Floater", "Canal",
|
||||
"Crown", "Crystal", "Herb", "Tnt", "Adamant", "Slab", "Ruby", "Bottle",
|
||||
"Shard",
|
||||
"EarthOrb", "FireOrb", "WaterOrb", "AirOrb"
|
||||
]
|
||||
|
||||
|
||||
class FF1Items:
|
||||
_item_table: List[ItemData] = []
|
||||
_item_table_lookup: Dict[str, ItemData] = {}
|
||||
|
||||
def _populate_item_table_from_data(self):
|
||||
base_path = Path(__file__).parent
|
||||
file_path = (base_path / "data/items.json").resolve()
|
||||
with open(file_path) as file:
|
||||
items = json.load(file)
|
||||
# Hardcode progression and categories for now
|
||||
self._item_table = [ItemData(name, code, "FF1Item", name in FF1_PROGRESSION_LIST)
|
||||
for name, code in items.items()]
|
||||
self._item_table_lookup = {item.name: item for item in self._item_table}
|
||||
|
||||
def _get_item_table(self) -> List[ItemData]:
|
||||
if not self._item_table or not self._item_table_lookup:
|
||||
self._populate_item_table_from_data()
|
||||
return self._item_table
|
||||
|
||||
def _get_item_table_lookup(self) -> Dict[str, ItemData]:
|
||||
if not self._item_table or not self._item_table_lookup:
|
||||
self._populate_item_table_from_data()
|
||||
return self._item_table_lookup
|
||||
|
||||
def get_item_names_per_category(self) -> Dict[str, Set[str]]:
|
||||
categories: Dict[str, Set[str]] = {}
|
||||
|
||||
for item in self._get_item_table():
|
||||
categories.setdefault(item.item_type, set()).add(item.name)
|
||||
|
||||
return categories
|
||||
|
||||
def generate_item(self, name: str, player: int) -> Item:
|
||||
item = self._get_item_table_lookup().get(name)
|
||||
return Item(name, item.progression, item.code, player)
|
||||
|
||||
def get_item_name_to_code_dict(self) -> Dict[str, int]:
|
||||
return {name: item.code for name, item in self._get_item_table_lookup().items()}
|
||||
|
||||
def get_item(self, name: str) -> ItemData:
|
||||
return self._get_item_table_lookup()[name]
|
||||
75
worlds/ff1/Locations.py
Normal file
75
worlds/ff1/Locations.py
Normal file
@@ -0,0 +1,75 @@
|
||||
import json
|
||||
from pathlib import Path
|
||||
from typing import Dict, NamedTuple, List, Optional
|
||||
|
||||
from BaseClasses import Region, RegionType, Location
|
||||
|
||||
EventId: Optional[int] = None
|
||||
CHAOS_TERMINATED_EVENT = 'Terminated Chaos'
|
||||
|
||||
|
||||
class LocationData(NamedTuple):
|
||||
name: str
|
||||
address: int
|
||||
|
||||
|
||||
class FF1Locations:
|
||||
_location_table: List[LocationData] = []
|
||||
_location_table_lookup: Dict[str, LocationData] = {}
|
||||
|
||||
def _populate_item_table_from_data(self):
|
||||
base_path = Path(__file__).parent
|
||||
file_path = (base_path / "data/locations.json").resolve()
|
||||
with open(file_path) as file:
|
||||
locations = json.load(file)
|
||||
# Hardcode progression and categories for now
|
||||
self._location_table = [LocationData(name, code) for name, code in locations.items()]
|
||||
self._location_table_lookup = {item.name: item for item in self._location_table}
|
||||
|
||||
def _get_location_table(self) -> List[LocationData]:
|
||||
if not self._location_table or not self._location_table_lookup:
|
||||
self._populate_item_table_from_data()
|
||||
return self._location_table
|
||||
|
||||
def _get_location_table_lookup(self) -> Dict[str, LocationData]:
|
||||
if not self._location_table or not self._location_table_lookup:
|
||||
self._populate_item_table_from_data()
|
||||
return self._location_table_lookup
|
||||
|
||||
def get_location_name_to_address_dict(self) -> Dict[str, int]:
|
||||
data = {name: location.address for name, location in self._get_location_table_lookup().items()}
|
||||
data[CHAOS_TERMINATED_EVENT] = EventId
|
||||
return data
|
||||
|
||||
@staticmethod
|
||||
def create_menu_region(player: int, locations: Dict[str, int],
|
||||
rules: Dict[str, List[List[str]]]) -> Region:
|
||||
menu_region = Region("Menu", RegionType.Generic, "Menu", player)
|
||||
for name, address in locations.items():
|
||||
location = Location(player, name, address, menu_region)
|
||||
## TODO REMOVE WHEN LOGIC FOR TOFR IS CORRECT
|
||||
if "ToFR" in name:
|
||||
rules_list = [["Rod", "Cube", "Lute", "Key", "Chime", "Oxyale",
|
||||
"Ship", "Canoe", "Floater", "Canal",
|
||||
"Crown", "Crystal", "Herb", "Tnt", "Adamant", "Slab", "Ruby", "Bottle"]]
|
||||
location.access_rule = generate_rule(rules_list, player)
|
||||
elif name in rules:
|
||||
rules_list = rules[name]
|
||||
location.access_rule = generate_rule(rules_list, player)
|
||||
menu_region.locations.append(location)
|
||||
|
||||
return menu_region
|
||||
|
||||
|
||||
def generate_rule(rules_list, player):
|
||||
def x(state):
|
||||
for rule in rules_list:
|
||||
current_state = True
|
||||
for item in rule:
|
||||
if not state.has(item, player):
|
||||
current_state = False
|
||||
break
|
||||
if current_state:
|
||||
return True
|
||||
return False
|
||||
return x
|
||||
22
worlds/ff1/Options.py
Normal file
22
worlds/ff1/Options.py
Normal file
@@ -0,0 +1,22 @@
|
||||
from typing import Dict
|
||||
|
||||
from Options import OptionDict
|
||||
|
||||
|
||||
class Locations(OptionDict):
|
||||
displayname = "locations"
|
||||
|
||||
|
||||
class Items(OptionDict):
|
||||
displayname = "items"
|
||||
|
||||
|
||||
class Rules(OptionDict):
|
||||
displayname = "rules"
|
||||
|
||||
|
||||
ff1_options: Dict[str, OptionDict] = {
|
||||
"locations": Locations,
|
||||
"items": Items,
|
||||
"rules": Rules
|
||||
}
|
||||
97
worlds/ff1/__init__.py
Normal file
97
worlds/ff1/__init__.py
Normal file
@@ -0,0 +1,97 @@
|
||||
from typing import Dict
|
||||
from BaseClasses import Item, Location, MultiWorld
|
||||
from .Items import ItemData, FF1Items, FF1_STARTER_ITEMS, FF1_PROGRESSION_LIST, FF1_BRIDGE
|
||||
from .Locations import EventId, FF1Locations, generate_rule, CHAOS_TERMINATED_EVENT
|
||||
from .Options import ff1_options
|
||||
from ..AutoWorld import World
|
||||
|
||||
|
||||
class FF1World(World):
|
||||
"""
|
||||
Final Fantasy 1, originally released on the NES on 1987, is the game that started the beloved, long running series.
|
||||
The randomizer takes the original 8-bit Final Fantasy game for NES (USA edition) and allows you to
|
||||
shuffle important aspects like the location of key items, the difficulty of monsters and fiends,
|
||||
and even the location of towns and dungeons.
|
||||
Part puzzle and part speed-run, it breathes new life into one of the most influential games ever made.
|
||||
"""
|
||||
|
||||
options = ff1_options
|
||||
game = "Final Fantasy"
|
||||
topology_present = False
|
||||
remote_items = True
|
||||
data_version = 0
|
||||
remote_start_inventory = True
|
||||
|
||||
ff1_items = FF1Items()
|
||||
ff1_locations = FF1Locations()
|
||||
item_name_groups = ff1_items.get_item_names_per_category()
|
||||
item_name_to_id = ff1_items.get_item_name_to_code_dict()
|
||||
location_name_to_id = ff1_locations.get_location_name_to_address_dict()
|
||||
|
||||
def __init__(self, world: MultiWorld, player: int):
|
||||
super().__init__(world, player)
|
||||
self.locked_items = []
|
||||
self.locked_locations = []
|
||||
|
||||
def generate_early(self):
|
||||
return
|
||||
|
||||
def create_regions(self):
|
||||
locations = get_options(self.world, 'locations', self.player)
|
||||
rules = get_options(self.world, 'rules', self.player)
|
||||
menu_region = self.ff1_locations.create_menu_region(self.player, locations, rules)
|
||||
terminated_event = Location(self.player, CHAOS_TERMINATED_EVENT, EventId, menu_region)
|
||||
terminated_item = Item(CHAOS_TERMINATED_EVENT, True, EventId, self.player)
|
||||
terminated_event.place_locked_item(terminated_item)
|
||||
|
||||
items = get_options(self.world, 'items', self.player)
|
||||
goal_rule = generate_rule([[name for name in items.keys() if name in FF1_PROGRESSION_LIST and name != "Shard"]],
|
||||
self.player)
|
||||
if "Shard" in items.keys():
|
||||
def goal_rule_and_shards(state):
|
||||
return goal_rule(state) and state.has("Shard", self.player, 32)
|
||||
terminated_event.access_rule = goal_rule_and_shards
|
||||
|
||||
menu_region.locations.append(terminated_event)
|
||||
self.world.regions += [menu_region]
|
||||
|
||||
def create_item(self, name: str) -> Item:
|
||||
return self.ff1_items.generate_item(name, self.player)
|
||||
|
||||
def set_rules(self):
|
||||
self.world.completion_condition[self.player] = lambda state: state.has(CHAOS_TERMINATED_EVENT, self.player)
|
||||
|
||||
def generate_basic(self):
|
||||
items = get_options(self.world, 'items', self.player)
|
||||
if FF1_BRIDGE in items.keys():
|
||||
self._place_locked_item_in_sphere0(FF1_BRIDGE)
|
||||
if items:
|
||||
possible_early_items = [name for name in FF1_STARTER_ITEMS if name in items.keys()]
|
||||
if possible_early_items:
|
||||
progression_item = self.world.random.choice(possible_early_items)
|
||||
self._place_locked_item_in_sphere0(progression_item)
|
||||
items = [self.create_item(name) for name, data in items.items() for x in range(data['count']) if name not in
|
||||
self.locked_items]
|
||||
|
||||
self.world.itempool += items
|
||||
|
||||
def _place_locked_item_in_sphere0(self, progression_item: str):
|
||||
if progression_item:
|
||||
rules = get_options(self.world, 'rules', self.player)
|
||||
sphere_0_locations = [name for name, rules in rules.items()
|
||||
if rules and len(rules[0]) == 0 and name not in self.locked_locations]
|
||||
if sphere_0_locations:
|
||||
initial_location = self.world.random.choice(sphere_0_locations)
|
||||
locked_location = self.world.get_location(initial_location, self.player)
|
||||
locked_location.place_locked_item(self.create_item(progression_item))
|
||||
self.locked_items.append(progression_item)
|
||||
self.locked_locations.append(locked_location.name)
|
||||
|
||||
def fill_slot_data(self) -> Dict[str, object]:
|
||||
slot_data: Dict[str, object] = {}
|
||||
|
||||
return slot_data
|
||||
|
||||
|
||||
def get_options(world: MultiWorld, name: str, player: int):
|
||||
return getattr(world, name, None)[player].value
|
||||
194
worlds/ff1/data/items.json
Normal file
194
worlds/ff1/data/items.json
Normal file
@@ -0,0 +1,194 @@
|
||||
{
|
||||
"None": 256,
|
||||
"Lute": 257,
|
||||
"Crown": 258,
|
||||
"Crystal": 259,
|
||||
"Herb": 260,
|
||||
"Key": 261,
|
||||
"Tnt": 262,
|
||||
"Adamant": 263,
|
||||
"Slab": 264,
|
||||
"Ruby": 265,
|
||||
"Rod": 266,
|
||||
"Floater": 267,
|
||||
"Chime": 268,
|
||||
"Tail": 269,
|
||||
"Cube": 270,
|
||||
"Bottle": 271,
|
||||
"Oxyale": 272,
|
||||
"EarthOrb": 273,
|
||||
"FireOrb": 274,
|
||||
"WaterOrb": 275,
|
||||
"AirOrb": 276,
|
||||
"Shard": 277,
|
||||
"Tent": 278,
|
||||
"Cabin": 279,
|
||||
"House": 280,
|
||||
"Heal": 281,
|
||||
"Pure": 282,
|
||||
"Soft": 283,
|
||||
"WoodenNunchucks": 284,
|
||||
"SmallKnife": 285,
|
||||
"WoodenRod": 286,
|
||||
"Rapier": 287,
|
||||
"IronHammer": 288,
|
||||
"ShortSword": 289,
|
||||
"HandAxe": 290,
|
||||
"Scimitar": 291,
|
||||
"IronNunchucks": 292,
|
||||
"LargeKnife": 293,
|
||||
"IronStaff": 294,
|
||||
"Sabre": 295,
|
||||
"LongSword": 296,
|
||||
"GreatAxe": 297,
|
||||
"Falchon": 298,
|
||||
"SilverKnife": 299,
|
||||
"SilverSword": 300,
|
||||
"SilverHammer": 301,
|
||||
"SilverAxe": 302,
|
||||
"FlameSword": 303,
|
||||
"IceSword": 304,
|
||||
"DragonSword": 305,
|
||||
"GiantSword": 306,
|
||||
"SunSword": 307,
|
||||
"CoralSword": 308,
|
||||
"WereSword": 309,
|
||||
"RuneSword": 310,
|
||||
"PowerRod": 311,
|
||||
"LightAxe": 312,
|
||||
"HealRod": 313,
|
||||
"MageRod": 314,
|
||||
"Defense": 315,
|
||||
"WizardRod": 316,
|
||||
"Vorpal": 317,
|
||||
"CatClaw": 318,
|
||||
"ThorHammer": 319,
|
||||
"BaneSword": 320,
|
||||
"Katana": 321,
|
||||
"Xcalber": 322,
|
||||
"Masamune": 323,
|
||||
"Cloth": 324,
|
||||
"WoodenArmor": 325,
|
||||
"ChainArmor": 326,
|
||||
"IronArmor": 327,
|
||||
"SteelArmor": 328,
|
||||
"SilverArmor": 329,
|
||||
"FlameArmor": 330,
|
||||
"IceArmor": 331,
|
||||
"OpalArmor": 332,
|
||||
"DragonArmor": 333,
|
||||
"Copper": 334,
|
||||
"Silver": 335,
|
||||
"Gold": 336,
|
||||
"Opal": 337,
|
||||
"WhiteShirt": 338,
|
||||
"BlackShirt": 339,
|
||||
"WoodenShield": 340,
|
||||
"IronShield": 341,
|
||||
"SilverShield": 342,
|
||||
"FlameShield": 343,
|
||||
"IceShield": 344,
|
||||
"OpalShield": 345,
|
||||
"AegisShield": 346,
|
||||
"Buckler": 347,
|
||||
"ProCape": 348,
|
||||
"Cap": 349,
|
||||
"WoodenHelm": 350,
|
||||
"IronHelm": 351,
|
||||
"SilverHelm": 352,
|
||||
"OpalHelm": 353,
|
||||
"HealHelm": 354,
|
||||
"Ribbon": 355,
|
||||
"Gloves": 356,
|
||||
"CopperGauntlets": 357,
|
||||
"IronGauntlets": 358,
|
||||
"SilverGauntlets": 359,
|
||||
"ZeusGauntlets": 360,
|
||||
"PowerGauntlets": 361,
|
||||
"OpalGauntlets": 362,
|
||||
"ProRing": 363,
|
||||
"Gold10": 364,
|
||||
"Gold20": 365,
|
||||
"Gold25": 366,
|
||||
"Gold30": 367,
|
||||
"Gold55": 368,
|
||||
"Gold70": 369,
|
||||
"Gold85": 370,
|
||||
"Gold110": 371,
|
||||
"Gold135": 372,
|
||||
"Gold155": 373,
|
||||
"Gold160": 374,
|
||||
"Gold180": 375,
|
||||
"Gold240": 376,
|
||||
"Gold255": 377,
|
||||
"Gold260": 378,
|
||||
"Gold295": 379,
|
||||
"Gold300": 380,
|
||||
"Gold315": 381,
|
||||
"Gold330": 382,
|
||||
"Gold350": 383,
|
||||
"Gold385": 384,
|
||||
"Gold400": 385,
|
||||
"Gold450": 386,
|
||||
"Gold500": 387,
|
||||
"Gold530": 388,
|
||||
"Gold575": 389,
|
||||
"Gold620": 390,
|
||||
"Gold680": 391,
|
||||
"Gold750": 392,
|
||||
"Gold795": 393,
|
||||
"Gold880": 394,
|
||||
"Gold1020": 395,
|
||||
"Gold1250": 396,
|
||||
"Gold1455": 397,
|
||||
"Gold1520": 398,
|
||||
"Gold1760": 399,
|
||||
"Gold1975": 400,
|
||||
"Gold2000": 401,
|
||||
"Gold2750": 402,
|
||||
"Gold3400": 403,
|
||||
"Gold4150": 404,
|
||||
"Gold5000": 405,
|
||||
"Gold5450": 406,
|
||||
"Gold6400": 407,
|
||||
"Gold6720": 408,
|
||||
"Gold7340": 409,
|
||||
"Gold7690": 410,
|
||||
"Gold7900": 411,
|
||||
"Gold8135": 412,
|
||||
"Gold9000": 413,
|
||||
"Gold9300": 414,
|
||||
"Gold9500": 415,
|
||||
"Gold9900": 416,
|
||||
"Gold10000": 417,
|
||||
"Gold12350": 418,
|
||||
"Gold13000": 419,
|
||||
"Gold13450": 420,
|
||||
"Gold14050": 421,
|
||||
"Gold14720": 422,
|
||||
"Gold15000": 423,
|
||||
"Gold17490": 424,
|
||||
"Gold18010": 425,
|
||||
"Gold19990": 426,
|
||||
"Gold20000": 427,
|
||||
"Gold20010": 428,
|
||||
"Gold26000": 429,
|
||||
"Gold45000": 430,
|
||||
"Gold65000": 431,
|
||||
"Smoke": 435,
|
||||
"FullCure": 432,
|
||||
"Blast": 434,
|
||||
"Phoenix": 433,
|
||||
"Flare": 437,
|
||||
"Black": 438,
|
||||
"Refresh": 436,
|
||||
"Guard": 439,
|
||||
"Wizard": 442,
|
||||
"HighPotion": 441,
|
||||
"Cloak": 443,
|
||||
"Quick": 440,
|
||||
"Ship": 480,
|
||||
"Bridge": 488,
|
||||
"Canal": 492,
|
||||
"Canoe": 498
|
||||
}
|
||||
257
worlds/ff1/data/locations.json
Normal file
257
worlds/ff1/data/locations.json
Normal file
@@ -0,0 +1,257 @@
|
||||
{
|
||||
"Coneria1": 257,
|
||||
"Coneria2": 258,
|
||||
"ConeriaMajor": 259,
|
||||
"Coneria4": 260,
|
||||
"Coneria5": 261,
|
||||
"Coneria6": 262,
|
||||
"MatoyasCave1": 299,
|
||||
"MatoyasCave3": 301,
|
||||
"MatoyasCave2": 300,
|
||||
"NorthwestCastle1": 273,
|
||||
"NorthwestCastle3": 275,
|
||||
"NorthwestCastle2": 274,
|
||||
"ToFTopLeft1": 263,
|
||||
"ToFBottomLeft": 265,
|
||||
"ToFTopLeft2": 264,
|
||||
"ToFRevisited6": 509,
|
||||
"ToFRevisited4": 507,
|
||||
"ToFRMasmune": 504,
|
||||
"ToFRevisited5": 508,
|
||||
"ToFRevisited3": 506,
|
||||
"ToFRevisited2": 505,
|
||||
"ToFRevisited7": 510,
|
||||
"ToFTopRight1": 267,
|
||||
"ToFTopRight2": 268,
|
||||
"ToFBottomRight": 266,
|
||||
"IceCave15": 377,
|
||||
"IceCave16": 378,
|
||||
"IceCave9": 371,
|
||||
"IceCave11": 373,
|
||||
"IceCave10": 372,
|
||||
"IceCave12": 374,
|
||||
"IceCave13": 375,
|
||||
"IceCave14": 376,
|
||||
"IceCave1": 363,
|
||||
"IceCave2": 364,
|
||||
"IceCave3": 365,
|
||||
"IceCave4": 366,
|
||||
"IceCave5": 367,
|
||||
"IceCaveMajor": 370,
|
||||
"IceCave7": 369,
|
||||
"IceCave6": 368,
|
||||
"Elfland1": 269,
|
||||
"Elfland2": 270,
|
||||
"Elfland3": 271,
|
||||
"Elfland4": 272,
|
||||
"Ordeals5": 383,
|
||||
"Ordeals6": 384,
|
||||
"Ordeals7": 385,
|
||||
"Ordeals1": 379,
|
||||
"Ordeals2": 380,
|
||||
"Ordeals3": 381,
|
||||
"Ordeals4": 382,
|
||||
"OrdealsMajor": 387,
|
||||
"Ordeals8": 386,
|
||||
"SeaShrine7": 411,
|
||||
"SeaShrine8": 412,
|
||||
"SeaShrine9": 413,
|
||||
"SeaShrine10": 414,
|
||||
"SeaShrine1": 405,
|
||||
"SeaShrine2": 406,
|
||||
"SeaShrine3": 407,
|
||||
"SeaShrine4": 408,
|
||||
"SeaShrine5": 409,
|
||||
"SeaShrine6": 410,
|
||||
"SeaShrine13": 417,
|
||||
"SeaShrine14": 418,
|
||||
"SeaShrine11": 415,
|
||||
"SeaShrine15": 419,
|
||||
"SeaShrine16": 420,
|
||||
"SeaShrineLocked": 421,
|
||||
"SeaShrine18": 422,
|
||||
"SeaShrine19": 423,
|
||||
"SeaShrine20": 424,
|
||||
"SeaShrine23": 427,
|
||||
"SeaShrine21": 425,
|
||||
"SeaShrine22": 426,
|
||||
"SeaShrine24": 428,
|
||||
"SeaShrine26": 430,
|
||||
"SeaShrine28": 432,
|
||||
"SeaShrine25": 429,
|
||||
"SeaShrine30": 434,
|
||||
"SeaShrine31": 435,
|
||||
"SeaShrine27": 431,
|
||||
"SeaShrine29": 433,
|
||||
"SeaShrineMajor": 436,
|
||||
"SeaShrine12": 416,
|
||||
"DwarfCave3": 291,
|
||||
"DwarfCave4": 292,
|
||||
"DwarfCave6": 294,
|
||||
"DwarfCave7": 295,
|
||||
"DwarfCave5": 293,
|
||||
"DwarfCave8": 296,
|
||||
"DwarfCave9": 297,
|
||||
"DwarfCave10": 298,
|
||||
"DwarfCave1": 289,
|
||||
"DwarfCave2": 290,
|
||||
"Waterfall1": 437,
|
||||
"Waterfall2": 438,
|
||||
"Waterfall3": 439,
|
||||
"Waterfall4": 440,
|
||||
"Waterfall5": 441,
|
||||
"Waterfall6": 442,
|
||||
"MirageTower5": 456,
|
||||
"MirageTower16": 467,
|
||||
"MirageTower17": 468,
|
||||
"MirageTower15": 466,
|
||||
"MirageTower18": 469,
|
||||
"MirageTower14": 465,
|
||||
"SkyPalace1": 470,
|
||||
"SkyPalace2": 471,
|
||||
"SkyPalace3": 472,
|
||||
"SkyPalace4": 473,
|
||||
"SkyPalace18": 487,
|
||||
"SkyPalace19": 488,
|
||||
"SkyPalace16": 485,
|
||||
"SkyPalaceMajor": 489,
|
||||
"SkyPalace17": 486,
|
||||
"SkyPalace22": 491,
|
||||
"SkyPalace21": 490,
|
||||
"SkyPalace23": 492,
|
||||
"SkyPalace24": 493,
|
||||
"SkyPalace31": 500,
|
||||
"SkyPalace32": 501,
|
||||
"SkyPalace33": 502,
|
||||
"SkyPalace34": 503,
|
||||
"SkyPalace29": 498,
|
||||
"SkyPalace26": 495,
|
||||
"SkyPalace25": 494,
|
||||
"SkyPalace28": 497,
|
||||
"SkyPalace27": 496,
|
||||
"SkyPalace30": 499,
|
||||
"SkyPalace14": 483,
|
||||
"SkyPalace11": 480,
|
||||
"SkyPalace12": 481,
|
||||
"SkyPalace13": 482,
|
||||
"SkyPalace15": 484,
|
||||
"SkyPalace10": 479,
|
||||
"SkyPalace5": 474,
|
||||
"SkyPalace6": 475,
|
||||
"SkyPalace7": 476,
|
||||
"SkyPalace8": 477,
|
||||
"SkyPalace9": 478,
|
||||
"MirageTower9": 460,
|
||||
"MirageTower13": 464,
|
||||
"MirageTower10": 461,
|
||||
"MirageTower12": 463,
|
||||
"MirageTower11": 462,
|
||||
"MirageTower1": 452,
|
||||
"MirageTower2": 453,
|
||||
"MirageTower4": 455,
|
||||
"MirageTower3": 454,
|
||||
"MirageTower8": 459,
|
||||
"MirageTower7": 458,
|
||||
"MirageTower6": 457,
|
||||
"Volcano30": 359,
|
||||
"Volcano32": 361,
|
||||
"Volcano31": 360,
|
||||
"Volcano28": 357,
|
||||
"Volcano29": 358,
|
||||
"Volcano21": 350,
|
||||
"Volcano20": 349,
|
||||
"Volcano24": 353,
|
||||
"Volcano19": 348,
|
||||
"Volcano25": 354,
|
||||
"VolcanoMajor": 362,
|
||||
"Volcano26": 355,
|
||||
"Volcano27": 356,
|
||||
"Volcano22": 351,
|
||||
"Volcano23": 352,
|
||||
"Volcano1": 330,
|
||||
"Volcano9": 338,
|
||||
"Volcano2": 331,
|
||||
"Volcano10": 339,
|
||||
"Volcano3": 332,
|
||||
"Volcano8": 337,
|
||||
"Volcano4": 333,
|
||||
"Volcano13": 342,
|
||||
"Volcano11": 340,
|
||||
"Volcano7": 336,
|
||||
"Volcano6": 335,
|
||||
"Volcano5": 334,
|
||||
"Volcano14": 343,
|
||||
"Volcano12": 341,
|
||||
"Volcano15": 344,
|
||||
"Volcano18": 347,
|
||||
"Volcano17": 346,
|
||||
"Volcano16": 345,
|
||||
"MarshCave6": 281,
|
||||
"MarshCave5": 280,
|
||||
"MarshCave7": 282,
|
||||
"MarshCave8": 283,
|
||||
"MarshCave10": 285,
|
||||
"MarshCave2": 277,
|
||||
"MarshCave11": 286,
|
||||
"MarshCave3": 278,
|
||||
"MarshCaveMajor": 284,
|
||||
"MarshCave12": 287,
|
||||
"MarshCave4": 279,
|
||||
"MarshCave1": 276,
|
||||
"MarshCave13": 288,
|
||||
"TitansTunnel1": 326,
|
||||
"TitansTunnel2": 327,
|
||||
"TitansTunnel3": 328,
|
||||
"TitansTunnel4": 329,
|
||||
"EarthCave1": 302,
|
||||
"EarthCave2": 303,
|
||||
"EarthCave5": 306,
|
||||
"EarthCave3": 304,
|
||||
"EarthCave4": 305,
|
||||
"EarthCave9": 310,
|
||||
"EarthCave10": 311,
|
||||
"EarthCave11": 312,
|
||||
"EarthCave6": 307,
|
||||
"EarthCave7": 308,
|
||||
"EarthCave12": 313,
|
||||
"EarthCaveMajor": 317,
|
||||
"EarthCave19": 320,
|
||||
"EarthCave17": 318,
|
||||
"EarthCave18": 319,
|
||||
"EarthCave20": 321,
|
||||
"EarthCave24": 325,
|
||||
"EarthCave21": 322,
|
||||
"EarthCave22": 323,
|
||||
"EarthCave23": 324,
|
||||
"EarthCave13": 314,
|
||||
"EarthCave15": 316,
|
||||
"EarthCave14": 315,
|
||||
"EarthCave8": 309,
|
||||
"Cardia11": 398,
|
||||
"Cardia9": 396,
|
||||
"Cardia10": 397,
|
||||
"Cardia6": 393,
|
||||
"Cardia8": 395,
|
||||
"Cardia7": 394,
|
||||
"Cardia13": 400,
|
||||
"Cardia12": 399,
|
||||
"Cardia4": 391,
|
||||
"Cardia5": 392,
|
||||
"Cardia3": 390,
|
||||
"Cardia1": 388,
|
||||
"Cardia2": 389,
|
||||
"CaravanShop": 767,
|
||||
"King": 513,
|
||||
"Princess2": 530,
|
||||
"Matoya": 522,
|
||||
"Astos": 519,
|
||||
"Bikke": 516,
|
||||
"CanoeSage": 533,
|
||||
"ElfPrince": 518,
|
||||
"Nerrick": 520,
|
||||
"Smith": 521,
|
||||
"CubeBot": 529,
|
||||
"Sarda": 525,
|
||||
"Fairy": 531,
|
||||
"Lefein": 527
|
||||
}
|
||||
Reference in New Issue
Block a user