===== **help $lock_utils** ==============================

**lock utilities (#53):
----**

lock utilities (#53) [ readable ] Owned by ScarFace (#2). Child of Generic Utilities Package (#79).#53:canonicalize_spaces #53:eval_key #53:eval_key_new #53:init_scanner #53:match_object #53:parse_A #53:parse_A_new #53:parse_E #53:parse_keyexp #53:scan_token #53:unparse_key

For more information on keys and locking, read `help locking', `help keys', and `help @lock'.:parse_keyexp (string keyexpression, object player)=> returns an object or list for the new key as defined by the keyexpression or a string describing the error if it failed.:eval_key (LIST|OBJ key, testobject)=> returns true if the given testobject satisfies the key.:unparse_key (LIST|OBJ key)=> returns a string describing the key in english/moo-code terms.

----

eval_key(LIST|OBJ coded key, OBJ testobject) => returns true if testobject will solve the provided key.

----

used by $lock_utils to unparse a key expression so one can use `here' and `me' as well as doing the regular object matching.

----

parse_keyexp(STRING keyexpression, OBJ player) => returns a list containing the coded key, or a string containing an error message if the attempt failed.

Grammar for key expressions:

E ::= A | E || A | E && A A ::= ( E ) | ! A | object | ? object

----

:unparse_key(LIST|OBJ coded key) => returns a string describing the key in english/moo-code terms.

Example:

$lock_utils:unparse_key({"||", $hacker, $housekeeper}) => "#18105[Hacker] || #36830[housekeeper]"

===== **help $match_utils** ============================

**matching utilities (#51):
----**

matching utilities (#51) [ readable ] Owned by Hacker (#37). Child of Generic Utilities Package (#79).#51:match #51:match_list #51:match_nth #51:match_verb #51:object_match_failed #51:"parse_ordinal_reference parse_ordref" #51:parse_possessive_reference

----

:match(string, object-list)

Return object in 'object-list' aliased to 'string'.

Matches on a wide variety of syntax, including:

"5th axe" -- The fifth object matching "axe" in the object list.

"where's sai" -- The only object contained in 'where' matching "sai" (possible $ambiguous_match).

"where's second staff" -- The second object contained in 'where' matching "staff".

"my third dagger" -- The third object in your inventory matching "dagger". Ordinal matches are determined according to the match's position in 'object-list' or, if a possessive (such as "where" above) is given, then the ordinal is the nth match in that object's inventory.

In the matching room (#3879@LambdaMOO), the 'object-list' consists of first the player's contents, then the room's, and finally all exits leading from the room.

----

:match_list(string, object_list) -> List of all matches.

----

:match_nth(string, objlist, n)

Find the nth object in 'objlist' that matches 'string'.

----

$match_utils:match_verb(verbname, object) => Looks for a command-line style verb named <verbname> on <object> with current values of prepstr, dobjstr, dobj, iobjstr, and iobj. If a match is made, the verb is called with @args[3] as arguments and 1 is returned. Otherwise, 0 is returned.

----

Usage: object_match_failed(object, string[, ambigs])

Prints a message if string does not match object. Generally used after object is derived from a :match_object(string).

ambigs is an optional list of the objects that were matched upon. If given, the message printed will list the ambiguous among them as choices.

----

:parse_ordref(string)

Parses strings referring to an 'nth' object.

=> {NUM n, STR object} Where 'n' is the number the ordinal represents, and 'object' is the rest of the string.

=> 0 If the given string is not an ordinal reference. Example:

:parse_ordref("second broadsword") => {2, "broadsword"}

:parse_ordref("second") => 0

Note that there must be more to the string than the ordinal alone.

----

:parse_possessive_reference(string)

Parses strings in a possessive format.

=> {STR whose, STR object} Where 'whose' is the possessor of 'object'. If the string consists only of a possessive string (ie: "my", or "yduJ's"), then 'object' will be an empty string.

=> 0 If the given string is not a possessive reference.

Example:

:parse_possessive_reference("joe's cat") => {"joe", "cat"}

:parse_possessive_reference("sis' fish") => {"sis", "fish"}

Strings are returned as a value suitable for a :match routine, thus 'my' becoming 'me'.

:parse_possessive_reference("my dog") => {"me", "dog"}

===== **help $Math_Utils** ============================

**Math Utilities (#27):
----**

Math Utilities (#27) [ readable ] Owned by Hacker (#37). Child of Generic Utilities Package (#79).

**Trigonometric/Exponential functions:**

sin(a),cos(a),tan(a)-- returns 10000*(the value of the corresponding trigonometric function) angle a is in degrees.arctan([x,]y)-- returns arctan(y/x) in degrees in the range -179..180. x defaults to 10000. Quadrant is that of (x,y).exp(x[,n])-- calculates e^x with an nth order taylor polynomial

combinations(n,r)-- returns the number of combinations given n objects taken r at a time.permutations(n,r)-- returns the number of permutations possible given n objects taken r at a time.

div(n,d)-- correct version of / (handles negative numbers correctly)mod(n,d)-- correct version of % (handles negative numbers correctly)divmod(n,d)-- {div(n,d),mod(n,d)}parts(n,q[,i])-- returns a list of two elements {integer,decimal fraction}

sqrt(x)-- returns the largest integer n <= the square root of xpow(x,n)-- returns x^nfactorial(x)-- returns x!

fibonacci(n)-- returns the 1st n fibonacci numbers in a listgeometric(x,n)-- returns the value of the nth order geometric series at x

gcd(a,b)-- find the greatest common divisor of the two numberslcm(a,b)-- find the least common multiple of the two numbersare_relatively_prime(a,b)-- return 1 if a and b are relatively primeis_prime(n)-- returns 1 if the number is a prime and 0 otherwise

random(n)-- returns a random number from 0..n if n > 0 or n..0 if n < 0random_range(n[,mean])-- returns a random number from mean - n..mean + n with mean defaulting to 0simpson({a,b},{f(a),f((a+b)/2),f(b)})-- returns the numerical approximation of an integral using simpson's rule

AND(x,y)-- returns x AND yOR(x,y)-- returns x OR yXOR(x,y)-- returns x XOR y (XOR is the exclusive-or function)NOT(x)-- returns the complement of xAll bitwise manipulation is of 32-bit values.

----

returns 10000 exp (x/10000)

The accuracy seems to be ~0.1% for 0<x<4

----

arctan(y/x) == arctan(x,y) => angle in degrees.

----

are_rel_prime(num1,num2): returns 1 if num1 and num2 are relatively prime.

since we have gcd, this is pretty easy.

----

Call with first arg either a number or a string, being the number desired for conversion. capital letters denote values from 10-35; lowercase letters from 36 to 61. Maximal base is 62.

You will be unable to use the extra 26 lowercases as separate unless you pass a nonzero fourth argument. Passing zero or none uses the default value, which is to have AAAA=aaaa.

The second and third arguments should be the base of the number and the base you want it in, respectively.

Any of the arguments can be strings or nums, but high-base numbers will need to be strings. This returns a string.

Any problems, talk to Ozymandias.

----

cos(x) -- given x in degrees, cos(x) will return cosine evaluated at x times 10000

----

combinations(n,r) -- returns the number of ways one can choose r objects from n distinct choices.

C(n,r) = n!/[r!(n-r)!] overflow may occur if n>29...

----

div(n,d) => q such that n = dq + r and (0<=r<d if d>0, -d<r<=0 if d<0).

----

divmod(n,d) => {q,r} such that n = dq + r handles negative numbers correctly 0<=r<d if d>0, -d<r<=0 if d<0.

----

exp(x[,n]) -- calculates an nth order taylor approximation for e^x.

n defaults to 5. Any n given must be >= 0. you need to divide the result the answer will be returned as {integer part,fractional part}

----

factorial(n) -- returns n factorial for 0 <= n (<= 12).

----

fibonacci(n) -- calculates the fibonacci numbers to the nth term and returns them in a list. n must be >= 0.

----

gcd(num1,num2): find the greatest common divisor of the two numbers using the division algorithm. the absolute values of num1 and num2 are used without loss of generality.

----

geometric(x,n) -- calculates the value of the geometric series at x to the nth term. i.e., approximates 1/(1-x) when |x| < 1. this, of course, is impossible in MOO, but someone may find it useful in some way. n defaults to 5. n must be >= 0.

----

is_prime(number) returns 1 if the number is prime or 0 if it isn't.

of course, only positive numbers are candidates for primality.

----

lcm(num1,num2): find the least common multiple of the two numbers. we shall use the positive lcm value without loss of generality. since we have gcd already, we'll just use lcm*gcd = num1*num2

----

A correct mod function.

mod(n,d) => r such that n = dq + r and (0<=r<d if d>0 or -d<r<=0 if d<0).

----

:norm(a,b,c,d...) => sqrt(a^2+b^2+c^2+...)

----

parts(n,q[,i]) -- returns a decomposition of n by q into integer and floating point parts with i = the number of digits after the decimal.

i defaults to 5.

warning: it is quite easy to hit maxint which results in unpredictable results

----

permutations(n,r) -- returns the number of ways possible for one to order r distinct objects given n locations.

P(n,r) = n!/(n-r)!

----

pow(x,n) -- returns x raised to the nth power. n must be >= 0.

----

random(): returns a random number in the following manner:

random(n > 0) will return a number in the range 0 to n

random(n < 0) will return a number in the range n to 0

----

random_range(range [,mean]): returns a random number within the given range from the mean. if the mean isn't given, it defaults to 0

e.g., random_range(10) => -10..10

random_range(10,4) => -6..14

----

simpson({a,b},{f(a),f((a+b)/2),f(b)}) -- given two endpoints, a and b, and the functions value at a, (a+b)/2, and b, this will calculate a numerical approximation of the integral using simpson's rule. the answer is returned as {integer,fraction}

----

sin(x) -- given x in degrees, sin(x) will return the value of the sine function at x times 10000

----

:sum(num, num, num ...) => Total of all arguments added together.

----

tan(x) -- given x in degrees, tan(x) will calculate the tangent at x times 10000

----

xcos(x) -- calculates the taylor approximation for the cosine function

----

xsin(x) -- calculates the taylor approximation for the sine function

===== **help $object_utils** ============================

**object utilities (#52):
----**

object utilities (#52) [ readable ] Owned by ScarFace (#2). Child of Generic Utilities Package (#79).

#52:all_contents | #52:all_properties | #52:all_properties_suspended |

#52:all_verbs | #52:ancestors | #52:branches |

#52:branches_suspended | #52:connected | #52:contains |

#52:defines_verb | #52:"descendants descendents" | #52:"descendants_suspended descendents_suspended" |

#52:descendants_with_property_suspended | #52:findable_properties | #52:has_callable_verb |

#52:has_property | #52:has_verb | #52:isa |

#52:isoneof | #52:leaves | #52:leaves_suspended |

#52:locations | #52:match_verb | #52:ordered_descendants |

#52:owned_properties | #52:property_conflicts |

These routines are useful for finding out information about individual objects.

**Examining everything an object has defined on it:**

all_verbs (object)=> like it saysall_properties (object)=> likewisefindable_properties(object)=> tests to see if caller can "find" themowned_properties (object[, owner])=> tests for ownership

ancestors(object[,object...])=> all ancestorsdescendants (object)=> all descendantsordered_descendants(object)=> descendants, in a different orderleaves (object)=> descendants with no childrenbranches (object)=> descendants with childrenisa (object,class)=> true iff object is a descendant of class (or ==)property_conflicts (object,newparent)=> can object chparent to newparent?isoneof (object,list)=> true if object :isa class in list of parents

contains (obj1, obj2)=> Does obj1 contain obj2 (nested)?all_contents (object)=> return all the (nested)contents of object locations (object)=> list of location hierarchy above object

has_property(object,pname)=> false/true according as object.(pname) existshas_verb (object,vname)=> false/{#obj} according as object:(vname) existshas_callable_verb=> same, but verb must be callable from a programdefines_verb=> does this object *define* this verbmatch_verb (object,vname)=> false/{location, newvname} (identify location and usable name of verb)

connected (object)=> true if object is a player and is connected

Many of the above verbs have ..._suspended versions to assist with very large object hierarchies.

The following exist:descendants_suspendedbranches_suspendedleaves_suspendedall_properties_suspendeddescendants_with_property_suspended

----

all_contents(object)

Return a list of all objects contained (at some level) by object.

----

Copied from object utilities (#3669):all_properties by Haakon (#2) Mon Dec 28 14:24:36 1992 PST

----

Usage: ancestors(object[, object...])

Return a list of all ancestors of the object(s) in args, with no duplicates.

If called with a single object, the result will be in order ascending up the inheritance hierarchy. If called with multiple objects, it probably won't.

----

:branches(object) => list of all descendants of object which have children.

----

:branches_suspended(object) => descendants of object having children. this version calls suspend(0) as needed

----

:connected(object) => true if object is a connected player. equivalent to (object in connected_players()) for valid players, perhaps with less server overhead.

use object:is_listening() if you want to allow for puppets and other non-player objects that still 'care' about what's said.

----

$object_utils:contains(obj1, obj2) -- does obj1 contain obj2?

Return true iff obj2 is under obj1 in the containment hierarchy; that is, if obj1 is obj2's location, or its location's location, or ...

----

:descendants_with_property_suspended(object,property) => list of descendants of object on which property is defined.

calls suspend(0) as needed

----

findable_properties(object)

Return a list of properties on those members of object's ancestor list that are readable or are owned by the caller (or all properties if the caller is a wizard).

----

Usage: has_callable_verb(object, verb)

See if an object has a verb that can be called by another verb (i.e., that has its x permission bit set).

Return {location}, where location is the object that defines the verb, or 0 if the object doesn't have the verb.

----

:has_verb(OBJ object, STR verbname)

Find out if an object has a verb matching the given verbname.

Returns {location} if so, 0 if not, where location is the object or the ancestor on which the verb is actually defined.

----

:isa(x,y) == valid(x) && (y==x || y in :ancestors(x))

----

:isoneof(x,y) = x isa z, for some z in list y

----

:leaves(object) => list of all childless descendents of object

----

:leaves_suspended(object) => list of all childless descendents of object this versions calls suspend(0) as needed

----

Usage: locations(object)

Return a listing of the location hierarchy above object.

----

:match_verb(OBJ object, STR verb)

Find out if an object has a given verb, and some information about it. Returns {OBJ location, STR verb} if matched, 0 if not.

Location is the object on which it is actually defined, verb is a name for the verb which can subsequently be used in verb_info (i.e., no asterisks).

----

owned_properties(what[, who])

Return a list of all properties on WHAT owned by WHO.

Only wizardly verbs can specify WHO; mortal verbs can only search for properties owned by their own owners. For more information, talk to Gary_Severn.

----

:property_conflicts(object,newparent)

Looks for propertyname conflicts that would keep chparent(object,newparent) from working.

Returns a list of elements of the form {<propname>, @<objectlist>} where <objectlist> is list of descendents of object defining <propname>.

===== **help $perm_utils** =============================

**Generic Utilities Package (#42):
----**

Generic Utilities Package (#42) [ readable ] Owned by ScarFace (#2). Child of Generic Utilities Package (#79).#42:apply #42:caller #42:controls #42:"controls_prop controls_property" #42:password_ok

For a complete description of a given verb, do `help $perm_utils:verbname'

:controls(who,what)-- can who write on object what:controls_property(who,what,propname)-- can who write on what.propname These routines check write flags and also the wizardliness of `who'. (these last two probably belong on $code_utils):apply(permstring,mods)-- used by @chmod to apply changes (e.g., +x) to a given permissions string:caller()-- returns the first caller in the callers() stack distinct from `this'

----

:apply(permstring,mods) => new permstring.

permstring is a permissions string, mods is a concatenation of strings of the form +<letters>, !<letters>, or -<letters>, where <letters> is a string of letters as might appear in a permissions string (`+' adds the specified permissions, `-' or `!' removes them; `-' and `!' are entirely equivalent).

----

@perm_utils:controls(who, what)

Is WHO allowed to hack on WHAT?

----

controls_prop(who, what, propname)

Is WHO allowed to hack on WHAT's PROPNAME?

----

password_ok(crypted STR, teststr STR) -> matches BOOL

Returns true if `teststr' matches `crypted' using the MOO's standard crypted checking algorithm.

===== **help $seq_utils** ===============================

**sequence utilities (#34):
----**

sequence utilities (#34) [ readable ] Owned by Hacker (#37). Child of Generic Utilities Package (#79).

A sequence is a set of integers (*)

This package supplies the following verbs:

For boolean expressions, note that the representation of the empty sequence is {} (boolean FALSE) and all non-empty sequences are represented as nonempty lists (boolean TRUE).:add (seq,f,t)=> seq with [f..t] interval added:remove (seq,f,t)=> seq with [f..t] interval removed:range (f,t)=> sequence corresponding to [f..t]{}=> empty sequence:contains (seq,n)=> n in seq:size (seq) => number of elements in seq:first (seq)=> first integer in seq or E_NONE:firstn (seq,n)=> first n integers in seq (as a sequence):last (seq)=> last integer in seq or E_NONE:lastn (seq,n)=> last n integers in seq (as a sequence):complement(seq)=> sequence consisting of integers not in seq:union (seq,seq,...)=> union of all sequences:intersect(seq,seq,...)=> intersection of all sequences:contract (seq,cseq)(see `help $seq_utils:contract'):expand (seq,eseq[,include])(see `help $seq_utils:expand'):extract(seq,array)=> array[@seq]:for([n,]seq,obj,verb,@args)=> for s in (seq) obj:verb(s,@args); endfor:tolist(seq)=> list corresponding to seq:tostr(seq)=> contents of seq as a string:from_list(list)=> sequence corresponding to list:from_sorted_list(list)=> sequence corresponding to list (assumed sorted):from_string(string)=> sequence corresponding to string

The representation used works better than the usual list implementation for sets consisting of long uninterrupted ranges of integers.

For sparse sets of integers the representation is decidedly non-optimal (though it never takes more than double the space of the usual list representation).

(*) i.e., **integers** in the range [$minint+1..$maxint]. The implementation
depends on $minint never being included in a sequence.

----

add(seq,start[,end]) => seq with range added.

remove(seq,start[,end]) => seq with range removed. both assume start<=end.

----

:complement(seq[,lower[,upper]]) => the sequence containing all integers *not* in seq.

If lower/upper are given, the resulting sequence is restricted to the specified range.

Bad things happen if seq is not a subset of [lower..upper]

----

:contains(seq,elt) => true iff elt is in seq.

----

:contract(seq,cseq)

cseq is assumed to be a finite sequence consisting of intervals [f1..a1-1],[f2..a2-1],... From seq, we remove any elements that are in those ranges and map each remaining element i to

i if i < f1 i-(a1-f1) if a1 <= i < f2 i-(a1-f1+a2-f2) if a2 <= i < f3 ...returning the resulting sequence. For any finite sequence cseq, the following always holds:

:contract(:expand(seq,cseq,include),cseq)==seq

----

:expand(seq,eseq[,include=0])

eseq is assumed to be a finite sequence consisting of intervals [f1..a1-1],[f2..a2-1],... We map each element i of seq to

i if i < f1 i+(a1-f1) if f1 <= i < f2-(a1-f1) i+(a1-f1+a2-f2) if f2-(a1-f1) <= i < f3-(a2-f2)-(a1-f1)... returning the resulting sequence if include=0,

returning the resulting sequence unioned with eseq if include=1;

----

extract(seq,array) => list of elements of array with indices in seq.

----

:firstn(seq,n) => first n elements of seq as a sequence.

----

:for([n,]seq,obj,verb,@args) => for s in (seq) obj:verb(s,@args); endfor

----

:fromlist(list) => corresponding sequence.

----

:from_sorted_list(sorted_list) => corresponding sequence.

----

:from_string(string) => corresponding sequence or E_INVARG string should be a comma separated list of numbers and number..number ranges

----

:intersection(seq1,seq2,...) => intersection of all sequences...

----

:lastn(seq,n) => last n elements of seq as a sequence.

----

:range(start,end) => sequence corresponding to [start..end] range

----

:size(seq) => number of elements in seq for sequences consisting of more than half of the 4294967298 available integers, this returns a negative number, which can either be interpreted as (cardinality - 4294967298) or -(size of complement sequence)

----

tostr(seq [,delimiter]) -- turns a sequence into a string, delimiting ranges with delimiter, defaulting to .. (e.g. 5..7)

----

:union(seq1,seq2,...) => union of all sequences...

----

:_union(seq,seq,...)

assumes all seqs are nonempty and that there are at least 2

===== **help $set_utils** ===============================

**Set Utilities (#28):
----**

Set Utilities (#28) [ readable ] Owned by Hacker (#37). Child of Generic Utilities Package (#79).#28:contains #28:diff*erence #28:"difference_suspended diff_suspended" #28:equal #28:"exclusive_or xor" #28:intersection #28:intersection_preserve_case #28:union

union(set, set, ...)=> unionintersection(set, set, ...)=> intersectionintersection_preserve_case(base set, set, set, ...)=> intersection with the case of the base set's elements preserveddiff*erence(set1, set2, ..., setn)=> result of removing all elements of sets 2..n from set 1.exclusive_or(set, set, set, ...) => all elements that are contained in exactly one of the setscontains(set1, set2, ..., setn)=> true if and only if all of sets 2..n are subsets of set 1equal(set1, set2)=> true if and only if set1 and set2 are equal

----

True if the first list given is a superset of all subsequent lists. False otherwise. {} is a superset of {} and nothing else; anything is a superset of {}. If only one list is given, return true.

----

Usage: diff(set 1, set 2, ..., set n)

Returns all elements of set 1 that are not in sets 2..n

----

Usage: diff(set 1, set 2, ..., set n)

Returns all elements of set 1 that are not in sets 2..n

----

True if the two lists given contain the same elements.

False otherwise.

----

Usage: exclusive_or(set, set, ...)

Return the set of all elements that are in exactly one of the input sets For two sets, this is the equivalent of (A u B) - (A n B).

----

Returns the set intersection of all the lists provided as arguments.

----

Copied from Fox (#54902):intersection Mon Dec 27 17:02:57 1993 PST a version of $set_utils:intersection that maintains the property that everything in the return value is in the first argument, even considering case

----

Returns the set union of all of the lists provided as arguments.