From 1c6503f49c6198a1cf821771b40f0b3f74e8067a Mon Sep 17 00:00:00 2001 From: cavesomething Date: Fri, 30 Apr 2010 17:19:34 +0000 Subject: [PATCH] Allow include rules to contain a "pre" block which will be evaluated to decide whether to allow the file(s) to be included. This is treated in exactly the same way as the "pre" blocks for all other rules. A test map demonstrating this in use is included. git-svn-id: svn://svn.code.sf.net/p/crossfire/code/maps/trunk@13049 282e977c-c81d-0410-88c4-b93c2d0d6712 --- python/CFDialog.py | 11 +++++++++++ python/dialog/npc_dialog.py | 20 ++++++++++++++++---- test/quest_handling/girl6.msg | 14 ++++++++++++++ test/quest_handling/girl7.msg | 9 +++++++++ test/quest_handling/girlmain.msg | 5 ++++- test/quest_handling/quest_map | 10 ++++++++-- 6 files changed, 62 insertions(+), 7 deletions(-) create mode 100644 test/quest_handling/girl6.msg create mode 100644 test/quest_handling/girl7.msg diff --git a/python/CFDialog.py b/python/CFDialog.py index 6ba983fdc..c298e012c 100644 --- a/python/CFDialog.py +++ b/python/CFDialog.py @@ -163,6 +163,17 @@ class DialogRule: def getRequires(self): return self.__requirements +# This is a subclass of the generic dialog rule that we use for determining whether to +# 'include' additional rules. +class IncludeRule(DialogRule): + def __init__(self, presemaphores): + self.__presems = presemaphores + + # I could get round doing this by creating a third class to inherit both this and + # DialogRule from, but this is the easier approach + def getPreconditions(self): + return self.__presems + 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 diff --git a/python/dialog/npc_dialog.py b/python/dialog/npc_dialog.py index 389b0ad2b..05c225024 100644 --- a/python/dialog/npc_dialog.py +++ b/python/dialog/npc_dialog.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- # npc_dialog.py - Dialog helper class # # Copyright (C) 2007 David Delbecq @@ -41,7 +42,7 @@ import Crossfire import os -from CFDialog import DialogRule, Dialog +from CFDialog import DialogRule, Dialog, IncludeRule import cjson location = "defaultdialognamespace" @@ -66,10 +67,21 @@ def parseJSON(filename): location = params["location"] for jsonRule in params["rules"]: if "include" in jsonRule: + shouldinclude = 0 + if "pre" in jsonRule: + incldialog = Dialog(player, npc, location) + inclrule = IncludeRule(jsonRule["pre"]) + # There will only ever be one 'pre' block for an include + shouldinclude = incldialog.matchConditions(inclrule) + else: + shouldinclude =1 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)) + if shouldinclude == 1: + # 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: + Crossfire.Log(Crossfire.LogDebug, "Ignoring NPC dialog from %s, conditions not met" % newfiles) else: parameters.append(jsonRule) return parameters diff --git a/test/quest_handling/girl6.msg b/test/quest_handling/girl6.msg new file mode 100644 index 000000000..2284b0651 --- /dev/null +++ b/test/quest_handling/girl6.msg @@ -0,0 +1,14 @@ +{ + "rules": [ + { + "match" : ["6", "six"], + "pre" : [], + "post" : [], + "msg" : ["You said 6."] + },{ + "match" : ["*"], + "pre" : [], + "post" : [], + "msg" : ["I can count up to 6 now, I am clevar."] + } +]} \ No newline at end of file diff --git a/test/quest_handling/girl7.msg b/test/quest_handling/girl7.msg new file mode 100644 index 000000000..a58697b66 --- /dev/null +++ b/test/quest_handling/girl7.msg @@ -0,0 +1,9 @@ +{ + "rules": [ + { + "match" : ["7", "seven"], + "pre" : [], + "post" : [], + "msg" : ["You said 7."] + } +]} \ No newline at end of file diff --git a/test/quest_handling/girlmain.msg b/test/quest_handling/girlmain.msg index f809829d9..ec620f2de 100644 --- a/test/quest_handling/girlmain.msg +++ b/test/quest_handling/girlmain.msg @@ -11,9 +11,12 @@ },{ "include" : ["test/quest_handling/girl3.msg", "test/quest_handling/girl4.msg"] },{ + "include" : ["test/quest_handling/girl7.msg", "test/quest_handling/girl6.msg"], + "pre" : [["token", "can count high", "1"]] + },{ "match" : ["*"], "pre" : [], - "post" : [], + "post" : [["settoken", "can count high", "1"]], "msg" : ["You didn't say a number to me."] } ]} diff --git a/test/quest_handling/quest_map b/test/quest_handling/quest_map index ef050e0a2..6c9bcdff0 100644 --- a/test/quest_handling/quest_map +++ b/test/quest_handling/quest_map @@ -5,7 +5,7 @@ width 20 height 10 msg Created: 2010-03-22 Cavesomething -Modified: 2010-04-27 Cavesomething +Modified: 2010-04-30 Cavesomething endmsg end arch graymarble @@ -1167,7 +1167,13 @@ end arch sign msg This dancing girl uses rules from multiple files that include each other. -say a number between 1 and 6, and you will get a response. +say a number between 1 and 5, and you will get a response. +If you say either 6 or 7, then she will only understand you if you have +said something other than 1-5 previously + +Demonstrates: +Dialogs 'include'ing files +Conditional including endmsg x 19 y 1