def __init__(self, rank): self.rank = rank e = Entrance() e.location = Location(1000 + RestStop.counter, dummy=True) self.locid = e.location.locid self.clusterid = self.locid e.x, e.y = 48, 21 e.dest, e.destx, e.desty = 0, 0, 0 e.entid = None self.entrances = [e] RestStop.counter += 1
def add_entrance(self, entrance): e = Entrance() e.copy(entrance) self.entrances.append(e)
def remap_maps(routes): conlinks = [] cononeways = [] conentrances = [] conclusters = [] for route in routes: conlinks.extend(route.consolidated_links) cononeways.extend(route.consolidated_oneways) conentrances.extend(route.consolidated_entrances) conclusters.extend(route.consolidated_clusters) conclusters = sorted(set(conclusters), key=lambda c: c.clusterid) if ANCIENT: unused_maps = [ l.locid for l in get_locations() if l.locid not in towerlocids and l.locid not in PROTECTED ] rest_maps = [l.locid for l in get_unused_locations() if l.locid != 414] else: unused_maps = [l.locid for l in get_unused_locations()] rest_maps = [] for cluster in conclusters: if not isinstance(cluster, RestStop): continue locid = cluster.locid newlocid = rest_maps.pop() locexchange[(locid, locid)] = newlocid try: unused_maps.remove(newlocid) except: import pdb pdb.set_trace() for cluster in conclusters: if isinstance(cluster, RestStop): continue locid = cluster.locid if (locid, cluster.clusterid) in locexchange: continue locclusters = [ c for c in conclusters if not isinstance(c, RestStop) and c.locid == locid ] if locid in towerlocids: for c in locclusters: locexchange[(locid, c.clusterid)] = locid else: location = get_location(locid) if locid in unused_maps: newlocid = locid unused_maps = [u for u in unused_maps if u != newlocid] else: newlocid = unused_maps.pop() if location.longentrances: locexchange[(locid, cluster.clusterid)] = newlocid else: for c in locclusters: locexchange[(locid, c.clusterid)] = newlocid newlocations = [] for newlocid in sorted(set(locexchange.values())): keys = [ key for (key, value) in locexchange.items() if value == newlocid ] assert len(set([a for (a, b) in keys])) == 1 copylocid = keys[0][0] if copylocid >= 1000: cluster = [c for c in conclusters if c.locid == copylocid][0] copylocid = 413 location = get_location(413) newlocation = Location(locid=newlocid, dummy=True) newlocation.copy(location) newlocation.events = [] newlocation.npcs = [] newlocation.entrance_set.entrances = [] newlocation.restrank = cluster.rank else: location = get_location(copylocid) entrances = location.entrances newlocation = Location(locid=newlocid, dummy=True) newlocation.copy(location) newlocation.events = [] newlocation.npcs = [] newlocation.entrance_set.entrances = [] fixed = [ e for e in entrances if (e.location.locid, e.entid) in FIXED_ENTRANCES ] newlocation.entrance_set.entrances.extend(fixed) locclusters = [ c for c in conclusters if locexchange[(c.locid, c.clusterid)] == newlocid ] clustents = [e for c in locclusters for e in c.entrances] clustents = [e for e in clustents if e in conentrances] for ent in clustents: destent = [(a, b) for (a, b) in conlinks if ent in (a, b)] destent += [(a, b) for (a, b) in cononeways if ent == a] assert len(destent) == 1 destent = destent[0] destent = [d for d in destent if d != ent][0] destclust = [c for c in conclusters if destent in c.entrances] assert len(destclust) == 1 destclust = destclust[0] newdestlocid = locexchange[(destclust.locid, destclust.clusterid)] if destent.location.locid >= 1000: destloc = get_location(413) destent = [d for d in destloc.entrances if d.entid == 3][0] else: destloc = get_location(destent.location.locid) destent = [ d for d in destloc.entrances if d.entid == destent.entid ][0] mirror = destent.mirror if mirror: dest = mirror.dest & 0xFE00 destx, desty = mirror.destx, mirror.desty if abs(destx - destent.x) + abs(desty - destent.y) > 3: mirror = None if not mirror: dest, destx, desty = 0x2000, destent.x, destent.y dest &= 0x3DFF dest |= newdestlocid entrance = Entrance() entrance.x, entrance.y = ent.x, ent.y entrance.dest, entrance.destx, entrance.desty = dest, destx, desty entrance.set_location(newlocation) newlocation.entrance_set.entrances.append(entrance) newlocation.setid = 0 newlocation.ancient_rank = 0 newlocation.copied = copylocid adjents = [] for ent in newlocation.entrances: for clust in locclusters: if isinstance(clust, RestStop): continue assert clust.locid == newlocation.copied if clust.has_adjacent_entrances: x, y = ent.x, ent.y for ent2 in clust.entgroups.keys(): if ent2.x == ent.x and ent2.y == ent.y: break else: continue entgroup = clust.entgroups[ent2] for ent3 in entgroup: x3, y3 = ent3.x, ent3.y if x == x3 and y == y3: continue entrance = Entrance() entrance.x, entrance.y = x3, y3 entrance.dest, entrance.destx, entrance.desty = ( ent.dest, ent.destx, ent.desty) entrance.set_location(newlocation) adjents.append(entrance) newlocation.entrance_set.entrances.extend(adjents) newlocations.append(newlocation) locations = get_locations() newlocids = [l.locid for l in newlocations] assert len(newlocids) == len(set(newlocids)) for location in newlocations: for e in location.entrances: if (location.locid, e.entid) not in FIXED_ENTRANCES: assert e.dest & 0x1FF in newlocids assert location not in locations if location.locid not in towerlocids: location.entrance_set.convert_longs() # XXX: Unnecessary??? for i, loc in enumerate(newlocations): if loc.locid in towerlocids: oldloc = get_location(loc.locid) oldloc.entrance_set.entrances = loc.entrances oldloc.ancient_rank = loc.ancient_rank oldloc.copied = oldloc.locid newlocations[i] = oldloc ranked_clusters = [] for n in range(len(routes[0].segments)): rankedcsets = [route.segments[n].ranked_clusters for route in routes] for tricluster in zip_longest(*rankedcsets, fillvalue=None): tricluster = list(tricluster) random.shuffle(tricluster) for cluster in tricluster: if cluster is None: continue if cluster.locid not in ranked_clusters: cluster.routerank = n ranked_clusters.append(cluster) ranked_locations = [] for cluster in ranked_clusters: locid, clusterid = cluster.locid, cluster.clusterid newlocid = locexchange[locid, clusterid] newloc = [l for l in newlocations if l.locid == newlocid][0] if newloc not in ranked_locations: newloc.routerank = cluster.routerank ranked_locations.append(newloc) assert len(set(ranked_locations)) == len(set(newlocations)) ranked_locations = [ l for l in ranked_locations if not hasattr(l, "restrank") ] for i, loc in enumerate(ranked_locations): loc.ancient_rank = i loc.make_tower_basic() if not ANCIENT: if loc.locid not in towerlocids: loc.make_tower_flair() from options import Options_ loc.unlock_chests( 200, 1000, uncapped_monsters=Options_.is_code_active('bsiab')) fsets = get_new_fsets("kefka's tower", 20) fset = random.choice(fsets) for formation in fset.formations: formation.set_music(6) formation.set_continuous_music() loc.setid = fset.setid switch292, gate292 = (292, 0), (292, 1) switch334, gate334 = (334, 5), (334, 3) swd = {switch292: None, switch334: None, gate292: None, gate334: None} segments = [s for route in routes for s in route.segments] for segment in segments: for cluster in segment.ranked_clusters: for key in list(swd.keys()): locid, entid = key if cluster.locid == locid and entid in cluster.entids: assert swd[key] is None swd[key] = (segment, cluster) assert None not in list(swd.values()) s292segment, s292cluster = swd[switch292] s334segment, s334cluster = swd[switch334] g292segment, g292cluster = swd[gate292] g334segment, g334cluster = swd[gate334] if s292segment == g334segment and s334segment == g292segment: assert s292segment != s334segment ranked292 = s292segment.ranked_clusters ranked334 = s334segment.ranked_clusters if (ranked292.index(s292cluster) > ranked292.index(g334cluster) and ranked334.index(s334cluster) > ranked334.index(g292cluster)): raise Exception("Dungeon cannot be completed with this layout.") return newlocations, unused_maps
def make_secret_treasure_room(mapid, beltroom): from itemrandomizer import get_secret_item candidates = [] for line in open(TREASURE_ROOMS_TABLE): locid, entid, chestid = tuple(map(int, line.strip().split(','))) location = get_location(locid) entrance = location.get_entrance(entid) chest = location.get_chest(chestid) candidates.append((location, entrance, chest)) location, entrance, chest = random.choice(candidates) newlocation = Location(mapid) newlocation.copy(location) newlocation.make_tower_basic() newlocation.entrance_set.entrances = [] newlocation.events = [] newlocation.npcs = [] c = ChestBlock(pointer=None, location=newlocation.locid) c.copy(chest) c.set_content_type(0x40) item = get_secret_item() c.contents = item.itemid c.set_new_id() c.do_not_mutate = True c.ignore_dummy = True newlocation.chests = [c] newlocation.secret_treasure = True newlocation.ancient_rank = 0 e = Entrance(None) e.copy(entrance) e.set_location(newlocation) e.destx, e.desty, e.dest = 36, 27, 287 newlocation.entrances.append(e) assert len(newlocation.entrances) == 1 e2 = Entrance() e2.x = 36 e2.y = 25 e2.destx, e2.desty, e2.dest = e.x, e.y, mapid beltroom.entrance_set.entrances = [ ent for ent in beltroom.entrances if not (ent.x == 36 and ent.y == 25) ] beltroom.entrance_set.entrances.append(e2) final_room = get_location(411) e3 = Entrance() e3.x = 109 e3.y = 46 e3.destx, e3.desty, e3.dest = 82, 46, 412 | 0x2000 final_room.entrance_set.entrances.append(e3) newlocation.attacks = 0 newlocation.setid = 0 newlocation.music = 21 return newlocation, beltroom
def remap_maps(routes): conlinks = [] cononeways = [] conentrances = [] conclusters = [] for route in routes: conlinks.extend(route.consolidated_links) cononeways.extend(route.consolidated_oneways) conentrances.extend(route.consolidated_entrances) conclusters.extend(route.consolidated_clusters) conclusters = sorted(set(conclusters), key=lambda c: c.clusterid) if ANCIENT: unused_maps = [l.locid for l in get_locations() if l.locid not in towerlocids and l.locid not in PROTECTED] rest_maps = [l.locid for l in get_unused_locations() if l.locid != 414] else: unused_maps = [l.locid for l in get_unused_locations()] rest_maps = [] for cluster in conclusters: if not isinstance(cluster, RestStop): continue locid = cluster.locid newlocid = rest_maps.pop() locexchange[(locid, locid)] = newlocid try: unused_maps.remove(newlocid) except: import pdb; pdb.set_trace() for cluster in conclusters: if isinstance(cluster, RestStop): continue locid = cluster.locid if (locid, cluster.clusterid) in locexchange: continue locclusters = [c for c in conclusters if not isinstance(c, RestStop) and c.locid == locid] if locid in towerlocids: for c in locclusters: locexchange[(locid, c.clusterid)] = locid else: location = get_location(locid) if locid in unused_maps: newlocid = locid unused_maps = [u for u in unused_maps if u != newlocid] else: newlocid = unused_maps.pop() if location.longentrances: locexchange[(locid, cluster.clusterid)] = newlocid else: for c in locclusters: locexchange[(locid, c.clusterid)] = newlocid newlocations = [] for newlocid in sorted(set(locexchange.values())): keys = [key for (key, value) in locexchange.items() if value == newlocid] assert len(set([a for (a, b) in keys])) == 1 copylocid = keys[0][0] if copylocid >= 1000: cluster = [c for c in conclusters if c.locid == copylocid][0] copylocid = 413 location = get_location(413) newlocation = Location(locid=newlocid, dummy=True) newlocation.copy(location) newlocation.events = [] newlocation.npcs = [] newlocation.entrance_set.entrances = [] newlocation.restrank = cluster.rank else: location = get_location(copylocid) entrances = location.entrances newlocation = Location(locid=newlocid, dummy=True) newlocation.copy(location) newlocation.events = [] newlocation.npcs = [] newlocation.entrance_set.entrances = [] fixed = [e for e in entrances if (e.location.locid, e.entid) in FIXED_ENTRANCES] newlocation.entrance_set.entrances.extend(fixed) locclusters = [c for c in conclusters if locexchange[(c.locid, c.clusterid)] == newlocid] clustents = [e for c in locclusters for e in c.entrances] clustents = [e for e in clustents if e in conentrances] for ent in clustents: destent = [(a, b) for (a, b) in conlinks if ent in (a, b)] destent += [(a, b) for (a, b) in cononeways if ent == a] assert len(destent) == 1 destent = destent[0] destent = [d for d in destent if d != ent][0] destclust = [c for c in conclusters if destent in c.entrances] assert len(destclust) == 1 destclust = destclust[0] newdestlocid = locexchange[(destclust.locid, destclust.clusterid)] if destent.location.locid >= 1000: destloc = get_location(413) destent = [d for d in destloc.entrances if d.entid == 3][0] else: destloc = get_location(destent.location.locid) destent = [d for d in destloc.entrances if d.entid == destent.entid][0] mirror = destent.mirror if mirror: dest = mirror.dest & 0xFE00 destx, desty = mirror.destx, mirror.desty if abs(destx - destent.x) + abs(desty - destent.y) > 3: mirror = None if not mirror: dest, destx, desty = 0x2000, destent.x, destent.y dest &= 0x3DFF dest |= newdestlocid entrance = Entrance() entrance.x, entrance.y = ent.x, ent.y entrance.dest, entrance.destx, entrance.desty = dest, destx, desty entrance.set_location(newlocation) newlocation.entrance_set.entrances.append(entrance) newlocation.setid = 0 newlocation.ancient_rank = 0 newlocation.copied = copylocid adjents = [] for ent in newlocation.entrances: for clust in locclusters: if isinstance(clust, RestStop): continue assert clust.locid == newlocation.copied if clust.has_adjacent_entrances: x, y = ent.x, ent.y for ent2 in clust.entgroups.keys(): if ent2.x == ent.x and ent2.y == ent.y: break else: continue entgroup = clust.entgroups[ent2] for ent3 in entgroup: x3, y3 = ent3.x, ent3.y if x == x3 and y == y3: continue entrance = Entrance() entrance.x, entrance.y = x3, y3 entrance.dest, entrance.destx, entrance.desty = ( ent.dest, ent.destx, ent.desty) entrance.set_location(newlocation) adjents.append(entrance) newlocation.entrance_set.entrances.extend(adjents) newlocations.append(newlocation) locations = get_locations() newlocids = [l.locid for l in newlocations] assert len(newlocids) == len(set(newlocids)) for location in newlocations: for e in location.entrances: if (location.locid, e.entid) not in FIXED_ENTRANCES: assert e.dest & 0x1FF in newlocids assert location not in locations if location.locid not in towerlocids: location.entrance_set.convert_longs() # XXX: Unnecessary??? for i, loc in enumerate(newlocations): if loc.locid in towerlocids: oldloc = get_location(loc.locid) oldloc.entrance_set.entrances = loc.entrances oldloc.ancient_rank = loc.ancient_rank oldloc.copied = oldloc.locid newlocations[i] = oldloc ranked_clusters = [] for n in range(len(routes[0].segments)): rankedcsets = [route.segments[n].ranked_clusters for route in routes] for tricluster in izip_longest(*rankedcsets, fillvalue=None): tricluster = list(tricluster) random.shuffle(tricluster) for cluster in tricluster: if cluster is None: continue if cluster.locid not in ranked_clusters: cluster.routerank = n ranked_clusters.append(cluster) ranked_locations = [] for cluster in ranked_clusters: locid, clusterid = cluster.locid, cluster.clusterid newlocid = locexchange[locid, clusterid] newloc = [l for l in newlocations if l.locid == newlocid][0] if newloc not in ranked_locations: newloc.routerank = cluster.routerank ranked_locations.append(newloc) assert len(set(ranked_locations)) == len(set(newlocations)) ranked_locations = [l for l in ranked_locations if not hasattr(l, "restrank")] for i, loc in enumerate(ranked_locations): loc.ancient_rank = i loc.make_tower_basic() if not ANCIENT: if loc.locid not in towerlocids: loc.make_tower_flair() loc.unlock_chests(200, 1000) fsets = get_new_fsets("kefka's tower", 20) fset = random.choice(fsets) for formation in fset.formations: formation.set_music(6) formation.set_continuous_music() loc.setid = fset.setid switch292, gate292 = (292, 0), (292, 1) switch334, gate334 = (334, 5), (334, 3) swd = {switch292: None, switch334: None, gate292: None, gate334: None} segments = [s for route in routes for s in route.segments] for segment in segments: for cluster in segment.ranked_clusters: for key in swd.keys(): locid, entid = key if cluster.locid == locid and entid in cluster.entids: assert swd[key] is None swd[key] = (segment, cluster) assert None not in swd.values() s292segment, s292cluster = swd[switch292] s334segment, s334cluster = swd[switch334] g292segment, g292cluster = swd[gate292] g334segment, g334cluster = swd[gate334] if s292segment == g334segment and s334segment == g292segment: assert s292segment != s334segment ranked292 = s292segment.ranked_clusters ranked334 = s334segment.ranked_clusters if (ranked292.index(s292cluster) > ranked292.index(g334cluster) and ranked334.index(s334cluster) > ranked334.index(g292cluster)): raise Exception("Dungeon cannot be completed with this layout.") return newlocations, unused_maps
def make_secret_treasure_room(mapid, beltroom): from itemrandomizer import get_secret_item candidates = [] for line in open(TREASURE_ROOMS_TABLE): locid, entid, chestid = tuple(map(int, line.strip().split(','))) location = get_location(locid) entrance = location.get_entrance(entid) chest = location.get_chest(chestid) candidates.append((location, entrance, chest)) location, entrance, chest = random.choice(candidates) newlocation = Location(mapid) newlocation.copy(location) newlocation.make_tower_basic() newlocation.entrance_set.entrances = [] newlocation.events = [] newlocation.npcs = [] c = ChestBlock(pointer=None, location=newlocation.locid) c.copy(chest) c.set_content_type(0x40) item = get_secret_item() c.contents = item.itemid c.set_new_id() c.do_not_mutate = True c.ignore_dummy = True newlocation.chests = [c] newlocation.secret_treasure = True newlocation.ancient_rank = 0 e = Entrance(None) e.copy(entrance) e.set_location(newlocation) e.destx, e.desty, e.dest = 36, 27, 287 newlocation.entrances.append(e) assert len(newlocation.entrances) == 1 e2 = Entrance() e2.x = 36 e2.y = 25 e2.destx, e2.desty, e2.dest = e.x, e.y, mapid beltroom.entrance_set.entrances = [ent for ent in beltroom.entrances if not (ent.x == 36 and ent.y == 25)] beltroom.entrance_set.entrances.append(e2) final_room = get_location(411) e3 = Entrance() e3.x = 109 e3.y = 46 e3.destx, e3.desty, e3.dest = 82, 46, 412 | 0x2000 final_room.entrance_set.entrances.append(e3) newlocation.attacks = 0 newlocation.setid = 0 newlocation.music = 21 return newlocation, beltroom