All map files converted to new YAML standard.

This commit is contained in:
Patrick Marsee 2019-03-09 19:08:46 -05:00
parent c5029ac0fc
commit adfb6b83f4
17 changed files with 3123 additions and 2691 deletions

1
.gitignore vendored
View file

@ -2,3 +2,4 @@ maps
saves saves
__pycache__ __pycache__
winsh.py winsh.py
yamltest.py

File diff suppressed because it is too large Load diff

View file

@ -1,100 +1,100 @@
#gameevents.py #gameevents.py
# Experimental: events are ordered in the order that they were created, # Experimental: events are ordered in the order that they were created,
# to resolve issues where two events happen at the same time. # to resolve issues where two events happen at the same time.
_eventNum = 0 _eventNum = 0
def resetEventNum(): def resetEventNum():
global _eventNum global _eventNum
_eventNum = 0 _eventNum = 0
class GameEvent(object): class GameEvent(object):
def __init__(self, eventType: str): def __init__(self, eventType: str):
global _eventNum global _eventNum
self.eventType = eventType self.eventType = eventType
# Experimental, also NOT THREAD SAFE! # Experimental, also NOT THREAD SAFE!
self.eventNum = _eventNum self.eventNum = _eventNum
_eventNum += 1 _eventNum += 1
def __str__(self): def __str__(self):
return "{0} ({1})".format(self.eventType, self.eventNum) return "{0} ({1})".format(self.eventType, self.eventNum)
def __eq__(self, other): def __eq__(self, other):
if isinstance(other, GameEvent): if isinstance(other, GameEvent):
return self.eventNum == other.eventNum return self.eventNum == other.eventNum
else: else:
return self.eventNum == other return self.eventNum == other
def __ne__(self, other): def __ne__(self, other):
if isinstance(other, GameEvent): if isinstance(other, GameEvent):
return self.eventNum != other.eventNum return self.eventNum != other.eventNum
else: else:
return self.eventNum != other return self.eventNum != other
def __lt__(self, other): def __lt__(self, other):
if isinstance(other, GameEvent): if isinstance(other, GameEvent):
return self.eventNum < other.eventNum return self.eventNum < other.eventNum
else: else:
return self.eventNum < other return self.eventNum < other
def __le__(self, other): def __le__(self, other):
if isinstance(other, GameEvent): if isinstance(other, GameEvent):
return self.eventNum <= other.eventNum return self.eventNum <= other.eventNum
else: else:
return self.eventNum <= other return self.eventNum <= other
def __gt__(self, other): def __gt__(self, other):
if isinstance(other, GameEvent): if isinstance(other, GameEvent):
return self.eventNum > other.eventNum return self.eventNum > other.eventNum
else: else:
return self.eventNum > other return self.eventNum > other
def __ge__(self, other): def __ge__(self, other):
if isinstance(other, GameEvent): if isinstance(other, GameEvent):
return self.eventNum >= other.eventNum return self.eventNum >= other.eventNum
else: else:
return self.eventNum >= other return self.eventNum >= other
class NoOpEvent(GameEvent): class NoOpEvent(GameEvent):
def __init__(self): def __init__(self):
super(NoOpEvent, self).__init__('noop') super(NoOpEvent, self).__init__('noop')
class GoEvent(GameEvent): class GoEvent(GameEvent):
def __init__(self, actor, x, y): def __init__(self, actor, x, y):
super(GoEvent, self).__init__('go') super(GoEvent, self).__init__('go')
self.actor = actor self.actor = actor
self.x = x self.x = x
self.y = y self.y = y
class ArriveEvent(GameEvent): class ArriveEvent(GameEvent):
def __init__(self, actor, x, y, t): def __init__(self, actor, x, y, t):
super(ArriveEvent, self).__init__('arrive') super(ArriveEvent, self).__init__('arrive')
self.actor = actor self.actor = actor
self.x = x self.x = x
self.y = y self.y = y
self.t = t self.t = t
class UseEvent(GameEvent): class UseEvent(GameEvent):
def __init__(self, thing): def __init__(self, thing):
super(UseEvent, self).__init__('use') super(UseEvent, self).__init__('use')
self.thing = thing self.thing = thing
class UseOnEvent(GameEvent): class UseOnEvent(GameEvent):
def __init__(self, item, thing): def __init__(self, item, thing):
super(UseOnEvent, self).__init__('useon') super(UseOnEvent, self).__init__('useon')
self.thing = thing # thing can be a coordinate pair? self.thing = thing # thing can be a coordinate pair?
self.item = item self.item = item
class TakeEvent(GameEvent): class TakeEvent(GameEvent):
def __init__(self, item): def __init__(self, item):
super(TakeEvent, self).__init__('take') super(TakeEvent, self).__init__('take')
self.item = item self.item = item
class DropEvent(GameEvent): class DropEvent(GameEvent):
def __init__(self, item): def __init__(self, item):
super(DropEvent, self).__init__('drop') super(DropEvent, self).__init__('drop')
self.item = item self.item = item

View file

