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: if self.fAwake:
self.drawI(ascr, client, True) self.drawI(ascr, client, True)
class MsgScroller(Token): 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") Token.InitPersistent(self, owner, "drawable", "msgscroller", "overlay")
self.colFg = colFg self.colFg = colFg
self.colBg = colBg self.colBg = colBg

View file

@ -54,7 +54,7 @@ class Rbot(TPrs):
def Move(self, pos): def Move(self, pos):
self.pos = pos self.pos = pos
class Defs(TPrs): class Defs(TPrs):
def InitPersistent(self, rgflagdef = None, rgbotdef = None): def InitPersistent(self, rgflagdef = None, rgbotdef = None):
self.rgflagdef = rgflagdef or [] self.rgflagdef = rgflagdef or []
@ -87,13 +87,16 @@ class Vm(TPrs):
self.rgrbotPlayer.remove(rbotPlayer) self.rgrbotPlayer.remove(rbotPlayer)
def Rgrbot(self): 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) return itertools.chain(self.mpbotdef.values(), self.rgrbotPlayer)
def Fail(self, stMessage, synt): def Fail(self, stMessage, synt):
self.Log(Fail(stMessage, synt)) self.Log(Fail(stMessage, synt))
def Log(self, fail): def Log(self, fail):
print(fail.stMessage, fail.synt) print(fail.stFailure, fail.synt)
class Stype(TPrs): class Stype(TPrs):
"Syntax type" "Syntax type"
@ -183,9 +186,9 @@ class Synt(Typeable):
def Project(self, pcur): def Project(self, pcur):
"Project the current synt into its corresponding pws." "Project the current synt into its corresponding pws."
pass pass
def Eval(self, vm): def Eval(self, env):
"Execute yourself, in the context of vm." "Execute yourself, in the context of vm."
return vm.Fail("Missing information", self) return env.vm.Fail("Missing information", self)
def StypeForChild(self, syntChild): def StypeForChild(self, syntChild):
"Return the stype that should be applied to the given child." "Return the stype that should be applied to the given child."
@ -316,11 +319,13 @@ class SyntText(Synt):
val = Synt.HandleTypeinKey(self, key) val = Synt.HandleTypeinKey(self, key)
self.st = self.GetStTypein() self.st = self.GetStTypein()
return val return val
def Eval(self, vm): def Eval(self, env):
return self.st return self.st
class SyntHole(SyntDesc): class SyntHole(SyntDesc):
desc = [[" "]] desc = [[" "]]
def Eval(self, env):
pass
class SyntBlock(Synt): class SyntBlock(Synt):
def Project(self, pcur): def Project(self, pcur):
@ -355,10 +360,10 @@ class SyntBlock(Synt):
return True return True
return False return False
def Eval(self, vm): def Eval(self, env):
for synt in self.rgsynt: for synt in self.rgsynt:
# todo: log failures # todo: log failures
synt.Eval(vm) synt.Eval(env)
class SyntLit(Synt): class SyntLit(Synt):
def InitPersistent(self, value, rtype): def InitPersistent(self, value, rtype):
@ -371,7 +376,7 @@ class SyntLit(Synt):
return self.rtype return self.rtype
def Project(self, pcur): def Project(self, pcur):
self.ProjectTypein(pcur) self.ProjectTypein(pcur)
def Eval(self, vm): def Eval(self, env):
return self.value return self.value
class SyntFlagRef(Synt): class SyntFlagRef(Synt):
@ -387,30 +392,30 @@ class SyntFlagRef(Synt):
def Project(self, pcur): def Project(self, pcur):
self.ProjectTypein(pcur) self.ProjectTypein(pcur)
def Eval(self, vm): def Eval(self, env):
try: try:
return vm.FFlagSet(self.flagdef) return env.vm.FFlagSet(self.flagdef)
except: except:
return vm.Fail("No such flag", self) return env.vm.Fail("No such flag", self)
class SyntIsFlagSet(SyntDesc): class SyntIsFlagSet(SyntDesc):
desc = [["set"]] desc = [["set"]]
def Eval(self, vm, val): def Eval(self, env, val):
return val return val
class SyntIsFlagUnset(SyntDesc): class SyntIsFlagUnset(SyntDesc):
desc = [["not set"]] desc = [["not set"]]
def Eval(self, vm, val): def Eval(self, env, val):
return not val return not val
class SyntIsFlagEqualTo(SyntDesc): class SyntIsFlagEqualTo(SyntDesc):
desc = [["equal to"], " ", RtypeFlag()] desc = [["equal to"], " ", RtypeFlag()]
flag = SyntDesc.DefProp(0) flag = SyntDesc.DefProp(0)
def Eval(self, vm, val): def Eval(self, env, val):
return val == self.flag.Eval(vm) return val == self.flag.Eval(env)
class SyntIsFlagNotEqualTo(SyntDesc): class SyntIsFlagNotEqualTo(SyntDesc):
desc = [["not equal to"], " ", RtypeFlag()] desc = [["not equal to"], " ", RtypeFlag()]
flag = SyntDesc.DefProp(0) flag = SyntDesc.DefProp(0)
def Eval(self, vm, val): def Eval(self, env, val):
return val != self.flag.Eval(vm) return val != self.flag.Eval(env)
class StypeFlagTest(StypeEnum): class StypeFlagTest(StypeEnum):
rgclsSynt = [SyntIsFlagSet, SyntIsFlagUnset, SyntIsFlagEqualTo, SyntIsFlagNotEqualTo] rgclsSynt = [SyntIsFlagSet, SyntIsFlagUnset, SyntIsFlagEqualTo, SyntIsFlagNotEqualTo]
@ -422,28 +427,27 @@ class SyntIf(SyntDesc):
test = SyntDesc.DefProp(1) test = SyntDesc.DefProp(1)
blockIfTrue = SyntDesc.DefProp(2) blockIfTrue = SyntDesc.DefProp(2)
blockIfFalse = SyntDesc.DefProp(3) blockIfFalse = SyntDesc.DefProp(3)
def Eval(self, vm): def Eval(self, env):
if self.test.Eval(vm, self.expr.Eval(vm)): if self.test.Eval(env, self.expr.Eval(env)):
return self.blockIfTrue.Eval(vm) return self.blockIfTrue.Eval(env)
else: else:
return self.blockIfFalse.Eval(vm) return self.blockIfFalse.Eval(env)
@RegStmt @RegStmt
class SyntSet(SyntDesc): class SyntSet(SyntDesc):
desc = [["Set flag"], " ", RtypeFlag(), " to ", RtypeUnion(RtypeBool(), RtypeFlag())] desc = [["Set flag"], " ", RtypeFlag(), " to ", RtypeUnion(RtypeBool(), RtypeFlag())]
lvalue = SyntDesc.DefProp(0) lvalue = SyntDesc.DefProp(0)
expr = SyntDesc.DefProp(1) expr = SyntDesc.DefProp(1)
def Eval(self, vm): def Eval(self, env):
# todo: fail if flagdef or expr isn't set properly? # 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 @RegStmt
class SyntPrint(SyntDesc): class SyntPrint(SyntDesc):
desc = [["Show Message"], " \"", SyntText, "\""] desc = [["Show Message"], " \"", SyntText, "\""]
expr = SyntDesc.DefProp(0) expr = SyntDesc.DefProp(0)
def Eval(self, vm): def Eval(self, env):
# todo env.GlobalMsg(self.expr.Eval(env))
print(self.expr.Eval(vm))
class Fail(TPrs): class Fail(TPrs):
""" """

View file

@ -21,6 +21,7 @@ from tpers import *
from datetime import * from datetime import *
from util import * from util import *
from scripting import Botdef, Flagdef, Defs, PselState, Pov, Vm from scripting import Botdef, Flagdef, Defs, PselState, Pov, Vm
from world import GameWorld
import telnet import telnet
import time import time
import login import login
@ -1122,56 +1123,6 @@ class GameSprEdit(GameWB):
def ClsCursor(self): def ClsCursor(self):
return CursorSprite 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 __name__ == "__main__":
if len(sys.argv) > 1: if len(sys.argv) > 1:
config.override(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"]