;##########  bootstrap.txt  ###########
;# Last updated:  5/25/99   J. Strout #
;######################################

;# 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", propname, "on", 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 "$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 " + `excluding`
.x
@set $thing.broadcast.desc = 'tell self and contents'
@setown $thing.broadcast = None


;print "$agent.say"
@newfunc $agent.say(self,str)
if str[0] == '"' or str[0] == "'": str = str[1:]
if str[-1] == '"' or str[-1] == "'": str = str[:-1]
self.location.broadcast( self.name + ' says, "' + str + '"', [self])
print 'You say, "' + 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 #" + str(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 obj.name, "beamed to", 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')
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 = self.name + '\n' + super(looker) + '\n'
# then add a list of room contents
for item in self.contents():
	if item!=looker and item.salient:
		desc = desc + "\n	 " + 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 " + self.name + " here."
if num==1:	return "There is a " + self.name + " here."
return "A " + self.name + " is lying here."
.x
@set $thing.listdesc.desc = 'return a line for the room contents.'
@setown $thing.listdesc = None


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


"$user.listdesc"
@newfunc $user.listdesc(self,looker)
if self.connected():
	return self.name + " is here."
else:
	return self.name + " is here (asleep)."
.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


;#=================== Other Basic Agent Verbs ==================
"$agent.emote"
@newfunc $agent.emote(self,str)
if str[0] == '"' or str[0] == "'": str = str[1:]
if str[-1] == '"' or str[-1] == "'": str = str[:-1]
if str[-1] != '.' and str[-1] != '!' and str[-1] != '?':
		str = str + '.'
self.location.broadcast( 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 dobj.location != self.location:
	print "The", dobj.name, "doesn't seem to be here."
elif dobj.immobile == 1:
	if dobj.immobiledesc:
		print dobj.immobiledesc
	else:
		print "You can't pick that up."
else:
	move(dobj,self)
	show( "%1I %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)
if dobj.location != self:
	self.tell("You don't have that.")
else:
	move(dobj, self.location)
	show( "%1I %1:(drops) %2i.", {1:self, 2:dobj} )
.x
@cmd $agent.drop <obj> calls drop(%1)
@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(self.name+" comes home.")
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(self.name+" heads home.")
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 " + self.location.owner.name \
                + ", and is not a public home."
.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 " + str(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 " + str(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.invoke"
@newfunc $exit.invoke(self,invoker=None)
if not invoker: invoker = user
if not self.dest:
	print self.name,"leads nowhere."
	return
oldroom = invoker.location
self.dest.broadcast(invoker.name+" enters the room.")
move(invoker,self.dest)
if self.name != "exit" and self.name != "out":
	oldroom.broadcast(invoker.name+" exits "+self.name+".")
else:
	oldroom.broadcast(invoker.name+" exits.")
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: " + self.name + '\n'
if self.desc: desc = desc + self.desc + '\n'
# then add a list of room contents
for item in self.contents():
	if item!=looker:
		desc = desc + "\n	 " + 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", what, "credits to", toWhom.name + "."
toWhom.tell( self.name + " gives you " + str(what) + " credits." )
.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( self.name, "pages you from", self.location.name,
        'with: "' + 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


"$user.@who"
@newfunc $user.who(self)
us = users()
if len(us)==1: print "There is 1 user",
else: print "There are", len(us), "users",
print "currently connected:"
now = time()
print "   %-23s %-23s %-11s  %-11s" % ('Name','Location','    On','   Idle')
print "   %-23s %-23s %-11s  %-11s" % ('----','--------','-----------','-----------')
for user in us:
	ontime = int( now - user.loginTime )
	actime = int( now - user.activeTime )
	print "   %-23s %-23s %2dh %2dm %2ds  %2dh %2dm %2ds" % \
		(user.name, user.location.name, \
		 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='')
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)
@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 '" + propname + "' deleted from", obj
.x
@cmd $builder.@delprop <obj>.<propname> calls delprop(%1,%2)
@set $builder.delprop.desc = "delete a POO 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", names[0]+".  Command aborted."
    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 newroom.name, "created as object", newroom, \
    	"and moved to", 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", exitThere.name, "created in",  \
            self.location.name, "as object", 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", exitHere.name, "created in",  \
        newroom.name, "as object", 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


"$builder.@renprop"
@newfunc $builder.renprop(self,obj,oldname,newname )
setattr( obj, newname, getattr(obj,oldname) )
delattr( obj, oldname )
print "Property", oldname, "on", obj, "renamed to", newname+"."
.x
@cmd $builder.@renprop <obj>.<propname> to <propname> calls renprop(%1,%2,%3)
@set $builder.renprop.desc = "rename a POO 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 onWhom.name + "'s password changed to", 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", str(ob.id)+"."
print "Password set to", ob.name
try:
	setattr(getObj('$usr'), ob.name, ob)
	print "$usr." + ob.name, "set to", ob
except:
	print "Couldn't set $usr." + ob.name
try:
	move(ob,ob.home)
	print "User moved to", ob.home
except:
	print "Can't move user home;",
	move(ob,self.location)
	print "moved to", 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: "+dobjstr
print "Name", name, "matches: ", 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


;#================= $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", 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", what.name+"."
else:
	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 = desc +  "\nThe " + self.name + " appears to be empty."
else:
	desc = desc +  "\nThe " + self.name + " contains:\n"
	for i in items:
		desc = desc + "    " + i.name + '\n'
return desc
.x
@set $container.description.desc = "list contents after description"
@setown $container.description = None