@ -1,439 +1,439 @@
# gamegui.py # gamegui.py
from tkinter import * from tkinter import *
from tkinter import ttk from tkinter import ttk
from tkinter import filedialog from tkinter import filedialog
from tkinter import messagebox from tkinter import messagebox
from tile import Tile from tile import Tile
from gamebase import GameBase from gamebase import GameBase
import io import io
class App(ttk.Frame): class App(ttk.Frame):
def __init__(self, master, gameBase): def __init__(self, master, gameBase):
#print('Initializing...') #print('Initializing...')
super(App, self).__init__(master) super(App, self).__init__(master)
self.gameBase = gameBase self.gameBase = gameBase
self.gameBase.outstream = io.StringIO() self.gameBase.outstream = io.StringIO()
self.gameBase.requestInput = self.requestInput self.gameBase.requestInput = self.requestInput
self.gameBase.onLevelLoad = self.getGraphics self.gameBase.onLevelLoad = self.getGraphics
self.selected = (-1, -1) self.selected = (-1, -1)
self.parent = master self.parent = master
self.mapSize = (800, 450) self.mapSize = (800, 450)
self.hasChanged = False self.hasChanged = False
self.fileName = 'Untitled' self.fileName = 'Untitled'
self.invTuple = tuple(self.gameBase.playerInv.keys()) self.invTuple = tuple(self.gameBase.playerInv.keys())
self.invNames = StringVar(value=self.invTuple) self.invNames = StringVar(value=self.invTuple)
#self.project = Project() #self.project = Project()
self.tool = StringVar() self.tool = StringVar()
self.brush = StringVar() self.brush = StringVar()
self.history = [] self.history = []
self.redos = [] self.redos = []
#self.selectedArea = (0, 0, self.project.x-1, self.project.y-1) #self.selectedArea = (0, 0, self.project.x-1, self.project.y-1)
self.parent.clipboard_clear() self.parent.clipboard_clear()
self.parent.clipboard_append('') self.parent.clipboard_append('')
self.grid() self.grid()
self.createWidgets() self.createWidgets()
self.makeTheDisplayWork() self.makeTheDisplayWork()
self.bindKeys() self.bindKeys()
#print('Done.') #print('Done.')
def createWidgets(self): def createWidgets(self):
#print('Creating Widgets...') #print('Creating Widgets...')
self.initWidth, self.initHeight = 0, 0 self.initWidth, self.initHeight = 0, 0
# create menu bar # create menu bar
self.createMenuBar() self.createMenuBar()
# create map # create map
self.createMapView() self.createMapView()
# create text out # create text out
self.createTextOut() self.createTextOut()
# create inventory list # create inventory list
self.createInventoryView() self.createInventoryView()
#self.tool.set('setone') #self.tool.set('setone')
#brushes = ttk.Combobox(self, textvariable = self.brush, values = tuple(sorted(Project.tileID.keys()))) #brushes = ttk.Combobox(self, textvariable = self.brush, values = tuple(sorted(Project.tileID.keys())))
#brushes.grid(column = 0, row = 6, sticky = (E, W)) #brushes.grid(column = 0, row = 6, sticky = (E, W))
#brushes.state(['readonly']) #brushes.state(['readonly'])
#brushes.set('Dirt') #brushes.set('Dirt')
#ttk.Separator(self, orient = VERTICAL).grid(column = 1, row = 0, rowspan = 9, sticky = (N, S)) #ttk.Separator(self, orient = VERTICAL).grid(column = 1, row = 0, rowspan = 9, sticky = (N, S))
ttk.Sizegrip(self).grid(column = 1, row = 1, sticky = (S, E)) ttk.Sizegrip(self).grid(column = 1, row = 1, sticky = (S, E))
self.columnconfigure(0, weight = 1) self.columnconfigure(0, weight = 1)
self.rowconfigure(0, weight = 1) self.rowconfigure(0, weight = 1)
#print('Done.') #print('Done.')
def createMenuBar(self): def createMenuBar(self):
#print('Creating the menubar...') #print('Creating the menubar...')
menubar = Menu(self.parent) menubar = Menu(self.parent)
menuFile = Menu(menubar) menuFile = Menu(menubar)
#menuEdit = Menu(menubar) #menuEdit = Menu(menubar)
menuHelp = Menu(menubar) menuHelp = Menu(menubar)
menubar.add_cascade(menu = menuFile, label = 'File') menubar.add_cascade(menu = menuFile, label = 'File')
menuFile.add_command(label = 'New', command = lambda: self.loadLevel('maps/apartment.xml'), accelerator = 'Ctrl+N') menuFile.add_command(label = 'New', command = lambda: self.loadLevel('maps/apartment.xml'), accelerator = 'Ctrl+N')
menuFile.add_command(label = 'Open...', command = self.fileOpen, accelerator = 'Ctrl+O') menuFile.add_command(label = 'Open...', command = self.fileOpen, accelerator = 'Ctrl+O')
menuFile.add_command(label = 'Save', command = self.fileSave, accelerator = 'Ctrl+S') menuFile.add_command(label = 'Save', command = self.fileSave, accelerator = 'Ctrl+S')
menuFile.add_command(label = 'Save As...', command = self.fileSaveAs) menuFile.add_command(label = 'Save As...', command = self.fileSaveAs)
menuFile.add_separator() menuFile.add_separator()
menuFile.add_command(label = 'Exit', command = self.onQuit, accelerator = 'Ctrl+Q') menuFile.add_command(label = 'Exit', command = self.onQuit, accelerator = 'Ctrl+Q')
#menubar.add_cascade(menu = menuEdit, label = 'Edit') #menubar.add_cascade(menu = menuEdit, label = 'Edit')
#menuEdit.add_command(label = 'Undo', command = self.undo, accelerator = 'Ctrl+Z') #menuEdit.add_command(label = 'Undo', command = self.undo, accelerator = 'Ctrl+Z')
#menuEdit.add_command(label = 'Redo', command = self.redo, accelerator = 'Ctrl+Y') #menuEdit.add_command(label = 'Redo', command = self.redo, accelerator = 'Ctrl+Y')
#menuEdit.add_separator() #menuEdit.add_separator()
#menuEdit.add_command(label = 'Cut', command = self.cut, accelerator = 'Ctrl+X') #menuEdit.add_command(label = 'Cut', command = self.cut, accelerator = 'Ctrl+X')
#menuEdit.add_command(label = 'Copy', command = self.copy, accelerator = 'Ctrl+C') #menuEdit.add_command(label = 'Copy', command = self.copy, accelerator = 'Ctrl+C')
#menuEdit.add_command(label = 'Paste', command = self.paste, accelerator = 'Ctrl+V') #menuEdit.add_command(label = 'Paste', command = self.paste, accelerator = 'Ctrl+V')
menubar.add_cascade(menu = menuHelp, label = 'Help') menubar.add_cascade(menu = menuHelp, label = 'Help')
menuHelp.add_command(label = 'About', command = self.about) menuHelp.add_command(label = 'About', command = self.about)
menuHelp.add_separator() menuHelp.add_separator()
menuHelp.add_command(label = 'Read Me', command = self.readme) menuHelp.add_command(label = 'Read Me', command = self.readme)
self.parent.configure(menu = menubar) self.parent.configure(menu = menubar)
#print('Done.') #print('Done.')
def createMapView(self): def createMapView(self):
mapFrame = ttk.LabelFrame(self, text = "map") mapFrame = ttk.LabelFrame(self, text = "map")
mapFrame.grid(column = 0, row = 0) mapFrame.grid(column = 0, row = 0)
self.levelDisplay = Canvas(mapFrame, width = self.mapSize[0], height = self.mapSize[1], scrollregion = '0 0 2048 2048') self.levelDisplay = Canvas(mapFrame, width = self.mapSize[0], height = self.mapSize[1], scrollregion = '0 0 2048 2048')
self.levelDisplay.grid(column = 0, row = 0) self.levelDisplay.grid(column = 0, row = 0)
vbar = ttk.Scrollbar(mapFrame, orient = VERTICAL, command = self.levelDisplay.yview) vbar = ttk.Scrollbar(mapFrame, orient = VERTICAL, command = self.levelDisplay.yview)
self.levelDisplay.configure(yscrollcommand = vbar.set) self.levelDisplay.configure(yscrollcommand = vbar.set)
vbar.grid(column = 1, row = 0, sticky = (N, S)) vbar.grid(column = 1, row = 0, sticky = (N, S))
hbar = ttk.Scrollbar(mapFrame, orient = HORIZONTAL, command = self.levelDisplay.xview) hbar = ttk.Scrollbar(mapFrame, orient = HORIZONTAL, command = self.levelDisplay.xview)
self.levelDisplay.configure(xscrollcommand = hbar.set) self.levelDisplay.configure(xscrollcommand = hbar.set)
hbar.grid(column = 0, row = 1, sticky = (E, W)) hbar.grid(column = 0, row = 1, sticky = (E, W))
self.bind('<Configure>', self.onResize) self.bind('<Configure>', self.onResize)
def createTextOut(self): def createTextOut(self):
textFrame = ttk.LabelFrame(self, text = "Info") textFrame = ttk.LabelFrame(self, text = "Info")
textFrame.grid(column = 0, row = 1) textFrame.grid(column = 0, row = 1)
self.infoDisplay = Text(textFrame, width = 80, height = 8, state = 'disabled') self.infoDisplay = Text(textFrame, width = 80, height = 8, state = 'disabled')
self.infoDisplay.grid(column = 0, row = 0) self.infoDisplay.grid(column = 0, row = 0)
vbar = ttk.Scrollbar(textFrame, orient = VERTICAL, command = self.infoDisplay.yview) vbar = ttk.Scrollbar(textFrame, orient = VERTICAL, command = self.infoDisplay.yview)
self.infoDisplay.configure(yscrollcommand = vbar.set) self.infoDisplay.configure(yscrollcommand = vbar.set)
vbar.grid(column = 1, row = 0, sticky = (N, S)) vbar.grid(column = 1, row = 0, sticky = (N, S))
self.infoCursor = 0 self.infoCursor = 0
def createInventoryView(self): def createInventoryView(self):
invFrame = ttk.LabelFrame(self, text = "Inventory") invFrame = ttk.LabelFrame(self, text = "Inventory")
invFrame.grid(column = 1, row = 0) invFrame.grid(column = 1, row = 0)
self.invDisplay = Listbox(invFrame, height = 24, listvariable = self.invNames) self.invDisplay = Listbox(invFrame, height = 24, listvariable = self.invNames)
self.invDisplay.grid(column = 0, row = 0) self.invDisplay.grid(column = 0, row = 0)
vbar = ttk.Scrollbar(invFrame, orient = VERTICAL, command = self.invDisplay.yview) vbar = ttk.Scrollbar(invFrame, orient = VERTICAL, command = self.invDisplay.yview)
self.invDisplay.configure(yscrollcommand = vbar.set) self.invDisplay.configure(yscrollcommand = vbar.set)
vbar.grid(column = 1, row = 0, sticky = (N, S)) vbar.grid(column = 1, row = 0, sticky = (N, S))
def getGraphics(self): def getGraphics(self):
self.tiles = {} self.tiles = {}
for i in range(len(self.gameBase.level.floorColors)): for i in range(len(self.gameBase.level.floorColors)):
self.tiles['e{0}'.format(i)] = Tile(self.gameBase.level.floorColors[i]) self.tiles['e{0}'.format(i)] = Tile(self.gameBase.level.floorColors[i])
for i in range(len(self.gameBase.level.wallColors)): for i in range(len(self.gameBase.level.wallColors)):
self.tiles['w{0}'.format(i)] = Tile(self.gameBase.level.wallColors[i]) self.tiles['w{0}'.format(i)] = Tile(self.gameBase.level.wallColors[i])
self.tiles['player'] = Tile('clear', 'blue', 'o') self.tiles['player'] = Tile('clear', 'blue', 'o')
for thing in self.gameBase.level.thingNames: for thing in self.gameBase.level.thingNames:
graphic = self.gameBase.level.thingNames[thing].graphic graphic = self.gameBase.level.thingNames[thing].graphic
self.tiles[thing] = Tile(graphic[0], graphic[1], graphic[2]) self.tiles[thing] = Tile(graphic[0], graphic[1], graphic[2])
def makeTheDisplayWork(self): def makeTheDisplayWork(self):
#print('Making the display work...') #print('Making the display work...')
# level display # level display
self.context = Menu(self.levelDisplay) self.context = Menu(self.levelDisplay)
self.context.add_command(label = 'Load Map', command = lambda: self.loadLevel('maps/apartment.xml')) self.context.add_command(label = 'Load Map', command = lambda: self.loadLevel('maps/apartment.xml'))
self.context.add_command(label = 'Go', command = lambda: self.go(self.selected[0], self.selected[1])) self.context.add_command(label = 'Go', command = lambda: self.go(self.selected[0], self.selected[1]))
self.context.add_command(label = 'Run', command = lambda: self.go(self.selected[0], self.selected[1], True)) self.context.add_command(label = 'Run', command = lambda: self.go(self.selected[0], self.selected[1], True))
self.context.add_command(label = 'Look', command = lambda: self.look(self.selected[0], self.selected[1])) self.context.add_command(label = 'Look', command = lambda: self.look(self.selected[0], self.selected[1]))
self.context.add_command(label = 'Use', command = lambda: self.use(self.selected[0], self.selected[1])) self.context.add_command(label = 'Use', command = lambda: self.use(self.selected[0], self.selected[1]))
self.context.add_command(label = 'Take', command = lambda: self.take(self.selected[0], self.selected[1])) self.context.add_command(label = 'Take', command = lambda: self.take(self.selected[0], self.selected[1]))
#self.context.add_command(label = 'Cut', command = self.cut, accelerator = 'Ctrl+X') #self.context.add_command(label = 'Cut', command = self.cut, accelerator = 'Ctrl+X')
#self.context.add_command(label = 'Goblin...') #self.context.add_command(label = 'Goblin...')
#self.context.entryconfigure('Goblin...', command = self.configureGoblin, state = DISABLED) #self.context.entryconfigure('Goblin...', command = self.configureGoblin, state = DISABLED)
#self.refreshDisplay() #self.refreshDisplay()
self.levelDisplay.bind('<1>', self.handleClick) self.levelDisplay.bind('<1>', self.handleClick)
self.levelDisplay.bind('<Double-1>', self.handleDoubleClick) self.levelDisplay.bind('<Double-1>', self.handleDoubleClick)
#self.levelDisplay.bind('<B1-Motion>', self.handleDragEvent) #self.levelDisplay.bind('<B1-Motion>', self.handleDragEvent)
#self.levelDisplay.bind('<ButtonRelease-1>', self.handleReleaseEvent) #self.levelDisplay.bind('<ButtonRelease-1>', self.handleReleaseEvent)
self.levelDisplay.bind('<3>', self.handleRightClick) self.levelDisplay.bind('<3>', self.handleRightClick)
# inventory list # inventory list
self.invContext = Menu(self.invDisplay) self.invContext = Menu(self.invDisplay)
self.invContext.add_command(label = 'Look', command = lambda: self.look(self.invTuple[self.invDisplay.curselection()[0]])) self.invContext.add_command(label = 'Look', command = lambda: self.look(self.invTuple[self.invDisplay.curselection()[0]]))
self.invContext.add_command(label = 'Use', command = lambda: self.use(self.invTuple[self.invDisplay.curselection()[0]])) self.invContext.add_command(label = 'Use', command = lambda: self.use(self.invTuple[self.invDisplay.curselection()[0]]))
self.invContext.add_command(label = 'Drop', command = lambda: self.drop(self.invTuple[self.invDisplay.curselection()[0]])) self.invContext.add_command(label = 'Drop', command = lambda: self.drop(self.invTuple[self.invDisplay.curselection()[0]]))
self.invDisplay.bind('<<ListboxSelect>>', lambda e: self.look(self.invTuple[self.invDisplay.curselection()[0]])) self.invDisplay.bind('<<ListboxSelect>>', lambda e: self.look(self.invTuple[self.invDisplay.curselection()[0]]))
self.invDisplay.bind('<3>', lambda e: self.invContext.post(e.x_root, e.y_root)) self.invDisplay.bind('<3>', lambda e: self.invContext.post(e.x_root, e.y_root))
#print('Done.') #print('Done.')
pass pass
def bindKeys(self): def bindKeys(self):
self.parent.bind('<Control-n>', lambda e: self.fileNew()) self.parent.bind('<Control-n>', lambda e: self.fileNew())
self.parent.bind('<Control-o>', lambda e: self.fileOpen()) self.parent.bind('<Control-o>', lambda e: self.fileOpen())
self.parent.bind('<Control-s>', lambda e: self.fileSave()) self.parent.bind('<Control-s>', lambda e: self.fileSave())
#self.parent.bind('<Control-z>', lambda e: self.undo()) #self.parent.bind('<Control-z>', lambda e: self.undo())
#self.parent.bind('<Control-y>', lambda e: self.redo()) #self.parent.bind('<Control-y>', lambda e: self.redo())
#self.parent.bind('<Control-x>', lambda e: self.cut()) #self.parent.bind('<Control-x>', lambda e: self.cut())
#self.parent.bind('<Control-c>', lambda e: self.copy()) #self.parent.bind('<Control-c>', lambda e: self.copy())
#self.parent.bind('<Control-v>', lambda e: self.paste()) #self.parent.bind('<Control-v>', lambda e: self.paste())
self.parent.bind('<Control-q>', lambda e: self.onQuit()) self.parent.bind('<Control-q>', lambda e: self.onQuit())
def refreshDisplay(self): def refreshDisplay(self):
#print('Refreshing the display...') #print('Refreshing the display...')
# refresh the map # refresh the map
self.levelDisplay.delete('all') self.levelDisplay.delete('all')
for y in range(self.gameBase.level.dimensions[1]): for y in range(self.gameBase.level.dimensions[1]):
for x in range(self.gameBase.level.dimensions[0]): for x in range(self.gameBase.level.dimensions[0]):
pos = self.gameBase.level.mapMatrix[y][x] pos = self.gameBase.level.mapMatrix[y][x]
if pos[0] == 'w': if pos[0] == 'w':
self.tiles['w{0}'.format(pos[1])].paint(self.levelDisplay, x, y) self.tiles['w{0}'.format(pos[1])].paint(self.levelDisplay, x, y)
else: else:
self.tiles['e{0}'.format(pos[1])].paint(self.levelDisplay, x, y) self.tiles['e{0}'.format(pos[1])].paint(self.levelDisplay, x, y)
for name in self.gameBase.level.thingNames: for name in self.gameBase.level.thingNames:
thing = self.gameBase.level.getThingByName(name) thing = self.gameBase.level.getThingByName(name)
self.tiles[name].paint(self.levelDisplay, thing.x, thing.y) self.tiles[name].paint(self.levelDisplay, thing.x, thing.y)
self.tiles['player'].paint(self.levelDisplay, self.gameBase.playerx, self.gameBase.playery) self.tiles['player'].paint(self.levelDisplay, self.gameBase.playerx, self.gameBase.playery)
# refresh the info box # refresh the info box
self.gameBase.outstream.seek(self.infoCursor) self.gameBase.outstream.seek(self.infoCursor)
#print(self.gameBase.outstream.tell()) #print(self.gameBase.outstream.tell())
#print(self.gameBase.outstream.read()) #print(self.gameBase.outstream.read())
self.infoDisplay['state'] = 'normal' self.infoDisplay['state'] = 'normal'
self.infoDisplay.insert('end', self.gameBase.outstream.read()) self.infoDisplay.insert('end', self.gameBase.outstream.read())
self.infoDisplay.see('end -1 chars') self.infoDisplay.see('end -1 chars')
self.infoDisplay['state'] = 'disabled' self.infoDisplay['state'] = 'disabled'
self.infoCursor = self.gameBase.outstream.tell() self.infoCursor = self.gameBase.outstream.tell()
#print(self.infoCursor) #print(self.infoCursor)
#print('Done.') #print('Done.')
def handleClick(self, event): def handleClick(self, event):
x = int(self.levelDisplay.canvasx(event.x) / 32) x = int(self.levelDisplay.canvasx(event.x) / 32)
y = int(self.levelDisplay.canvasy(event.y) / 32) y = int(self.levelDisplay.canvasy(event.y) / 32)
if (x, y) != self.selected: if (x, y) != self.selected:
self.selected = (x, y) self.selected = (x, y)
self.look(x, y) self.look(x, y)
def handleDoubleClick(self, event): def handleDoubleClick(self, event):
x = int(self.levelDisplay.canvasx(event.x) / 32) x = int(self.levelDisplay.canvasx(event.x) / 32)
y = int(self.levelDisplay.canvasy(event.y) / 32) y = int(self.levelDisplay.canvasy(event.y) / 32)
thing = self.gameBase.level.getThingAtCoords(x, y) thing = self.gameBase.level.getThingAtCoords(x, y)
if thing != None and thing.useable: if thing != None and thing.useable:
self.use(x, y) self.use(x, y)
else: else:
self.go(x, y) self.go(x, y)
def handleRightClick(self, event): def handleRightClick(self, event):
x = int(self.levelDisplay.canvasx(event.x) / 32) x = int(self.levelDisplay.canvasx(event.x) / 32)
y = int(self.levelDisplay.canvasy(event.y) / 32) y = int(self.levelDisplay.canvasy(event.y) / 32)
self.selected = (x, y) self.selected = (x, y)
self.context.post(event.x_root, event.y_root) self.context.post(event.x_root, event.y_root)
#def openInvContext(self, event): #def openInvContext(self, event):
# self.invContext.post(event.x_root, event.y_root) # self.invContext.post(event.x_root, event.y_root)
def handleDragEvent(self, event): def handleDragEvent(self, event):
x = min(int(self.levelDisplay.canvasx(event.x) / 32), self.project.x-1) x = min(int(self.levelDisplay.canvasx(event.x) / 32), self.project.x-1)
y = min(int(self.levelDisplay.canvasy(event.y) / 32), self.project.y-1) y = min(int(self.levelDisplay.canvasy(event.y) / 32), self.project.y-1)
if self.tool.get() == 'select': if self.tool.get() == 'select':
rect = self.levelDisplay.find_withtag('selectArea') rect = self.levelDisplay.find_withtag('selectArea')
self.selectedArea = (min(x, self.firstX), min(y, self.firstY), self.selectedArea = (min(x, self.firstX), min(y, self.firstY),
max(x, self.firstX), max(y, self.firstY)) max(x, self.firstX), max(y, self.firstY))
self.levelDisplay.coords(rect, self.levelDisplay.coords(rect,
(self.selectedArea[0]*32, self.selectedArea[1]*32, (self.selectedArea[0]*32, self.selectedArea[1]*32,
self.selectedArea[2]*32+31, self.selectedArea[3]*32+31)) self.selectedArea[2]*32+31, self.selectedArea[3]*32+31))
def handleReleaseEvent(self, event): def handleReleaseEvent(self, event):
x = int(self.levelDisplay.canvasx(event.x) / 32) x = int(self.levelDisplay.canvasx(event.x) / 32)
y = int(self.levelDisplay.canvasy(event.y) / 32) y = int(self.levelDisplay.canvasy(event.y) / 32)
if self.tool.get() == 'select': if self.tool.get() == 'select':
rect = self.levelDisplay.find_withtag('selectArea') rect = self.levelDisplay.find_withtag('selectArea')
self.selectedArea = (min(x, self.firstX), min(y, self.firstY), self.selectedArea = (min(x, self.firstX), min(y, self.firstY),
max(x, self.firstX), max(y, self.firstY)) max(x, self.firstX), max(y, self.firstY))
self.levelDisplay.coords(rect, self.levelDisplay.coords(rect,
(self.selectedArea[0]*32, self.selectedArea[1]*32, (self.selectedArea[0]*32, self.selectedArea[1]*32,
self.selectedArea[2]*32+31, self.selectedArea[3]*32+31)) self.selectedArea[2]*32+31, self.selectedArea[3]*32+31))
tiles = self.project.getTiles(self.selectedArea) tiles = self.project.getTiles(self.selectedArea)
for y in range(len(tiles)): for y in range(len(tiles)):
for x in range(len(tiles[0])): for x in range(len(tiles[0])):
if type(tiles[y][x]) == Project.GoblinSettings: if type(tiles[y][x]) == Project.GoblinSettings:
self.context.entryconfigure('Goblin...', state = NORMAL) self.context.entryconfigure('Goblin...', state = NORMAL)
break break
break break
else: pass else: pass
def loadLevel(self, fileName): def loadLevel(self, fileName):
self.gameBase.loadMap([fileName]) self.gameBase.loadMap([fileName])
#self.getGraphics() #self.getGraphics()
self.refreshDisplay() self.refreshDisplay()
def go(self, x, y, running = False): def go(self, x, y, running = False):
#print("go called") #print("go called")
#print(x, y) #print(x, y)
if running: if running:
self.gameBase.go(['-r', str(x), str(y)]) self.gameBase.go(['-r', str(x), str(y)])
else: else:
self.gameBase.go([str(x), str(y)]) self.gameBase.go([str(x), str(y)])
self.gameBase.gameEventLoop() self.gameBase.gameEventLoop()
self.refreshDisplay() #inefficient, but will work for now. self.refreshDisplay() #inefficient, but will work for now.
def look(self, x, y = 1): def look(self, x, y = 1):
#print("look called") #print("look called")
#if x == self.gameBase.playerx and y == self.gameBase.playery: #if x == self.gameBase.playerx and y == self.gameBase.playery:
# self.gameBase.look([ # self.gameBase.look([
if isinstance(x, int): if isinstance(x, int):
thing = self.gameBase.level.getThingAtCoords(x, y) thing = self.gameBase.level.getThingAtCoords(x, y)
if thing != None: if thing != None:
self.gameBase.look([thing.name]) self.gameBase.look([thing.name])
else: else:
self.gameBase.look([]) self.gameBase.look([])
else: else:
self.gameBase.look([x]) self.gameBase.look([x])
self.gameBase.gameEventLoop() self.gameBase.gameEventLoop()
self.refreshDisplay() #inefficient, but will work for now. self.refreshDisplay() #inefficient, but will work for now.
def use(self, x, y = 1): def use(self, x, y = 1):
if isinstance(x, int): if isinstance(x, int):
self.gameBase.use([str(x), str(y)]) self.gameBase.use([str(x), str(y)])
else: else:
self.gameBase.use([x]) self.gameBase.use([x])
self.gameBase.gameEventLoop() self.gameBase.gameEventLoop()
self.refreshDisplay() #inefficient, but will work for now. self.refreshDisplay() #inefficient, but will work for now.
def take(self, x, y): def take(self, x, y):
self.gameBase.take([str(x), str(y)]) self.gameBase.take([str(x), str(y)])
self.gameBase.gameEventLoop() self.gameBase.gameEventLoop()
self.refreshDisplay() #inefficient, but will work for now. self.refreshDisplay() #inefficient, but will work for now.
self.invTuple = tuple(self.gameBase.playerInv.keys()) self.invTuple = tuple(self.gameBase.playerInv.keys())
self.invNames.set(self.invTuple) self.invNames.set(self.invTuple)
def drop(self, item): def drop(self, item):
self.gameBase.drop([item]) self.gameBase.drop([item])
self.gameBase.gameEventLoop() self.gameBase.gameEventLoop()
self.refreshDisplay() self.refreshDisplay()
self.invTuple = tuple(self.gameBase.playerInv.keys()) self.invTuple = tuple(self.gameBase.playerInv.keys())
self.invNames.set(self.invTuple) self.invNames.set(self.invTuple)
def requestInput(self, prompt = ''): def requestInput(self, prompt = ''):
answer = messagebox.askyesno(message=prompt, icon='question', title='Prompt') answer = messagebox.askyesno(message=prompt, icon='question', title='Prompt')
if answer: if answer:
return 'y' return 'y'
else: else:
return 'n' return 'n'
def fileNew(self): def fileNew(self):
#print('Creating a new project...') #print('Creating a new project...')
if self.askToSave(): if self.askToSave():
self.newDialog = Toplevel(self.parent) self.newDialog = Toplevel(self.parent)
self.newDialog.title('New Project') self.newDialog.title('New Project')
newFrame = Frame(self.newDialog) newFrame = Frame(self.newDialog)
newFrame.grid() newFrame.grid()
self.hei = StringVar() self.hei = StringVar()
self.wid = StringVar() self.wid = StringVar()
ttk.Label(newFrame, text = 'Width:').grid(column = 0, row = 0, sticky = W) ttk.Label(newFrame, text = 'Width:').grid(column = 0, row = 0, sticky = W)
ttk.Label(newFrame, text = 'Height:').grid(column = 0, row = 1, sticky = W) ttk.Label(newFrame, text = 'Height:').grid(column = 0, row = 1, sticky = W)
Spinbox(newFrame, from_ = 16, to = 255, increment = 1, textvariable = self.wid Spinbox(newFrame, from_ = 16, to = 255, increment = 1, textvariable = self.wid
).grid(column = 1, row = 0, sticky = W) ).grid(column = 1, row = 0, sticky = W)
Spinbox(newFrame, from_ = 16, to = 255, increment = 1, textvariable = self.hei Spinbox(newFrame, from_ = 16, to = 255, increment = 1, textvariable = self.hei
).grid(column = 1, row = 1, sticky = W) ).grid(column = 1, row = 1, sticky = W)
ttk.Button(newFrame, text = 'Create', command = self.__confirmNewDimensions, ttk.Button(newFrame, text = 'Create', command = self.__confirmNewDimensions,
default = 'active').grid(column = 0, row = 2) default = 'active').grid(column = 0, row = 2)
ttk.Button(newFrame, text = 'Cancel', command = self.newDialog.destroy ttk.Button(newFrame, text = 'Cancel', command = self.newDialog.destroy
).grid(column = 1, row = 2) ).grid(column = 1, row = 2)
#print('Done.') #print('Done.')
def fileOpen(self): def fileOpen(self):
#print('Opening a project...') #print('Opening a project...')
if self.askToSave(): if self.askToSave():
newName = filedialog.askopenfilename(defaultextension = '.dat', initialdir = 'saves') newName = filedialog.askopenfilename(defaultextension = '.dat', initialdir = 'saves')
if newName != '': if newName != '':
self.fileName = newName self.fileName = newName
self.gameBase.loadGame((self.fileName,)) self.gameBase.loadGame((self.fileName,))
self.gameBase.gameEventLoop() self.gameBase.gameEventLoop()
self.refreshDisplay() self.refreshDisplay()
self.invTuple = tuple(self.gameBase.playerInv.keys()) self.invTuple = tuple(self.gameBase.playerInv.keys())
self.invNames.set(self.invTuple) self.invNames.set(self.invTuple)
#print('Done.') #print('Done.')
def fileSave(self): def fileSave(self):
#print('Saving a project...') #print('Saving a project...')
newName = self.fileName newName = self.fileName
if self.fileName == 'Untitled': if self.fileName == 'Untitled':
self.fileSaveAs() self.fileSaveAs()
elif newName != '': elif newName != '':
self.fileName = newName self.fileName = newName
self.gameBase.saveGame((self.fileName,)) self.gameBase.saveGame((self.fileName,))
self.hasChanged = False self.hasChanged = False
#print('Done.') #print('Done.')
def fileSaveAs(self): def fileSaveAs(self):
newName = filedialog.asksaveasfilename(defaultextension = '.dat', initialdir = 'saves') newName = filedialog.asksaveasfilename(defaultextension = '.dat', initialdir = 'saves')
if newName != '': if newName != '':
self.fileName = newName self.fileName = newName
self.gameBase.saveGame((self.fileName,)) self.gameBase.saveGame((self.fileName,))
self.hasChanged = False self.hasChanged = False
def onQuit(self): def onQuit(self):
if self.askToSave(): if self.askToSave():
exit() exit()
def askToSave(self): def askToSave(self):
if self.hasChanged: if self.hasChanged:
insecure = messagebox.askyesnocancel( insecure = messagebox.askyesnocancel(
message = 'Do you want to save ' + self.fileName + ' before continuing?', message = 'Do you want to save ' + self.fileName + ' before continuing?',
icon = 'warning', title = 'New File') icon = 'warning', title = 'New File')
print(type(insecure)) print(type(insecure))
if insecure == None: return False if insecure == None: return False
elif insecure == True: elif insecure == True:
self.fileSave() self.fileSave()
return True return True
else: return True else: return True
else: return True else: return True
def about(self): def about(self):
self.newDialog = Toplevel(self.parent) self.newDialog = Toplevel(self.parent)
self.newDialog.title('About') self.newDialog.title('About')
newFrame = Frame(self.newDialog) newFrame = Frame(self.newDialog)
newFrame.grid() newFrame.grid()
ttk.Label(newFrame, text = 'I Am Gnome Level Editor v.0.9.0013').grid() ttk.Label(newFrame, text = 'I Am Gnome Level Editor v.0.9.0013').grid()
ttk.Button(newFrame, text = 'Okay', command = self.newDialog.destroy).grid() ttk.Button(newFrame, text = 'Okay', command = self.newDialog.destroy).grid()
def readme(self): def readme(self):
self.newDialog = Toplevel(self.parent) self.newDialog = Toplevel(self.parent)
self.newDialog.title('About') self.newDialog.title('About')
newFrame = Frame(self.newDialog) newFrame = Frame(self.newDialog)
newFrame.grid() newFrame.grid()
text = Text(newFrame, width=80, height=40, wrap = 'word') text = Text(newFrame, width=80, height=40, wrap = 'word')
text.grid(column = 0, row = 0) text.grid(column = 0, row = 0)
sbar = ttk.Scrollbar(newFrame, orient = VERTICAL, command = text.yview) sbar = ttk.Scrollbar(newFrame, orient = VERTICAL, command = text.yview)
sbar.grid(column = 1, row = 0, sticky = (N, S, W)) sbar.grid(column = 1, row = 0, sticky = (N, S, W))
text.configure(yscrollcommand = sbar.set) text.configure(yscrollcommand = sbar.set)
text.state(['disabled']) text.state(['disabled'])
file = open('iag_readme.txt', 'r') file = open('iag_readme.txt', 'r')
text.insert('1.0', file.read()) text.insert('1.0', file.read())
def onResize(self, event): def onResize(self, event):
if self.initWidth == 0 and self.initHeight == 0: if self.initWidth == 0 and self.initHeight == 0:
self.initWidth = event.width self.initWidth = event.width
self.initHeight = event.height self.initHeight = event.height
else: else:
wDelta = event.width - int(self.initWidth) wDelta = event.width - int(self.initWidth)
hDelta = event.height - int(self.initHeight) hDelta = event.height - int(self.initHeight)
self.levelDisplay.configure(width = self.mapSize[0] + wDelta, height = self.mapSize[1] + hDelta) self.levelDisplay.configure(width = self.mapSize[0] + wDelta, height = self.mapSize[1] + hDelta)
# main # main
if __name__ == '__main__': if __name__ == '__main__':
root = Tk() root = Tk()
root.title('Game Gui (debug)') root.title('Game Gui (debug)')
#root.geometry("1024x768") #root.geometry("1024x768")
#root.resizable(FALSE, FALSE) #root.resizable(FALSE, FALSE)
root.option_add('*tearOff', FALSE) root.option_add('*tearOff', FALSE)
root.columnconfigure(0, weight = 1) root.columnconfigure(0, weight = 1)
root.rowconfigure(0, weight = 1) root.rowconfigure(0, weight = 1)
newApp = App(root, GameBase()) newApp = App(root, GameBase())
newApp.grid(sticky = (N, S, E, W)) newApp.grid(sticky = (N, S, E, W))
root.mainloop() root.mainloop()

