Пример #1
0
 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 __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
Пример #6
0
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
Пример #7
0
 def add_entrance(self, entrance):
     e = Entrance()
     e.copy(entrance)
     self.entrances.append(e)
Пример #8
0
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