# Misc functions from string import lower,printable,Template,capitalize as fcap import re,shlex import asyncore as ac from random import * NL = "\r\n" is_a = isinstance cap = lambda x: x[:1].upper() + x[1:] # capitalize first letter sxarg = shlex.split # split with quote handling def sxarg(x): try: return shlex.split(x) # shlex.split has trouble with improper quotes except: return x.split() # Sort of like MERC's one_arg, except much much stupider def xarg(t): ts = sxarg(t) return ts and [ts[0]," ".join(ts[1:])] or ts # does t match any of the names in ns? def nmatch(t,ns): for x in ns: if x.startswith(t): return 1 # split up a string into keywords tok = lambda t: map(lower,t.strip().split()) # connected players def cplayers(): return [c.p for c in ac.socket_map.itervalues() if c.p] # n = name to find, xs = list to search, gn = extract obj def find(n,xs,gn=lambda x:x): skip = 0 ns = tok(n) if not ns: return 0 if ns[-1].isdigit(): # "green tea 2" gets the second green tea skip = max(int(ns[-1])-1,0) del ns[-1] for z in xs: x = gn(z) if not x.names: x.names = tok(x.name) for n in ns: if not nmatch(n,x.names): break else: if skip: skip -= 1 else: return z # fix dangling color '{' def cfix(r): if r and r[-1] == '{' and (len(r) == 1 or r[-2] != '{'): r += '{' return r # fits a list to a certain size, filling empty spaces with g def fit(x,z=2,g=''): return x[:z] + [g] * (z-len(x)) # respect descriptions rscale = ("hellishly vile",20,"utterly pathetic",30,"mildly idiotic", 50,"rather frumpish",70,"slightly unkempt",85,"decent",99,"respectable", 275,"very respectable",350,"trendy",650,"stunning",750,"debonair",999,"awesome") # health descs (by percent) hscale = ("near death",10,"horribly disfigured",20,"ghastly pale", 30,"terribly wounded",50,"badly bruised",70,"bruised",80,"slightly scratched", 95,"pretty good shape",100,"in perfect health") def scale(s,m): r = 0 for x in s: if is_a(x,int) and m < x: break r = x return r # broadcast messages # uses format strings like $SN (subj name) # targets: S for subj, V for vict, O for obj # formats: N for name, T for text, E for he/she/it, # M for him/her/it, S for his/her/its # # broadcats functions: # room - third-party bystanders excluding subj and vict in subj's room # subj - subj only # vict - vict only # all - everyone in subj's room # world - global except subj # It's a "class act"! Get it? Ahahaha - okay, sorry, no more puns class Act(object): def __init__(S,subj=0,vict=0,obj=0): S._s = subj; S._v = vict; S._o = obj def repl(S, m): x, y = m.group(1, 2) r = {'S':S._s,'V':S._v,'O':S._o}[x] if y == 'N': t = r.name if y == 'T': t = cfix(r) if y == 'E': t = r.SE if y == 'M': t = r.SM if y == 'S': t = r.SS return t room = lambda S,t: S.act(t, S._s.room.people, [S._s,S._v,S._o]) subj = lambda S,t: S.act(t, [S._s]) vict = lambda S,t: S.act(t, [S._v], [S._s]) obj = lambda S,t: S.act(t, [S._o], [S._s,S._v]) all = lambda S,t: S.act(t, S._s.room.people) world = lambda S,t: S.act(t, cplayers(), [S._s]) # text, seq of viewers, seq to exclude def act(S,t,vs,ex=[]): if not t: return S x = cap(re.sub("\$([SVO])([NTEMS])",S.repl,t)) for v in (y for y in vs if y not in ex): v.sendl(x) return S # allow chaining