irmen / Tale

Interactive fiction (text adventure) and Mud framework
http://tale.readthedocs.io/
GNU Lesser General Public License v3.0
145 stars 35 forks source link

Add nearby_locations iterator for Location class #23

Closed sils closed 9 years ago

sils commented 9 years ago

the message_nearby_locations seems to do that manually though it would be quite useful to simply be able to do

location = Location("Kitchen", ...) # And define exits to other rooms as well of course
for loc in location.nearby():
    pass  # Whatever's appropriate
sils commented 9 years ago

Here's what I'm trying to build currently:

@heartbeat
class BurnableLocation(Location):
    def __init__(self, name, description=None, burning=False):
        super(BurnableLocation, self).__init__(name, description=description)
        self.burning = burning
        self._health = 100

    @property
    def health(self):
        return self._health

    @health.setter
    def health(self, value):
        oldhealth = self._health
        if self._health < 70 < oldhealth:
            self.tell("{name} is burning!")
            message_nearby_locations(self, "You smell something weird...")
            # Spreads to nearby locations
            # FIXME, requires https://github.com/irmen/Tale/issues/23
            for location in self.nearby_locations():
                if isinstance(location, BurnableLocation):
                    location.burning = random.randint(0, 10) > 9
        if self._health < 30 < oldhealth:
            self.tell("{name} is burning!".format(**self.__dict__))
            message_nearby_locations(self, "You smell burning plastic and it "
                                           "get's warm - something seems to "
                                           "be wrong...")
            # Spreads to nearby locations
            # FIXME, requires https://github.com/irmen/Tale/issues/23
            for location in self.nearby_locations():
                if isinstance(location, BurnableLocation):
                    location.burning = random.randint(0, 10) > 6
        if self._health == 0 < oldhealth:
            self.tell("{name} is burned down "
                      "completely.".format(**self.__dict__))
            message_nearby_locations(self, "You see smoke from {name}.")

    def heartbeat(self, ctx):
        if not self.burning:
            return

        self.health -= random.randint(0, 8)

That's just playground prototype code which still contains quite some duplication and needs refinement but I think it gets the idea across ;)

irmen commented 9 years ago

will add this generator but it cannot replace the message_nearby_locations method, because that one is meant to spread a sound to 'adjacent' rooms. Such a room then also gets notified what the direction was that the sound came from.

So it cannot be used in your code above because it will print confusing text in this case.

In the mean time, the following expression should yield you all the adjacent locations of a room: (e.target for e in current_room.exits.values()) and if you want to avoid traps (rooms without exits): (e.target for e in current_room.exits.values() if e.target.exits)