# 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)