From 3dd87784f35394e84032c1d943849ee196884ed3 Mon Sep 17 00:00:00 2001 From: Jeremy Penner Date: Fri, 31 Jul 2020 22:44:39 -0400 Subject: [PATCH] Implement "Show message" --- basetoken.py | 2 +- scripting.py | 56 ++++++++++++++++++----------------- whiteboard.py | 51 +------------------------------- world.py | 81 +++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 113 insertions(+), 77 deletions(-) create mode 100644 world.py diff --git a/basetoken.py b/basetoken.py index ca77213..f094815 100644 --- a/basetoken.py +++ b/basetoken.py @@ -856,7 +856,7 @@ class OvPopup(OvStatic): if self.fAwake: self.drawI(ascr, client, True) class MsgScroller(Token): - def InitPersistent(self, owner, colFg=ansi.BLUE, colBg=ansi.BLACK, y=config.H): + def InitPersistent(self, owner, colFg=(ansi.CYAN | ansi.FBRIGHT), colBg=ansi.BLACK, y=config.H): Token.InitPersistent(self, owner, "drawable", "msgscroller", "overlay") self.colFg = colFg self.colBg = colBg diff --git a/scripting.py b/scripting.py index 5e4bc8b..2d81aff 100644 --- a/scripting.py +++ b/scripting.py @@ -54,7 +54,7 @@ class Rbot(TPrs): def Move(self, pos): self.pos = pos - + class Defs(TPrs): def InitPersistent(self, rgflagdef = None, rgbotdef = None): self.rgflagdef = rgflagdef or [] @@ -87,13 +87,16 @@ class Vm(TPrs): self.rgrbotPlayer.remove(rbotPlayer) def Rgrbot(self): + for botdef in self.defs.rgbotdef: + if not botdef.fPlayer and botdef not in self.mpbotdef: + self.mpbotdef[botdef] = Rbot(botdef) return itertools.chain(self.mpbotdef.values(), self.rgrbotPlayer) def Fail(self, stMessage, synt): self.Log(Fail(stMessage, synt)) def Log(self, fail): - print(fail.stMessage, fail.synt) + print(fail.stFailure, fail.synt) class Stype(TPrs): "Syntax type" @@ -183,9 +186,9 @@ class Synt(Typeable): def Project(self, pcur): "Project the current synt into its corresponding pws." pass - def Eval(self, vm): + def Eval(self, env): "Execute yourself, in the context of vm." - return vm.Fail("Missing information", self) + return env.vm.Fail("Missing information", self) def StypeForChild(self, syntChild): "Return the stype that should be applied to the given child." @@ -316,11 +319,13 @@ class SyntText(Synt): val = Synt.HandleTypeinKey(self, key) self.st = self.GetStTypein() return val - def Eval(self, vm): + def Eval(self, env): return self.st class SyntHole(SyntDesc): desc = [[" "]] + def Eval(self, env): + pass class SyntBlock(Synt): def Project(self, pcur): @@ -355,10 +360,10 @@ class SyntBlock(Synt): return True return False - def Eval(self, vm): + def Eval(self, env): for synt in self.rgsynt: # todo: log failures - synt.Eval(vm) + synt.Eval(env) class SyntLit(Synt): def InitPersistent(self, value, rtype): @@ -371,7 +376,7 @@ class SyntLit(Synt): return self.rtype def Project(self, pcur): self.ProjectTypein(pcur) - def Eval(self, vm): + def Eval(self, env): return self.value class SyntFlagRef(Synt): @@ -387,30 +392,30 @@ class SyntFlagRef(Synt): def Project(self, pcur): self.ProjectTypein(pcur) - def Eval(self, vm): + def Eval(self, env): try: - return vm.FFlagSet(self.flagdef) + return env.vm.FFlagSet(self.flagdef) except: - return vm.Fail("No such flag", self) + return env.vm.Fail("No such flag", self) class SyntIsFlagSet(SyntDesc): desc = [["set"]] - def Eval(self, vm, val): + def Eval(self, env, val): return val class SyntIsFlagUnset(SyntDesc): desc = [["not set"]] - def Eval(self, vm, val): + def Eval(self, env, val): return not val class SyntIsFlagEqualTo(SyntDesc): desc = [["equal to"], " ", RtypeFlag()] flag = SyntDesc.DefProp(0) - def Eval(self, vm, val): - return val == self.flag.Eval(vm) + def Eval(self, env, val): + return val == self.flag.Eval(env) class SyntIsFlagNotEqualTo(SyntDesc): desc = [["not equal to"], " ", RtypeFlag()] flag = SyntDesc.DefProp(0) - def Eval(self, vm, val): - return val != self.flag.Eval(vm) + def Eval(self, env, val): + return val != self.flag.Eval(env) class StypeFlagTest(StypeEnum): rgclsSynt = [SyntIsFlagSet, SyntIsFlagUnset, SyntIsFlagEqualTo, SyntIsFlagNotEqualTo] @@ -422,28 +427,27 @@ class SyntIf(SyntDesc): test = SyntDesc.DefProp(1) blockIfTrue = SyntDesc.DefProp(2) blockIfFalse = SyntDesc.DefProp(3) - def Eval(self, vm): - if self.test.Eval(vm, self.expr.Eval(vm)): - return self.blockIfTrue.Eval(vm) + def Eval(self, env): + if self.test.Eval(env, self.expr.Eval(env)): + return self.blockIfTrue.Eval(env) else: - return self.blockIfFalse.Eval(vm) + return self.blockIfFalse.Eval(env) @RegStmt class SyntSet(SyntDesc): desc = [["Set flag"], " ", RtypeFlag(), " to ", RtypeUnion(RtypeBool(), RtypeFlag())] lvalue = SyntDesc.DefProp(0) expr = SyntDesc.DefProp(1) - def Eval(self, vm): + def Eval(self, env): # todo: fail if flagdef or expr isn't set properly? - vm.SetFlag(self.lvalue.flagdef, self.expr.Eval(vm)) + env.vm.SetFlag(self.lvalue.flagdef, self.expr.Eval(env)) @RegStmt class SyntPrint(SyntDesc): desc = [["Show Message"], " \"", SyntText, "\""] expr = SyntDesc.DefProp(0) - def Eval(self, vm): - # todo - print(self.expr.Eval(vm)) + def Eval(self, env): + env.GlobalMsg(self.expr.Eval(env)) class Fail(TPrs): """ diff --git a/whiteboard.py b/whiteboard.py index 598fb4f..cd12729 100755 --- a/whiteboard.py +++ b/whiteboard.py @@ -21,6 +21,7 @@ from tpers import * from datetime import * from util import * from scripting import Botdef, Flagdef, Defs, PselState, Pov, Vm +from world import GameWorld import telnet import time import login @@ -1122,56 +1123,6 @@ class GameSprEdit(GameWB): def ClsCursor(self): return CursorSprite -class Player(TokenClient): - def InitPersistent(self, owner, client): - TokenClient.InitPersistent(self, owner, client, "drawable", "player") - self.rbot = self.game.vm.AddPlayer() - - def die(self): - self.game.vm.RemovePlayer(self.rbot) - TokenClient.die(self) - - def run(self): - while True: - key = self.EvKey().receive(self) - posNew = self.rbot.Pos().Clone() - if key == ansi.K_UP: - posNew.Up() - elif key == ansi.K_DOWN: - posNew.Down() - elif key == ansi.K_LEFT: - posNew.Left() - elif key == ansi.K_RIGHT: - posNew.Right() - if not posNew.Equals(self.rbot.Pos()): - # is there an rbot here? - rgrbotCollide = [rbot for rbot in self.game.vm.Rgrbot() if rbot != self.rbot and rbot.Pos().Equals(posNew)] - if len(rgrbotCollide) > 0: - rgrbotCollide[0].botdef.syntOnTouch.Eval(self.game.vm) - elif self.game.board.AchAtPos(posNew) == ansi.achBlank: - self.rbot.Move(posNew) - - def draw(self, ascr, client): - if client == self.client: - self.game.board.draw(ascr) - for rbot in self.game.vm.Rgrbot(): - ascr.PutAch(rbot.Ach(), rbot.Pos().X(), rbot.Pos().Y()) - -# idea: synchronous event pair to implement "show message" w/ blocking - -class GameWorld(Game): - def InitPersistent(self, board): - Game.InitPersistent(self) - self.board = board - self.vm = Vm(board.defs) - self.dtStart = datetime.now() - - def StName(self): - return self.dtStart.strftime("%b %d, %Y at %I:%M%p") + " [" + str(len(self.RgclientConnected())) + "]" - - def GetRgclsTokTrans(self): - return [[AutoJoiner, Player], AutoKiller] - if __name__ == "__main__": if len(sys.argv) > 1: config.override(sys.argv[1]) diff --git a/world.py b/world.py new file mode 100644 index 0000000..c9748d4 --- /dev/null +++ b/world.py @@ -0,0 +1,81 @@ +# This file is part of MarMOTS. +# +# MarMOTS is free software: you can redistribute it and/or modify it under the terms of the GNU Affero +# General Public License as published by the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# MarMOTS is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General +# Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License along with MarMOTS. If not, +# see . +# +# Copyright 2020 Jeremy Penner + +import ansi_cython as ansi +from scripting import Vm +from basetoken import AutoJoiner, AutoKiller, MsgScroller +from engine import Game, TokenClient +from datetime import datetime +import traceback + +class Player(TokenClient): + def InitPersistent(self, owner, client): + TokenClient.InitPersistent(self, owner, client, "drawable", "player") + self.rbot = self.game.vm.AddPlayer() + self.vm = self.game.vm + + def die(self): + self.vm.RemovePlayer(self.rbot) + TokenClient.die(self) + + def run(self): + while True: + key = self.EvKey().receive(self) + posNew = self.rbot.Pos().Clone() + if key == ansi.K_UP: + posNew.Up() + elif key == ansi.K_DOWN: + posNew.Down() + elif key == ansi.K_LEFT: + posNew.Left() + elif key == ansi.K_RIGHT: + posNew.Right() + if not posNew.Equals(self.rbot.Pos()): + # is there an rbot here? + rgrbotCollide = [rbot for rbot in self.vm.Rgrbot() if rbot != self.rbot and rbot.Pos().Equals(posNew)] + if len(rgrbotCollide) > 0: + try: + rgrbotCollide[0].botdef.syntOnTouch.Eval(self) + except: + traceback.print_exc() + elif self.game.board.AchAtPos(posNew) == ansi.achBlank: + self.rbot.Move(posNew) + + def draw(self, ascr, client): + if client == self.client: + self.game.board.draw(ascr) + for rbot in self.vm.Rgrbot(): + ascr.PutAch(rbot.Ach(), rbot.Pos().X(), rbot.Pos().Y()) + + def GlobalMsg(self, stMsg): + self.game.rgtoken("msgscroller")[0].evPost.fire(stMsg) + +# idea: synchronous event pair to implement "show message" w/ blocking + +class GameWorld(Game): + def InitPersistent(self, board): + Game.InitPersistent(self) + self.board = board + self.vm = Vm(board.defs) + self.dtStart = datetime.now() + + def StName(self): + return self.dtStart.strftime("%b %d, %Y at %I:%M%p") + " [" + str(len(self.RgclientConnected())) + "]" + + def GetRgclsTokTrans(self): + return [[AutoJoiner, Player], MsgScroller, AutoKiller] + + def GetRgtagDraw(self): + return ["player", "overlay"]