Implement "Show message"

This commit is contained in:
Jeremy Penner 2020-07-31 22:44:39 -04:00
parent 6f5e58e777
commit 3dd87784f3
4 changed files with 113 additions and 77 deletions

View file

@ -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

View file

@ -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):
"""

View file

@ -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])

81
world.py Normal file
View file

@ -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 <https://www.gnu.org/licenses/>.
#
# 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"]