source: branches/active/character_customization/game/parpg/dialogue.py @ 833

Revision 774, 8.1 KB checked in by aspidites, 8 years ago (diff)

Patch by Aspidites

  • removed shebang from all python files except launcher scripts
  • added shebang to pychan_designer
  • Property svn:eol-style set to native
Line 
1#   This file is part of PARPG.
2#
3#   PARPG is free software: you can redistribute it and/or modify
4#   it under the terms of the GNU General Public License as published by
5#   the Free Software Foundation, either version 3 of the License, or
6#   (at your option) any later version.
7#
8#   PARPG is distributed in the hope that it will be useful,
9#   but WITHOUT ANY WARRANTY; without even the implied warranty of
10#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11#   GNU General Public License for more details.
12#
13#   You should have received a copy of the GNU General Public License
14#   along with PARPG.  If not, see <http://www.gnu.org/licenses/>.
15"""
16Provides classes used to contain and organize dialogue data for use within
17in-game dialogues between the player character and NPCs.
18"""
19try:
20    from collections import OrderedDict
21except ImportError:
22    # Python version 2.4-2.6 doesn't have the OrderedDict
23    from parpg.common.ordereddict import OrderedDict
24
25class Dialogue(object):
26    """
27    Represents a complete dialogue and acts as a container for the dialogue
28    data belonging to a particular NPC.
29    """
30    __slots__ = ['npc_name', 'avatar_path', 'default_greeting',
31                 'greetings', 'sections']
32   
33    def __init__(self, npc_name, avatar_path, default_greeting, greetings=None,
34                 sections=None):
35        """
36        Initialize a new L{Dialogue} instance.
37       
38        @param npc_name: name displayed for the NPC in the dialogue.
39        @type npc_name: basestring
40        @param avatar_path: path to the image that should be displayed as the
41            NPC's avatar.
42        @type avatar_path: basestring
43        @param default_greeting: section of dialogue that should be
44            displayed when the dialogue is first initiated and no other start
45            sections are available.
46        @type default_greeting: L{DialogueSection}
47        @param greetings: sections of dialogue defining the conditions
48            under which each should be displayed when the dialogue is first
49            initiated.
50        @type greetings: list of
51            L{RootDialogueSections<DialogueGreeting>}
52        @param sections: sections of dialogue that make up this
53            L{Dialogue} instance.
54        @type sections: list of L{DialogueSections<DialogueSection>}
55        """
56        self.npc_name = npc_name
57        self.avatar_path = avatar_path
58        self.default_greeting = default_greeting
59        self.greetings = greetings if greetings is not None else []
60        self.sections = OrderedDict()
61        all_sections = [default_greeting]
62        if (greetings is not None):
63            all_sections += greetings
64        if (sections is not None):
65            all_sections += sections
66        if (__debug__):
67            section_ids = [section.id for section in all_sections]
68        for section in all_sections:
69            # Sanity check: All DialogueResponses should have next_section_id
70            # attributes that refer to valid DialogueSections in the Dialogue.
71            if (__debug__):
72                for response in section.responses:
73                    assert response.next_section_id in section_ids + \
74                        ['end', 'back'], ('"{0}" does not refer to a ' 
75                                          'DialogueSection in this Dialogue')\
76                        .format(response.next_section_id)
77            self.sections[section.id] = section
78   
79    def __str__(self):
80        """Return the string representation of a L{Dialogue} instance."""
81        string_representation = 'Dialogue(npc_id={0.npc_name})'.format(self)
82        return string_representation
83
84
85class DialogueNode(object):
86    """
87    Abstract base class that represents a node or related group of attributes
88    within a Dialogue.
89    """
90    def __init__(self, text, actions=None):
91        """
92        Initialize a new L{DialogueNode} instance.
93       
94        @param text: textual content of the L{DialogueNode}.
95        @type text: basestring
96        @param actions: dialogue actions associated with the L{DialogueNode}.
97        @type actions: list of L{DialogueActions<DialogueAction>}
98        """
99        self.text = text
100        self.actions = actions or []
101
102
103class DialogueSection(DialogueNode):
104    """DialogueNode that represents a distinct section of the dialogue."""
105    __slots__ = ['id', 'text', 'responses', 'actions']
106   
107    def __init__(self, id_, text, responses=None, actions=None):
108        """
109        Initialize a new L{DialogueSection} instance.
110       
111        @param id_: named used to uniquely identify the L{DialogueSection}
112            within a L{Dialogue}.
113        @type id_: basestring
114        @param text: text displayed as the NPC's part of the L{Dialogue}.
115        @type text: basestring
116        @param responses: possible responses that the player can choose from.
117        @type responses: list of L{DialogueResponses<DialogueResponse>}
118        @param actions: dialogue actions that should be executed when the
119            L{DialogueSection} is reached.
120        @type actions: list of L{DialogueActions<DialogueAction>}
121        """
122        DialogueNode.__init__(self, text=text, actions=actions)
123        self.id = id_
124        if (responses is not None):
125            self.responses = list(responses)
126
127
128class DialogueGreeting(DialogueSection):
129    """
130    Represents a root section of dialogue in a L{Dialogue} along with the
131    conditional statement used to determine the whether this section should be
132    displayed first upon dialogue initiation.
133   
134    @ivar id: Name used to uniquely identify the L{DialogueSection} to which
135        the L{DialogueRootSectionReference} points.
136    @type id: basestring
137    @ivar condition: Boolean Python expression used to determine if the
138        L{DialogueSection} referenced is a valid starting section.
139    @type condition: basestring
140    """
141    __slots__ = ['id', 'condition', 'text', 'actions', 'responses']
142   
143    def __init__(self, id_, condition, text, responses=None, actions=None):
144        """
145        Initialize a new L{DialogueGreeting} instance.
146       
147        @param id_: named used to uniquely identify the L{DialogueSection}
148            within a L{Dialogue}.
149        @type id_: basestring
150        @param condition: Boolean Python expression used to determine if this
151            root dialogue section should be displayed.
152        @type condition: basestring
153        @param text: text displayed as the NPC's part of the L{Dialogue}.
154        @type text: basestring
155        @param responses: possible responses that the player can choose from.
156        @type responses: list of L{DialogueResponses<DialogueResponse>}
157        @param actions: dialogue actions that should be executed when the
158            L{DialogueSection} is reached.
159        @type actions: list of L{DialogueActions<DialogueAction>}
160        """
161        DialogueSection.__init__(self, id_=id_, text=text, responses=responses,
162                                 actions=actions)
163        self.condition = condition
164
165
166class DialogueResponse(DialogueNode):
167    """
168    L{DialogueNode} that represents one possible player response to a
169    particular L{DialogueSection}.
170    """
171    __slots__ = ['text', 'actions', 'condition', 'next_section_id']
172   
173    def __init__(self, text, next_section_id, actions=None, condition=None):
174        """
175        Initialize a new L{DialogueResponse} instance.
176       
177        @param text: text displayed as the content of the player's response.
178        @type text: basestring
179        @param next_section_id: ID of the L{DialogueSection} that should be
180            jumped to if this response is chosen by the player.
181        @type next_section_id: basestring
182        @param actions: dialogue actions that should be executed if this
183            response is chosen by the player.
184        @type actions: list of L{DialogueActions<DialogueAction>}
185        @param condition: Python expression that when evaluated determines
186            whether the L{DialogueResponse} should be displayed to the player
187            as a valid response.
188        @type condition: basestring
189        """
190        DialogueNode.__init__(self, text=text, actions=actions)
191        self.condition = condition
192        self.next_section_id = next_section_id
Note: See TracBrowser for help on using the repository browser.