Added loci, and made dialog processing internal to the engine.
This commit is contained in:
parent
5010042430
commit
9cda61a895
11 changed files with 1860 additions and 1269 deletions
102
gameutil.py
Normal file
102
gameutil.py
Normal file
|
@ -0,0 +1,102 @@
|
|||
# gameutil.py
|
||||
|
||||
# This is a home for nice helper functions that were useful, but also cluttered
|
||||
# the GameBase class.
|
||||
|
||||
import re as _re
|
||||
|
||||
coordRegex = _re.compile(r'(?:(-?[a-zA-Z]+) ?(-?[0-9]+))|(?:(-?[0-9]+),? (-?[0-9]+))|(?:\(([0-9]+), ([0-9]+)\))')
|
||||
|
||||
def letterToNumber(letter):
|
||||
if letter.isdecimal():
|
||||
return int(letter)
|
||||
ret = 0
|
||||
sign = 1
|
||||
start = 0
|
||||
for i in range(len(letter)):
|
||||
if letter[i] == '-':
|
||||
sign = -sign
|
||||
start -= 1
|
||||
elif letter[i].isalpha():
|
||||
if letter[i].isupper():
|
||||
ret += (ord(letter[i]) - ord('A')) * (26**(i+start))
|
||||
else:
|
||||
ret += (ord(letter[i]) - ord('a')) * (26**(i+start))
|
||||
else:
|
||||
return ret * sign
|
||||
return ret * sign
|
||||
|
||||
def numberToLetter(number):
|
||||
if isinstance(number, str):
|
||||
return number
|
||||
ret = ''
|
||||
sign = ''
|
||||
if number == 0:
|
||||
return 'A'
|
||||
elif number < 0:
|
||||
sign = '-'
|
||||
number = -number
|
||||
while number > 0:
|
||||
ret += chr(ord('A') + number % 26)
|
||||
number = int(number / 26)
|
||||
return sign + ret
|
||||
|
||||
def parseCoords(level, args, usePlayerCoords = True, player = None):
|
||||
"""Takes an argument list, and figures out what it's talking about.
|
||||
Returns (thing, x, y). "Thing" can be None."""
|
||||
if level == None:
|
||||
raise ValueError('Coordinates cannot be parsed because there is no map.')
|
||||
x = -1
|
||||
y = -1
|
||||
|
||||
# first, try by name for objects in the map
|
||||
name = ' '.join(args)
|
||||
thing = level.getThingByName(name)
|
||||
if thing != None:
|
||||
if usePlayerCoords:
|
||||
return thing, thing.playerx, thing.playery
|
||||
else:
|
||||
return thing, thing.x, thing.y
|
||||
|
||||
# Second, try by name for objects in the inventory
|
||||
if player != None:
|
||||
if name in player.thingNames:
|
||||
return player.getThingByName(name), -1, -1
|
||||
|
||||
# Third, try by location
|
||||
coordStr = args[0]
|
||||
if len(args) > 1:
|
||||
coordStr += ' ' + args[1]
|
||||
match = coordRegex.match(coordStr)
|
||||
if match != None: # if coordinates were given
|
||||
groups = match.groups()
|
||||
ind = 0
|
||||
for i in range(len(groups)):
|
||||
if groups[i] == None or groups[i] == match.group():
|
||||
continue
|
||||
else:
|
||||
ind = i
|
||||
break
|
||||
x = letterToNumber(groups[ind])
|
||||
y = letterToNumber(groups[ind+1])
|
||||
thing = level.getThingAtCoords(x, y)
|
||||
if thing != None and usePlayerCoords:
|
||||
return thing, thing.playerx, thing.playery
|
||||
else:
|
||||
return thing, x, y
|
||||
else: # if a name was given
|
||||
return None, -1, -1
|
||||
|
||||
def startDialog(thing, outstream, dialog):
|
||||
if 'dialogs' in thing.customValues:
|
||||
if isinstance(thing.customValues['dialogs'], list):
|
||||
if 'dialogPtr' in thing.customValues and isinstance(thing.customValues['dialogPtr'], int):
|
||||
dialog(thing.customValues['dialogs'][thing.customValues['dialogPtr']], thing)
|
||||
else:
|
||||
dialog(thing.customValues['dialogs'][0], thing)
|
||||
elif isinstance(thing.customValues['dialogs'], str):
|
||||
dialog(thing.customValues['dialogs'], thing)
|
||||
else:
|
||||
raise GameError("Character '{}' has dialog of an unexpected type.".format(thing.name))
|
||||
else:
|
||||
print("{} has nothing to say to you.".format(thing.name), file = outstream)
|
Loading…
Add table
Add a link
Reference in a new issue