1769
gamemap.py

File diff suppressed because it is too large Load diff

View file

@ -1,213 +1,213 @@
# gameshell.py # gameshell.py
from shell import Shell from shell import Shell
from gamebase import GameBase from gamebase import GameBase
import sys as _sys import sys as _sys
#import re #import re
import heapq import heapq
#import gamemap #import gamemap
import gameevents import gameevents
#from os import get_terminal_size #from os import get_terminal_size
#import random #import random
class GameShell(Shell): class GameShell(Shell):
UP = 1 UP = 1
RIGHT = 2 RIGHT = 2
DOWN = 4 DOWN = 4
LEFT = 8 LEFT = 8
WALLS = ('++', '++', ' +', '++', '++', '||', '++', '|+', '+ ', '++', WALLS = ('++', '++', ' +', '++', '++', '||', '++', '|+', '+ ', '++',
'==', '++', '++', '+|', '++', '++') '==', '++', '++', '+|', '++', '++')
def __init__(self, gameBase): def __init__(self, gameBase):
super(GameShell, self).__init__() super(GameShell, self).__init__()
self.outstream = _sys.stdout self.outstream = _sys.stdout
self.gameBase = gameBase self.gameBase = gameBase
self.colorMode = 0 self.colorMode = 0
# register functions # register functions
self.registerCommand('map', self.showMap) self.registerCommand('map', self.showMap)
self.registerCommand('ls', self.showMap) self.registerCommand('ls', self.showMap)
self.registerCommand('go', self.gameBase.go) self.registerCommand('go', self.gameBase.go)
self.registerCommand('move', self.gameBase.go) self.registerCommand('move', self.gameBase.go)
self.registerCommand('walk', self.gameBase.go) self.registerCommand('walk', self.gameBase.go)
self.registerCommand('look', self.gameBase.look) self.registerCommand('look', self.gameBase.look)
self.registerCommand('use', self.gameBase.use) self.registerCommand('use', self.gameBase.use)
self.registerCommand('loadMap', self.gameBase.loadMap) self.registerCommand('loadMap', self.gameBase.loadMap)
self.registerCommand('man', self.man) self.registerCommand('man', self.man)
self.registerCommand('help', self.man) self.registerCommand('help', self.man)
self.registerCommand('save', self.gameBase.saveGame) self.registerCommand('save', self.gameBase.saveGame)
self.registerCommand('load', self.gameBase.loadGame) self.registerCommand('load', self.gameBase.loadGame)
self.registerCommand('take', self.gameBase.take) self.registerCommand('take', self.gameBase.take)
self.registerCommand('get', self.gameBase.take) self.registerCommand('get', self.gameBase.take)
self.registerCommand('drop', self.gameBase.drop) self.registerCommand('drop', self.gameBase.drop)
self.registerCommand('inv', self.inv) self.registerCommand('inv', self.inv)
self.registerCommand('bag', self.inv) self.registerCommand('bag', self.inv)
self.registerCommand('items', self.inv) self.registerCommand('items', self.inv)
self.registerCommand('status', self.status) self.registerCommand('status', self.status)
self.registerCommand('options', self.options) self.registerCommand('options', self.options)
self.registerCommand('colorTest', self.colorTest) self.registerCommand('colorTest', self.colorTest)
self.registerAlias('run', ['go', '-r']) self.registerAlias('run', ['go', '-r'])
# Helper functions # Helper functions
def man(self, args): def man(self, args):
super(GameShell, self).man(args) super(GameShell, self).man(args)
#heapq.heappush(self.gameBase.eventQueue, (self.gameBase.gameTime, gameevents.NoOpEvent())) #heapq.heappush(self.gameBase.eventQueue, (self.gameBase.gameTime, gameevents.NoOpEvent()))
def options(self, args): def options(self, args):
i = 0 i = 0
while i < len(args): while i < len(args):
if args[i] == 'color': if args[i] == 'color':
i += 1 i += 1
if args[i] in ('0', '3', '4', '8', '24'): if args[i] in ('0', '3', '4', '8', '24'):
self.colorMode = int(args[i]) self.colorMode = int(args[i])
i += 1 i += 1
def __colorTestRoutine(self, lower, upper): def __colorTestRoutine(self, lower, upper):
colors = [] colors = []
step = int((upper - lower) / 8) step = int((upper - lower) / 8)
#print(step) #print(step)
for g in range(lower, upper, step): for g in range(lower, upper, step):
colors.append(self.color(upper-1, g, lower, False)) colors.append(self.color(upper-1, g, lower, False))
#print(len(colors)) #print(len(colors))
colors.append(self.color(upper-1, upper-1, lower, False)) colors.append(self.color(upper-1, upper-1, lower, False))
for r in range(upper-step, lower-1, -step): for r in range(upper-step, lower-1, -step):
colors.append(self.color(r, upper-1, lower, False)) colors.append(self.color(r, upper-1, lower, False))
#print(len(colors)) #print(len(colors))
for b in range(lower+step, upper, step): for b in range(lower+step, upper, step):
colors.append(self.color(lower, upper-1, b, False)) colors.append(self.color(lower, upper-1, b, False))
#print(len(colors)) #print(len(colors))
colors.append(self.color(lower, upper-1, upper-1, False)) colors.append(self.color(lower, upper-1, upper-1, False))
for g in range(upper-step, lower-1, -step): for g in range(upper-step, lower-1, -step):
colors.append(self.color(lower, g, upper-1, False)) colors.append(self.color(lower, g, upper-1, False))
#print(len(colors)) #print(len(colors))
for r in range(lower+step, upper, step): for r in range(lower+step, upper, step):
colors.append(self.color(r, lower, upper-1, False)) colors.append(self.color(r, lower, upper-1, False))
colors.append(self.color(upper-1, lower, upper-1, False)) colors.append(self.color(upper-1, lower, upper-1, False))
#print(len(colors)) #print(len(colors))
for b in range(upper-step, lower, -step): for b in range(upper-step, lower, -step):
colors.append(self.color(upper-1, lower, b, False)) colors.append(self.color(upper-1, lower, b, False))
#print(len(colors)) #print(len(colors))
colors.append('\x1b[0m') colors.append('\x1b[0m')
print(' '.join(colors)) print(' '.join(colors))
def colorTest(self, args): def colorTest(self, args):
for i in (3, 4, 8, 24): for i in (3, 4, 8, 24):
print(i) print(i)
self.colorMode = i self.colorMode = i
self.__colorTestRoutine(0, 128) # dark self.__colorTestRoutine(0, 128) # dark
self.__colorTestRoutine(0, 256) # medium self.__colorTestRoutine(0, 256) # medium
self.__colorTestRoutine(128, 256) # light self.__colorTestRoutine(128, 256) # light
def showMap(self, args): def showMap(self, args):
"""map [-l] """map [-l]
See a map of the local area. "ls" is an alias of map. See a map of the local area. "ls" is an alias of map.
"l" and "legend" are aliases of -l. "l" and "legend" are aliases of -l.
If -l is given, a map legend will be printed under the map.""" If -l is given, a map legend will be printed under the map."""
xAxis = ' ' + ''.join([self.gameBase.numberToLetter(i).ljust(2) for i in range(self.gameBase.level.dimensions[0])]) + '\n' xAxis = ' ' + ''.join([self.gameBase.numberToLetter(i).ljust(2) for i in range(self.gameBase.level.dimensions[0])]) + '\n'
rows = [] rows = []
index = 0 index = 0
exits = {} exits = {}
doors = {} doors = {}
useables = {} useables = {}
items = {} items = {}
level = self.gameBase.level level = self.gameBase.level
textColor = level.wallColors[0] textColor = level.wallColors[0]
floorColor = level.floorColors[0] floorColor = level.floorColors[0]
for y in range(level.dimensions[1]): for y in range(level.dimensions[1]):
rows.append(['{0}{1:2} {2}{3}'.format(self.clearColor(), y, self.color(textColor[1:]), self.color(floorColor[1:], fg = False))]) rows.append(['{0}{1:2} {2}{3}'.format(self.clearColor(), y, self.color(textColor[1:]), self.color(floorColor[1:], fg = False))])
rows[-1].append(self.color(textColor[1:])) rows[-1].append(self.color(textColor[1:]))
for x in range(level.dimensions[0]): for x in range(level.dimensions[0]):
pos = level.mapMatrix[y][x] pos = level.mapMatrix[y][x]
thing = level.getThingAtPos(index) thing = level.getThingAtPos(index)
if x == self.gameBase.playerx and y == self.gameBase.playery: if x == self.gameBase.playerx and y == self.gameBase.playery:
if '#0000FF' != textColor: if '#0000FF' != textColor:
textColor = '#0000FF' textColor = '#0000FF'
rows[-1].append(self.color(textColor[1:])) rows[-1].append(self.color(textColor[1:]))
rows[-1].append('()') rows[-1].append('()')
elif thing: elif thing:
if thing.graphic[1] != textColor: if thing.graphic[1] != textColor:
textColor = thing.graphic[1] textColor = thing.graphic[1]
rows[-1].append(self.color(textColor[1:])) rows[-1].append(self.color(textColor[1:]))
if thing.thingType == 'x': # exit if thing.thingType == 'x': # exit
rows[-1].append('X{0}'.format(thing.exitid)) rows[-1].append('X{0}'.format(thing.exitid))
exits[thing.exitid] = (thing.name, thing.graphic[1]) exits[thing.exitid] = (thing.name, thing.graphic[1])
elif thing.thingType == 'd': # door elif thing.thingType == 'd': # door
doors[len(doors)+1] = (thing.name, thing.graphic[1]) doors[len(doors)+1] = (thing.name, thing.graphic[1])
rows[-1].append('D{0}'.format(len(doors))) rows[-1].append('D{0}'.format(len(doors)))
elif thing.thingType == 'u': # useable elif thing.thingType == 'u': # useable
useables[len(useables)+1] = (thing.name, thing.graphic[1]) useables[len(useables)+1] = (thing.name, thing.graphic[1])
rows[-1].append('U{0}'.format(len(useables))) rows[-1].append('U{0}'.format(len(useables)))
elif thing.thingType == 'i': # item elif thing.thingType == 'i': # item
items[len(items)+1] = (thing.name, thing.graphic[1]) items[len(items)+1] = (thing.name, thing.graphic[1])
rows[-1].append('I{0}'.format(len(items))) rows[-1].append('I{0}'.format(len(items)))
elif pos[0] == 'w': elif pos[0] == 'w':
if level.wallColors[level.mapMatrix[y][x][1]] != textColor: if level.wallColors[level.mapMatrix[y][x][1]] != textColor:
textColor = level.wallColors[level.mapMatrix[y][x][1]] textColor = level.wallColors[level.mapMatrix[y][x][1]]
rows[-1].append(self.color(textColor[1:])) rows[-1].append(self.color(textColor[1:]))
sides = 0 sides = 0
if y > 0 and level.mapMatrix[y-1][x][0] == 'w': if y > 0 and level.mapMatrix[y-1][x][0] == 'w':
sides += GameShell.UP sides += GameShell.UP
if x < level.dimensions[0]-1 and level.mapMatrix[y][x+1][0] == 'w': if x < level.dimensions[0]-1 and level.mapMatrix[y][x+1][0] == 'w':
sides += GameShell.RIGHT sides += GameShell.RIGHT
if y < level.dimensions[1]-1 and level.mapMatrix[y+1][x][0] == 'w': if y < level.dimensions[1]-1 and level.mapMatrix[y+1][x][0] == 'w':
sides += GameShell.DOWN sides += GameShell.DOWN
if x > 0 and level.mapMatrix[y][x-1][0] == 'w': if x > 0 and level.mapMatrix[y][x-1][0] == 'w':
sides += GameShell.LEFT sides += GameShell.LEFT
rows[-1].append(GameShell.WALLS[sides]) rows[-1].append(GameShell.WALLS[sides])
else: else:
rows[-1].append(' ') rows[-1].append(' ')
index += 1 index += 1
rows[-1] = ''.join(rows[-1]) rows[-1] = ''.join(rows[-1])
print(xAxis) print(xAxis)
print('{0}\n'.format(self.clearColor(False)).join(rows) + self.clearColor()) print('{0}\n'.format(self.clearColor(False)).join(rows) + self.clearColor())
self.setClearColor() self.setClearColor()
if len(args) > 0: if len(args) > 0:
if args[0] == '-l' or args[0] == 'l' or args[0] == 'legend': if args[0] == '-l' or args[0] == 'l' or args[0] == 'legend':
legend = ["\n---Legend---\n", "{0}(){1} - {2}".format(self.color('0000FF'), self.clearColor(), self.gameBase.playerName), legend = ["\n---Legend---\n", "{0}(){1} - {2}".format(self.color('0000FF'), self.clearColor(), self.gameBase.playerName),
"Xn - Exit to another area"] "Xn - Exit to another area"]
for i in exits: for i in exits:
legend.append(' {0}X{1}{2} - {3}'.format(self.color(exits[i][1][1:]), i, self.clearColor(), exits[i][0])) legend.append(' {0}X{1}{2} - {3}'.format(self.color(exits[i][1][1:]), i, self.clearColor(), exits[i][0]))
legend.append("Un - Useable object") legend.append("Un - Useable object")
for i in useables: for i in useables:
legend.append(' {0}U{1}{2} - {3}'.format(self.color(useables[i][1][1:]), i, self.clearColor(), useables[i][0])) legend.append(' {0}U{1}{2} - {3}'.format(self.color(useables[i][1][1:]), i, self.clearColor(), useables[i][0]))
legend.append("In - Item") legend.append("In - Item")
for i in items: for i in items:
legend.append(' {0}I{1}{2} - {3}'.format(self.color(items[i][1][1:]), i, self.clearColor(), items[i][0])) legend.append(' {0}I{1}{2} - {3}'.format(self.color(items[i][1][1:]), i, self.clearColor(), items[i][0]))
legend.append("Dn - Door") legend.append("Dn - Door")
for i in doors: for i in doors:
legend.append(' {0}D{1}{2} - {3}'.format(self.color(doors[i][1][1:]), i, self.clearColor(), doors[i][0])) legend.append(' {0}D{1}{2} - {3}'.format(self.color(doors[i][1][1:]), i, self.clearColor(), doors[i][0]))
print('\n'.join(legend)) print('\n'.join(legend))
#heapq.heappush(self.gameBase.eventQueue, (self.gameBase.gameTime, gameevents.NoOpEvent())) #heapq.heappush(self.gameBase.eventQueue, (self.gameBase.gameTime, gameevents.NoOpEvent()))
return return
def status(self, args): def status(self, args):
ret = [] ret = []
if self.gameBase.level != None: if self.gameBase.level != None:
ret.append("Level:{0:.>74}".format(self.gameBase.level.name)) ret.append("Level:{0:.>74}".format(self.gameBase.level.name))
else: else:
ret.append("Level:{0:.>74}".format("None")) ret.append("Level:{0:.>74}".format("None"))
ret.append("Gametime:{0:.>71.3}".format(self.gameBase.gameTime)) ret.append("Gametime:{0:.>71.3}".format(self.gameBase.gameTime))
ret.append("Event queue:") ret.append("Event queue:")
for i in sorted(self.gameBase.eventQueue): for i in sorted(self.gameBase.eventQueue):
ret.append("{0:.<8.3}:{1:.>72}".format(i[0], str(i[1]))) ret.append("{0:.<8.3}:{1:.>72}".format(i[0], str(i[1])))
ret.append("Player name:{0:.>68}".format(self.gameBase.playerName)) ret.append("Player name:{0:.>68}".format(self.gameBase.playerName))
ret.append("Player position:{0:.>64}".format("{0}{1}".format(self.gameBase.numberToLetter(self.gameBase.playerx), self.gameBase.playery))) ret.append("Player position:{0:.>64}".format("{0}{1}".format(self.gameBase.numberToLetter(self.gameBase.playerx), self.gameBase.playery)))
ret.append("Prev. position:{0:.>65}".format("{0}{1}".format(self.gameBase.numberToLetter(self.gameBase.prevx), self.gameBase.prevy))) ret.append("Prev. position:{0:.>65}".format("{0}{1}".format(self.gameBase.numberToLetter(self.gameBase.prevx), self.gameBase.prevy)))
print('\n'.join(ret)) print('\n'.join(ret))
#heapq.heappush(self.gameBase.eventQueue, (self.gameBase.gameTime, gameevents.NoOpEvent())) #heapq.heappush(self.gameBase.eventQueue, (self.gameBase.gameTime, gameevents.NoOpEvent()))
return return
def inv(self, args): def inv(self, args):
print('\n'.join([i for i in self.gameBase.playerInv])) print('\n'.join([i for i in self.gameBase.playerInv]))
def update(self): def update(self):
self.gameBase.gameEventLoop() self.gameBase.gameEventLoop()
if __name__ == '__main__': if __name__ == '__main__':
sh = GameShell(GameBase()) sh = GameShell(GameBase())
sh.run() sh.run()

