In-game chat, add quit options to script editor and game world
This commit is contained in:
parent
3dd87784f3
commit
7cfe7184dc
13
scripting.py
13
scripting.py
|
@ -444,7 +444,7 @@ class SyntSet(SyntDesc):
|
||||||
|
|
||||||
@RegStmt
|
@RegStmt
|
||||||
class SyntPrint(SyntDesc):
|
class SyntPrint(SyntDesc):
|
||||||
desc = [["Show Message"], " \"", SyntText, "\""]
|
desc = [["Broadcast"], " message to all players: \"", SyntText, "\""]
|
||||||
expr = SyntDesc.DefProp(0)
|
expr = SyntDesc.DefProp(0)
|
||||||
def Eval(self, env):
|
def Eval(self, env):
|
||||||
env.GlobalMsg(self.expr.Eval(env))
|
env.GlobalMsg(self.expr.Eval(env))
|
||||||
|
@ -463,9 +463,11 @@ class Fail(TPrs):
|
||||||
# projection cursor
|
# projection cursor
|
||||||
class Pcur(object):
|
class Pcur(object):
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def PwProjected(defs, synt):
|
def PwProjected(defs, synt, dgDone):
|
||||||
pcur = Pcur(defs, synt)
|
pcur = Pcur(defs, synt)
|
||||||
synt.Project(pcur)
|
synt.Project(pcur)
|
||||||
|
PwStatic(pcur.pwVert, ' ')
|
||||||
|
PwButton(pcur.pwVert, 'Save and go back to editor', defs, dgDone)
|
||||||
return pcur.pwSplit
|
return pcur.pwSplit
|
||||||
|
|
||||||
def __init__(self, defs, synt):
|
def __init__(self, defs, synt):
|
||||||
|
@ -909,7 +911,10 @@ class Pov(TokenClient):
|
||||||
self.pselstate = self.game.rgtoken("pselstate")[0]
|
self.pselstate = self.game.rgtoken("pselstate")[0]
|
||||||
|
|
||||||
def PwProjected(self):
|
def PwProjected(self):
|
||||||
return Pcur.PwProjected(self.defs, self.block)
|
return Pcur.PwProjected(self.defs, self.block, self.Back)
|
||||||
|
|
||||||
|
def Back(self, val, pw):
|
||||||
|
self.client.leaveGame()
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
while True:
|
while True:
|
||||||
|
@ -942,7 +947,7 @@ class PselState(LeaveJoinToken):
|
||||||
del self.mpclient_psel[client]
|
del self.mpclient_psel[client]
|
||||||
def OnJoin(self, client):
|
def OnJoin(self, client):
|
||||||
print("client joined,", client)
|
print("client joined,", client)
|
||||||
self.mpclient_psel[client] = Psel(Pcur.PwProjected(self.defs, self.block).PwFirstSelectable(), Ksel.NAV)
|
self.mpclient_psel[client] = Psel(Pcur.PwProjected(self.defs, self.block, None).PwFirstSelectable(), Ksel.NAV)
|
||||||
class Mpksel(object):
|
class Mpksel(object):
|
||||||
def __init__(self, pwRoot, client, mpclient_psel):
|
def __init__(self, pwRoot, client, mpclient_psel):
|
||||||
self.mppw_ksel = {}
|
self.mppw_ksel = {}
|
||||||
|
|
197
whiteboard.py
197
whiteboard.py
|
@ -21,7 +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
|
from world import GameWorld, Chl, ChlMsg, ChlAct, ChlSys, Chat, MiChat, Joiner
|
||||||
import telnet
|
import telnet
|
||||||
import time
|
import time
|
||||||
import login
|
import login
|
||||||
|
@ -231,96 +231,6 @@ class Whiteboard(Token):
|
||||||
if versionOld < 5:
|
if versionOld < 5:
|
||||||
self.board = Board(self.game.gameLobby, self.game.stName, self.game.user, rglayer, dt)
|
self.board = Board(self.game.gameLobby, self.game.stName, self.game.user, rglayer, dt)
|
||||||
|
|
||||||
class Chl(object):
|
|
||||||
def __init__(self, client, st):
|
|
||||||
self.user = client.cld.user
|
|
||||||
self.st = st.rstrip()
|
|
||||||
|
|
||||||
class ChlMsg(Chl):
|
|
||||||
def StUser(self):
|
|
||||||
return "<" + self.user + ">"
|
|
||||||
def Col(self):
|
|
||||||
return ansi.WHITE
|
|
||||||
|
|
||||||
class ChlAct(Chl):
|
|
||||||
def StUser(self):
|
|
||||||
return "* " + self.user
|
|
||||||
def Col(self):
|
|
||||||
return ansi.MAGENTA
|
|
||||||
|
|
||||||
class ChlSys(Chl):
|
|
||||||
def StUser(self):
|
|
||||||
return self.user
|
|
||||||
def Col(self):
|
|
||||||
return ansi.BLUE
|
|
||||||
|
|
||||||
class Chat(TPrs):
|
|
||||||
def InitTransient(self):
|
|
||||||
TPrs.InitTransient(self)
|
|
||||||
self.cchl = 100
|
|
||||||
self.MakeTransient("game", None)
|
|
||||||
self.MakeTransient("evChat", None)
|
|
||||||
|
|
||||||
def InitPersistent(self):
|
|
||||||
TPrs.InitPersistent(self)
|
|
||||||
self.rgchl = []
|
|
||||||
|
|
||||||
def AttachToGame(self, game):
|
|
||||||
with self.SetTransiently():
|
|
||||||
self.game = game
|
|
||||||
self.evChat = Event(game)
|
|
||||||
|
|
||||||
def DetachFromGame(self):
|
|
||||||
with self.SetTransiently():
|
|
||||||
self.game = None
|
|
||||||
self.evChat = None
|
|
||||||
|
|
||||||
def Add(self, chl):
|
|
||||||
if len(chl.st) > 0:
|
|
||||||
self.rgchl.insert(0, chl)
|
|
||||||
if len(self.rgchl) > self.cchl:
|
|
||||||
self.rgchl = self.rgchl[:self.cchl]
|
|
||||||
self.evChat.fire(chl)
|
|
||||||
|
|
||||||
def CChl(self):
|
|
||||||
return len(self.rgchl)
|
|
||||||
|
|
||||||
def CUsers(self):
|
|
||||||
return len(self.game.RgclientConnected())
|
|
||||||
|
|
||||||
def DrawMsg(self, ascr, x, y, w, h, colBg=ansi.BLACK, ichl=0):
|
|
||||||
yDraw = y + h - 1
|
|
||||||
for chl in self.rgchl[ichl:]:
|
|
||||||
stUser = chl.StUser()
|
|
||||||
colFg = chl.Col()
|
|
||||||
wMsg = w - len(stUser) - 1
|
|
||||||
rgstMsg = RgstWrapped(chl.st, wMsg)
|
|
||||||
|
|
||||||
rgstMsg.reverse()
|
|
||||||
for istMsg, stMsg in enumerate(rgstMsg):
|
|
||||||
if istMsg == len(rgstMsg) - 1:
|
|
||||||
st = "{0} {1:{2}}".format(stUser, stMsg, wMsg)
|
|
||||||
else:
|
|
||||||
st = "{0:{1}} {2:{3}}".format("", len(stUser), stMsg, wMsg)
|
|
||||||
ascr.PutSt(st, x, yDraw, colFg, colBg)
|
|
||||||
yDraw = yDraw - 1
|
|
||||||
if yDraw == y - 1:
|
|
||||||
return
|
|
||||||
while yDraw >= y:
|
|
||||||
ascr.PutSt("{0:{1}}".format("", w), x, yDraw, ansi.WHITE, colBg)
|
|
||||||
yDraw = yDraw - 1
|
|
||||||
|
|
||||||
def DrawUsers(self, ascr, x, y, w, h, colBg=ansi.BLACK, iuser=0):
|
|
||||||
yDraw = y
|
|
||||||
for client in sorted(self.game.RgclientConnected(), lambda c1, c2: cmp(c1.Cldg(self.game).iclient, c2.Cldg(self.game).iclient))[iuser:]:
|
|
||||||
ascr.PutSt("{0:{1}}".format(str(client.Cldg(self.game).iclient) + ") " + client.cld.user, w), x, yDraw, ansi.WHITE, colBg)
|
|
||||||
yDraw = yDraw + 1
|
|
||||||
if yDraw == y + h:
|
|
||||||
break
|
|
||||||
while yDraw < y + h:
|
|
||||||
ascr.PutSt("{0:{1}}".format("", w), x, yDraw, ansi.WHITE, colBg)
|
|
||||||
yDraw = yDraw + 1
|
|
||||||
|
|
||||||
class Cursor(TokenClient):
|
class Cursor(TokenClient):
|
||||||
def InitPersistent(self, game, client):
|
def InitPersistent(self, game, client):
|
||||||
TokenClient.InitPersistent(self, game, client, "drawable", "cursor")
|
TokenClient.InitPersistent(self, game, client, "drawable", "cursor")
|
||||||
|
@ -357,7 +267,8 @@ class Cursor(TokenClient):
|
||||||
|
|
||||||
miQuit = MiButton("Back to Menu", self.client.leaveGame)
|
miQuit = MiButton("Back to Menu", self.client.leaveGame)
|
||||||
self.cf = self.MenuDrawing(miFg, miBg, miChars, miQuit)
|
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])
|
chat = self.game.drawing.chat
|
||||||
|
self.miChat = MiMenu([None, MiChat(self.client, 13, chat), MiTypein(Partial(chat.SendMsg, self.client)), None, miQuit, None])
|
||||||
self.rgmiLayer = RgmiProjected(self.game.drawing.rglayer, DgProjectMiButton(self.SelectLayer, self.StLayerName))
|
self.rgmiLayer = RgmiProjected(self.game.drawing.rglayer, DgProjectMiButton(self.SelectLayer, self.StLayerName))
|
||||||
self.miLayers = self.MenuLayers(miQuit)
|
self.miLayers = self.MenuLayers(miQuit)
|
||||||
self.ovPopup = OvPopup(self, self.client, MiTab.MiTabbed(["Drawing", self.cf], [self.StLayerTab(), self.miLayers], ["Chat", self.miChat]))
|
self.ovPopup = OvPopup(self, self.client, MiTab.MiTabbed(["Drawing", self.cf], [self.StLayerTab(), self.miLayers], ["Chat", self.miChat]))
|
||||||
|
@ -384,7 +295,7 @@ class Cursor(TokenClient):
|
||||||
return botdef
|
return botdef
|
||||||
|
|
||||||
def MenuDrawing(self, miFg, miBg, miChars, miQuit):
|
def MenuDrawing(self, miFg, miBg, miChars, miQuit):
|
||||||
return MiMenu([None, miFg, miBg, None, miChars, None, MiButton("Save", self.Save), None, miQuit, None])
|
return MiMenu([None, miFg, miBg, None, miChars, None, MiButton("Save to ANSI Gallery", self.Save), None, miQuit, None])
|
||||||
|
|
||||||
def MenuLayers(self, miQuit):
|
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),
|
return MiMenu(Rgseq([None], self.rgmiLayer, [None, MiButton("New Layer", self.NewLayer), MiButton("Move up", self.LayerUp), MiButton("Move down", self.LayerDown),
|
||||||
|
@ -439,12 +350,6 @@ class Cursor(TokenClient):
|
||||||
if not fBlink and self.cDontBlink > 0:
|
if not fBlink and self.cDontBlink > 0:
|
||||||
self.cDontBlink = self.cDontBlink - 1
|
self.cDontBlink = self.cDontBlink - 1
|
||||||
|
|
||||||
def SendMsg(self, st):
|
|
||||||
if st.lower().startswith("/me ") and len(st.rstrip()) > 3:
|
|
||||||
self.game.drawing.chat.Add(ChlAct(self.client, st[4:]))
|
|
||||||
else:
|
|
||||||
self.game.drawing.chat.Add(ChlMsg(self.client, st))
|
|
||||||
|
|
||||||
def OnChat(self, chl):
|
def OnChat(self, chl):
|
||||||
if type(chl) != ChlSys:
|
if type(chl) != ChlSys:
|
||||||
self.miChat.FlagNotice()
|
self.miChat.FlagNotice()
|
||||||
|
@ -704,97 +609,6 @@ def IchFromCh(ch):
|
||||||
return 9
|
return 9
|
||||||
return int(ch) - 1
|
return int(ch) - 1
|
||||||
|
|
||||||
class MiChat(Mi):
|
|
||||||
KWNDMSG = 0
|
|
||||||
KWNDUSERS = 1
|
|
||||||
def InitPersistent(self, client, height, chat):
|
|
||||||
Mi.InitPersistent(self)
|
|
||||||
self.client = client
|
|
||||||
self.chat = chat
|
|
||||||
self.height = height
|
|
||||||
assert height > 2
|
|
||||||
self.kwnd = self.KWNDMSG
|
|
||||||
self.imsg = 0
|
|
||||||
self.iuser = 0
|
|
||||||
|
|
||||||
def StName(self):
|
|
||||||
return "Chat"
|
|
||||||
|
|
||||||
def HandleKey(self, key):
|
|
||||||
if self.kwnd == self.KWNDUSERS:
|
|
||||||
if key == ansi.K_LEFT:
|
|
||||||
self.kwnd = self.KWNDMSG
|
|
||||||
elif (key == 'a' or key == 'A') and self.iuser > 0:
|
|
||||||
self.iuser = self.iuser - 1
|
|
||||||
elif (key == 'z' or key == 'Z') and self.iuser < self.chat.CUsers() - 1:
|
|
||||||
self.iuser = self.iuser + 1
|
|
||||||
else:
|
|
||||||
return False
|
|
||||||
else: #KWNDMSG
|
|
||||||
if key == ansi.K_RIGHT:
|
|
||||||
self.kwnd = self.KWNDUSERS
|
|
||||||
elif (key == 'a' or key == 'A') and self.imsg < self.chat.CChl() - 1:
|
|
||||||
self.imsg = self.imsg + 1
|
|
||||||
elif (key == 'z' or key == 'Z') and self.imsg > 0:
|
|
||||||
self.imsg = self.imsg - 1
|
|
||||||
else:
|
|
||||||
return False
|
|
||||||
return True
|
|
||||||
|
|
||||||
def Height(self, w):
|
|
||||||
return self.height
|
|
||||||
|
|
||||||
def ColBgDefault(self):
|
|
||||||
return ansi.BLACK
|
|
||||||
def ColBgSelected(self, fPri):
|
|
||||||
return ansi.BLACK
|
|
||||||
def ColFg(self):
|
|
||||||
return ansi.WHITE
|
|
||||||
|
|
||||||
def FIgnoreParent(self):
|
|
||||||
return True
|
|
||||||
|
|
||||||
def Draw(self, ascr, x, y, w, selor):
|
|
||||||
wChat = (w / 4) * 3
|
|
||||||
wUser = (w / 4) - 1
|
|
||||||
self.chat.DrawMsg(ascr, x, y, wChat, self.height - 1, self.ColBg(selor), self.imsg)
|
|
||||||
for yT in range(y, y + self.height - 1):
|
|
||||||
ascr.PutAch(ansi.MkAch(chr(179)), x + wChat, yT)
|
|
||||||
ascr.PutSt("{0:{1}<{2}}{3}{0:{1}<{4}}".format("", chr(196), wChat, chr(193), wUser), x, y + self.height - 1)
|
|
||||||
self.chat.DrawUsers(ascr, x + wChat + 1, y, wUser, self.height - 1, self.ColBg(selor), self.iuser)
|
|
||||||
if selor.KSel() == Selor.PRI:
|
|
||||||
if self.kwnd == self.KWNDMSG:
|
|
||||||
xBar = x + wChat - 1
|
|
||||||
pct = 1 - (self.imsg / float(self.chat.CChl()))
|
|
||||||
else: # KWNDUSERS
|
|
||||||
xBar = x + w - 1
|
|
||||||
pct = self.iuser / float(self.chat.CUsers())
|
|
||||||
yBar = int(y + (pct * (self.height - 4)))
|
|
||||||
ascr.PutAch(ansi.MkAch("A", ansi.RED, ansi.WHITE), xBar, yBar)
|
|
||||||
ascr.PutAch(ansi.MkAch(chr(186), ansi.RED, ansi.WHITE), xBar, yBar + 1)
|
|
||||||
ascr.PutAch(ansi.MkAch("Z", ansi.RED, ansi.WHITE), xBar, yBar + 2)
|
|
||||||
|
|
||||||
class Joiner(LeaveJoinToken):
|
|
||||||
def InitPersistent(self, owner):
|
|
||||||
Token.InitPersistent(self, owner)
|
|
||||||
self.msgScroller = self.game.rgtoken("msgscroller")[0]
|
|
||||||
self.board = self.game.drawing
|
|
||||||
|
|
||||||
def OnJoin(self, client):
|
|
||||||
with client.Cldg(self.game).SetTransiently() as cldg:
|
|
||||||
cldg.iclient = -1
|
|
||||||
iclient = 1
|
|
||||||
rgiclient = [clientT.Cldg(self.game).iclient for clientT in self.game.RgclientConnected()]
|
|
||||||
while iclient in rgiclient:
|
|
||||||
iclient = iclient + 1
|
|
||||||
cldg.iclient = iclient
|
|
||||||
self.msgScroller.evPost.fire(client.cld.user + "(#" + str(cldg.iclient) + ") has joined! :)")
|
|
||||||
self.board.chat.Add(ChlSys(client, "has joined"))
|
|
||||||
|
|
||||||
def OnLeave(self, client):
|
|
||||||
self.msgScroller.evPost.fire(client.cld.user + " has left! :(")
|
|
||||||
self.board.chat.Add(ChlSys(client, "has left"))
|
|
||||||
|
|
||||||
class Lobby(TokenClient):
|
class Lobby(TokenClient):
|
||||||
def InitPersistent(self, owner, client):
|
def InitPersistent(self, owner, client):
|
||||||
TokenClient.InitPersistent(self, owner, client)
|
TokenClient.InitPersistent(self, owner, client)
|
||||||
|
@ -1098,6 +912,9 @@ class GameWB(Game):
|
||||||
self.drawing.chat.AttachToGame(self)
|
self.drawing.chat.AttachToGame(self)
|
||||||
self.rgdgdie.append(self.drawing.chat.DetachFromGame)
|
self.rgdgdie.append(self.drawing.chat.DetachFromGame)
|
||||||
|
|
||||||
|
def Chat(self):
|
||||||
|
return self.drawing.chat
|
||||||
|
|
||||||
def ClsCursor(self):
|
def ClsCursor(self):
|
||||||
return Cursor
|
return Cursor
|
||||||
|
|
||||||
|
|
218
world.py
218
world.py
|
@ -14,17 +14,216 @@
|
||||||
# Copyright 2020 Jeremy Penner
|
# Copyright 2020 Jeremy Penner
|
||||||
|
|
||||||
import ansi_cython as ansi
|
import ansi_cython as ansi
|
||||||
|
from tpers import TPrs, Partial
|
||||||
from scripting import Vm
|
from scripting import Vm
|
||||||
from basetoken import AutoJoiner, AutoKiller, MsgScroller
|
from basetoken import AutoJoiner, AutoKiller, MsgScroller, Mi, MiButton, MiTypein, MiMenu, OvPopup
|
||||||
from engine import Game, TokenClient
|
from basetoken import LeaveJoinToken, Selor
|
||||||
|
from util import RgstWrapped
|
||||||
|
from engine import Game, Token, TokenClient, Event
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
import traceback
|
import traceback
|
||||||
|
|
||||||
|
|
||||||
|
class Chl(object):
|
||||||
|
def __init__(self, client, st):
|
||||||
|
self.user = client.cld.user
|
||||||
|
self.st = st.rstrip()
|
||||||
|
|
||||||
|
class ChlMsg(Chl):
|
||||||
|
def StUser(self):
|
||||||
|
return "<" + self.user + ">"
|
||||||
|
def Col(self):
|
||||||
|
return ansi.WHITE
|
||||||
|
|
||||||
|
class ChlAct(Chl):
|
||||||
|
def StUser(self):
|
||||||
|
return "* " + self.user
|
||||||
|
def Col(self):
|
||||||
|
return ansi.MAGENTA
|
||||||
|
|
||||||
|
class ChlSys(Chl):
|
||||||
|
def StUser(self):
|
||||||
|
return self.user
|
||||||
|
def Col(self):
|
||||||
|
return ansi.BLUE
|
||||||
|
|
||||||
|
class Chat(TPrs):
|
||||||
|
def InitTransient(self):
|
||||||
|
TPrs.InitTransient(self)
|
||||||
|
self.cchl = 100
|
||||||
|
self.MakeTransient("game", None)
|
||||||
|
self.MakeTransient("evChat", None)
|
||||||
|
|
||||||
|
def InitPersistent(self):
|
||||||
|
TPrs.InitPersistent(self)
|
||||||
|
self.rgchl = []
|
||||||
|
|
||||||
|
def AttachToGame(self, game):
|
||||||
|
with self.SetTransiently():
|
||||||
|
self.game = game
|
||||||
|
self.evChat = Event(game)
|
||||||
|
|
||||||
|
def DetachFromGame(self):
|
||||||
|
with self.SetTransiently():
|
||||||
|
self.game = None
|
||||||
|
self.evChat = None
|
||||||
|
|
||||||
|
def Add(self, chl):
|
||||||
|
if len(chl.st) > 0:
|
||||||
|
self.rgchl.insert(0, chl)
|
||||||
|
if len(self.rgchl) > self.cchl:
|
||||||
|
self.rgchl = self.rgchl[:self.cchl]
|
||||||
|
self.evChat.fire(chl)
|
||||||
|
|
||||||
|
def SendMsg(self, client, st):
|
||||||
|
if st.lower().startswith("/me ") and len(st.rstrip()) > 3:
|
||||||
|
self.Add(ChlAct(client, st[4:]))
|
||||||
|
else:
|
||||||
|
self.Add(ChlMsg(client, st))
|
||||||
|
|
||||||
|
def CChl(self):
|
||||||
|
return len(self.rgchl)
|
||||||
|
|
||||||
|
def CUsers(self):
|
||||||
|
return len(self.game.RgclientConnected())
|
||||||
|
|
||||||
|
def DrawMsg(self, ascr, x, y, w, h, colBg=ansi.BLACK, ichl=0):
|
||||||
|
yDraw = y + h - 1
|
||||||
|
for chl in self.rgchl[ichl:]:
|
||||||
|
stUser = chl.StUser()
|
||||||
|
colFg = chl.Col()
|
||||||
|
wMsg = w - len(stUser) - 1
|
||||||
|
rgstMsg = RgstWrapped(chl.st, wMsg)
|
||||||
|
|
||||||
|
rgstMsg.reverse()
|
||||||
|
for istMsg, stMsg in enumerate(rgstMsg):
|
||||||
|
if istMsg == len(rgstMsg) - 1:
|
||||||
|
st = "{0} {1:{2}}".format(stUser, stMsg, wMsg)
|
||||||
|
else:
|
||||||
|
st = "{0:{1}} {2:{3}}".format("", len(stUser), stMsg, wMsg)
|
||||||
|
ascr.PutSt(st, x, yDraw, colFg, colBg)
|
||||||
|
yDraw = yDraw - 1
|
||||||
|
if yDraw == y - 1:
|
||||||
|
return
|
||||||
|
while yDraw >= y:
|
||||||
|
ascr.PutSt("{0:{1}}".format("", w), x, yDraw, ansi.WHITE, colBg)
|
||||||
|
yDraw = yDraw - 1
|
||||||
|
|
||||||
|
def DrawUsers(self, ascr, x, y, w, h, colBg=ansi.BLACK, iuser=0):
|
||||||
|
yDraw = y
|
||||||
|
for client in sorted(self.game.RgclientConnected(), lambda c1, c2: cmp(c1.Cldg(self.game).iclient, c2.Cldg(self.game).iclient))[iuser:]:
|
||||||
|
ascr.PutSt("{0:{1}}".format(str(client.Cldg(self.game).iclient) + ") " + client.cld.user, w), x, yDraw, ansi.WHITE, colBg)
|
||||||
|
yDraw = yDraw + 1
|
||||||
|
if yDraw == y + h:
|
||||||
|
break
|
||||||
|
while yDraw < y + h:
|
||||||
|
ascr.PutSt("{0:{1}}".format("", w), x, yDraw, ansi.WHITE, colBg)
|
||||||
|
yDraw = yDraw + 1
|
||||||
|
|
||||||
|
class MiChat(Mi):
|
||||||
|
KWNDMSG = 0
|
||||||
|
KWNDUSERS = 1
|
||||||
|
def InitPersistent(self, client, height, chat):
|
||||||
|
Mi.InitPersistent(self)
|
||||||
|
self.client = client
|
||||||
|
self.chat = chat
|
||||||
|
self.height = height
|
||||||
|
assert height > 2
|
||||||
|
self.kwnd = self.KWNDMSG
|
||||||
|
self.imsg = 0
|
||||||
|
self.iuser = 0
|
||||||
|
|
||||||
|
def StName(self):
|
||||||
|
return "Chat"
|
||||||
|
|
||||||
|
def HandleKey(self, key):
|
||||||
|
if self.kwnd == self.KWNDUSERS:
|
||||||
|
if key == ansi.K_LEFT:
|
||||||
|
self.kwnd = self.KWNDMSG
|
||||||
|
elif (key == 'a' or key == 'A') and self.iuser > 0:
|
||||||
|
self.iuser = self.iuser - 1
|
||||||
|
elif (key == 'z' or key == 'Z') and self.iuser < self.chat.CUsers() - 1:
|
||||||
|
self.iuser = self.iuser + 1
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
else: #KWNDMSG
|
||||||
|
if key == ansi.K_RIGHT:
|
||||||
|
self.kwnd = self.KWNDUSERS
|
||||||
|
elif (key == 'a' or key == 'A') and self.imsg < self.chat.CChl() - 1:
|
||||||
|
self.imsg = self.imsg + 1
|
||||||
|
elif (key == 'z' or key == 'Z') and self.imsg > 0:
|
||||||
|
self.imsg = self.imsg - 1
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
def Height(self, w):
|
||||||
|
return self.height
|
||||||
|
|
||||||
|
def ColBgDefault(self):
|
||||||
|
return ansi.BLACK
|
||||||
|
def ColBgSelected(self, fPri):
|
||||||
|
return ansi.BLACK
|
||||||
|
def ColFg(self):
|
||||||
|
return ansi.WHITE
|
||||||
|
|
||||||
|
def FIgnoreParent(self):
|
||||||
|
return True
|
||||||
|
|
||||||
|
def Draw(self, ascr, x, y, w, selor):
|
||||||
|
wChat = (w / 4) * 3
|
||||||
|
wUser = (w / 4) - 1
|
||||||
|
self.chat.DrawMsg(ascr, x, y, wChat, self.height - 1, self.ColBg(selor), self.imsg)
|
||||||
|
for yT in range(y, y + self.height - 1):
|
||||||
|
ascr.PutAch(ansi.MkAch(chr(179)), x + wChat, yT)
|
||||||
|
ascr.PutSt("{0:{1}<{2}}{3}{0:{1}<{4}}".format("", chr(196), wChat, chr(193), wUser), x, y + self.height - 1)
|
||||||
|
self.chat.DrawUsers(ascr, x + wChat + 1, y, wUser, self.height - 1, self.ColBg(selor), self.iuser)
|
||||||
|
if selor.KSel() == Selor.PRI:
|
||||||
|
if self.kwnd == self.KWNDMSG:
|
||||||
|
xBar = x + wChat - 1
|
||||||
|
pct = 1 - (self.imsg / float(self.chat.CChl()))
|
||||||
|
else: # KWNDUSERS
|
||||||
|
xBar = x + w - 1
|
||||||
|
pct = self.iuser / float(self.chat.CUsers())
|
||||||
|
yBar = int(y + (pct * (self.height - 4)))
|
||||||
|
ascr.PutAch(ansi.MkAch("A", ansi.RED, ansi.WHITE), xBar, yBar)
|
||||||
|
ascr.PutAch(ansi.MkAch(chr(186), ansi.RED, ansi.WHITE), xBar, yBar + 1)
|
||||||
|
ascr.PutAch(ansi.MkAch("Z", ansi.RED, ansi.WHITE), xBar, yBar + 2)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class Joiner(LeaveJoinToken):
|
||||||
|
def InitPersistent(self, owner):
|
||||||
|
Token.InitPersistent(self, owner)
|
||||||
|
self.msgScroller = self.game.rgtoken("msgscroller")[0]
|
||||||
|
|
||||||
|
def OnJoin(self, client):
|
||||||
|
with client.Cldg(self.game).SetTransiently() as cldg:
|
||||||
|
cldg.iclient = -1
|
||||||
|
iclient = 1
|
||||||
|
rgiclient = [clientT.Cldg(self.game).iclient for clientT in self.game.RgclientConnected()]
|
||||||
|
while iclient in rgiclient:
|
||||||
|
iclient = iclient + 1
|
||||||
|
cldg.iclient = iclient
|
||||||
|
self.msgScroller.evPost.fire(client.cld.user + "(#" + str(cldg.iclient) + ") has joined! :)")
|
||||||
|
self.game.Chat().Add(ChlSys(client, "has joined"))
|
||||||
|
|
||||||
|
def OnLeave(self, client):
|
||||||
|
self.msgScroller.evPost.fire(client.cld.user + " has left! :(")
|
||||||
|
self.game.Chat().Add(ChlSys(client, "has left"))
|
||||||
|
|
||||||
|
## TODO:
|
||||||
|
## - fix numbering
|
||||||
|
|
||||||
class Player(TokenClient):
|
class Player(TokenClient):
|
||||||
def InitPersistent(self, owner, client):
|
def InitPersistent(self, owner, client):
|
||||||
TokenClient.InitPersistent(self, owner, client, "drawable", "player")
|
TokenClient.InitPersistent(self, owner, client, "drawable", "player")
|
||||||
self.rbot = self.game.vm.AddPlayer()
|
self.rbot = self.game.vm.AddPlayer()
|
||||||
self.vm = self.game.vm
|
self.vm = self.game.vm
|
||||||
|
chat = self.game.chat
|
||||||
|
miQuit = MiButton("Leave Game", self.client.leaveGame)
|
||||||
|
self.mi = MiMenu([None, MiChat(self.client, 13, chat), MiTypein(Partial(chat.SendMsg, self.client)), None, miQuit, None])
|
||||||
|
self.ovPopup = OvPopup(self, self.client, self.mi)
|
||||||
|
|
||||||
def die(self):
|
def die(self):
|
||||||
self.vm.RemovePlayer(self.rbot)
|
self.vm.RemovePlayer(self.rbot)
|
||||||
|
@ -42,6 +241,9 @@ class Player(TokenClient):
|
||||||
posNew.Left()
|
posNew.Left()
|
||||||
elif key == ansi.K_RIGHT:
|
elif key == ansi.K_RIGHT:
|
||||||
posNew.Right()
|
posNew.Right()
|
||||||
|
elif key == ansi.K_TAB:
|
||||||
|
self.ovPopup.evShow.fire()
|
||||||
|
self.ovPopup.evDone.receive(self)
|
||||||
if not posNew.Equals(self.rbot.Pos()):
|
if not posNew.Equals(self.rbot.Pos()):
|
||||||
# is there an rbot here?
|
# is there an rbot here?
|
||||||
rgrbotCollide = [rbot for rbot in self.vm.Rgrbot() if rbot != self.rbot and rbot.Pos().Equals(posNew)]
|
rgrbotCollide = [rbot for rbot in self.vm.Rgrbot() if rbot != self.rbot and rbot.Pos().Equals(posNew)]
|
||||||
|
@ -70,12 +272,22 @@ class GameWorld(Game):
|
||||||
self.board = board
|
self.board = board
|
||||||
self.vm = Vm(board.defs)
|
self.vm = Vm(board.defs)
|
||||||
self.dtStart = datetime.now()
|
self.dtStart = datetime.now()
|
||||||
|
self.chat = Chat()
|
||||||
|
|
||||||
|
def InitTransient(self):
|
||||||
|
Game.InitTransient(self)
|
||||||
|
if not self.FDead():
|
||||||
|
self.chat.AttachToGame(self)
|
||||||
|
self.rgdgdie.append(self.chat.DetachFromGame)
|
||||||
|
|
||||||
|
def Chat(self):
|
||||||
|
return self.chat
|
||||||
|
|
||||||
def StName(self):
|
def StName(self):
|
||||||
return self.dtStart.strftime("%b %d, %Y at %I:%M%p") + " [" + str(len(self.RgclientConnected())) + "]"
|
return self.dtStart.strftime("%b %d, %Y at %I:%M%p") + " [" + str(len(self.RgclientConnected())) + "]"
|
||||||
|
|
||||||
def GetRgclsTokTrans(self):
|
def GetRgclsTokTrans(self):
|
||||||
return [[AutoJoiner, Player], MsgScroller, AutoKiller]
|
return [[AutoJoiner, Player], MsgScroller, Joiner, AutoKiller]
|
||||||
|
|
||||||
def GetRgtagDraw(self):
|
def GetRgtagDraw(self):
|
||||||
return ["player", "overlay"]
|
return ["player", "overlay"]
|
||||||
|
|
Loading…
Reference in a new issue