gameshell/gameutil.py

105 lines
3.4 KiB
Python
Raw Normal View History

# 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.')
if len(args) == 0:
return None, -1, -1
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)