568
shell.py
View file

@ -1,284 +1,284 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# #
# gameshell.py # gameshell.py
# #
# Copyright 2018 chees <chees@DESKTOP-0CA7MCF> # Copyright 2018 chees <chees@DESKTOP-0CA7MCF>
# #
# This program is free software; you can redistribute it and/or modify # This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or # the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version. # (at your option) any later version.
# #
# This program is distributed in the hope that it will be useful, # This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of # but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details. # GNU General Public License for more details.
# #
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software # along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301, USA. # MA 02110-1301, USA.
# #
# Ver. 0.1.0033 # Ver. 0.1.0033
import types as _types import types as _types
import traceback as _tb import traceback as _tb
import math as _math import math as _math
import re as _re import re as _re
_CONV24TO8 = 6 / 256 _CONV24TO8 = 6 / 256
class Shell(object): class Shell(object):
def __init__(self): def __init__(self):
self.__commands = {'exit': self.exitShell, 'batch': self.batch, 'alias': self.makeAlias, 'def': self.defineBatch} self.__commands = {'exit': self.exitShell, 'batch': self.batch, 'alias': self.makeAlias, 'def': self.defineBatch}
self.__aliases = {} self.__aliases = {}
self.__batches = {} self.__batches = {}
self.ps1 = '> ' self.ps1 = '> '
self.ps2 = '. ' self.ps2 = '. '
self.colorMode = 0 # bits of color depth. Supports: 0, 3, 4, 8, 24 self.colorMode = 0 # bits of color depth. Supports: 0, 3, 4, 8, 24
self.prevColor = '\x1b[0m' self.prevColor = '\x1b[0m'
self.__exit = False self.__exit = False
def __color24(self, r, g, b, fg = True): def __color24(self, r, g, b, fg = True):
if fg: if fg:
return '\x1b[38;2;{0};{1};{2}m'.format(r, g, b) return '\x1b[38;2;{0};{1};{2}m'.format(r, g, b)
else: else:
return '\x1b[48;2;{0};{1};{2}m'.format(r, g, b) return '\x1b[48;2;{0};{1};{2}m'.format(r, g, b)
def __color8(self, r, g, b, fg = True): def __color8(self, r, g, b, fg = True):
r = _math.floor(r * _CONV24TO8) r = _math.floor(r * _CONV24TO8)
g = _math.floor(g * _CONV24TO8) g = _math.floor(g * _CONV24TO8)
b = _math.floor(b * _CONV24TO8) b = _math.floor(b * _CONV24TO8)
ret = 16 + b + 6 * g + 36 * r ret = 16 + b + 6 * g + 36 * r
if fg: if fg:
return '\x1b[38;5;{0}m'.format(ret) return '\x1b[38;5;{0}m'.format(ret)
else: else:
return '\x1b[48;5;{0}m'.format(ret) return '\x1b[48;5;{0}m'.format(ret)
def __color4(self, r, g, b, fg = True): def __color4(self, r, g, b, fg = True):
color = _math.floor(r / 128) + 2 * _math.floor(g / 128) + 4 * _math.floor(b / 128) color = _math.floor(r / 128) + 2 * _math.floor(g / 128) + 4 * _math.floor(b / 128)
r2, g2, b2 = r % 128, g % 128, b % 128 r2, g2, b2 = r % 128, g % 128, b % 128
if r2 + g2 + b2 >= 192: if r2 + g2 + b2 >= 192:
color += 60 color += 60
if fg: if fg:
color += 30 color += 30
else: else:
color += 40 color += 40
return '\x1b[{0}m'.format(color) return '\x1b[{0}m'.format(color)
def __color3(self, r, g, b, fg = True): def __color3(self, r, g, b, fg = True):
color = _math.floor(r / 128) + 2 * _math.floor(g / 128) + 4 * _math.floor(b / 128) color = _math.floor(r / 128) + 2 * _math.floor(g / 128) + 4 * _math.floor(b / 128)
if fg: if fg:
color += 30 color += 30
else: else:
color += 40 color += 40
return '\x1b[{0}m'.format(color) return '\x1b[{0}m'.format(color)
def colorFromHex(self, color): def colorFromHex(self, color):
"""expects string formmatted like 3377DD""" """expects string formmatted like 3377DD"""
return int(color[0:2], 16), int(color[2:4], 16), int(color[4:6], 16) return int(color[0:2], 16), int(color[2:4], 16), int(color[4:6], 16)
def color(self, r, g = 0, b = 0, fg = True, setPrevColor = True): def color(self, r, g = 0, b = 0, fg = True, setPrevColor = True):
if isinstance(r, str): if isinstance(r, str):
r, g, b = self.colorFromHex(r) r, g, b = self.colorFromHex(r)
ret = '' ret = ''
if self.colorMode == 0: # no color if self.colorMode == 0: # no color
ret = '' ret = ''
elif self.colorMode == 3: elif self.colorMode == 3:
ret = self.__color3(r, g, b, fg) ret = self.__color3(r, g, b, fg)
elif self.colorMode == 4: elif self.colorMode == 4:
ret = self.__color4(r, g, b, fg) ret = self.__color4(r, g, b, fg)
elif self.colorMode == 8: elif self.colorMode == 8:
ret = self.__color8(r, g, b, fg) ret = self.__color8(r, g, b, fg)
elif self.colorMode == 24: elif self.colorMode == 24:
ret = self.__color24(r, g, b, fg) ret = self.__color24(r, g, b, fg)
else: else:
ret = '' ret = ''
if ret == self.prevColor: if ret == self.prevColor:
return '' return ''
if setPrevColor: if setPrevColor:
self.prevColor = ret self.prevColor = ret
return ret return ret
def setColor(self, r, g = 0, b = 0, fg = True): def setColor(self, r, g = 0, b = 0, fg = True):
"""Set the text color.""" """Set the text color."""
print(color(r, g, b, fg), end = '') print(color(r, g, b, fg), end = '')
return return
def clearColor(self, setPrevColor = True): def clearColor(self, setPrevColor = True):
ret = '' ret = ''
if self.colorMode > 0: if self.colorMode > 0:
ret = '\x1b[0m' ret = '\x1b[0m'
if ret == self.prevColor: if ret == self.prevColor:
return '' return ''
if setPrevColor: if setPrevColor:
self.prevColor = ret self.prevColor = ret
return ret return ret
def setClearColor(self): def setClearColor(self):
print(self.clearColor()) print(self.clearColor())
return return
def run(self): def run(self):
"""The main game/shell loop""" """The main game/shell loop"""
while not self.__exit: while not self.__exit:
print(self.ps1, end = '') print(self.ps1, end = '')
command = self.scanInput() command = self.scanInput()
# we have to handle shell built-ins first (when we get some) # we have to handle shell built-ins first (when we get some)
self.handleCommand(command) self.handleCommand(command)
self.update() self.update()
self.__exit = False self.__exit = False
def man(self, args): def man(self, args):
help(self.__commands[args[0]]) help(self.__commands[args[0]])
def registerCommand(self, commandName: str, command: _types.FunctionType): def registerCommand(self, commandName: str, command: _types.FunctionType):
"""command must be a function that takes one argument: a list of strings, """command must be a function that takes one argument: a list of strings,
conventionally called args or argv""" conventionally called args or argv"""
self.__commands[commandName] = command self.__commands[commandName] = command
def registerAlias(self, a: str, original: list): def registerAlias(self, a: str, original: list):
"""makes 'a' an alias for original. """makes 'a' an alias for original.
'a' must be one token, but original can be multiple.""" 'a' must be one token, but original can be multiple."""
self.__aliases[a] = original self.__aliases[a] = original
def registerBatch(self, name: str, commands: list): def registerBatch(self, name: str, commands: list):
self.__batches[name] = commands self.__batches[name] = commands
def getAlias(self, a: str): def getAlias(self, a: str):
if a in self.__aliases: if a in self.__aliases:
return self.__aliases[a] return self.__aliases[a]
else: else:
return None return None
def getBatch(self, name: str): def getBatch(self, name: str):
if name in self.__batches: if name in self.__batches:
return ['batch'] return ['batch']
else: else:
return None return None
def scanLine(self, instr): def scanLine(self, instr):
"""Take a line of text and turn it into an argument list""" """Take a line of text and turn it into an argument list"""
if instr == '': if instr == '':
return [] return []
inQuotes = False inQuotes = False
ret = [] ret = []
argStart = 0 argStart = 0
c = 0 c = 0
while c < len(instr): while c < len(instr):
if inQuotes: if inQuotes:
if instr[c] == '"': if instr[c] == '"':
inQuotes = False inQuotes = False
ret.append(instr[argStart:c]) ret.append(instr[argStart:c])
argStart = c+1 argStart = c+1
else: else:
if instr[c] == '"': if instr[c] == '"':
inQuotes = True inQuotes = True
if argStart != c: if argStart != c:
ret.append(instr[argStart:c]) ret.append(instr[argStart:c])
argStart = c+1 argStart = c+1
elif instr[c] in ' \t\n': elif instr[c] in ' \t\n':
if argStart != c: if argStart != c:
ret.append(instr[argStart:c]) ret.append(instr[argStart:c])
argStart = c + 1 argStart = c + 1
c += 1 c += 1
if argStart != c: if argStart != c:
ret.append(instr[argStart:c]) ret.append(instr[argStart:c])
a = self.getAlias(ret[0]) a = self.getAlias(ret[0])
if a: if a:
ret = a + ret[1:] ret = a + ret[1:]
b = self.getBatch(ret[0]) b = self.getBatch(ret[0])
if b: if b:
ret = b + ret ret = b + ret
ret[0] = _re.sub(r'\A\$\((\w+)\)', r'\1', ret[0]) ret[0] = _re.sub(r'\A\$\((\w+)\)', r'\1', ret[0])
return ret return ret
# Default functions # Default functions
def exitShell(self, args): def exitShell(self, args):
"""The default exit command.""" """The default exit command."""
self.__exit = True self.__exit = True
def makeAlias(self, args): def makeAlias(self, args):
"""Make an alias.""" """Make an alias."""
self.registerAlias(args[0], args[1:]) self.registerAlias(args[0], args[1:])
def defineBatch(self, args): def defineBatch(self, args):
"""Define a batch file.""" """Define a batch file."""
if len(args) < 1: if len(args) < 1:
raise ValueError('def takes at least one argument') raise ValueError('def takes at least one argument')
ret = [] ret = []
command = input(self.ps2) command = input(self.ps2)
while command != 'end': while command != 'end':
ret.append(command) ret.append(command)
command = input(self.ps2) command = input(self.ps2)
for i in args: for i in args:
self.registerBatch(i, ret) self.registerBatch(i, ret)
def batch(self, args): def batch(self, args):
"""Run commands in batch mode """Run commands in batch mode
$0 is the name of the batch $0 is the name of the batch
$1 - $n are individual arguments $1 - $n are individual arguments
$* is all the arguments except 0 $* is all the arguments except 0
$>0 - $>n is all arguments after the nth $>0 - $>n is all arguments after the nth
$>=0 - $>=n is the nth and later arguments""" $>=0 - $>=n is the nth and later arguments"""
script = self.__batches[args[0]] script = self.__batches[args[0]]
var = _re.compile(r'\$((?:[>][=]?)?[0-9]+)') var = _re.compile(r'\$((?:[>][=]?)?[0-9]+)')
u = False u = False
for line in script: for line in script:
if u: if u:
self.update() self.update()
else: else:
u = True u = True
newLine = line.replace(r'$*', ' '.join(args[1:])) newLine = line.replace(r'$*', ' '.join(args[1:]))
matches = var.finditer(newLine) matches = var.finditer(newLine)
for m in matches: for m in matches:
n = m.group(1) n = m.group(1)
if n[0] == '>': if n[0] == '>':
if n[1] == '=': if n[1] == '=':
num = int(n[2:]) num = int(n[2:])
else: else:
num = int(n[1:])+1 num = int(n[1:])+1
newLine = newLine.replace(m.group(), ' '.join(args[num:])) newLine = newLine.replace(m.group(), ' '.join(args[num:]))
else: else:
newLine = newLine.replace(m.group(), args[int(n)]) newLine = newLine.replace(m.group(), args[int(n)])
newLine = _re.sub(r'\A({0})'.format(args[0]), r'$(\1)', newLine) newLine = _re.sub(r'\A({0})'.format(args[0]), r'$(\1)', newLine)
#print(newLine) #print(newLine)
self.handleCommand(self.scanLine(newLine)) self.handleCommand(self.scanLine(newLine))
# Beyond this point are functions that are called within the main loop. # Beyond this point are functions that are called within the main loop.
def scanInput(self): def scanInput(self):
"""Parses input. Override this for custom input parsing, or input source.""" """Parses input. Override this for custom input parsing, or input source."""
return self.scanLine(input()) return self.scanLine(input())
def handleCommand(self, command): def handleCommand(self, command):
if len(command) == 0: if len(command) == 0:
return return
if command[0] in self.__commands: if command[0] in self.__commands:
try: try:
self.__commands[command[0]](command[1:]) self.__commands[command[0]](command[1:])
except Exception as e: except Exception as e:
_tb.print_exc() _tb.print_exc()
print(e) print(e)
else: else:
self.handleUnknownCommand(command) self.handleUnknownCommand(command)
def handleUnknownCommand(self, command): def handleUnknownCommand(self, command):
"""Handle commands that aren't registered. Override this if you want to do """Handle commands that aren't registered. Override this if you want to do
something with those commands.""" something with those commands."""
print("Bad command.") print("Bad command.")
def update(self): def update(self):
"""Runs at the end of each loop. Does nothing by default. Override this if """Runs at the end of each loop. Does nothing by default. Override this if
there is something you want the shell to do between every command.""" there is something you want the shell to do between every command."""
pass pass
def main(args): def main(args):
return 0 return 0
if __name__ == '__main__': if __name__ == '__main__':
import sys import sys
sys.exit(main(sys.argv)) sys.exit(main(sys.argv))

