Comment the code, convert a few odd tabs to spaces, and make a couple minor

formatting changes to improve the consistency of the class structure.  No
functional changes made.


git-svn-id: svn://svn.code.sf.net/p/crossfire/code/maps/trunk@10466 282e977c-c81d-0410-88c4-b93c2d0d6712
master
kbulgrien 2008-11-15 04:52:11 +00:00
parent dcecb2b60d
commit 5f6869717a
1 changed files with 69 additions and 9 deletions

View File

@ -182,32 +182,70 @@ class DialogRule:
self.__postsems= postsemaphores
self.__prefunction = prefunction
self.__postfunction = postfunction
# The keyword is a string. Multiple keywords may be defined in the string
# by delimiting them with vertical bar (|) characters. "*" is a special
# keyword that matches anything.
def getKeyword(self):
return self.__keyword
# Messages are stored in a list of strings. One or more messages may be
# defined in the list. If more than one message is present, a random
# string is returned.
def getMessage(self):
msg = self.__message
l = len(msg)
r = random.randint(0,l-1)
return msg[r]
# Return the preconditions of a rule. They are a list of one or more lists
# that specify a flag name to check, and one or more acceptable values it
# may have in order to allow the rule to be triggered.
def getPreconditions(self):
return self.__presems
# Return the postconditions for a rule. They are a list of one or more
# lists that specify a flag to be set in the player file and what value it
# should be set to.
def getPostconditions(self):
return self.__postsems
# A prefunction is a callback that is run in order to implement complex
# preconditions. The value returned by the called function determines
# whether or not the rule trigger.
def getPrefunction(self):
return self.__prefunction
# A postfunction is a callback that is run only if the rule is triggered,
# and only after the answer has been given to the player. It may be used
# to trigger some particular action as a result of the player saying the
# right (or wrong) thing at a particular point in a dialog.
def getPostfunction(self):
return self.__postfunction
class Dialog:
# A character is the source that supplies keywords that drive the dialog.
# The speaker is the NPC that responds to the keywords. A location is an
# unique identifier that is used to distinguish dialogs from each other.
def __init__(self, character, speaker, location):
self.__character = character
self.__location = location
self.__speaker = speaker
self.__rules = []
# Create rules of the DialogRule class that define dialog flow. An index
# defines the order in which rules are processed. FIXME: addRule could
# very easily create the index. It is unclear why this mundane activity
# is left for the dialog maker.
def addRule(self, rule, index):
self.__rules.insert(index,rule)
# A function to call when saying something to an NPC to elicit a response
# based on defined rules. It iterates through the rules and determines if
# the spoken text matches a keyword. If so, the rule preconditions and/or
# prefunctions are checked. If all conditions they define are met, then
# the NPC responds, and postconditions, if any, are set. Postfunctions
# also execute if present.
def speak(self, msg):
for rule in self.__rules:
if self.isAnswer(msg, rule.getKeyword())==1:
@ -217,6 +255,10 @@ class Dialog:
return 0
return 1
# Determine if the message sent to an NPC matches a string in the keyword
# list. The match check is case-insensitive, and succeeds if a keyword
# string is found in the message. This means that the keyword string(s)
# only need to be a substring of the message in order to trigger a reply.
def isAnswer(self, msg, keyword):
if keyword=="*":
return 1
@ -226,6 +268,12 @@ class Dialog:
return 1
return 0
# Check the preconditions specified in rule have been met. Preconditions
# are lists of one or more conditions to check. Each condition specifies
# a player file flag to check, and a list of one or more values that allow
# the condition check to succeed. If all preconditions are met, and if a
# prefunction has been defined, it is also called to implement more
# complex conditions that determine if the rule is allowed to trigger.
def matchConditions(self, rule):
for condition in rule.getPreconditions():
status = self.getStatus(condition[0])
@ -239,6 +287,9 @@ class Dialog:
return rule.getPrefunction()(self.__character, rule)
return 1
# If a rule triggers, this function is called to make identified player
# file changes, and to call any declared postfunctions to implement more
# dramatic effects than the setting of a flag in the player file.
def setConditions(self, rule):
for condition in rule.getPostconditions():
key = condition[0]
@ -248,6 +299,11 @@ class Dialog:
if rule.getPostfunction() <> None:
rule.getPostfunction()(self.__character, rule)
# Search the player file for a particular flag, and if it exists, return
# its value. Flag names are combined with the unique dialog "location"
# identifier, and are therefore are not required to be unique. This also
# prevents flags from conflicting with other non-dialog-related contents
# in the player file.
def getStatus(self, key):
character_status=self.__character.ReadKey("dialog_"+self.__location);
if character_status=="":
@ -259,6 +315,10 @@ class Dialog:
return subpair[1]
return "0"
# Store a flag in the player file and set it to the specified value. Flag
# names are combined with the unique dialog "location" identifier, and are
# therefore are not required to be unique. This also prevents flags from
# conflicting with other non-dialog-related contents in the player file.
def setStatus(self, key, value):
character_status=self.__character.ReadKey("dialog_"+self.__location);
finished=""