Added conditional evaluation to dialogs. Conditionals for the NPC have been tested, for the player have not.
This commit is contained in:
parent
b332d579e9
commit
ed7fe60a6d
3 changed files with 94 additions and 46 deletions
91
gameshell.py
91
gameshell.py
|
@ -315,33 +315,74 @@ If -l is given, a map legend will be printed under the map."""
|
|||
return charsRead / 27 # based on average 250 words per minute, and word length of 5.5 + 1 for space.
|
||||
|
||||
def dialog(self, dialogObj):
|
||||
if 'opener' in dialogObj:
|
||||
print(_tw.fill(dialogObj['opener'], width = TERM_SIZE))
|
||||
if 'script' in dialogObj:
|
||||
self.gameBase.parseScript(dialogObj['script'])
|
||||
while isinstance(dialogObj, dict):
|
||||
if 'action' in dialogObj:
|
||||
action = dialogObj['action']
|
||||
if action == 'answer':
|
||||
answer = 0
|
||||
if 'answers' in dialogObj and isinstance(dialogObj['answers'], list):
|
||||
for i in range(len(dialogObj['answers'])):
|
||||
print(_tw.fill('{}: {}'.format(i+1, dialogObj['answers'][i]), width = TERM_SIZE))
|
||||
answer = int(input(self.ps2)) - 1
|
||||
if 'replies' in dialogObj and isinstance(dialogObj['replies'], list):
|
||||
ret = self.dialog(dialogObj['replies'][answer])
|
||||
if ret > 1:
|
||||
return ret - 1
|
||||
elif ret == 0:
|
||||
return 0
|
||||
# if ret == 1, then do this dialog again
|
||||
|
||||
elif len(action) >= 4 and action[:4] == 'back':
|
||||
if len(action) == 4:
|
||||
return 1
|
||||
return int(action[4:])
|
||||
elif action == 'exit':
|
||||
return 0
|
||||
if 'cond' in dialogObj:
|
||||
cases = dialogObj['cond']
|
||||
ret = 0
|
||||
for case in cases:
|
||||
cond = case['case'].split() # should be list like ["value", "==", 1]
|
||||
if len(cond) == 1 and (cond[0] == 'else' or self.gameBase.getValueFromString(cond[0])):
|
||||
ret = self.dialog(case)
|
||||
break
|
||||
elif len(cond) == 3 and self.gameBase.compareValues(cond[1], cond[0], cond[2]):
|
||||
ret = self.dialog(case)
|
||||
break
|
||||
else:
|
||||
raise RuntimeError("All routes are false: {}".format(testValue))
|
||||
if ret > 1:
|
||||
return ret - 1
|
||||
else:
|
||||
return ret
|
||||
# if ret == 1 or ret == 0, go back again.
|
||||
elif 'opener' in dialogObj:
|
||||
print(_tw.fill(dialogObj['opener'], width = TERM_SIZE))
|
||||
while isinstance(dialogObj, dict):
|
||||
if 'action' in dialogObj:
|
||||
action = dialogObj['action']
|
||||
if action == 'answer':
|
||||
answer = 0
|
||||
skips = []
|
||||
j = 0 # follower to i
|
||||
if 'answers' in dialogObj and isinstance(dialogObj['answers'], list):
|
||||
for i in range(len(dialogObj['answers'])):
|
||||
ans = dialogObj['answers'][i]
|
||||
if ans[0] == '?':
|
||||
condEnd = ans.index(':')
|
||||
cond = ans[1:condEnd].strip().split()
|
||||
if self.gameBase.compareValues(cond[1], cond[0], cond[2]):
|
||||
print(_tw.fill('{}: {}'.format(j+1, ans[condEnd+1:]), width = TERM_SIZE))
|
||||
j += 1
|
||||
else:
|
||||
skips.append(i)
|
||||
else:
|
||||
print(_tw.fill('{}: {}'.format(j+1, ans), width = TERM_SIZE))
|
||||
j += 1
|
||||
answer = int(input(self.ps2)) - 1
|
||||
# account for offset if there were answer options that didn't meet conditions
|
||||
for i in skips:
|
||||
if i <= answer:
|
||||
answer += 1
|
||||
else:
|
||||
break
|
||||
if 'replies' in dialogObj and isinstance(dialogObj['replies'], list):
|
||||
ret = self.dialog(dialogObj['replies'][answer])
|
||||
if ret > 1:
|
||||
return ret - 1
|
||||
elif ret == 0:
|
||||
return 0
|
||||
# if ret == 1, then do this dialog again
|
||||
|
||||
elif len(action) >= 4 and action[:4] == 'back':
|
||||
if len(action) == 4:
|
||||
return 1
|
||||
return int(action[4:])
|
||||
elif action == 'exit':
|
||||
return 0
|
||||
else:
|
||||
raise RuntimeError('Malformed action: {}'.format(action))
|
||||
else:
|
||||
raise RuntimeError("Dialog branch with neither switch nor openner.")
|
||||
|
||||
def playercmd(self, args):
|
||||
self.handleCommand(args)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue