Things can now be shared globally by maps.
This commit is contained in:
parent
aba0014e27
commit
963c77f77c
3 changed files with 73 additions and 35 deletions
86
gamemap.py
86
gamemap.py
|
@ -5,6 +5,38 @@ import ruamel.yaml
|
|||
import math as _mt
|
||||
import gamethings as _gt
|
||||
import gamelocus as _gl
|
||||
from ruamel.yaml.comments import CommentedMap
|
||||
|
||||
class Singleton(object):
|
||||
"""This is a super basic class (would be a struct in other languages)
|
||||
that represents where a singleton Thing should be in a map."""
|
||||
yaml_flag = u'!Singleton'
|
||||
|
||||
def __init__(self, name: str, x: int, y: int):
|
||||
self.name = name
|
||||
self.x = x
|
||||
self.y = y
|
||||
|
||||
@classmethod
|
||||
def to_yaml(cls, representer, node):
|
||||
representer.represent_mapping({
|
||||
'name': self.name,
|
||||
'location': (self.x, self.y)
|
||||
})
|
||||
|
||||
@classmethod
|
||||
def from_yaml(cls, constructor, node):
|
||||
parts = CommentedMap()
|
||||
constructor.construct_mapping(node, parts, True)
|
||||
# since all parts are necessary, I won't bother with if statements
|
||||
# and let it crash.
|
||||
if not isinstance(parts['name'], str):
|
||||
raise RuntimeError("Name must be a string.")
|
||||
if not isinstance(parts['location'], list):
|
||||
raise RuntimeError("Location must be a list.")
|
||||
if not (isinstance(parts['location'][0], int) and isinstance(parts['location'][1], int)):
|
||||
raise RuntimeError("Coordinates must be integers.")
|
||||
return cls(parts['name'], parts['location'][0], parts['location'][1])
|
||||
|
||||
class MapError(RuntimeError):
|
||||
pass
|
||||
|
@ -24,6 +56,7 @@ class GameMap(object):
|
|||
yaml.register_class(_gt.Door)
|
||||
yaml.register_class(_gt.MapExit)
|
||||
yaml.register_class(_gt.MapEntrance)
|
||||
yaml.register_class(Singleton)
|
||||
|
||||
def __init__(self, name, graph, matrix, dimensions):
|
||||
self.name = name
|
||||
|
@ -63,7 +96,7 @@ class GameMap(object):
|
|||
return text.replace('\n', end)
|
||||
|
||||
@staticmethod
|
||||
def read(infile = None, prevMap = None, preLoaded = False, nextThing = 0):
|
||||
def read(infile = None, prevMap = None, singletons = 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."""
|
||||
|
@ -106,7 +139,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, preLoaded, nextThing)
|
||||
nextThing = GameMap.loadThings(level, info, prevMap, singletons, preLoaded, nextThing)
|
||||
|
||||
return level, nextThing
|
||||
|
||||
|
@ -171,7 +204,7 @@ list of lists of tuples."""
|
|||
return mat, graph, dim
|
||||
|
||||
@staticmethod
|
||||
def loadThings(level, info, prevMap = None, preLoaded = False, nextThing = 0):
|
||||
def loadThings(level, info, prevMap = None, singletons = None, preLoaded = False, nextThing = 0):
|
||||
"""load the things from the xml part of the map file."""
|
||||
if 'openingText' in info:
|
||||
level.openingText = info['openingText']
|
||||
|
@ -197,37 +230,50 @@ list of lists of tuples."""
|
|||
if 'loadOnce' in info and not preLoaded:
|
||||
for thing in info['loadOnce']:
|
||||
#print(type(thing))
|
||||
nextThing = level.addThing(thing, nextThing, True)
|
||||
if isinstance(thing, _gt.Thing):
|
||||
nextThing = level.addThing(thing, 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))
|
||||
nextThing = level.addThing(thing, nextThing)
|
||||
if ((thing.thingType == 'x' and not hasKnownEntrance) or thing.thingType == 'a') and prevMap == thing.exitid:
|
||||
level.playerStart = (thing.x, thing.y)
|
||||
hasKnownEntrance = True
|
||||
if isinstance(thing, _gt.Thing):
|
||||
nextThing = level.addThing(thing, nextThing)
|
||||
if ((thing.thingType == 'x' and not hasKnownEntrance) or thing.thingType == 'a') and prevMap == thing.exitid:
|
||||
level.playerStart = (thing.x, thing.y)
|
||||
hasKnownEntrance = True
|
||||
elif isinstance(thing, Singleton):
|
||||
if singletons != None:
|
||||
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)
|
||||
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):
|
||||
if thing == None:
|
||||
if thing == None: # it must be a singleton
|
||||
return nextThing
|
||||
#if thing.name in self.thingNames: # resolved
|
||||
# raise ValueError("Cannot have two objects named {0}.".format(thing.name))
|
||||
if thing.thingID == -1: # This is to ensure that we don't double up IDs.
|
||||
thing.thingID = nextThing
|
||||
nextThing += 1
|
||||
# Some things, like containers, have other things as custom values,
|
||||
# so they need IDs as well.
|
||||
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
|
||||
# Some things, like containers, have other things as custom values,
|
||||
# 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
|
||||
pos = self.coordsToInt(thing.x, thing.y)
|
||||
if pos not in self.thingPos:
|
||||
self.thingPos[pos] = [thing.thingID]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue