%# (c) 1999 - AccesSoft - See license.txt for details
%#$Id: bootstrap.txt,v 1.2 2004/02/26 08:52:21 daveron Exp $

%# prepare our creative powers
%transfer(None,me,10000)
%me.accept = 1
%thing = getObj(1)
%thing.f = 1

%# create Agent in our image, then give it a navel
%me.f = 1
%agent = create(me,me,"Agent")
%agent.setParents(thing)
%agent.f = 1
%agent.accept = 1
%me.f = 0

%# create other user types, so we can start adding methods
%user = create(me,agent,"User")
%user.f = 1

%builder = create(me,user,"Builder")
%builder.f = 1

%coder = create(me,builder,"Coder")
%coder.f = 1
%coder.programmer = 1

%wizard = create(me,coder,"Wizard")
%wizard.f = 1
%wizard.programmer = 1
%wizard.wizard = 1

%# set properties on #0
%ref = getObj(0)
%ref.thing = thing
%ref.base = thing
%ref.place = getObj(3)
%ref.dir = getObj(4)
%ref.agent = agent
%ref.user = user
%ref.builder = builder
%ref.coder = coder
%ref.wiz = wizard

%# become our creation's child (a very Zen thing)
%me.setParents(wizard)
%print "You are now a wizard in name as well as powers;"
%print "It is time to start creating functions."

%# set other base-class properties as appropriate
%ref.place.f = 1
%ref.place.accept = 1
%ref.dir.f = 1
%ref.dir.accept = 1
%ref.dir.immobile = 0

%#================== Basic Building & Coding ================
%print "$coder.@newfunc"
%caller.enterFunc( getObj('$coder'), 'newfunc(self,caller,obj,funcname)' )
caller.enterFunc( obj, funcname )
.x
%getObj("$coder").setCmdDef('@newfunc','@newfunc <obj>.<funcdef>', 'newfunc(caller,%1,%2)' )
%getObj("$coder").setCmdDef('@newfunc','@newfunc <funcdef>', 'newfunc(caller,caller,%1)' )
%getObj("$coder").setCmdDef('@newfunc','@newfunc <funcdef> on <obj>', 'newfunc(caller,%2,%1)' )
%getObj("$coder").newfunc.desc = "create a new function"
%getObj("$coder").getprop('newfunc').owner = None
%getObj("$coder").getprop('newfunc').val.x = 0

%print "$coder.@cmd"
@newfunc $coder.at_cmd(self, obj, pattern, funcdef)
verb = string.split(pattern)[0]
obj.setCmdDef(verb, pattern, funcdef)
print verb, "command defined on", obj
.x
%getObj("$coder").setCmdDef('@cmd','@cmd <obj>.<str> calls <funcdef>', 'at_cmd(%1,%2,%3)' )
%getObj("$coder").at_cmd.desc = "set a CmdDef"
%getObj("$coder").getprop('at_cmd').owner = None
%getObj("$coder").getprop('at_cmd').val.x = 0

%print "$builder.@set"
@newfunc $builder.at_set(self, ref, propname, val)
setattr( ref, propname, val )
.x
@cmd $builder.@set <obj>.<propname> = <val> calls at_set(%1,%2,%3)
@cmd $builder.@set <obj>.<propname> to <val> calls at_set(%1,%2,%3)
@cmd $builder.@set <obj>.<propname>=<val> calls at_set(%1,%2,%3)
@set $builder.at_set.desc = "set a property value"
%getObj("$builder").getprop("at_set").owner = None
%getObj("$builder").getprop('at_set').val.x = 0

%print "$wiz.@setown"
@newfunc $wiz.at_setown(self, ref, propname, owner)
prop = ref.getprop(propname)
if prop: prop.owner = owner
else: print "There is no property named %s on %s." % (propname, ref.name)
.x
@cmd $wiz.@setown <obj>.<str> = <obj> calls at_setown(%1,%2,%3)
@cmd $wiz.@setown <obj>.<str> to <obj> calls at_setown(%1,%2,%3)
@cmd $wiz.@setown <obj>.<str> = None calls at_setown(%1,%2,None)
@cmd $wiz.@setown <obj>.<str> to None calls at_setown(%1,%2,None)
@set $wiz.at_setown.desc = "set a property's owner"
@setown $wiz.at_setown = None
%getObj("$wiz").getprop('at_setown').val.x = 0

%print "$builder.@setperm"
@newfunc $builder.setperm(self,obj,propname,perms)
prop = obj.getprop(propname)
for perm in ['w','r','c']:
    if string.find(perms,perm) >= 0: setattr(prop,perm,1)
    else: setattr(prop,perm,0)
