Change the npc_dialog.py file to allow message files to include other message

files.


git-svn-id: svn://svn.code.sf.net/p/crossfire/code/maps/trunk@13007 282e977c-c81d-0410-88c4-b93c2d0d6712
master
cavesomething 2010-04-27 17:04:29 +00:00
parent a0aa175a40
commit 22e874afb9
1 changed files with 39 additions and 83 deletions

View File

@ -17,10 +17,8 @@
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
# #
# #
# This is a simple script that makes use of CFDialog.py and that receives # This is a simple script that makes use of CFNPCDialog.py and that receives
# parameters from a JSON inside the event message. Alternatively, the JSON # parameters from a JSON inside the event message.
# parameters, if >= 4096 characters, can be stored in a separate file.
# Use the classical script parameter to specify relative location of dialog.
# #
# An example of a map file entry is: # An example of a map file entry is:
# #
@ -31,103 +29,61 @@
# endmsg # endmsg
# x 11 # x 11
# y 7 # y 7
# resist_physical 100
# resist_magic 100
# weight 50000000
# friendly 1
# stand_still 1
# arch event_say # arch event_say
# name start/sigmund.msg # name start/sigmund.msg
# title Python # title Python
# slaying /python/misc/npc_dialog.py # slaying /python/dialog/npc_dialog.py
# end # end
# end # end
# #
# An example of a JSON dialog similar to the one described in CFDialog.py is: # see http://wiki.metalforge.net/doku.php/user:cavesomething:guide_to_quest_dialogs
# # for lots of detail on how to use this, and look at examples in test/quest_handling
# {
# "location" : "test_grandpa_01",
# "rules": [
# {
# "match" : ["hello","hi"],
# "pre" : [["hello","0"]],
# "post" : [["hello","1"]],
# "msg" : ["Hello, lad!","Hi, young fellow!","Howdy!"]
# },
# {
# "match": ["hello","hi"],
# "pre" :[["hello","1"]],
# "post" :[["hello", "*"]],
# "msg" : ["I've heard, you know, I'm not deaf *grmbl*"]
# },
# {
# "match" : ["*"],
# "pre" : [["hello","*"]],
# "post" : [["hello", "*"]],
# "msg" : ["What ?", "Huh ?", "What do you want ?"]
# }
# ]}
#
# For detailed descriptions of the match, pre, post, and msg formats, see the
# ../CFDialog.py script.
#
# "match" is a list of keyword strings, and corresponds to what the player says
# that the dialog will respond to.
#
# In the above example, the first rule is applied if the player/character says
# "hello" or "hi" and if the "hello" flag is set to "0" (default). When the
# rule is applied, the "hello" flag is then set to "1".
#
# "pre" is a list of preconditions that identifies flags that must be set to a
# particular value in order to trigger a response if a match is detected.
#
# "post" is a list of postconditions that specify flags that are to be set if a
# response is triggered.
#
# All of the rule values are lists, and must be enclosed by square braces, but
# pre and post are lists of lists, so the nested square braces ([[]]) are
# required except that using an empty list [] is the best way to indicate when
# the rule does not need to check preconditions or set postconditions.
#
# "msg" defines one or more responses that will be given if the rule triggers.
# When more than one "msg" value is set up, the NPC randomly selects which one
# to say each time the rule is applied.
#
# A relatively complex example of an npc_dialog.py dialog is given in the Gork
# treasure room quest. See ../scorn/kar/gork.msg in particular as it
# demonstrates how multiple precondition flag values may be exploited to
# produce non-linear and variable-path conversations that are less likely to
# frustrate a player. Refer also to ../scorn/kar/mork.msg to see how more
# than one dialog can reference the same dialog flags.
import Crossfire import Crossfire
import os import os
from CFDialog import DialogRule, Dialog from CFDialog import DialogRule, Dialog
import cjson import cjson
location = "defaultdialognamespace"
def parseJSON(filename):
global location
parameters = []
for filenm in filename:
filepath = os.path.join(Crossfire.DataDirectory(),
Crossfire.MapDirectory(),
filenm)
try:
f = open(filepath,'rb')
except:
Crossfire.Log(Crossfire.LogDebug, "Error loading NPC dialog %s" % filepath)
raise
else:
Crossfire.Log(Crossfire.LogDebug, "Loading NPC dialog %s" % filepath)
params = cjson.decode(f.read())
f.close()
if "location" in params:
location = params["location"]
for jsonRule in params["rules"]:
if "include" in jsonRule:
newfiles = jsonRule["include"]
# this isn't a 'real' rule, so we don't include it, but we do
# include the results of parsing it.
parameters.extend(parseJSON(newfiles))
else:
parameters.append(jsonRule)
return parameters
npc = Crossfire.WhoAmI() npc = Crossfire.WhoAmI()
event = Crossfire.WhatIsEvent() #event = Crossfire.WhatIsEvent()
player = Crossfire.WhoIsActivator() player = Crossfire.WhoIsActivator()
if (Crossfire.ScriptParameters() != None): if (Crossfire.ScriptParameters() != None):
filename = os.path.join(Crossfire.DataDirectory(), filename = Crossfire.ScriptParameters()
Crossfire.MapDirectory(), dialogs = parseJSON([filename])
Crossfire.ScriptParameters())
try:
f = open(filename,'rb')
except:
Crossfire.Log(Crossfire.LogDebug, "Error loading NPC dialog %s" % filename)
raise
else:
Crossfire.Log(Crossfire.LogDebug, "Loading NPC dialog %s" % filename)
parameters = cjson.decode(f.read())
f.close()
else:
parameters = cjson.decode(event.Message)
location = parameters["location"];
speech = Dialog(player, npc, location) speech = Dialog(player, npc, location)
index = 0; index = 0;
for jsonRule in parameters["rules"]: for jsonRule in dialogs:
rule = DialogRule(jsonRule["match"], rule = DialogRule(jsonRule["match"],
jsonRule["pre"], jsonRule["pre"],
jsonRule["msg"], jsonRule["msg"],