View file

@ -1,51 +1,51 @@
{ {
"openingText": "Floor 1 map loaded successfully. Normally, this would describe the environment.", "openingText": "Floor 1 map loaded successfully. Normally, this would describe the environment.",
"playerStart": [5, 26], "playerStart": [5, 26],
"layout": [ "layout": [
"w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w ", "w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w ",
"w w ", "w w ",
"w w w w w w w w w w w ", "w w w w w w w w w w w ",
"w w w w w w w ", "w w w w w w w ",
"w w w w w w w w w w w ", "w w w w w w w w w w w ",
"w w w w w w w w w ", "w w w w w w w w w ",
"w w w w w w ", "w w w w w w ",
"w w w w w w w w w w w w ", "w w w w w w w w w w w w ",
"w w w w w w w w w w w w w ", "w w w w w w w w w w w w w ",
"w w w w w w w w w w w w w w w w w w ", "w w w w w w w w w w w w w w w w w w ",
"w w w w w w w w w w w ", "w w w w w w w w w w w ",
"w w w w w w w w w ", "w w w w w w w w w ",
"w w w w w w w ", "w w w w w w w ",
"w w w w w w w w w w w w w w w w w w ", "w w w w w w w w w w w w w w w w w w ",
"w w w w w w w w w w ", "w w w w w w w w w w ",
"w w w w w w ", "w w w w w w ",
"w w w w w w ", "w w w w w w ",
"w w w w w w w w w w ", "w w w w w w w w w w ",
"w w w w w w w w w w ", "w w w w w w w w w w ",
"w w w w w w w w w w w w ", "w w w w w w w w w w w w ",
"w w w w w w ", "w w w w w w ",
"w w w w ", "w w w w ",
"w w w w w w ", "w w w w w w ",
"w w w w w w w w w w ", "w w w w w w w w w w ",
"w w w w w w w ", "w w w w w w w ",
"w w w w w ", "w w w w w ",
"w w w w w w ", "w w w w w w ",
"w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w " "w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w "
], ],
"things": [ "things": [
{ {
"type": "exit", "type": "exit",
"id": 1, "id": 1,
"location": [5, 10], "location": [5, 10],
"destination": "testing/test2.xml", "destination": "testing/test2.xml",
"name": "upstairs" "name": "upstairs"
}, },
{ {
"type": "exit", "type": "exit",
"id": 2, "id": 2,
"location": [21, 23], "location": [21, 23],
"destination": "testing/test4.xml", "destination": "testing/test4.xml",
"name": "downstairs" "name": "downstairs"
} }
] ]
} }