if type(prop.val) == InstanceType and prop.val.__class__ == Func:
	prop.val.x = ('x' in perms)
elif 'x' in perms:
	print "'x' applies only to functions, not to", type(prop.val)
print "Permissions set."
.x
@cmd $builder.@setperm <obj>.<propname> to <str> calls setperm(%1,%2,%3)
@cmd $builder.@setperm <obj>.<propname> = <str> calls setperm(%1,%2,%3)
@set $builder.setperm.desc = "set permissions on a property"
@setown $builder.setperm = None
@setperm $builder.setperm = rc


%print "$coder.@whichcmd"
@newfunc $coder.at_whichcmd(self, obj, cmd)
.da
if not obj:
  print "What?"
  return
for x in obj.getCmdDef(None,0):
  if x.pat[0:len(cmd)] == cmd:
    print "%s[#%s]" % (obj.name, obj.id) + ": ",
    print x.pat
for x in obj.parents:
  self.at_whichcmd(x, cmd)
.x
@cmd $coder.@whichcmd <obj>.<str> calls at_whichcmd(%1,%2)
@cmd $coder.@whichcmd <str> calls at_whichcmd(caller,%1)
@cmd $coder.@commands <obj> calls at_whichcmd(%1,"")
@cmd $coder.@commands calls at_whichcmd(caller,"")
@setown $coder.at_whichcmd = None
@setperm $coder.at_whichcmd = rxc


%print "$thing.broadcast"
@newfunc $thing.broadcast(self,msg,excluding=[])
# first, tell msg to myself
self.tell(msg)

# then, broadcast to all contents (not in excluding)
try: stuff = self.contents()
except: return
if stuff:
	if not excluding:
		for item in stuff:
			item.broadcast(msg,excluding)
	elif type(excluding) == InstanceType:
		for item in filter(lambda x,y=excluding:x != y, stuff):
			item.broadcast(msg,excluding)
	elif type(excluding) == ListType or type(excluding) == TupleType:
		for item in filter(lambda x,y=excluding:x not in y, stuff):
			item.broadcast(msg,excluding)
	else: raise "ParamError", "Can't exclude %s" % excluding
.x
@set $thing.broadcast.desc = 'tell self and contents'
@setown $thing.broadcast = None


%print "$agent.say"
@newfunc $agent.say(self,str)
self.location.broadcast('%s says, "%s"' % (self.name, str), [self])
print 'You say, "%s"' % str
.x
@cmd $agent.say <str> calls say(%1)
@set $agent.say.desc = "speak a string to the room"
@setown $agent.say = None
@setperm $agent.say = rc


"$builder.@create"
@newfunc $builder.create(self,parent,newname='')
if parent.isa(getObj('$user')) and not self.wizard:
	print "Only wizards can create users."
	return
ob = create(self, parent, newname)
print ob.name,"created as object #%s." % ob.id
.x
@cmd $builder.@create <obj> as <str> calls create(%1,%2)
@set $builder.create.desc = "make a new POO object"
@setperm $builder.create = rc


"$wiz.beam"
@newfunc $wiz.beam(self,obj,where)
if type(where) != InstanceType:
	print "Invalid location."
else:
	move(obj,where)
	print "%s beamed to %s." % (obj.name, where.name)
	if obj == self: self.do_cmd("look")
.x
@cmd $wiz.beam <obj> to <obj> calls beam(%1,%2)
@set $wiz.beam.desc = "teleport an object to any location"
@setown $wiz.beam = None
@setperm $wiz.beam = rc

%#=================== Advanced Parsing Support =================
"$thing.findComponent
@newfunc $thing.findComponent(self,compName)
"""$thing.findComponent(self,compName):
return an object reference for the specified component;
if not found, return this object, and store the component
name in self.component for future reference."""
for ob in self.contents():				# try exact match first
	if ob.name == compName: return ob
compName = string.lower(compName)
for ob in self.contents():
	if ob.name == compName: return ob
	if compName in ob.aliases: return ob
# no match?  store it for future reference, and return self
self.component = compName
return self
.x

%#======================= Looking & Describing =================
"$base.description"
@newfunc $base.description(self,looker)
# by default, just return contents of 'desc' field
# but first convert lists into string
if type(self.desc) == ListType or type(self.desc) == TupleType:
	return string.join(self.desc,'\n')
if not self.desc:
   return ''
return self.desc
.x
@set $thing.description.desc = "return self.desc"
@setown $thing.description = None
@set $thing.desc = "You see nothing special."


"$place.description"
@newfunc $place.description(self,looker)
# first, get the room name and the standard description
desc = '%s\n%s\n' % (self.name, super(looker))
# then add a list of room contents
for item in self.contents():
	if item!=looker and item.salient:
		desc = "%s\n    %s" % (desc, item.listdesc(looker))
return desc
.x
@set $place.description.desc = "return standard desc plus room contents"
@setown $place.description = None
@set $thing.salient = 1

"$base.listdesc"
@newfunc $base.listdesc(self,looker)
return self.name
.x
@setown $base.listdesc = None


"$thing.listdesc"
@newfunc $thing.listdesc(self,looker)
num = randint(0,2)
if num==0:	return "You see a %s here." % self.name
if num==1:	return "There is a %s here." % self.name
return "A %s is lying here." % self.name
.x
@set $thing.listdesc.desc = 'return a line for the room contents.'
@setown $thing.listdesc = None


"$agent.listdesc"
@newfunc $agent.listdesc(self,looker)
return "%s is here." % self.name
.x
@set $agent.listdesc.desc = 'return <name> is here.'
@setown $agent.listdesc = None

"$agent.description"
@newfunc $agent.description(self,looker)
description = super(looker)
if not description:
   description = ''
if len (self.contents()):
  description = '%sCarrying:\n' % description
  for obj in self.contents():
    description = '%s  %s\n' % (description, obj.name)
return description
.x
@set $agent.description.desc = $thing.description.desc
@setown $agent.description = None

"$user.listdesc"
@newfunc $user.listdesc(self,looker)
if self.connected():
	return "%s is here." % self.name
else:
	return "%s is here (asleep)." % self.name
.x
@set $user.listdesc.desc = 'return <name> is here [(asleep)].'
@setown $user.listdesc = None


"$user.look"
@newfunc $user.look(self,atwhat=None)
if not atwhat: atwhat = self.location
# call the description function, if any
if callable(atwhat.description):
	print atwhat.description(self)
else:
	print "You see nothing special."
.x
@cmd $user.look calls look(None)
@cmd $user.look <obj> calls look(%1)
@cmd $user.look at <obj> calls look(%1)
@set $user.look.desc = "print object description."
@setown $user.look = None
@setperm $user.look = rc
@cmd $user.l calls look(None)
@cmd $user.l <obj> calls look(%1)
@cmd $user.l at <obj> calls look(%1)

%#=================== Other Basic Agent Verbs ==================
"$agent.emote"
@newfunc $agent.emote(self,str)
self.location.broadcast('%s %s ' % (self.name, str))
.x
@cmd $agent.emote <str> calls emote(%1)
@set $agent.emote.desc = "strike a pose"
@setown $agent.emote = None
@setperm $agent.emote = rc

"$agent.get"
@newfunc $agent.get(self,dobj)
if not self.wizard:
  if dobj.location != self.location:
    print "The", dobj.name, "doesn't seem to be here."
  elif dobj.immobile == 1:
    if dobj.immobiledesc:
      print dobj.immobiledesc
      return
    else:
      print "You can't pick that up."
      return
move(dobj,self)
show( "%1N %1:(gets) %2i.", {1:self, 2:dobj} )
.x
@cmd $agent.get <obj> calls get(%1)
@cmd $agent.take <obj> calls get(%1)
@set $agent.get.desc = "get an object"
@setperm $agent.get = rc


"$agent.drop"
@newfunc $agent.drop(self,dobj,dest)
if dobj.location != self:
  self.tell("You don't have that.")
  return
if callable(dest.accept): OK = dest.accept(dobj)
else: OK = dest.accept
if not OK:
  self.tell("You cannot drop that there.")
  return
move(dobj, dest)
show( "%1I %1:(drops) %2i.", {1:self, 2:dobj} )
.x
@cmd $agent.drop <obj> calls drop(%1,here)
@cmd $agent.drop <obj> in <obj> calls drop(%1,%2)
@cmd $agent.drop <obj> into <obj> calls drop(%1,%2)
@set $agent.drop.desc = "drop an object"
@setperm $agent.drop = rc


"$user.inventory"
@newfunc $user.inventory(self)
if not self.contents and not self.__credits:
	print "You are empty-handed."
else:
	print "You have", self.__credits,
	if self.__credits == 1: print "credit,",
	else: print "credits,",
	if not self.contents():
		print "and are carrying nothing."
	else:
		print "and are carrying:"
		for item in self.contents():
			print "   -", item.name
.x
@cmd $user.inventory calls inventory()
@cmd $user.inv calls inventory()
@cmd $user.i calls inventory()
@set $user.inventory.desc = "print credits and contents"
@setown $user.inventory = None
@setperm $user.inventory = rc


"$agent.@home"
@newfunc $agent.at_home(self)
oldroom = self.location
newroom = self.home
newroom.broadcast("%s comes home." % self.name)
move(self,newroom)
print "There's no place like home..."
print "There's no place like home..."
print "There's no place like home..."
oldroom.broadcast("%s heads home." % self.name)
self.do_cmd('look')
.x
@cmd $agent.@home calls at_home()
@set $agent.at_home.desc = "teleport to self.home"
@setperm $agent.at_home = rc


"$agent.@sethome"
@newfunc $agent.sethome(self)
if self.location.owner == self or self.location.public_home:
        self.home = self.location
        print "This is now your home."
else:
        print "This room belongs to %s, and is not a public home." % self.location.owner.name
.x
@cmd $agent.@sethome calls sethome()
@set $agent.sethome.desc = "self.home = self.location"
@setperm $agent.sethome = rc


%#============= More Building & Coding Support ============
@newfunc $coder.delcmd(self, obj, pattern)
verb = string.split(pattern)[0]
obj.setCmdDef(verb, pattern, None)
print verb, "command removed from", obj
.x
@cmd $coder.@delcmd <obj>.<str> calls delcmd(%1,%2)
@set $coder.delcmd.desc = "delete a CmdDef"
@setown $coder.delcmd = None
@setperm $coder.delcmd = rc


@newfunc $builder.recycle(self,what)
# make sure it's OK
if what.owner != self and not self.wizard:
	print "That is not yours to recycle!"
	return
# do the deed
destroy( what )
print "Thank you for recycling!"
.x
@cmd $builder.@recycle <obj> calls recycle(%1)
@set $builder.recycle.desc = "destroy a POO object"
@setperm $builder.recycle = rc


"$builder.showprops"
@newfunc $builder.showprops(self,what,header='',test=None)
if header:
	print header
	print "-" * len(header)
if test==None: test = lambda x:1
for p in filter(test,what.proplist()):
	try:
		text = tostr(getattr(what,p))
		if len(text) > 50: text = text[:47] + '...'
		pr = what.getprop(p)
		if (pr):
			print "%-15s %-50s %5s %4s" % (p,text,pr.owner,pr.permstr())
		else:
			print "%-15s %-50s  (built-in)" % (p,text)
	except:
		print "%-15s [ can't read ]" % p
.x
@set $coder.showprops.desc = "print props which test true"
@setown $coder.showprops = None

"$builder.@ex"
@newfunc $builder.exprops(self,dobj)
if type(dobj) != InstanceType:
	print "ex what?!?"
	return
self.showprops( dobj, \
	'Properties of %s ("%s")' % (dobj, dobj.name) )
.x
@cmd $builder.@ex <obj> calls exprops(%1)
@set $builder.exprops.desc = "list all properties on dobj"
@setown $builder.exprops = None
@setperm $builder.exprops = rc


"$builder.@dir"
@newfunc $builder.dir(self,dobj)
if not dobj: dobj = self.curpath
self.showprops( dobj, \
	'Object Refs of %s ("%s")' % (dobj, dobj.name), 
	lambda x,y=dobj: x != 'owner' and x != 'location'	\
		and type(getattr(y,x)) == InstanceType and
		getattr(y,x).__class__ != Func )
.x
@cmd $builder.@dir <obj> calls dir(%1)
@set $builder.dir.desc = "list object references on dobj"
@setown $builder.dir = None
@setperm $builder.dir = rc


%#==================== Exits ====================
@create $thing as exit
@set #0.exit = exit
@set exit.salient = 0
@set exit.dest = None
@set exit.immobile = 1
@set exit.f = 1


"$exit.lockcheck"
@newfunc $exit.lockcheck(self,invoker,lock)
.da
if lock == None: return 1
if callable (lock): return self.lock(invoker)
if type (lock) == type([]):
  for x in lock:
    if self.lockcheck(invoker,x): return 1 # recurse
  return 0
if type (lock) == type (invoker): return lock == invoker
if type (lock) == type (''): return invoker.name == lock
.x
@set $exit.invoke.desc = "check the lock on exit"


"$exit.invoke"
@newfunc $exit.invoke(self,invoker=None)
if not invoker: invoker = user
if not self.dest:
	print self.name,"leads nowhere."
	return
if not self.lockcheck(invoker, self.lock):
  if self.fail:
    if callable (self.fail): self.fail (invoker)
    else: show (self.fail, {1:invoker, 2:self})
  else:
    show ("%1N %1:(tries) to go %2n and %1:(fails).", {1:invoker, 2:self})
  return
oldroom = invoker.location
if self.success:
  if callable (self.success): self.success (invoker)
  else: show (self.success, {1:invoker, 2:self})
else: show ("%1N %1:(goes) %2n.", {1:invoker, 2:self})
move(invoker,self.dest)
if self.drop:
  if callable (self.drop): self.success (invoker)
  else: show (self.drop, {1:invoker, 2:self})
else: show ("%1N %1:(enters) the room.", {1:invoker}, 2)
if hasattr(invoker,'do_cmd'): invoker.do_cmd('look')
.x
@set $exit.invoke.desc = "move caller to .dest"
@cmd $exit.<this> calls invoke()
@cmd $exit.go <this> calls invoke()


%#==================== Directories =====================
"$dir.description"
@newfunc $dir.description(self,looker)
desc = "Directory: %s\n" % self.name
if self.desc: desc = "%s%s\n" % (desc, self.desc)
# then add a list of room contents
for item in self.contents():
	if item!=looker:
		desc = "%s\n    " % (desc, item.name)
return desc
.x
@set $dir.description.desc = "List name, desc, and contents"
@setown $dir.description = None


"$dir.enter"
@newfunc $dir.enter(self,who)
if self.owner == who or who.wizard or self.r:
	move(who,self)
	who.do_cmd('look')
else:
	print "You do not have permission to enter that directory."
.x
@cmd $dir.enter <this> calls enter(caller)
@set $dir.enter.desc = "Enter a directory."
@setperm $dir.enter = rc


"$dir.up"
@newfunc $dir.up(self,who)
move(who,self.location)
who.do_cmd('look')
.x
@cmd $dir.up calls up(caller)
@set $dir.up.desc = "Go to the object containing this directory."
@setperm $dir.up = rc


%#================= Initial Geography =================
@create $thing as Void
@set #0.void = Void
@set Void.desc = "This object contains the main directories and the universe of rooms in the system."
@set Void.accept = 1
%move(getObj('$void'),None)

@create $place as Universe
@set #0.universe = Universe
@set Universe.desc = "This room should contain all other rooms in the game.  Thus, by broadcasting a message here, everyone will hear it."
beam Universe to $void
@create $place as Newbie Room
@set $agent.home = Newbie Room
beam $agent.home to $universe
@home
@set here.desc = "This room is $agent.home, so new users have their home here by default."

@create $dir as root
@set #0.root = root
beam $root to $void

@create $dir as sys
@set #0.sys = sys
beam sys to $root

@create $dir as pub
@set #0.pub = pub
beam pub to $root

@create $dir as usr
@set #0.usr = usr
beam usr to $root


@create $dir as rooms
beam $place to rooms
beam rooms to $pub
@create $dir as exits
beam $exit to exits
beam exits to $pub
@create $dir as containers
beam containers to $pub
@create $dir as periodic
beam periodic to $pub
@create $dir as misc
beam $thing to misc
beam $agent to misc
beam misc to $pub

@create $dir as usertypes
beam $user to usertypes
beam $builder to usertypes
beam $coder to usertypes
beam $wiz to usertypes
beam usertypes to $sys


%#================= Nonvital (but handy!) functions ==============

%#------- extra functions on $agent -------
"$agent.give"
@newfunc $agent.give(self,what,toWhom)
if type(what) != IntType or type(toWhom) != InstanceType:
	print "Usage: Give <number of credits> to <user|object>"
	return
if what < 0:
	print "Nice try!"
	return
transfer( self, toWhom, what )
print "You give %s credits to %s" % (what, toWhom.name)
toWhom.tell("%s gives you %s credits." % (self.name, what))
.x
@cmd $agent.give <int> to <obj> calls give(%1,%2)
@cmd $agent.give <obj> <int> calls give(%2,%1)
@set $agent.give.desc = "give credits to another user or object"
@setperm $agent.give = rc


"$agent.@page"
@newfunc $agent.page(self,whom,msg)
# find recipient
if type(whom) == StringType:
    matches = filter( lambda x,y=whom:x.name == y, users() )
    if not matches:
        print whom, "is not logged in."
        return
    whom = matches[0]

# is recipient accepting pages?
if whom.nopage:
    print whom.name, "is not accepting pages."
    return
    
# send the message
whom.tell('%s pages you from %s with: "%s".' % (self.name, self.location.name, msg))
print "Message sent."
.x
@cmd $agent.@page <str> with <str> calls page(%1,%2)
@cmd $agent.@page <str> = <str> calls page(%1,%2)
@cmd $agent.@page <str>=<str> calls page(%1,%2)
@set $agent.page.desc = "send a message to a user"
@setperm $agent.page = rc


%#------- extra functions on $user -------

"$user.@password"
@newfunc $user.passwd(self,newpassword)
setattr(self,'password',md5.new(newpassword).digest())
print "Password changed to:", newpassword
.x
@cmd $user.@password <str> calls passwd(%1)
@set $user.passwd.desc = "set password (encrypted)"
@setperm $user.passwd = rc

@newfunc setprompt(self,prompt) on $user
if prompt == 'default':
	user._prompt = 'poo>'
	print "Prompt reset to the default."
else:
	user._prompt = prompt
	print "Prompt set."
.x
@set $user.setprompt.desc = "set prompt"
@setperm $user.setprompt = rc
@cmd $user.@setprompt  calls setprompt(%1)

"$user.@who"
@newfunc $user.who(self)
.da
us = users()
if len(us)==1: print "There is 1 user",
else: print "There are", len(us), "users",
print "currently connected:"
now = time.time()
print "   %- 23s %- 23s %- 11s  %- 11s" % ('Name','Location','On','Idle')
print "   %- 23s %- 23s %- 11s  %- 11s" % ('----','--------', \
  '-----------','-----------')
for user in us:
	name = user.name
	location = user.location.name
	if self.wizard:
	  name = "%s [#%s]" % (name, user.id)
	  location = "%s [#%s]" % (location, user.location.id)
	try: ontime = int (now - user.loginTime)
	except: ontime = 0
	try: actime = int (now - user.activeTime)
	except: actime = 0
	print "   %-23s %-23s %2dh %2dm %2ds  %2dh %2dm %2ds" % \
		(name, location, \
		 ontime/3600, (ontime%3600)/60, ontime%60, \
		 actime/3600, (actime%3600)/60, actime%60)
.x
@cmd $user.who calls who()
@cmd $user.@who calls who()
@set $user.who.desc = "list connected users + some info"
@setperm $user.who = rc


"$user.help"
@newfunc $user.printHelp(self,topic='')
print "topic: ", topic
if type(topic) == InstanceType:
	if not topic.help:
		print help(topic.name)
	elif type(topic.help) == ListType or type(topic.help) == TupleType:
		print string.join(dobj.help,'\n')
	else:
		print topic.help
else:
    print help(topic)
.x
@cmd $user.help calls printHelp()
@cmd $user.help <obj> calls printHelp(%1)
@cmd $user.help <str> calls printHelp(%1)
@cmd $user.@help calls printHelp()
@cmd $user.@help <obj> calls printHelp(%1)
@cmd $user.@help <str> calls printHelp(%1)
@set $user.printHelp.desc = "access the help database"
@setown $user.printHelp = None
@setperm $user.printHelp = rc


%#------- extra functions on $builder -------
@newfunc $builder.delprop(self,obj,propname)
delattr( obj, propname )
print "Property '%s' deleted from %s" % (propname, obj)
.x
@cmd $builder.@delprop <obj>.<propname> calls delprop(%1,%2)
@set $builder.delprop.desc = "delete a MOOP property"
@setown $builder.delprop = None
@setperm $builder.delprop = rc


"$builder.@dig"
@newfunc $builder.dig(self, dir, newroom)
# parse common directions
map = {	'n':	('north', 's'),
		'e':	('east', 'w'),
		's':	('south', 'n'),
		'w':	('west', 'e'),
		'ne':	('northeast', 'sw'),
		'se':	('southeast', 'nw'),
		'sw':	('southwest', 'ne'),
		'nw':	('northwest', 'se'),
		'u':	('up', 'd'),
		'd':	('down', 'u') }
if dir not in map.keys():
    print "Direction", dir, "not recognized; command aborted."
    return
tup = map[dir]
names = [tup[0], dir]
revnames = [ map[tup[1]][0], tup[1] ]	

# check for existing exit
if (filter(lambda x,y=names[0]: x.name==y, self.location.contents())):
    print "Looks like there's already an exit %s.  Command aborted." % names[0]
    return
# create the room; place in same location as this room
if type(newroom) != InstanceType:
    newroom = create( self, getObj('$place'), newroom )
    move( newroom, self.location.location )
    print "%s created as object %s and moved to %s (%s)" % (newroom.name, newroom, newroom.location, newroom.location.name)
exitThere = create( self, getObj('$exit'), names[0] )
exitThere.aliases = names[1:]
exitThere.dest = newroom
exitThere.getprop('dest').owner = self
move( exitThere, self.location )
print "Exit %s created in %s as object %s" % (exitThere.name, self.location.name, exitThere)
exitHere = create( self, getObj('$exit'), revnames[0] )
exitHere.aliases = revnames[1:]
exitHere.dest = self.location
exitHere.getprop('dest').owner = self
move( exitHere, newroom )
print "Exit %s created in %s as object %s" % (exitHere.name, newroom.name, exitHere)
.x
@cmd $builder.@dig <str> to <str> calls dig(%1,%2)
@cmd $builder.@dig <str> to <obj> calls dig(%1,%2)
@set $builder.dig.desc = "create a room connected to the current one"
@setperm $builder.dig = rc

@newfunc $builder.at_contents(self,obj,parobj=None)
.da
objlist = obj.contents ()
if parobj:
  objlist = filter (lambda x,y=getObj(parobj):y in x.parents, objlist)
for o in objlist:
  print '%s [#%d]' % (o.name, o.id)
objlist = None
.x
@cmd $builder.@contents <obj> calls at_contents(%1)
@set $builder.at_contents.desc = "lists the contents of an object"
@setperm $builder.at_contents = rc


@cmd $builder.@exits <obj> calls at_contents(%1,'$exit')
@cmd $builder.@exits calls at_contents(here,'$exit')


"$builder.@renprop"
@newfunc $builder.renprop(self,obj,oldname,newname )
setattr( obj, newname, getattr(obj,oldname) )
delattr( obj, oldname )
print "Property %s on %s renamed to %s." % (oldname, obj, newname)
.x
@cmd $builder.@renprop <obj>.<propname> to <propname> calls renprop(%1,%2,%3)
@set $builder.renprop.desc = "rename a MOOP property"
@setown $builder.renprop = None
@setperm $builder.renprop = rc


"$builder.@edit"
@newfunc $builder.edit(self,obj,propname)
# find object reference and prop name
# if prop doesn't exist, create an empty tuple
if not getattr(obj,propname):
    setattr( obj, propname, () )
# start editing
self.startEdit( obj, propname )
.x
@cmd $builder.@edit <obj>.<propname> calls edit(%1,%2)
@set $builder.edit.desc = "edit a list, tuple, or function"
@setown $builder.edit = None
@setperm $builder.edit = rc


"$builder.@list"
@newfunc $builder.list(self,obj,propname,fromLine=1,toLine=99999)
dobj = getattr(obj,propname)
if type(dobj) == ListType or type(dobj) == TupleType:
	for line in dobj[fromLine-1:toLine]: print line
else:
	print "Unable to list data of type", type(dobj)
.x
@cmd $builder.@list <obj>.<propname> calls list(%1,%2)
@cmd $builder.@list <obj>.<propname> <int> calls list(%1,%2,%3,%3)
@cmd $builder.@list <obj>.<propname> <int>- calls list(%1,%2,%3)
@cmd $builder.@list <obj>.<propname> -<int> calls list(%1,%2,1,%3)
@cmd $builder.@list <obj>.<propname> <int>-<int> calls list(%1,%2,%3,%4)
@set $builder.list.desc = "list a tuple or list"
@setown $builder.list = None
@setperm $builder.list = rc


%#------- extra functions on $coder -------
"$coder.@list"
@newfunc $coder.list(self,obj,propname,fromLine=1,toLine=99999)
dobj = getattr(obj,propname)
if type(dobj) == InstanceType and dobj.__class__ == Func:
	dobj.list(fromLine, toLine)
else: super(obj,propname,fromLine,toLine)
.x
@cmd $coder.@list <obj>.<propname> calls list(%1,%2)
@cmd $coder.@list <obj>.<propname> <int> calls list(%1,%2,%3,%3)
@cmd $coder.@list <obj>.<propname> <int>- calls list(%1,%2,%3)
@cmd $coder.@list <obj>.<propname> -<int> calls list(%1,%2,1,%3)
@cmd $coder.@list <obj>.<propname> <int>-<int> calls list(%1,%2,%3,%4)
@set $coder.list.desc = "list a function"
@setown $coder.list = None
@setperm $coder.list = rc


%#------- extra functions on $wiz -------
"$wiz.@movprop"
@newfunc $wiz.movprop(self,obj,propname,newobj)
setattr( newobj, propname, getattr(obj,propname) )
delattr( obj, propname )
print "Property", propname, "moved from", obj, "to", newobj, '.'
.x
@cmd $wiz.@movprop <obj>.<propname> to <obj> calls movprop(%1,%2,%3)
@set $wiz.movprop.desc = "move prop from one object to another"
@setown $wiz.movprop = None
@setperm $wiz.movprop = rc


