Added the ability to create prefabs.

This commit is contained in:
Patrick Marsee 2021-11-14 22:25:30 -05:00
parent 871646fccc
commit 18595087ff
5 changed files with 304 additions and 59 deletions

View file

@ -50,6 +50,7 @@ class GameMap(object):
tileRegex = re.compile(r'([a-z ])([0-9]+|[ ])')
matrixRegex = re.compile(r'(?:[ \t]*(?:[a-z ](?:[0-9]+|[ ]))+(\n))+')
yaml = ruamel.yaml.YAML()
yaml.register_class(_gt.Prefab)
yaml.register_class(_gt.Item)
yaml.register_class(_gt.Useable)
yaml.register_class(_gt.NPC)
@ -96,7 +97,16 @@ class GameMap(object):
return text.replace('\n', end)
@staticmethod
def read(infile = None, prevMap = None, singletons = None, preLoaded = False, nextThing = 0):
def resolvePrefab(prefabs: dict, thing: _gt.Thing):
"""Resolve what type of prefab a thing is. If it isn't a prefab or there are no prefabs loaded, just return the thing."""
if prefabs == None or len(prefabs) == 0 or not isinstance(thing, _gt.Prefab):
return thing
if thing.name not in prefabs:
raise MapError(f"Attempted to load an unrecognized prefab named {thing.name}.")
return prefabs[thing.name].fromPrefab(thing)
@staticmethod
def read(infile = None, prevMap = None, singletons = None, prefabs = None, preLoaded = False, nextThing = 0):
"""Read map data and return a Map object. If infile is not provided, then
it will read from stdin. Otherwise, it should be a valid file name.
Entering a map through stdin will be obsolete once testing is over."""
@ -139,7 +149,7 @@ Entering a map through stdin will be obsolete once testing is over."""
level = GameMap(infile, mapGraph, mapMatrix, dimensions)
# Now, load other info
nextThing = GameMap.loadThings(level, info, prevMap, singletons, preLoaded, nextThing)
nextThing = GameMap.loadThings(level, info, prevMap, singletons, prefabs, preLoaded, nextThing)
return level, nextThing
@ -204,7 +214,7 @@ list of lists of tuples."""
return mat, graph, dim
@staticmethod
def loadThings(level, info, prevMap = None, singletons = None, preLoaded = False, nextThing = 0):
def loadThings(level, info, prevMap = None, singletons = None, prefabs = None, preLoaded = False, nextThing = 0):
"""load the things from the xml part of the map file."""
if 'openingText' in info:
level.openingText = info['openingText']
@ -231,14 +241,14 @@ list of lists of tuples."""
for thing in info['loadOnce']:
#print(type(thing))
if isinstance(thing, _gt.Thing):
nextThing = level.addThing(thing, nextThing, True)
nextThing = level.addThing(GameMap.resolvePrefab(prefabs, thing), prefabs, nextThing, True)
else:
raise MapError("Non-thing loaded as a thing:\n{}".format(thing))
if 'loadAlways' in info:
for thing in info['loadAlways']:
#print(type(thing))
if isinstance(thing, _gt.Thing):
nextThing = level.addThing(thing, nextThing)
nextThing = level.addThing(GameMap.resolvePrefab(prefabs, thing), prefabs, nextThing)
if ((thing.thingType == 'x' and not hasKnownEntrance) or thing.thingType == 'a') and prevMap == thing.exitid:
level.playerStart = (thing.x, thing.y)
hasKnownEntrance = True
@ -247,14 +257,14 @@ list of lists of tuples."""
single = singletons[thing.name]
single.x, single.y = thing.x, thing.y
single.prevx, single.prevy = thing.x, thing.y
nextThing = level.addThing(single, nextThing)
nextThing = level.addThing(single, prefabs, nextThing)
else:
raise MapError("Non-thing loaded as a thing:\n{}".format(thing))
return nextThing
# stuff the gameshell itself might use
def addThing(self, thing, nextThing = 0, persist = False):
def addThing(self, thing, prefabs = None, nextThing = 0, persist = False):
if thing == None: # it must be a singleton
return nextThing
#if thing.name in self.thingNames: # resolved
@ -266,14 +276,14 @@ list of lists of tuples."""
# so they need IDs as well.
# Let's only add them if they weren't already loaded.
if thing.thingType in 'iun':
nextThing = GameMap.addThingRecursive(thing.customValues, nextThing)
if thing.thingType == 'n':
for i in thing.tempInventory:
if i.thingID == -1:
i.thingID = nextThing
nextThing = GameMap.addThingRecursive(i.customValues, nextThing + 1)
thing.addThing(i)
del thing.tempInventory
nextThing = GameMap.addThingRecursive(thing.customValues, prefabs, nextThing)
if thing.thingType == 'n':
for i in thing.tempInventory:
if i.thingID == -1:
i.thingID = nextThing
nextThing = GameMap.addThingRecursive(i.customValues, prefabs, nextThing + 1)
thing.addThing(i)
del thing.tempInventory
pos = self.coordsToInt(thing.x, thing.y)
if pos not in self.thingPos:
self.thingPos[pos] = [thing.thingID]
@ -289,21 +299,21 @@ list of lists of tuples."""
return nextThing
@staticmethod
def addThingRecursive(container, nextThing = 0):
def addThingRecursive(container, prefabs = None, nextThing = 0):
if isinstance(container, _gt.Thing):
if container.thingID == -1:
container.thingID = nextThing
nextThing = GameMap.addThingRecursive(container.customValues, nextThing)
nextThing = GameMap.addThingRecursive(container.customValues, prefabs, nextThing)
return nextThing + 1
else:
return nextThing
elif isinstance(container, dict):
for i in container:
nextThing = GameMap.addThingRecursive(container[i], nextThing)
nextThing = GameMap.addThingRecursive(GameMap.resolvePrefab(prefabs, container[i]), prefabs, nextThing)
return nextThing
elif isinstance(container, list):
for i in container:
nextThing = GameMap.addThingRecursive(i, nextThing)
nextThing = GameMap.addThingRecursive(GameMap.resolvePrefab(prefabs, i), prefabs, nextThing)
return nextThing
else:
return nextThing