View file

@ -1,35 +1,35 @@
<map openingText="Floor 1 map loaded successfully. Normally, this would describe the environment." playerStart="5, 26"> <map openingText="Floor 1 map loaded successfully. Normally, this would describe the environment." playerStart="5, 26">
<layout> <layout>
w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w
w w w w
w w w w w w w w w w w w w w w w w w w w w w
w w w w w w w w w w w w w w
w w w w w w w w w w w w w w w w w w w w w w
w w w w w w w w w w w w w w w w w w
w w w w w w w w w w w w
w w w w w w w w w w w w w w w w w w w w w w w w
w w w w w w w w w w w w w w w w w w w w w w w w w w
w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w
w w w w w w w w w w w w w w w w w w w w w w
w w w w w w w w w w w w w w w w w w
w w w w w w w w w w w w w w
w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w
w w w w w w w w w w w w w w w w w w w w
w w w w w w w w w w w w
w w w w w w w w w w w w
w w w w w w w w w w w w w w w w w w w w
w w w w w w w w w w w w w w w w w w w w
w w w w w w w w w w w w w w w w w w w w w w w w
w w w w w w w w w w w w
w w w w w w w w
w w w w w w w w w w w w
w w w w w w w w w w w w w w w w w w w w
w w w w w w w w w w w w w w
w w w w w w w w w w
w w w w w w w w w w w w
w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w
</layout> </layout>
<exit id="1" location="5, 10" destination="testing/test2.xml" name="upstairs"/> <exit id="1" location="5, 10" destination="testing/test2.xml" name="upstairs"/>
<exit id="2" location="21, 23" destination="testing/test4.xml" name="downstairs"/> <exit id="2" location="21, 23" destination="testing/test4.xml" name="downstairs"/>
</map> </map>

