diff --git a/whiteboard.py b/whiteboard.py index d10f3a3..4134686 100644 --- a/whiteboard.py +++ b/whiteboard.py @@ -19,8 +19,6 @@ class Layer(TPrs): def SetName(self, st): self.stName = st - def Draw(self, ascr): - ascr.PutAscr(self.ascr) def FSelectable(self): return True @@ -29,30 +27,38 @@ class Project(Ownable): Ownable.InitPersistent(self, owner) self.stName = stName self.user = user - self.rgboard = [] + self.rgdrawing = [] self.rgscript = [] + def NewBoard(self, stName, user): board = Board(self, stName, user) - self.rgboard.insert(0, board) + self.rgdrawing.insert(0, board) return board - def BoardTouched(self, board): - if board != self.rgboard[0]: - self.rgboard.remove(board) - self.rgboard.insert(0, board) - self.owner.BoardTouched(board) + + def NewSprite(self, stName, user, w, h): + sprite = Sprite(self, stName, user, w, h) + self.rgdrawing.insert(0, sprite) + return sprite + + def DrawingTouched(self, drawing): + if drawing != self.rgdrawing[0]: + self.rgdrawing.remove(drawing) + self.rgdrawing.insert(0, drawing) + self.owner.DrawingTouched(drawing) def StName(self): return self.owner.StNameProject(self) def StLastModified(self): - boardLast = None - for board in self.rgboard: - if boardLast == None or board.dtLastModified > boardLast.dtLastModified: - boardLast = board - if boardLast != None: - return boardLast.StLastModified() + drawingLast = None + for drawing in self.rgdrawing: + if drawingLast == None or drawing.dtLastModified > drawingLast.dtLastModified: + drawingLast = drawing + if drawingLast != None: + return drawingLast.StLastModified() return "never" - -@Version(3) -class Board(Ownable): + def RgstMetadata(self): + return ["by " + self.user, "", "Last modified:", self.StLastModified()] + +class Drawing(Ownable): def InitPersistent(self, owner, stName, user, rglayer=None, dtLastModified=None): Ownable.InitPersistent(self, owner) if rglayer == None: @@ -65,9 +71,13 @@ class Board(Ownable): self.SetTimestamp() else: self.dtLastModified = dtLastModified - + def StName(self): - return self.owner.owner.StNameBoard(self) + return self.owner.owner.StNameDrawing(self) + + def RgstMetadata(self): + return [self.StType(), "by " + self.user, "", "Last modified", self.StLastModified()] + def StLastModified(self): return self.dtLastModified.strftime("%b %d, %Y at %I:%M%p") @@ -92,19 +102,23 @@ class Board(Ownable): self.rglayer.remove(layer) self.rglayer.insert(ilayer, layer) - def W(self): return config.W - def H(self): return config.H - def Touch(self): self.SetTimestamp() - self.owner.BoardTouched(self) + self.owner.DrawingTouched(self) def SetTimestamp(self): self.dtLastModified = datetime.now() - + +@Version(3) +class Board(Drawing): + def StType(self): + return "Board" + def W(self): return config.W + def H(self): return config.H + def draw(self, ascr): for layer in reversed(self.rglayer): - layer.Draw(ascr) + ascr.PutAscr(layer.ascr) def Save(self): fn = config.DIR_ANSI + "/" + "_".join([str(x) for x in time.localtime()]) @@ -116,7 +130,7 @@ class Board(Ownable): fl.write("") with open(fn + ".ans", "w") as fl: fl.write(ascr.Ast()) - + def UpgradeFrom(self, versionOld): if versionOld < 2: gameWB = [gameWB for gameWB in self.owner.rggameWB if gameWB.rgtoken("whiteboard")[0].board == self][0] @@ -125,6 +139,22 @@ class Board(Ownable): if versionOld < 3: self.chat = Chat() +class Sprite(Drawing): + def InitPersistent(self, owner, stName, user, w, h): + self.w = w + self.h = h + Drawing.InitPersistent(self, owner, stName, user, [Layer(ansi.Ascr(w, h), "Frame 1")]) + + def StType(self): return "Sprite" + def W(self): return self.w + def H(self): return self.h + + def draw(self, ascr, x, y, iframe): + ascr.PutAscr(self.rglayer[iframe].ascr, x, y) + + def RgstMetadata(self): + return [self.StType(), "by " + self.user, "", str(self.w) + "x" + str(self.h), str(len(self.rglayer)) + " frames", "", "Last modified", self.StLastModified()] + @Version(5) class Whiteboard(Token): def InitPersistent(self, game, board): @@ -238,8 +268,15 @@ class Cursor(TokenClient): TokenClient.InitPersistent(self, game, client, "drawable", "cursor") self.fBlink = False self.cDontBlink = 0 - self.whiteboard = self.game.rgtoken("whiteboard")[0].board - self.pos = ansi.Pos(self.whiteboard.W(), self.whiteboard.H()) + self.pos = ansi.Pos(self.game.drawing.W(), self.game.drawing.H()) + self.SetupMenus() + self.SelectLayer(self.game.drawing.rglayer[0]) + self.CreateDrawingToken() + + def CreateDrawingToken(self): + WhiteboardDraw(self, self.client) + + def SetupMenus(self): miFg = MiColour("Foreground", ansi.rgcolorFg, ansi.WHITE) miBg = MiColour("Background", ansi.rgcolorBg, ansi.BLACK) miChars = MiChars([[49, 50, 51, 52, 53, 54, 55, 56, 57, 48], #digits @@ -259,21 +296,26 @@ class Cursor(TokenClient): [139, 140, 141, 161, 153, 148, 147, 149, 162, 32], #i, o [154, 129, 150, 151, 163, 32, 32, 32, 32, 32], #u ], miFg, miBg) + miQuit = MiButton("Back to Menu", self.client.leaveGame) - self.cf = MiMenu([None, miFg, miBg, None, miChars, None, MiButton("Save", self.Save), None, miQuit, None]) - self.miChat = MiMenu([None, MiChat(client, 13, self.whiteboard.chat), MiTypein(self.SendMsg), None, miQuit, None]) - self.rgmiLayer = RgmiProjected(self.whiteboard.rglayer, DgProjectMiButton(self.SelectLayer)) - self.miLayers = MiMenu(Rgseq([None], self.rgmiLayer, [None, MiButton("New Layer", self.NewLayer), MiButton("Move up", self.LayerUp), MiButton("Move down", self.LayerDown), - None, MiToggle("Show One"), None, MiStatic("Rename selected layer:"), MiTypein(self.RenameLayer, "LayerName", 80), None, miQuit, None])) - self.ovPopup = OvPopup(self, self.client, MiTab.MiTabbed(["Drawing", self.cf], ["Layers", self.miLayers], ["Chat", self.miChat])) + self.cf = self.MenuDrawing(miFg, miBg, miChars, miQuit) + self.miChat = MiMenu([None, MiChat(self.client, 13, self.game.drawing.chat), MiTypein(self.SendMsg), None, miQuit, None]) + self.rgmiLayer = RgmiProjected(self.game.drawing.rglayer, DgProjectMiButton(self.SelectLayer)) + self.miLayers = self.MenuLayers(miQuit) + self.ovPopup = OvPopup(self, self.client, MiTab.MiTabbed(["Drawing", self.cf], [self.StLayerTab(), self.miLayers], ["Chat", self.miChat])) miStatus = MiMenuHoriz([MiStatic("Hit for menu"), MiValue(miChars)]) miStatus.ListenForNotice(self.miChat) self.ovStatus = OvStatic(self, self.client, miStatus, OvStatic.BOTTOM) - self.SelectLayer(self.whiteboard.rglayer[0]) - WhiteboardDraw(self, client) + def MenuDrawing(self, miFg, miBg, miChars, miQuit): + return MiMenu([None, miFg, miBg, None, miChars, None, MiButton("Save", self.Save), None, miQuit, None]) + + def MenuLayers(self, miQuit): + return MiMenu(Rgseq([None], self.rgmiLayer, [None, MiButton("New Layer", self.NewLayer), MiButton("Move up", self.LayerUp), MiButton("Move down", self.LayerDown), + None, MiToggle("Show One"), None, MiStatic("Rename selected layer:"), MiTypein(self.RenameLayer, "LayerName", 80), None, miQuit, None])) + def StLayerTab(self): return "Layers" def Save(self): - self.whiteboard.Save() + self.game.drawing.Save() msgscroller = self.game.rgtoken("msgscroller")[0] msgscroller.evPost.fire("Saved picture") @@ -290,20 +332,20 @@ class Cursor(TokenClient): stLayer = None while stLayer == None: stLayer = "Layer " + str(ilayer) - if self.whiteboard.LayerByName(stLayer) != None: + if self.game.drawing.LayerByName(stLayer) != None: stLayer = None ilayer = ilayer + 1 - layerNew = self.whiteboard.NewLayer(stLayer) + layerNew = self.game.drawing.NewLayer(stLayer) if layerNew != None: self.SelectLayer(layerNew) return True def LayerUp(self): - self.whiteboard.MoveLayer(self.GetLayer(), True) + self.game.drawing.MoveLayer(self.GetLayer(), True) return True def LayerDown(self): - self.whiteboard.MoveLayer(self.GetLayer(), False) + self.game.drawing.MoveLayer(self.GetLayer(), False) return True def RenameLayer(self, st): @@ -318,16 +360,16 @@ class Cursor(TokenClient): def SendMsg(self, st): if st.lower().startswith("/me ") and len(st.rstrip()) > 3: - self.whiteboard.chat.Add(ChlAct(self.client, st[4:])) + self.game.drawing.chat.Add(ChlAct(self.client, st[4:])) else: - self.whiteboard.chat.Add(ChlMsg(self.client, st)) + self.game.drawing.chat.Add(ChlMsg(self.client, st)) def OnChat(self, chl): if type(chl) != ChlSys: self.miChat.FlagNotice() def run(self): - with self.whiteboard.chat.evChat.oob(self, self.OnChat): + with self.game.drawing.chat.evChat.oob(self, self.OnChat): while True: key = self.client.evKey.receive(self) fDontBlink = True @@ -370,21 +412,21 @@ class Cursor(TokenClient): if fDontBlink: self.cDontBlink = 2 if self.fBlink else 1 - if self.pos.Y() < self.whiteboard.H() / 2: + if (self.game.drawing.H() < config.H) or (self.pos.Y() < self.game.drawing.H() / 2): self.ovStatus.kplace = OvStatic.BOTTOM else: self.ovStatus.kplace = OvStatic.TOP def PutWb(self, ch): self.Put(ch, self.GetLayer().ascr) - self.whiteboard.Touch() + self.game.drawing.Touch() - def Put(self, ch, ascr): + def Put(self, ch, ascr, xzOffset = 0, yzOffset = 0): if type(ch) == str: ach = ansi.MkAch(ch, self.cf.Value("Foreground"), self.cf.Value("Background")) else: ach = ch - ascr.PutAch(ach, self.pos.X(), self.pos.Y()) + ascr.PutAch(ach, self.pos.X() + xzOffset, self.pos.Y() + yzOffset) def GetAch(self): return self.GetLayer().ascr.GetAch(self.pos.X(), self.pos.Y()) @@ -397,17 +439,59 @@ class Cursor(TokenClient): while not fStop: fStop = not dgMove() or self.GetAch() != ach + def XzYzScreenPic(self): + layer = self.GetLayer() + return ((config.W - layer.ascr.W()) / 2, (config.H - layer.ascr.H()) / 2) + + def FDrawCursor(self): + return self.fBlink or self.cDontBlink > 0 + def draw(self, ascr, client): - if self.fBlink or self.cDontBlink > 0: + if self.FDrawCursor(): if client == self.client: chCursor = chr(176) ach = ascr.GetAch(self.pos.X(), self.pos.Y()) if ach != None and ansi.ChFromAch(ach) == chCursor: chCursor = chr(177) - self.Put(chCursor, ascr) + self.Put(chCursor, ascr, *self.XzYzScreenPic()) elif self.fBlink: - self.Put(str(self.client.Cldg().iclient)[0], ascr) + self.Put(str(self.client.Cldg().iclient)[0], ascr, *self.XzYzScreenPic()) +class CursorSprite(Cursor): + def InitPersistent(self, game, client): + Cursor.InitPersistent(self, game, client) + self.blinkerAnimate = None + + def CreateDrawingToken(self): + SpriteDraw(self, self.client) + + def MenuDrawing(self, miFg, miBg, miChars, miQuit): + return MiMenu([None, miFg, miBg, None, miChars, None, miQuit, None]) + + def MenuLayers(self, miQuit): + return MiMenu(Rgseq([None], self.rgmiLayer, [None, MiButton("New Frame", self.NewLayer), MiButton("Move up", self.LayerUp), MiButton("Move down", self.LayerDown), + None, MiStatic("Rename selected frame:"), MiTypein(self.RenameLayer, "LayerName", 80), None, MiButton("Animate", self.Animate), None, miQuit, None])) + + def StLayerTab(self): return "Frames" + def NewLayer(self): + stLayer = "Frame " + str(len(self.game.drawing.rglayer) + 1) + layerNew = self.game.drawing.NewLayer(stLayer) + if layerNew != None: + self.SelectLayer(layerNew) + return True + + def Animate(self): + if (self.blinkerAnimate == None): + self.blinkerAnimate = Blinker(self, self.SelectLayer, self.game.drawing.rglayer, interval = 300) + self.ovPopup.SetSelection("animate", self.miLayers.MiByName("Animate")) + else: + self.blinkerAnimate.die() + self.blinkerAnimate = None + self.ovPopup.SetSelection("animate", None) + def FDrawCursor(self): + if self.blinkerAnimate: + return False + return Cursor.FDrawCursor(self) class WhiteboardDraw(TokenClient): def InitPersistent(self, owner, client): TokenClient.InitPersistent(self, owner, client, "drawable", "solid") @@ -415,9 +499,31 @@ class WhiteboardDraw(TokenClient): def draw(self, ascr, client): if client == self.client: if self.owner.miLayers.Value("Show One"): - self.owner.GetLayer().Draw(ascr) + ascr.PutAscr(self.owner.GetLayer().ascr) else: - self.owner.whiteboard.draw(ascr) + self.game.drawing.draw(ascr) + +class SpriteDraw(TokenClient): + def InitPersistent(self, owner, client): + TokenClient.InitPersistent(self, owner, client, "drawable", "solid") + + def draw(self, ascr, client): + if client == self.client: + (xz, yz) = self.owner.XzYzScreenPic() + x = xz + 1 + y = yz + 1 + layer = self.owner.GetLayer() + ascr.PutAscr(layer.ascr, x, y) + # draw border + ascr.PutAch(ansi.MkAch(chr(218), ansi.WHITE | ansi.FBRIGHT), x - 1, y - 1) # top-left + ascr.PutAch(ansi.MkAch(chr(191), ansi.WHITE | ansi.FBRIGHT), x + layer.ascr.W(), y - 1) # top-right + ascr.PutAch(ansi.MkAch(chr(192), ansi.WHITE | ansi.FBRIGHT), x - 1, y + layer.ascr.H()) # bottom-left + ascr.PutAch(ansi.MkAch(chr(217), ansi.WHITE | ansi.FBRIGHT), x + layer.ascr.W(), y + layer.ascr.H()) # bottom-right + for yT in (y - 1, y + layer.ascr.H()): + ascr.PutSt(chr(196) * layer.ascr.W(), x, yT, ansi.WHITE | ansi.FBRIGHT) # - + for xT in (x - 1, x + layer.ascr.W()): + for yT in xrange(y, y + layer.ascr.H()): + ascr.PutAch(ansi.MkAch(chr(179), ansi.WHITE | ansi.FBRIGHT), xT, yT) # | class CursorBlinker(Token): def InitPersistent(self, owner): @@ -539,7 +645,7 @@ class Joiner(LeaveJoinToken): def InitPersistent(self, owner): Token.InitPersistent(self, owner) self.msgScroller = self.game.rgtoken("msgscroller")[0] - self.board = self.game.rgtoken("whiteboard")[0].board + self.board = self.game.drawing def OnJoin(self, client): with client.Cldg().SetTransiently() as cldg: @@ -559,7 +665,11 @@ class Joiner(LeaveJoinToken): class Lobby(TokenClient): def InitPersistent(self, owner, client): TokenClient.InitPersistent(self, owner, client) - self.lobbyCurrent = LobbyProject(self, client) + drawing = client.Cldg(self.game).drawingSelected + if drawing == None: + self.lobbyCurrent = LobbyProject(self, client) + else: + self.lobbyCurrent = LobbyBoard(self, client, drawing.owner, drawing) def SwitchToLobby(self, lobbyNew): lobbyOld = self.lobbyCurrent @@ -567,62 +677,88 @@ class Lobby(TokenClient): lobbyOld.die() class LobbyI(TokenClient): - def InitPersistent(self, owner, client, *rgmiListTop): + def InitPersistent(self, owner, client, objSelected = None, *rgmiListTop): TokenClient.InitPersistent(self, owner, client) rgmiList = RgmiProjected(self.RgObj(), DgProjectMiButton(self.OnObjSelected)) if rgmiListTop != None: rgmiList = Rgseq(rgmiListTop, rgmiList) self.miDrawings = MiMenu(rgmiList) - self.miCmds = MiMenu([None, None, MiTypein(self.NewI, "ObjectName"), MiButton(self.StNewObj(), self.NewI), - None, None, None, None, None, None, None, None, MiStatic("Last modified:"), MiDgText(self.StLastModifiedI)]) + if objSelected: + mi = self.miDrawings.MiByName(objSelected.StName()) + self.miDrawings.selMi.SetSelected(mi) + self.miCmds = self.CreateMiCmds() OvMenu(self, client, MiMenuHoriz([self.miDrawings, self.miCmds], [65, 35]), OvMenu.FILL) - def StNewObj(self): - "Text for the 'New X' text field" - raise "not implemented" def RgObj(self): "Return the list of objects we are selecting from" raise "not implemented" + def OnObjSelected(self, obj): "Called when an object is selected by the user" raise "not implemented" - def New(self, stName): - "Create a new object with the given name" - raise "not implemented" - def StLastModified(self, obj): - "Return a string stating when the object was last modified" + + def RgstMetadata(self, obj): + "Return a list of strings containing user-readable metadata about the object" raise "not implemented" - def StLastModifiedI(self): - return self.StLastModified(self.miDrawings.Value()) - def NewI(self, stName = None): - if stName == None: - stName = self.miCmds.Value("ObjectName") - if stName != "": - self.New(stName) + def StMetadata(self): + try: + return "\n".join(self.RgstMetadata(self.miDrawings.Value())) + except: + return "" + + def MiTypein_MiButton(self, stBtnLabel, stMiTypein, dgOnSelect): + def NewI(stName = None): + if stName == None: + stName = self.miCmds.Value(stMiTypein) + if stName != "": + dgOnSelect(stName) + return (MiTypein(NewI, stMiTypein), MiButton(stBtnLabel, NewI)) class LobbyBoard(LobbyI): - def InitPersistent(self, owner, client, project): + def InitPersistent(self, owner, client, project, drawing = None): self.project = project - LobbyI.InitPersistent(self, owner, client, MiButton("<-- Back to projects", self.Back), None) + LobbyI.InitPersistent(self, owner, client, drawing, MiButton("<-- Back to projects", self.Back), None) + + def CreateMiCmds(self): + miTypeinBoard, miBtnNewBoard = self.MiTypein_MiButton("New Board", "BoardName", self.NewBoard) + miTypeinSpr, miBtnNewSpr = self.MiTypein_MiButton("New Sprite", "SpriteName", self.NewSprite) + miTypeinW = MiTypein(None, "w") + miTypeinW.SetValue("1") + miTypeinH = MiTypein(None, "h") + miTypeinH.SetValue("1") + self.miDimensions = MiMenuHoriz([MiStatic("W:"), miTypeinW, MiStatic("H:"), miTypeinH]) + + return MiMenu([None, None, miTypeinBoard, miBtnNewBoard, None, None, miTypeinSpr, self.miDimensions, miBtnNewSpr, None, None, None, None, None, MiDgText(self.StMetadata)]) - def StNewObj(self): - return "New Board" def RgObj(self): - return self.project.rgboard + return self.project.rgdrawing def OnObjSelected(self, board): self.client.leaveGame(board) - def New(self, stName): + def NewBoard(self, stName): self.OnObjSelected(self.project.NewBoard(stName, self.client.cld.user)) - def StLastModified(self, board): + def NewSprite(self, stName): + try: + w = int(self.miDimensions.Value("w")) + h = int(self.miDimensions.Value("h")) + if 0 < w < config.W and 0 < h < config.H: + self.OnObjSelected(self.project.NewSprite(stName, self.client.cld.user, w, h)) + except: + pass + def RgstMetadata(self, board): if board != None: - return board.StLastModified() - return self.project.StLastModified() + return board.RgstMetadata() + return self.project.RgstMetadata() + def Back(self): - self.owner.SwitchToLobby(LobbyProject(self.owner, self.client)) + self.owner.SwitchToLobby(LobbyProject(self.owner, self.client, self.project)) class LobbyProject(LobbyI): + def CreateMiCmds(self): + miTypein, miBtnNew = self.MiTypein_MiButton("New Project", "ProjName", self.New) + return MiMenu([None, None, miTypein, miBtnNew, None, None, None, None, None, None, None, None, MiDgText(self.StMetadata)]) + def StNewObj(self): return "New Project" def RgObj(self): @@ -632,8 +768,8 @@ class LobbyProject(LobbyI): def New(self, stName): project = self.game.NewProject(stName, self.client.cld.user) self.OnObjSelected(project) - def StLastModified(self, project): - return project.StLastModified() + def RgstMetadata(self, project): + return project.RgstMetadata() class RunnerWB(Runner): def InitPersistent(self): @@ -642,9 +778,11 @@ class RunnerWB(Runner): def RunGame(self, client): if (client.joinGame(GameLogin())): + client.Cldg(self.gameLobby).drawingSelected = None while True: - board = client.joinGame(self.gameLobby) - client.joinGame(self.gameLobby.GameFromBoard(board)) + drawing = client.joinGame(self.gameLobby) + client.Cldg(self.gameLobby).drawingSelected = drawing + client.joinGame(self.gameLobby.GameFromDrawing(drawing)) class GameLogin(Game): def GetRgclsTokTrans(self): @@ -658,39 +796,44 @@ class GameLobby(Game): def InitTransient(self): Game.InitTransient(self) - self.mpboard_gameWB = {} + self.mpdrawing_game = {} def GetRgclsTokTrans(self): return [[AutoJoiner, Lobby]] - def GameFromBoard(self, board): - if not (board in self.mpboard_gameWB): - gameWB = GameWB(self, board) + def GameFromDrawing(self, drawing): + if not (drawing in self.mpdrawing_game): + if drawing.StType() == "Board": + game = GameWB(self, drawing) + elif drawing.StType() == "Sprite": + game = GameSprEdit(self, drawing) + else: + assert False, "Lobby not prepared to deal with drawing of type " + drawing.StType() def KillBoard(): - del self.mpboard_gameWB[board] - gameWB.rgdgdie.append(KillBoard) - self.mpboard_gameWB[board] = gameWB - return gameWB - return self.mpboard_gameWB[board] + del self.mpdrawing_game[drawing] + game.rgdgdie.append(KillBoard) + self.mpdrawing_game[drawing] = game + return game + return self.mpdrawing_game[drawing] - def CclientBoard(self, board): - if board in self.mpboard_gameWB: - return len(self.mpboard_gameWB[board].rgclient) + def CclientDrawing(self, drawing): + if drawing in self.mpdrawing_game: + return len(self.mpdrawing_game[drawing].rgclient) return 0 def StNameProject(self, project): - return project.stName + " (by " + project.user + ") [" + str(sum([self.CclientBoard(board) for board in project.rgboard])) + "]" + return project.stName + " [" + str(sum([self.CclientDrawing(drawing) for drawing in project.rgdrawing])) + "]" - def StNameBoard(self, board): - return board.stName + " (by " + board.user + ") [" + str(self.CclientBoard(board)) + "]" + def StNameDrawing(self, drawing): + return drawing.stName + " [" + str(self.CclientDrawing(drawing)) + "]" def NewProject(self, stName, user): proj = Project(self, stName, user) self.rgproject.insert(0, proj) return proj - def BoardTouched(self, board): - project = board.owner + def DrawingTouched(self, drawing): + project = drawing.owner if project != self.rgproject[0]: self.rgproject.remove(project) self.rgproject.insert(0, project) @@ -711,30 +854,35 @@ class GameLobby(Game): project = Project(self, "Drawings", "Willy Marmot") for board in self.rgboard: board.TransferToOwner(project) - project.rgboard.append(board) + project.rgdrawing.append(board) del self.rgboard self.rgproject = [project] + self.mpuser_cldg = {} # ugh, upgrading parent classes is broken in our model :( class GameWB(Game): def InitPersistent(self, gameLobby, board): self.gameLobby = gameLobby - self.board = board + self.drawing = board Game.InitPersistent(self) def InitTransient(self): Game.InitTransient(self) if not self.FDead(): - self.board.chat.AttachToGame(self) - self.rgdgdie.append(self.board.chat.DetachFromGame) + self.drawing.chat.AttachToGame(self) + self.rgdgdie.append(self.drawing.chat.DetachFromGame) - def GetRgclsTokPers(self): - return [[Whiteboard, self.board]] + def ClsCursor(self): + return Cursor def GetRgclsTokTrans(self): - return [MsgScroller, Joiner, [AutoJoiner, Cursor], [AliveWithPlayers, CursorBlinker], AutoKiller] + return [MsgScroller, Joiner, [AutoJoiner, self.ClsCursor()], [AliveWithPlayers, CursorBlinker], AutoKiller] def GetRgtagDraw(self): return ["background", "solid", "cursor", "menu", "msgscroller"] +class GameSprEdit(GameWB): + def ClsCursor(self): + return CursorSprite + if __name__ == "__main__": Run(RunnerWB, "whiteboard.marm")