Exemplo n.º 1
0
    def setup_items(self, game):

        # --------------- Common effects of commands

        def update_score(game, points):
            game.score += points

        def update_health(player, points):
            player.health += points

        def make_creature_hostile(creature):
            creature.become_hostile()

        def instant_death(player):
            player.health = 0

        def lose_item(player, item):
            player.inventory.remove_item(item)

        def end_section(name, game, player, points):
            update_score(game, points)
            result = Result(
                "Congratulations! You have finished {}. ".format(name))
            status = game.status()
            result.append(status.get_message())
            return result

        # ---------------- Create basic locations and objects

        player = game.player

        crumbly_room = Location(
            game,
            name='Crumbly Room',
            description='A small storage room with crumbling plaster walls')
        paneled_room = Location(
            game,
            name='Wood Paneled Room',
            description='A large, warm room with wood-paneled walls')
        north_tower = Location(
            game,
            name='North Tower',
            description='A tower with a high ceiling and red-stained windows')
        balcony = Location(
            game,
            name='Balcony',
            description=
            'A breezy, open balcony with a beautiful view of the landscape below',
            traits=Traits(precarious=True))
        east_tower = Location(
            game,
            name='East Tower',
            description='The tall tower at the eastern side of the house')
        roof = Location(
            game,
            name='Roof',
            description='You are on the roof of the eastern tower.  ' +
            'There is a ladder leading back downwards, and to the west is an open window.',
            traits=Traits(precarious=True))

        west_tower = Location(
            game,
            name='West Tower',
            description='The tall tower at the western side of the house.')

        master_bedroom = Location(
            game,
            'Master Bedroom',
            description=
            'This appears to be a former bedroom, but the bed itself is missing.  '
            + 'A window to the east is open.')
        basement = Location(game,
                            'Basement',
                            description='An empty room, very drafty')
        garden = Location(game, 'garden', description='a lush blooming garden')
        patio = Location(game, 'patio', description='an empty stone patio')
        front_porch = Location(
            game,
            'porch',
            description=
            'The front porch of the house.  A metal gate prevents you from leaving'
        )
        front_porch.add_modifier('front')

        metal_gate = Surface(
            game,
            name='gate',
            description=
            'An impassable metal gate with two locks: one golden and one bronze, '
            + 'blocking your exit!')
        metal_gate.traits.closed = True
        metal_gate.add_modifier('metal')
        front_porch.add_item(metal_gate)

        golden_lock = Door(game, name='lock', description='a golden lock')
        golden_lock.add_modifier('golden')
        metal_gate.add_item(golden_lock, force=True)

        bronze_lock = Door(game, name='lock', description='a bronze lock')
        bronze_lock.add_modifier('bronze')
        metal_gate.add_item(bronze_lock, force=True)

        street = Location(game, 'street', description='an empty street')

        fancy_painting = Item(
            game,
            name='painting',
            description='An ornate painting of the house\'s previous owner',
            aliases=['portrait', 'picture'],
            size=15,
            value=100)
        fancy_painting.add_modifier('fancy')
        west_tower.add_item(fancy_painting)

        east_tower.add_exit(direction.west, paneled_room)
        crumbly_room.add_exit(direction.north, paneled_room)
        paneled_room.add_exit(direction.south, crumbly_room)
        paneled_room.add_exit(direction.north, north_tower)
        paneled_room.add_exit(direction.east, east_tower)
        paneled_room.add_exit(direction.west, west_tower)
        west_tower.add_exit(direction.east, paneled_room)
        roof.add_exit(direction.west, master_bedroom)
        master_bedroom.add_exit(direction.down, basement)
        master_bedroom.add_exit(direction.east, roof)
        basement.add_exit(direction.up, master_bedroom)
        basement.add_exit(direction.west, garden)
        garden.add_exit(direction.east, basement)
        garden.add_exit(direction.south, patio)
        patio.add_exit(direction.north, garden)
        patio.add_exit(direction.south, front_porch)

        front_porch.add_exit(direction.north, patio)
        front_porch.add_exit(
            direction.south,
            street,
            condition=lambda g, p: not metal_gate.traits.closed,
            after=lambda g, p, l, d: end_section("section one", g, p, 50),
            fail_result=Failure("The metal gate blocks your way"))

        def too_small_check(g, p):
            return p.inventory.used_capacity() <= 25

        too_small_result = Failure(
            "Your load is too large to fit through the small hole")

        east_tower.add_exit(
            direction.up,
            roof,
            description='A ladder leads up to a hole in the ceiling far above',
            condition=too_small_check,
            fail_result=too_small_result)
        roof.add_exit(
            direction.down,
            east_tower,
            description="There is a hole here leading down to the tower below",
            condition=too_small_check,
            fail_result=too_small_result)

        sturdy_door = Door(
            game,
            name='door',
            description=
            'A sturdy door leading out to the balcony above the tower')
        sturdy_door.add_modifier('sturdy')

        silver_key = Key(game,
                         name='key',
                         description='A brilliant silver key')
        silver_key.add_modifier('silver')

        steel_key = Key(game, name='key', description='A small steel key')
        steel_key.add_modifier('steel')
        steel_key.set_lockable(sturdy_door)
        roof.add_item(steel_key)

        north_tower.add_item(sturdy_door)
        north_tower.add_exit(direction.south, paneled_room)
        north_tower.add_exit(
            direction.up,
            balcony,
            description="Stairs lead up to a door high above",
            condition=lambda g, p: not sturdy_door.traits.closed,
            fail_result=Failure("A sturdy door blocks the way"))
        balcony.add_exit(direction.down, north_tower)

        light_thing = Item(
            game,
            name='thing',
            description='An easily carried thing, light as a feather',
            size=0)
        light_thing.add_modifier('light')

        fragile_thing = Item(game,
                             name='thing',
                             description='An easily breakable, delicate thing',
                             traits=Traits(fragile=True),
                             size=15)
        fragile_thing.add_modifier('fragile')

        heavy_thing = Item(
            game,
            name='thing',
            description='A heavy block of some unknown material',
            size=45)
        heavy_thing.add_modifier('heavy')

        trunk = Container(game,
                          name='trunk',
                          description='An old wooden trunk',
                          aliases=['chest', 'box'],
                          size=75,
                          value=5,
                          capacity=90)
        trunk.add_modifier('wooden')
        sword = Weapon(game,
                       name='sword',
                       description='A serviceable iron sword',
                       size=15,
                       value=15,
                       damage=50,
                       defense=10,
                       accuracy=80)
        sword.add_modifier('iron')
        trunk.add_item(sword, force=True)

        diamond = Item(game,
                       name='diamond',
                       aliases=['gem', 'jewel'],
                       size=5,
                       value=100,
                       description='A brilliant diamond')

        apple = Edible(game,
                       name='apple',
                       description='A delicious, juicy red apple',
                       size=15,
                       value=5)
        small_table = Surface(game,
                              name='table',
                              description='A small table',
                              size=20,
                              capacity=15)
        small_table.add_modifier('small')
        small_table.add_item(apple, force=True)

        large_table = Surface(game,
                              name='table',
                              description='A large table',
                              size=75,
                              capacity=100)
        large_table.add_modifier('large')
        large_table.add_item(heavy_thing, force=True)
        large_table.add_item(light_thing, force=True)
        large_table.add_item(fragile_thing, force=True)

        bread = Edible(game,
                       name='bread',
                       description='A loaf of crusty brown bread',
                       size=20,
                       value=5,
                       healing=10)

        puddle = Drinkable(game,
                           name='puddle',
                           aliases=['water'],
                           description='A puddle of refreshing water',
                           size=25,
                           value=5,
                           healing=15)

        mouse = Item(
            game,
            name='mouse',
            description='A small mouse scampers back and forth across the ' +
            'room here, searching for food.  It is carrying something '
            'shiny in its mouth.',
            traits=Traits(compelling=True),
            size=0,
            value=0)
        mouse.add_modifier('brown')
        west_tower.add_item(mouse)

        core = Item(game,
                    name='core',
                    description='The core of an eaten apple',
                    size=5,
                    value=0)
        core.add_modifier('apple')
        apple.add_consumed(core)

        crumbs = Edible(game,
                        name='crumbs',
                        description='A small pile of leftover bread crumbs',
                        aliases=['pile'],
                        traits=Traits(composite=True, plural=True),
                        size=5,
                        value=0,
                        healing=0)
        bread.add_consumed(crumbs)

        mud = Item(game,
                   name='mud',
                   description='A clump of soggy wet mud',
                   traits=Traits(composite=True),
                   size=15,
                   value=1)
        puddle.add_consumed(mud)
        vase = Container(game,
                         name='flowerpot',
                         description='a patterned flowerpot',
                         aliases=['flowerpot', 'pot', 'vase'],
                         traits=Traits(closed=False, fragile=True),
                         size=5,
                         value=10,
                         capacity=3)
        flower = Item(game,
                      name='flower',
                      description='a beautiful, fragrant sunflower',
                      size=3,
                      value=5)
        crumbly_room.add_item(small_table)
        crumbly_room.add_item(large_table)
        paneled_room.add_item(trunk)
        paneled_room.add_item(puddle)

        vase.add_item(flower)
        balcony.add_item(vase)

        villager = Creature(
            game,
            name='villager',
            traits=Traits(mobile=True),
            aliases=['farmer'],
            description="A stout but simple villager in farming garb",
            health=75,
            strength=25,
            dexterity=65,
            location=paneled_room)
        villager.add_wanted_item(apple)
        villager.add_item(diamond)

        golden_key = Key(game,
                         name='key',
                         description='A fashionable golden key')
        golden_key.add_modifier('golden')
        golden_key.set_lockable(golden_lock)

        red_fox = Creature(game,
                           name='fox',
                           traits=Traits(hostile=True, mobile=False),
                           description="a bloodthirsty red fox",
                           health=65,
                           strength=15,
                           dexterity=50,
                           location=front_porch)
        red_fox.add_modifier('red')
        red_fox.add_item(golden_key)

        bronze_key = Key(game, name='key', description='A dull bronze key')
        bronze_key.add_modifier('bronze')
        bronze_key.set_lockable(bronze_lock)

        brown_fox = Creature(game,
                             name='fox',
                             traits=Traits(hostile=True, mobile=False),
                             description="a vicious brown fox",
                             health=65,
                             strength=25,
                             dexterity=50,
                             location=front_porch)
        brown_fox.add_modifier('brown')
        red_fox.add_item(bronze_key)

        townsfolk = Creature(
            game,
            name='townsfolk',
            traits=Traits(mobile=True),
            description='A short, well-dressed man with a stubbly beard',
            aliases=['folk', 'man'],
            health=75,
            strength=30,
            dexterity=65,
            location=north_tower)
        townsfolk.add_wanted_item(diamond)
        townsfolk.add_item(bread)

        def shadow_action(game, player):
            player.health -= 5
            return Result("A dark shadow looms ominously in the corner")

        shadow = Creature(
            game,
            name='shadow',
            traits=Traits(hostile=False, mobile=True, evident=False),
            description=
            'You attempt to examine the shadow, but your vision blurs as you try to focus '
            'on its constantly shifting shape, preventing you from forming '
            'any clear impression',
            health=9001,
            strength=20,
            dexterity=90,
            location=east_tower)
        shadow.add_modifier('dark')
        shadow.entry_action = lambda g, p: Result(
            "A dark shadow enters.  The temperature in the room drops "
            "several degrees, as does your blood")
        shadow.exit_action = lambda g, p: Result(
            "The shadow leaves the room, and you once again find "
            "you can breathe freely")
        shadow.present_action = shadow_action

        # -------- Consequences: game milestones and achievements, and special results
        vocabulary = game.vocabulary

        open = vocabulary.lookup_verb_by_name('open')
        get = vocabulary.lookup_verb_by_name('get')
        ask = vocabulary.lookup_verb_by_name('ask')
        smell = vocabulary.lookup_verb_by_name('smell')
        jump = vocabulary.lookup_verb_by_name('jump')
        drop = vocabulary.lookup_verb_by_name('drop')
        throw = vocabulary.lookup_verb_by_name('throw')
        kill = vocabulary.lookup_verb_by_name('kill')
        unlock = vocabulary.lookup_verb_by_name('unlock')

        # Trying to pick up creatures turns them hostile
        for creature in vocabulary.get_objects_of_class(Creature):
            get.add_consequence(schema=Schema(roles={
                Role.AGENT: player,
                Role.THEME: creature
            }),
                                necessary_result=result.GENERIC_FAILURE,
                                effect=lambda schema: make_creature_hostile(
                                    schema[Role.THEME]))

        # Be careful in precarious places!
        for room in vocabulary.get_objects_of_class(Location):
            if room.traits.precarious:
                jump.add_consequence(
                    schema=Schema(roles={Role.AGENT: player}),
                    necessary_result=result.GENERIC_SUCCESS,
                    necessary_location=room,
                    effect=lambda schema: instant_death(player),
                    consequent_result=Success(
                        "In your excitement, you slip and fall to the hard ground far below!\n"
                        +
                        "You should probably be more careful where you do your jumping."
                    ))

                # TODO: Some kind of pattern-matching logic here.  This configures for _no_ theme, not _any_ theme ...
                throw.add_consequence(
                    schema=Schema(roles={Role.AGENT: player}),
                    necessary_result=result.GENERIC_FAILURE,
                    necessary_location=room,
                    effect=lambda schema: lose_item(player, schema[Role.THEME]
                                                    ),
                    consequent_result=Failure(
                        "You toss it carelessly, and it sails over the edge and out of sight"
                    ))

        # The mouse is too fast to catch or kill, but it's hungry
        def fed_mouse(crumbs):
            west_tower.remove_item(mouse)
            west_tower.remove_item(crumbs)
            west_tower.add_item(silver_key)

        get.add_consequence(
            schema=Schema(roles={
                Role.AGENT: player,
                Role.THEME: mouse
            }),
            necessary_result=result.GENERIC_SUCCESS,
            necessary_location=west_tower,
            effect=lambda schema: player.drop(mouse),
            consequent_result=Failure(
                "You try, but the mouse is far too small and fast for you to catch!"
            ))

        drop.add_consequence(schema=Schema(roles={
            Role.AGENT: player,
            Role.THEME: crumbs
        }),
                             necessary_result=result.GENERIC_SUCCESS,
                             necessary_location=west_tower,
                             effect=lambda schema: update_score(game, 20))

        drop.add_consequence(
            schema=Schema(roles={
                Role.AGENT: player,
                Role.THEME: crumbs
            }),
            necessary_result=result.GENERIC_SUCCESS,
            necessary_location=west_tower,
            effect=lambda schema: fed_mouse(crumbs),
            consequent_result=Success(
                "The mouse devours the crumbs, dropping something shiny to the floor in the "
                "process.  It then returns to its hole, well-fed and content"))

        # Foxes work cooperatively!
        def killed_fox(dead_fox, other_fox, key):
            dead_fox.remove_item(key)
            if other_fox.is_alive:
                other_fox.add_item(key)
                return result.GENERIC_SUCCESS
            else:
                return result.GENERIC_FAILURE

        kill.add_consequence(
            schema=Schema(roles={
                Role.AGENT: player,
                Role.THEME: red_fox
            }),
            necessary_result=result.GENERIC_SUCCESS,
            effect=killed_fox(red_fox, brown_fox, golden_key),
            consequent_result=Success(
                "As the red fox falls dead to the ground, its brother retrieves "
                "the golden key from its lifeless form"))

        kill.add_consequence(
            schema=Schema(roles={
                Role.AGENT: player,
                Role.THEME: brown_fox
            }),
            necessary_result=result.GENERIC_SUCCESS,
            effect=killed_fox(brown_fox, red_fox, bronze_key),
            consequent_result=Success(
                "As the brown fox falls dead to the ground, its brother retrieves "
                "the bronze key from its lifeless form"))

        # Achievement: unlock and open the sturdy door
        open.add_consequence(schema=Schema(roles={
            Role.AGENT: player,
            Role.PATIENT: sturdy_door
        }),
                             necessary_result=result.GENERIC_SUCCESS,
                             effect=lambda schema: update_score(game, 10))

        # Achievement: get the diamond from the villager
        ask.add_consequence(
            schema=Schema(roles={
                Role.AGENT: player,
                Role.PATIENT: villager,
                Role.THEME: diamond
            }),
            necessary_result=result.GENERIC_SUCCESS,
            effect=lambda schema: update_score(game, 20))

        get.add_consequence(schema=Schema(roles={
            Role.AGENT: player,
            Role.THEME: diamond
        }),
                            necessary_result=result.GENERIC_SUCCESS,
                            effect=lambda schema: update_score(game, 20))

        get.add_consequence(
            schema=Schema(roles={
                Role.AGENT: player,
                Role.PATIENT: villager,
                Role.THEME: diamond
            }),
            necessary_result=result.GENERIC_SUCCESS,
            effect=lambda schema: update_score(game, 20))

        # Health bonus: smell the sunflower
        smell.add_consequence(
            schema=Schema(roles={
                Role.AGENT: player,
                Role.THEME: flower
            }),
            necessary_result=result.GENERIC_SUCCESS,
            effect=lambda schema: update_health(player, 10),
            consequent_result=Success(
                "You feel revived by the bloom's invigorating fragrance"))

        def unlock_gate(this_lock, other_lock):
            this_lock.traits.locked = False
            if other_lock.traits.locked:
                return result.GENERIC_FAILURE
            else:
                update_score(game, 50)
                metal_gate.traits.closed = False
                return result.GENERIC_SUCCESS

        unlock.add_consequence(
            schema=Schema(
                roles={
                    Role.AGENT: player,
                    Role.THEME: golden_lock,
                    Role.INSTRUMENT: golden_key
                }),
            necessary_result=result.GENERIC_SUCCESS,
            effect=lambda schema: unlock_gate(golden_lock, bronze_lock),
            consequent_result=WON_GAME)

        unlock.add_consequence(
            schema=Schema(
                roles={
                    Role.AGENT: player,
                    Role.THEME: golden_lock,
                    Role.INSTRUMENT: golden_key
                }),
            necessary_result=result.GENERIC_SUCCESS,
            effect=lambda schema: unlock_gate(golden_lock, bronze_lock),
            consequent_result=WON_GAME)

        # Start game in crumbly room
        return crumbly_room