def init_beast(custom_data, all_beasts, id_prepend=''): beast = Beast(custom_data.get('symbol', '?')) beast.id = uuid.uuid4().hex for key, value in custom_data.items(): if isinstance(value, dict): setattr(beast, key, dict(value.items())) else: setattr(beast, key, value) if id_prepend and not beast.absolute_id: beast.id = '%s_%s' % (id_prepend, beast.id) beast.type = custom_data.get('type', None) beast.sprite = custom_data['sprite'] for beast_data in custom_data.get('also', []): if inspect.isfunction(beast_data): beast_data = beast_data() also_beast = init_beast(beast_data, all_beasts, id_prepend) all_beasts.append(also_beast) beast.also_beasts.append(also_beast) return beast
def generate(maps): customs = collections.defaultdict(list) all_beasts = {} all_maps = [] for map_data in maps: beast_map = initialize_grid(map_data) all_maps.append(beast_map) for beast in beast_map.all_beasts(): all_beasts[beast.id] = beast if beast.type: customs[beast.type].append(beast) if beast.stitches: customs['stitched'].append(beast) if beast.dimension: customs['pocket'].append(beast) for pocket in customs['pocket']: do_pocket(pocket, all_beasts, customs) for alta in customs['alta']: alta.all = all_beasts[alta.to_id] for teleporter in customs['teleporter']: do_teleporter(teleporter, all_beasts, customs) for wall in customs['wall']: adjacent = '%s%s%s%s' % ( 'l' if wall.left.type != 'wall' else '', 'r' if wall.right.type != 'wall' else '', 'u' if wall.up.type != 'wall' else '', 'd' if wall.down.type != 'wall' else '', ) corners = '%s%s%s%s' % ( 'F' if wall.left.up.type != 'wall' else '', 'J' if wall.right.down.type != 'wall' else '', '7' if wall.right.up.type != 'wall' else '', 'L' if wall.left.down.type != 'wall' else '', ) if adjacent == 'l': wall.right = wall if adjacent == 'r': wall.left = wall if adjacent == 'u': wall.down = wall if adjacent == 'd': wall.up = wall if not adjacent and corners == 'F': wall.right = wall wall.down = wall if not adjacent and corners == 'J': wall.left = wall wall.up = wall if not adjacent and corners == '7': wall.left = wall wall.down = wall if not adjacent and corners == 'L': wall.right = wall wall.up = wall for extender in customs['portal_extender']: base = all_beasts.get(extender.base_id) reciprocal = getattr(extender, 'reciprocal', False) offset_x = base.x - extender.x offset_y = base.y - extender.y rel_string = '' if offset_x > 0: rel_string += 'l' * offset_x if offset_x < 0: rel_string += 'r' * (offset_x * -1) if offset_y > 0: rel_string += 'u' * offset_y if offset_y < 0: rel_string += 'd' * (offset_y * -1) for key in base.stitches.keys(): extender.stitches[key] = base.stitches[key] + rel_string + '/r' if reciprocal else '' for stitched in all_beasts.values(): stitches = stitched.stitches if stitches: stitch(stitched, all_beasts, stitches.get('up', ''), stitches.get('down', ''), stitches.get('left', ''), stitches.get('right', ''), stitches.get('inner', '')) # Stitch up the levels that have stitched borders for level in all_maps: if level.wrap_mode == 'stitched': for direction, other_map in level.stitches.items(): points = [] other_points = [] other_map = [m for m in all_maps if m.id == other_map][0] if direction == 'left': points = level.left_wall_points() other_points = other_map.right_wall_points() if direction == 'right': points = level.right_wall_points() other_points = other_map.left_wall_points() if direction == 'up': points = level.up_wall_points() other_points = other_map.down_wall_points() if direction == 'down': points = level.down_wall_points() other_points = other_map.up_wall_points() points = sorted(points) other_points = sorted(other_points) for i, point in enumerate(points): i = float(i) / len(points) other_i = int(math.floor(i * (len(points) / len(other_points)))) setattr(level.get(*point), direction, other_map.get(*other_points[other_i])) for origin in customs['rill_origin']: rills = customs['rill'] rill_path = [origin] n = origin while n is not None: c = n n = None for adjacent in c.all_orig: if adjacent in rills and adjacent not in rill_path: rill_path.append(adjacent) rills.remove(adjacent) n = adjacent watchers = [Beast('r') for b in rill_path] for n, watcher in enumerate(watchers): watcher.sprite = 'rill' watcher.left = watchers[n - 1] watcher.right = watchers[n + 1] if n < len(watchers) - 1 else watchers[0] watcher.up = rill_path[n] watcher.down = rill_path[n] all_beasts[watcher.id] = watcher # Rill rider rill_rider = next(b for b in origin.also_beasts if b.type == 'rill_rider') rill_rider.up = watchers[0] all_beasts[rill_rider.id] = rill_rider for n, lurkroom in enumerate(customs['lurkroom']): previous = customs['lurkroom'][n - 1] lurkmap = lurkroom.map previous_lurkmap = previous.map for (x, y) in lurkmap.right_wall_points(): lurkmap.get(x, y).right = previous_lurkmap.get(0, y) previous_lurkmap.get(0, y).left = lurkmap.get(x, y) # THE GOLDEN RILL golden_rill = [] shuffled_beasts = all_beasts.values() random.shuffle(shuffled_beasts) for beast in shuffled_beasts: rill_segment = Beast('golden_rill') rill_segment.sprite = 'golden_rill' rill_segment.up = beast rill_segment.down = beast golden_rill.append(rill_segment) for n, beast in enumerate(golden_rill): left = golden_rill[n - 1] beast.left = left beast.left.right = beast for rider in customs['golden_rill_rider']: rider.up = random.choice(golden_rill) all_beasts['golden_rill_origin'].down = golden_rill[0] for rill in golden_rill: all_beasts[rill.id] = rill return all_beasts.values()