"$wiz.@opassword"
@newfunc $wiz.opassword(self,newpassword,onWhom)
setattr(onWhom,'password',md5.new(newpassword).digest())
print "%s's password changed to %s" % (onWhom.name, newpassword)
.x
@cmd $wiz.@opassword <str> on <obj> calls opassword(%1,%2)
@cmd $wiz.@opassword <str> for <obj> calls opassword(%1,%2)
@set $wiz.opassword.desc = "set password on another user"
@setown $wiz.opassword = None
@setperm $wiz.opassword = rc


"$wiz.@newuser"
@newfunc $wiz.newuser(self,base,name)
if type(base) != InstanceType or base.__class__ != User \
		or type(name) != StringType:
	print "Usage: @newuser <base class> as <name>"
	print " E.g.: @newuser $sys.usertypes.Coder as Monty"
	return
ob = create(self, base, name)
ob.programmer = base.programmer
ob.wizard = base.wizard
ob.owner = ob
setattr(ob, 'password',md5.new(ob.name).digest())
print base.name, ob.name, "created as object %s." % ob.id
print "Password set to", ob.name
try:
	setattr(getObj('$usr'), ob.name, ob)
	print "$usr.%s set to %s." % (ob.name, ob)
except:
	print "Couldn't set $usr.%s" % ob.name
try:
	move(ob,ob.home)
	print "User moved to %s" % ob.home
except:
	print "Can't move user home;",
	move(ob,self.location)
	print "moved to %s" % self.location
.x
@cmd $wiz.@newuser <obj> as <str> calls newuser(%1,%2)
@set $wiz.newuser.desc = "create a new user"
@setown $wiz.newuser = None
@setperm $wiz.newuser = rc


"$wiz.find"
@newfunc $wiz.find(self,name)
# search the database for the given object name
matches = filter(lambda x,a=name:x.name==a, getObj('ALL'))
if not matches:
    raise "NotFound", "No object names match: %s" % dobjstr
print "Name %s matches: %s" % (name, tostr(matches))
return matches
.x
@cmd $wiz.find <str> calls find(%1)
@set $wiz.find.desc = "find objects by name"
@setown $wiz.find = None
@setperm $wiz.find = rc

@newfunc $wiz.force(self,who,command)
if not self.wizard:
  print 'Wizard-only command, sorry.'
  return
who.do_cmd (command)
print who.name, 'forced to', command
.x
@cmd $wiz.@force <obj> = <str> calls force(%1,%2)
@cmd $wiz.@force <obj>=<str> calls force(%1,%2)
@cmd $wiz.@force <obj> to <str> calls force(%1,%2)
@set $wiz.force.desc = "force a user to execute a command"
@setperm $wiz.force = rc


%#================= $container ==============
"creating $container"
@create $thing as container
@set container.f = 1
@set container.accept = 1
@set #0.container = container
beam container to $pub.containers


"$container.get"
@newfunc $container.getContent(self,itemName,who)
cont = self.contents()
matches = filter(lambda x,a=itemName:x.name==a, cont)
if not matches:
	matches = filter(lambda x,a=itemName:x.aliases and a in x.aliases,
			cont)
if not matches:
	print "Get WHAT from the %s?!?" % self.name
else:
	what = matches[0]
	move( what, who )
	show( "%1I %1:(gets) %2i from %3i.", {1:who, 2:what, 3:self} )
.x
@cmd $container.get <str> from <this> calls getContent(%1,caller)
@cmd $container.get <str> out of <this> calls getContent(%1,caller)
@cmd $container.get <str> in <this> calls getContent(%1,caller)
@set $container.getContent.desc = "get object from contents"
@setperm $container.getContent = rc


"$container.put"
@newfunc $container.put(self,what,who)
if what.location != who:
  print "You don't seem to have the %s." % what.name
  return
move(what,self)
show( "%1I %1:(puts) %2i into %3i.", {1:who, 2:what, 3:self} )
.x
@cmd $container.put <obj> into <this> calls put(%1,caller)
@cmd $container.put <obj> in <this> calls put(%1,caller)
@set $container.put.desc = "put object into contents"
@setperm $container.put = rc

"$container.description"
@newfunc $container.description(self,looker)
# first, get standard description
desc = super(looker)
# then add list of contents
items = filter( lambda x:x.salient, self.contents() )
if not items:
	desc = "%s\nThe %s appears to be empty." % (desc, self.name)
else:
	desc = desc +  "\nThe %s contains:\n" % (self.name)
	for i in items:
		desc = "%s    %s\n" % (desc, i.name)
return desc
.x
@set $container.description.desc = "list contents after description"
@setown $container.description = None

@newfunc #0.login(self,who)
who.do_cmd ("emote has connected.")
who.do_cmd ("look")
.x

@newfunc #0.logout(self,who)
who.do_cmd ("emote has disconnected.")
who.do_cmd ("@home")
.x