View file

@ -1,45 +1,45 @@
%YAML 1.2 %YAML 1.2
--- ---
openingText: Floor 1 map loaded successfully. Normally, this would describe the environment. openingText: Floor 1 map loaded successfully. Normally, this would describe the environment.
playerStart: [5, 26] playerStart: [5, 26]
layout: | layout: |
w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w0 w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w0
w w0 w w0
w w w w w w w w w w w0 w w w w w w w w w w w0
w w w w w w w0 w w w w w w w0
w w w w w w w w w w w0 w w w w w w w w w w w0
w w w w w w w w w0 w w w w w w w w w0
w w w w w w0 w w w w w w0
w w w w w w w w w w w w0 w w w w w w w w w w w w0
w w w w w w w w w w w w w0 w w w w w w w w w w w w w0
W w w w w w w w w w w w w w w w w w0 W w w w w w w w w w w w w w w w w w0
w w w w w w w w w w w0 w w w w w w w w w w w0
w w w w w w w w w0 w w w w w w w w w0
w w w w w w w0 w w w w w w w0
w w w w w w w w w w w w w w w w w w0 w w w w w w w w w w w w w w w w w w0
w w w w w w w w w w0 w w w w w w w w w w0
w w w w w w0 w w w w w w0
w w w w w w0 w w w w w w0
w w w w w w w w w w0 w w w w w w w w w w0
w w w w w w w w w w0 w w w w w w w w w w0
w w w w w w w w w w w w0 w w w w w w w w w w w w0
w w w w w w0 w w w w w w0
w w w w0 w w w w0
w w w w w w0 w w w w w w0
w w w w w w w w w w0 w w w w w w w w w w0
w w w w w w w0 w w w w w w w0
w w w w w0 w w w w w0
w w w w w w0 w w w w w w0
w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w0 w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w0
things: loadAlways:
- !Exit - !Exit
id: 1 id: 1
location: [5, 10] location: [5, 10]
destination: testing/test2.xml destination: testing/test2.yml
name: upstairs name: upstairs
- !Exit - !Exit
id: 2 id: 2
location: [21, 23] location: [21, 23]
destination: testing/test4.xml destination: testing/test4.yml
name: downstairs name: downstairs

View file

@ -1,37 +1,37 @@
<map openingText="Floor 2" playerStart="6, 10"> <map openingText="Floor 2" playerStart="6, 10">
<layout> <layout>
w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w
w w w w w w x3 w w w w w w w w w w w w w w w x3 w w w w w w w w w
w w w w w w w w w w w w w w w w w w w w w w w w w w
w w w w w w w w w w w w w w w w w w w w
w w w w w w w w w w w w w w
w w w w w w w w w w w w w w w w w w w w w w
w w w w w w w w w w w w w w w w w w w w
w w w w w w w w w w w w w w w w w w w w
w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w
w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w
w x1 x2 w w w w w x1 x2 w w w w
w w w w w w w w w w w w w w
w w w w w w w w w w w w w w w w w w
w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w
w w w w w w w w w w w w w w w w w x4 w w w w w w w w w w w w w w w w w w x4 w
w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w
w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w
w w w w w w w w w w w w w w w w
w w w w w w w w w w w w w w w w w w w w
w w w w w w w w w w w w w w w w w w
w w w w w w w w
w w w w w w w w
w w w w w w w w w w w w
w w w w w w w w w w w w w w
w w w w w w w w
w w w w w w w w
w w w w w w w w w w w w
w w w w w w w w w w w w w w w w w w w w w w w w
</layout> </layout>
<exit id="1" location="5, 10" destination="testing/test1.xml" name="downstairs"/> <exit id="1" location="5, 10" destination="testing/test1.xml" name="downstairs"/>
<exit id="2" location="7, 10" destination="testing/test3.xml" name="upstairs"/> <exit id="2" location="7, 10" destination="testing/test3.xml" name="upstairs"/>
<exit id="3" location="6, 1" destination="testing/test3.xml" name="north"/> <exit id="3" location="6, 1" destination="testing/test3.xml" name="north"/>
<exit id="4" location="25, 14" destination="testing/test3.xml" name="east"/> <exit id="4" location="25, 14" destination="testing/test3.xml" name="east"/>
</map> </map>

62
testing/test2.yml Normal file
View file

@ -0,0 +1,62 @@
%YAML 1.2
---
layout: |
w0w0w0w0w0w0w0w0w0w0w0w0w0w0w0w0w0w0w0w0w0w0w0w0w0w0w0w0w0w0
w0w0w0w0w0w0 w0 w0 w0 w0w0w0w0w0w0
w0w0w0w0 w0 w0 w0w0 w0 w0w0w0w0
w0w0w0w0 w0 w0 w0w0 w0w0
w0w0 w0 w0w0w0 w0
w0w0 w0w0w0 w0w0w0w0w0 w0
w0 w0 w0 w0 w0w0w0w0w0 w0
w0 w0 w0 w0 w0w0w0w0w0 w0
w0 w0 w0w0w0w0 w0w0w0w0w0w0w0w0w0w0
w0w0w0w0w0w0w0w0w0w0 w0w0w0 w0w0 w0w0w0w0
w0 w0w0 w0 w0
w0 w0 w0w0w0 w0 w0
w0 w0w0 w0w0w0w0 w0 w0
w0 w0w0 w0w0w0w0w0w0w0w0w0 w0 w0w0w0w0
w0w0w0w0w0 w0w0w0 w0w0w0w0w0w0w0 w0w0 w0
w0w0w0w0 w0w0w0 w0w0w0w0w0w0w0 w0w0 w0
w0 w0w0w0w0w0 w0 w0 w0w0w0w0w0w0w0w0w0w0w0w0
w0 w0w0w0w0w0 w0 w0 e0
w0w0w0w0w0w0w0w0 w0 w0 e0
w0w0w0w0w0w0 w0 w0 w0 e0
w0 w0 w0 w0 e0
w0 w0 w0 w0 e0
w0 w0w0w0w0 w0 e0
w0 w0w0w0w0 w0 w0 e0
w0 w0 w0 w0 e0
w0 w0 w0 w0 e0
w0 w0 w0w0w0w0 e0
w0w0w0w0w0w0w0w0w0w0w0w0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0
openingText: Floor 2
playerStart: [6, 10]
description: ''
floorColors: ['#9F7F5F']
wallColors: ['#7F3F0F']
loadAlways:
- !Exit
name: downstairs
location: [5, 10]
id: 1
destination: testing/test1.yml
graphic: {fgc: '#7F7F7F', shape: '#'}
- !Exit
name: upstairs
location: [7, 10]
id: 2
destination: testing/test3.yml
graphic: {fgc: '#7F7F7F', shape: '#'}
- !Exit
name: north
location: [6, 1]
id: 3
destination: testing/test3.yml
graphic: {fgc: '#7F7F7F', shape: '#'}
- !Exit
name: east
location: [25, 14]
id: 4
destination: testing/test3.yml
graphic: {fgc: '#7F7F7F', shape: '#'}
loadOnce: []

