~divmod-dev/divmod.org/no-addperson-2190

« back to all changes in this revision

Viewing changes to Imaginary/imagination/observation.py

  • Committer: exarkun
  • Date: 2006-02-26 02:37:39 UTC
  • Revision ID: svn-v4:866e43f7-fbfc-0310-8f2a-ec88d1da2979:trunk:4991
Merge move-pottery-to-trunk

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
from zope.interface import implements
 
2
from imagination import simulacrum, actions, errors, architecture, containment
 
3
from imagination.text import english
 
4
from imagination.facets import Faceted, Facet
 
5
 
 
6
# XXX I think (hope) we've reached the last major problem with
 
7
# look. That is, we don't know the relationship of objects returned
 
8
# from our collect(): things in the next room over are getting mixed
 
9
# in with things in our current room. There are two solutions two
 
10
# solutions to this, afaict:
 
11
 
 
12
# * Implement some kind of relationship inferencer right here in
 
13
# observation.py that, given a flat list of objects (collect's return
 
14
# value), figures out their relationship by looking at
 
15
# ILocatable.locations. I'm not sure this is sufficient.
 
16
 
 
17
# * Implement an alternative collector (in simulacrum.py) that returns
 
18
# information about how an object was reached. A rough guess at what
 
19
# the return value would look like: {room1: [book, {door: [{room:
 
20
# rock}]}]}. But that looks a bit ugly, perhaps something more
 
21
# encapsulated. - rade
 
22
 
 
23
 
 
24
# XXX - I think, ultimately, the event we should be sending to the
 
25
# actor ought to be an actual graph of the things around him. The way
 
26
# we're sending each object as its own event is going to make it
 
27
# really hard to make a richer UI -- but if we send a single event
 
28
# describing the visible things starting at his location, things like
 
29
# graphical maps would be easy-shmeasy. Or, simpler, putting headers
 
30
# above relevant sections of items in the text UI.
 
31
 
 
32
class Look(actions.TargetAction):
 
33
    allowImplicitTarget = True
 
34
    onlyBroadcastToActor = True
 
35
 
 
36
    allowNoneInterfaceTypes = ['Target']
 
37
 
 
38
    def collectThings(self, iName, iface, start=None):
 
39
        if start is None:
 
40
            start = self.actor
 
41
        visionEvaluator = Faceted()
 
42
        if iName is None:
 
43
            visionEvaluator[simulacrum.ICallableCriterion] = simulacrum.always
 
44
        else:
 
45
            ka = simulacrum.KnownAs(iName, self.actor)
 
46
            visionEvaluator[simulacrum.ICallableCriterion] = ka
 
47
            visionEvaluator[simulacrum.IKnownAs] = ka
 
48
        visionEvaluator[architecture.ISightOnly] = True
 
49
        return simulacrum.collect(start, ILookTarget, visionEvaluator, radius=2)
 
50
 
 
51
    def doAction(self):
 
52
        if self.target is None:
 
53
            self.target = containment.ILocatable(self.actor).location
 
54
        else:
 
55
            pass
 
56
 
 
57
        if self.target is None:
 
58
            raise errors.ActionFailed("Can't look at nothing (YOU ARE NOWHERE!)")
 
59
 
 
60
        if simulacrum.ICollector(self.target) is not containment.ILocatable(self.actor).location:
 
61
            simulacrum.ISeer(self.actor).see(english.INoun(self.target).explainTo(self.actor))
 
62
            return
 
63
 
 
64
        # We don't have a very specific target --
 
65
        # Find everything that can be looked at which is nearby.
 
66
        collected = self.collectThings(None, None, start=self.target)
 
67
 
 
68
        # Emit explanations of everything found to the
 
69
        # actor as events which can be seen.
 
70
        loc = containment.ILocatable(self.actor).location
 
71
        locations = {}
 
72
        exits = []
 
73
        for radius, thing in collected:
 
74
            if english.INoun(thing) is english.INoun(self.actor):
 
75
                continue
 
76
            else:
 
77
                where = containment.ILocatable(thing).location
 
78
                if where is not None and where is not simulacrum.ICollector(self.actor):
 
79
                    locations.setdefault(where, []).append(thing)
 
80
                elif architecture.IExit(thing, None) is not None:
 
81
                    exits.append(thing)
 
82
 
 
83
        L = []
 
84
        see = L.append
 
85
        see(("[ ", loc, " ]", "\n"))
 
86
        see((english.INoun(loc).explainTo(self.actor), "\n\n"))
 
87
        thingsHere = locations.pop(loc, ())
 
88
        for t in thingsHere:
 
89
            if t not in locations:
 
90
                see((t, " is here.", "\n"))
 
91
 
 
92
        def commify(L):
 
93
            if len(L) > 1:
 
94
                return [(e, ", ") for e in L[:-1]], "and ", L[-1]
 
95
            return L
 
96
        for (where, what) in locations.iteritems():
 
97
            see((where, " containing ", commify(what), " is here.", "\n"))
 
98
 
 
99
        see("Exits:\n")
 
100
        for exit in exits:
 
101
            see((exit, "\n"))
 
102
        simulacrum.ISeer(self.actor).see(L)
 
103
 
 
104
##        location = None
 
105
##        otherLocs = []
 
106
##        exits = []
 
107
##        allElse = []
 
108
##        inventory = []
 
109
##        for radius, thing in collected:
 
110
##            elif simulacrum.ICollector(thing) is containment.ILocatable(self.actor).location:
 
111
##                location = thing
 
112
##            elif architecture.IExit(thing, None) is not None:
 
113
##                exits.append(thing)
 
114
##            elif containment.ILocatable(thing).location is simulacrum.ICollector(self.actor):
 
115
##                inventory.append(thing)
 
116
##            else:
 
117
##                allElse.append(thing)
 
118
 
 
119
##        if location is not None:
 
120
##            header = "\x1B[31m%s\x1B[0m" % (location.expressTo(self.actor),)
 
121
##            see(header)
 
122
##            see(location.explainTo(self.actor))
 
123
 
 
124
##        for (header, stuff) in [("\x1B[32mExits\x1B[0m", exits),
 
125
##                                ("\x1B[33mOther Stuff\x1B[0m", allElse),
 
126
##                                ("\x1B[34mInventory\x1B[0m", inventory)]:
 
127
##            if stuff:
 
128
##                see(header)
 
129
##                for thing in stuff:
 
130
##                    see(thing.expressTo(self.actor))
 
131
 
 
132
ILookTarget = english.INoun
 
133
 
 
134
from imagination.text import english
 
135
 
 
136
class LookParser(english.Subparser):
 
137
    simpleTargetParsers = {'look': Look}
 
138
 
 
139
class Looker(Facet):
 
140
    implements(ILookActor)
 
141
 
 
142
english.registerSubparser(LookParser())