View file

@ -1,26 +1,26 @@
<map openingText="Floor 3" playerStart="6, 10"> <map openingText="Floor 3" playerStart="6, 10">
<layout> <layout>
w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w
w x3 w w w w w w w w w w w w w w w w w w w x3 w w w w w w w w w w w w w w w w w w
w w w w w w w w w w w w w w w w w w
w w w w w w w w w w w w w w w w w w
w w w w w w w w w w w w w w w w w w
w w w w w w w w w w w w w w w w w w w w
w w w w w w w w w w w w w w w w w w w w w w w w w w w w
w w w w w w w w w w w w w w w w w w w w w w w w w w w w
w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w
w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w
w w w x2 w w w w w w w w w x2 w w w w w w
w w w w w w w w w w w w w w w w
w w w w w w w w w w w w w w w w w w w w w w w w
w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w
w w w w w w w w w x4 w w w w w w w w w w x4 w
w w w w w w w w w w w w w w w w w w w w
w w w w w w w w w w w w w w w w w w
w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w
</layout> </layout>
<exit id="2" location="7, 10" destination="testing/test2.xml" name="downstairs"/> <exit id="2" location="7, 10" destination="testing/test2.xml" name="downstairs"/>
<exit id="3" location="6, 1" destination="testing/test2.xml" name="north"/> <exit id="3" location="6, 1" destination="testing/test2.xml" name="north"/>
<exit id="4" location="25, 14" destination="testing/test2.xml" name="east"/> <exit id="4" location="25, 14" destination="testing/test2.xml" name="east"/>
</map> </map>

46
testing/test3.yml Normal file
View file

@ -0,0 +1,46 @@
%YAML 1.2
---
layout: |
w0w0w0w0w0w0w0w0w0w0w0w0w0w0w0w0w0w0w0w0w0w0w0w0w0w0w0w0w0w0
w0 w0w0w0w0 w0w0w0w0w0w0w0w0 w0w0w0w0w0w0
w0 w0w0 w0 w0 w0w0w0w0
w0 w0w0 w0 w0 w0w0w0w0
w0w0w0 w0 w0w0 w0w0w0
w0w0w0 w0w0 w0w0 w0w0w0
w0w0w0w0w0w0w0w0w0w0 w0 w0w0 w0
w0w0w0w0w0w0w0w0w0w0 w0 w0w0 w0
w0w0w0w0w0 w0w0w0w0 w0 w0w0w0w0w0w0 w0
w0w0w0w0w0 w0w0w0 w0w0w0w0w0w0w0w0w0w0w0w0w0w0w0
w0 w0w0 w0w0 w0w0 w0 w0
w0 w0w0 w0w0w0 w0 w0
w0 w0w0 w0w0 w0w0w0 w0w0 w0 w0
w0 w0w0 w0w0w0w0w0w0w0w0w0w0w0w0w0w0 w0w0w0w0w0w0
w0w0w0w0 w0w0w0w0 w0 w0
w0w0w0w0 w0w0w0w0 w0 w0
w0 w0w0w0w0w0w0 w0 w0
w0w0w0w0w0w0w0w0w0w0w0w0e0e0e0e0e0e0e0e0e0e0w0w0w0w0w0w0w0w0
openingText: Floor 3
playerStart: [6, 10]
description: ''
floorColors: ['#9F7F5F']
wallColors: ['#7F3F0F']
loadAlways:
- !Exit
name: downstairs
location: [7, 10]
id: 2
destination: testing/test2.yml
graphic: {fgc: '#7F7F7F', shape: '#'}
- !Exit
name: north
location: [6, 1]
id: 3
destination: testing/test2.yml
graphic: {fgc: '#7F7F7F', shape: '#'}
- !Exit
name: east
location: [25, 14]
id: 4
destination: testing/test2.yml
graphic: {fgc: '#7F7F7F', shape: '#'}
loadOnce: []

View file

@ -1,34 +1,34 @@
<map openingText="Basement" playerStart="22, 22"> <map openingText="Basement" playerStart="22, 22">
<layout> <layout>
w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w
w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w
w w w w w w w w w w w w w w w w w w
w w w w w w w w w w w w w w w w w w w w
w w w w w w w w w w w w
w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w
w w w w
w w w w
w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w
w w w w w w w w
w w w w w w w w
w w w w w w w w w w w w w w w w
w w w w w w w w
w w w w w w w w
w w w w w w w w
w w w w w w w w w w w w w w w w
w w w w w w w w w w w w w w w w w w w w
w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w
w w w w w w w w
w w w w w w w w
w w w w w w w w w w w w
w w w w w w w w w w w w
w w x2 w w w x2 w
w w w w w w
w w w w w w w w
w w w w w w w w w w
w w w w w w w w
w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w
</layout> </layout>
<exit id="2" location="23, 22" destination="testing/test1.xml" name="upstairs"/> <exit id="2" location="23, 22" destination="testing/test1.xml" name="upstairs"/>
</map> </map>

44
testing/test4.yml Normal file
View file

@ -0,0 +1,44 @@
%YAML 1.2
---
layout: |
w0w0w0w0w0w0w0w0w0w0w0w0w0w0w0w0w0w0w0w0w0w0w0w0w0w0w0w0w0w0
w0w0w0w0w0w0w0w0 w0w0w0w0w0w0w0w0w0w0w0 w0
w0w0 w0 w0w0 w0 w0 w0 w0
w0w0 w0 w0w0w0 w0 w0 w0 w0
w0 w0w0 w0 w0 w0
w0 w0w0 w0w0w0 w0w0w0w0w0w0w0w0w0w0 w0w0w0w0
w0 w0
w0 w0
w0w0w0w0 w0w0w0w0w0w0w0w0w0w0w0w0w0w0w0w0w0w0w0w0 w0
w0 w0 w0 w0
w0 w0 w0 w0
w0 w0w0 w0w0 w0 w0 w0
w0 w0 w0 w0
w0 w0 w0 w0
w0 w0 w0 w0
w0 w0w0 w0w0 w0 w0 w0
w0 w0 w0w0w0 w0w0w0 w0 w0
w0w0w0w0w0w0w0w0w0w0 w0w0w0 w0w0w0 w0 w0w0
w0 w0 w0 w0
w0 w0 w0 w0
w0 w0 w0w0 w0 w0
w0 w0 w0w0 w0 w0
w0 w0 w0
w0 w0 w0
w0 w0 w0 w0
w0 w0 w0 w0 w0
w0 w0 w0 w0
w0w0w0w0w0w0w0w0w0w0w0w0w0w0w0w0w0w0w0w0w0w0w0w0w0w0w0w0w0w0
openingText: Basement
playerStart: [22, 22]
description: ''
floorColors: ['#9F7F5F']
wallColors: ['#7F3F0F']
loadAlways:
- !Exit
name: upstairs
location: [23, 22]
id: 2
destination: testing/test1.xml
graphic: {fgc: '#7F7F7F', shape: '#'}
loadOnce: []

88
tile.py
View file

@ -1,44 +1,44 @@
from tkinter import * from tkinter import *
class Tile: class Tile:
"""A representation of a tile on the display""" """A representation of a tile on the display"""
shapes = {'circle' : 'o', 'cross' : 'x', 'triangle' : '^', 'none' : ' ', shapes = {'circle' : 'o', 'cross' : 'x', 'triangle' : '^', 'none' : ' ',
'square' : '#', 'vertical' : '|', 'horizontal' : '-'} 'square' : '#', 'vertical' : '|', 'horizontal' : '-'}
def __init__(self, bgroundColor, fgroundColor = 'white', fgroundShape = ' '): def __init__(self, bgroundColor, fgroundColor = 'white', fgroundShape = ' '):
self.bgc = bgroundColor self.bgc = bgroundColor
self.fgc = fgroundColor self.fgc = fgroundColor
self.fgs = fgroundShape self.fgs = fgroundShape
def paint(self, display, x, y): #display being a canvas def paint(self, display, x, y): #display being a canvas
if type(display) != Canvas: if type(display) != Canvas:
raise TypeError('Display must be a tkinter.Canvas.') raise TypeError('Display must be a tkinter.Canvas.')
else: else:
tag = '(' + str(int(x)) + ', ' + str(int(y)) + ')' tag = '(' + str(int(x)) + ', ' + str(int(y)) + ')'
display.delete(tag) #delete the old tile before creating a new one. display.delete(tag) #delete the old tile before creating a new one.
if self.bgc != 'clear': if self.bgc != 'clear':
display.create_rectangle((x*32, y*32, x*32+32, y*32+32), display.create_rectangle((x*32, y*32, x*32+32, y*32+32),
fill = self.bgc, width = 0, tags = (tag)) fill = self.bgc, width = 0, tags = (tag))
if self.fgs == Tile.shapes['triangle']: if self.fgs == Tile.shapes['triangle']:
display.create_polygon((x*32+15, y*32+2, x*32+2, y*32+30, display.create_polygon((x*32+15, y*32+2, x*32+2, y*32+30,
x*32+30, y*32+30, x*32+16, y*32+2), x*32+30, y*32+30, x*32+16, y*32+2),
fill = self.fgc, width = 0, tags = (tag)) fill = self.fgc, width = 0, tags = (tag))
elif self.fgs == Tile.shapes['circle']: elif self.fgs == Tile.shapes['circle']:
display.create_oval((x*32+2, y*32+2, x*32+30, y*32+30), display.create_oval((x*32+2, y*32+2, x*32+30, y*32+30),
fill = self.fgc, width = 0, tags = (tag)) fill = self.fgc, width = 0, tags = (tag))
elif self.fgs == Tile.shapes['cross']: elif self.fgs == Tile.shapes['cross']:
display.create_line((x*32+2, y*32+2, x*32+30, y*32+30), display.create_line((x*32+2, y*32+2, x*32+30, y*32+30),
fill = self.fgc, width = 3, tags = (tag)) fill = self.fgc, width = 3, tags = (tag))
display.create_line((x*32+30, y*32+2, x*32+2, y*32+30), display.create_line((x*32+30, y*32+2, x*32+2, y*32+30),
fill = self.fgc, width = 3, tags = (tag)) fill = self.fgc, width = 3, tags = (tag))
elif self.fgs == Tile.shapes['square']: elif self.fgs == Tile.shapes['square']:
display.create_rectangle((x*32+2, y*32+2, x*32+30, y*32+30), display.create_rectangle((x*32+2, y*32+2, x*32+30, y*32+30),
fill = self.fgc, width = 0, tags = (tag)) fill = self.fgc, width = 0, tags = (tag))
elif self.fgs == Tile.shapes['vertical']: elif self.fgs == Tile.shapes['vertical']:
display.create_line((x*32+16, y*32, x*32+16, y*32+32), display.create_line((x*32+16, y*32, x*32+16, y*32+32),
fill = self.fgc, width = 3, tags = (tag)) fill = self.fgc, width = 3, tags = (tag))
elif self.fgs == Tile.shapes['horizontal']: elif self.fgs == Tile.shapes['horizontal']:
display.create_line((x*32, y*32+16, x*32+32, y*32+16), display.create_line((x*32, y*32+16, x*32+32, y*32+16),
fill = self.fgc, width = 3, tags = (tag)) fill = self.fgc, width = 3, tags = (tag))
else: pass else: pass