1 - The Code

This section of this book contains the code, available for viewing, editing, contributing, tweaking, etc.

That is to say, the code will be developed within this collaborative book paradigm. The 'official installation packages' will be released on ftp.pennmush.org for public download (no need to copy/paste bits and pieces out of this book - whole package compilations will be available for that purpose).

Each module will have a subsection to itself, with optional subsections thereunder (e.g., a module with 5 objects might have an intro page with 5 sub-pages, one for each object).

At least that's the initial plan. We'll see how things go, after we get some code online and some participation started.

1.0 - Official Release

This section will include all pieces of contributed code which have been selected for inclusion in the official release of the WARPEDcore.

This section's activity should, for the most part, be limited to either...

  1. a new contribution migrating into the official release from the unofficial contribution section.
  2. or...

  3. a patch or bug-fix is needed for an existing official release module

At least that's the plan. We'll see how it goes...

1.0.0 ~reboot


@@ ========================================================================
@@ .:....1....:....2....:....3....:....4....:....5....:....6....:....7....:
@@ ------------------------------------------------------------------------
@@ WARPED      ~~~~~~~~~~~~~~~~                                           ~
@@        ~~~~~~~~~        ~~~~~~~~~              WARPEDcore             ~~
@@     ~~~~~~                    ~~~~~~             ~reboot            ~~~
@@   ~~~~          Adoption          ~~~~         200609250b         ~~~~
@@  ~~~              Date              ~~~~~~                    ~~~~~~
@@ ~~             2006.09.25              ~~~~~~~~~        ~~~~~~~~~
@@ ~                                           ~~~~~~~~~~~~~~~~        core
@@ ------------------------------------------------------------------------
@@ .:....1....:....2....:....3....:....4....:....5....:....6....:....7....:
@@ ========================================================================

@@
@@ LEGAL
@@
@@ This material is released under the terms of the
@@ WARPEDcore Softcode and Documentation License (WSDL).
@@ For details, see: http://community.pennmush.org
@@
@@ USE AT YOUR OWN RISK.
@@
@@ Copyright 2006, The WARPEDcore Project
@@
@@ .:....1....:....2....:....3....:....4....:....5....:....6....:....7....:
@@
@@ README
@@
@@ PLEASE READ THIS SECTION. It is IMPORTANT!
@@
@@
@@ This is a very powerful and delicate piece of code. PLEASE read ALL
@@ of the comments VERY CAREFULLY. Most of this code must be manually
@@ installed (edit a line appropriately, copy/paste).
@@
@@ DO NOT, I repeat, DO NOT attempt to quote this file into your game!
@@
@@
@@ USE AT YOUR OWN RISK.
@@
@@
@@ .:....1....:....2....:....3....:....4....:....5....:....6....:....7....:
@@
@@ BEGIN REQUIREMENTS
@@
@@ * PennMUSH version 1.7.7p21 or newer.
@@
@@ .:....1....:....2....:....3....:....4....:....5....:....6....:....7....:
@@
@@ The Theory
@@
@@ Unless you've tweaked a great deal, your #1/startup contains one of the
@@ following:
@@
@@ a) a very long string of @<command>;@<command>;@<command>[;etc]'s.
@@
@@ b) at least one @dolist.
@@
@@ c) a combination of the above.
@@
@@ If startup sequencing is highly important, you probably have "c"
@@ (above), in which you have the most crucial items done as direct
@@ commands, followed by a dolist or two for the rest.
@@
@@ Depending on how much tweaking you've done, you may or may not have a
@@ well-organized and easily managed process.
@@
@@ That's what this package attempts to provide - a well-organized and
@@ easily managed god/startup - while also retaining as much startup
@@ precidence as possible.
@@
@@ .:....1....:....2....:....3....:....4....:....5....:....6....:....7....:
@@
@@ The 'cut' line.
@@
@@ The text above this point contains no code, and should be removed
@@ if you intend to /quote this file in some way. The recommended procedure
@@ is to read and follow the instructions and to copy, line by line, the
@@ needed pieces as you go; however, I did attempt to write this so that it
@@ could be /quoted if done so with care and responsibility. And, even if
@@ you do /quote it, you will inevitably have some manual adjustments to
@@ make when it's done.
@@
@@ ========================================================================
@@ . . C . . u . . t . . H . . e . . r . . e . .
@@ ========================================================================
@@ .:....1....:....2....:....3....:....4....:....5....:....6....:....7....:
@@ ------------------------------------------------------------------------
@@ authorship, credit, and copyright information.
@@ .:....1....:....2....:....3....:....4....:....5....:....6....:....7....:
@@
&~.legal #1=WARPEDcore~reboot, see: http://community.pennmush.org
&~.version #1=200609250b
@@
@@ ========================================================================
@@ .:....1....:....2....:....3....:....4....:....5....:....6....:....7....:
@@ ------------------------------------------------------------------------
@@
@@ data attributes
@@
@@ ------------------------------------------------------------------------
@@
@@ configs
@@
@@ .:....1....:....2....:....3....:....4....:....5....:....6....:....7....:
@@
@@ god configs
@@
@@
@@
&~`ORDER #1=0:First 1:Attribute 2:Function 3:Command 4:Hook 5-8:Unused 9:Last
@@
&~`ORDER.NOTE #1=Neither this attribute nor its contents is used by the @startup and/or ~`<reboot> code in any way. It's simply a way to store your design plan for reference (e.g., "okay, it's been 3 years since I had to make any changes to this -- now, which numeric group was I using for @commands again?"). It contains a suggested default arrangement. If you don't need it (and plan to dump everything into ~`0???), ignore it.
@@
@@ .:....1....:....2....:....3....:....4....:....5....:....6....:....7....:
@@
@@ local configs
@@
@@
&~`RENUM`INTERVAL #1=10
@@
&~`RENUM`INTERVAL.NOTE #1=This is the renumbering interval used for the auto-renumbering.
@@
@@
@@ ========================================================================
@@ .:....1....:....2....:....3....:....4....:....5....:....6....:....7....:
@@ ------------------------------------------------------------------------
@@
@@ the code.
@@
@@ ------------------------------------------------------------------------
@@
@@ functions
@@
@@ .:....1....:....2....:....3....:....4....:....5....:....6....:....7....:
@@
@@ the renumbering function
@@
@@
&~`RENUM`UFUN #1=iter(lnum(0,9), setq(0,itext(0))[iter(setr(1, filter(me/~`NNNN`FILTER, lattr(me/~`%q0???))), set(me, itext(0).TEMP:[v(itext(0))])[attrib_set(me/[itext(0)])])][iter(%q1, set(me, %q0[rjust(mul(inum(0), v(~`RENUM`INTERVAL)), 3, 0)]:[v(itext(0).TEMP)])[attrib_set(me/[itext(0)].TEMP)])])
@@
&~`RENUM`UFUN.NOTE #1=this function divides the possible 10,000 attribs into groups of 1000, by managing the first number as a separate iteration process, renumbering each group of 1000 (possible) attribs as a separate sub-process. This allows you, if you so choose, to manage groups of processes separately. For example, putting all "really super important" startup commands in STARTUP`0??? attributes, all remaining @attribute commands in STARTUP`1??? attributes, all remaining @command commands in STARTUP`2??? attributes, etc. (or, if don't have very many and don't need such subdivisions, you can put them all into the 0??? category and be done with it - you just won't be utilizing this subdividing feature). It must be operated manually (Logged into god, think u(me/~`RENUM`UFUN))
@@
&~`NNNN`FILTER #1=isnum(rest(%0,`))
@@
&~`NNNN`FILTER.NOTE #1=This is the filter to ensure that only ~`#### attributes are processed, just in case someone adds a ~`NOTE or whatever without thinking. It is used by ~`RENUM`UFUN and @startup.
@@
@@
@@ ========================================================================
@@ .:....1....:....2....:....3....:....4....:....5....:....6....:....7....:
@@ ------------------------------------------------------------------------
@@
@@ globals
@@
@@ ------------------------------------------------------------------------
@@
@@ @attribs
@@
@@ .:....1....:....2....:....3....:....4....:....5....:....6....:....7....:
@@
@@ These are @attribs needed by the WARPEDcore
@@
@@ &~`0010 #1=@attribute/access/retroactive ~=safe veiled visual no_clone
@@
@@ This prepares the ~ attribute (and subsequent tree features) for use
@@ with the WARPEDcore.
@@
@@
@@ ========================================================================
@@ .:....1....:....2....:....3....:....4....:....5....:....6....:....7....:
@@ ------------------------------------------------------------------------
@@
@@ Help
@@
@@ .:....1....:....2....:....3....:....4....:....5....:....6....:....7....:
@@
@@ No such animal.
@@
@@ ========================================================================
@@ .:....1....:....2....:....3....:....4....:....5....:....6....:....7....:
@@ ------------------------------------------------------------------------
@@
@@ activation
@@
@@ .:....1....:....2....:....3....:....4....:....5....:....6....:....7....:
@@
@@ the @startup attribute
@@
@@ .:....1....:....2....:....3....:....4....:....5....:....6....:....7....:
@@
@@ simplest conversion is...
@@
@@ first, make a backup copy of your existing #1/startup.
@@
@cpattr #1/STARTUP=#1/STARTUP.BACKUP
@@
@@ confirm the operation..
@@
ex #1/STARTUP
ex #1/STARTUP.BACKUP
@@
@@ next, copy your existing glob of goo from #1/startup to this system's
@@ "Last" numeric group, in the last entry (this assumes a 'failsafe'
@@ position for all your pre-existing code)...
@@
@cpattr #1/STARTUP=#1/~`9999
@@
@@ then, at your leisure, proceed to gradually migrate things from their
@@ current location (#1/~`9999) into their appropriate new separate
@@ attributes.
@@
@@ give #1 an appropriate new @startup.
@@
@startup #1=@dolist/delimit | [iter(sort(filter(me/~`NNNN`FILTER, lattr(me/~`????)), a), v(itext(0)), %b, |)]=##
@@
&STARTUP`NOTE #1=This makes something like "@dolist/delimit | @<command>|@<command>|@<command>[&c]=##"; and it does so in a manner which prevents non-god insertion of malicious commands. YMMV.
@@
@@ When you finish migrating everything from ~`9999 into appropriate
@@ individual attribute placements (deleting each piece from this
@@ attribute as you do so, eventually deleting this attribute as well),
@@ you can delete #1/STARTUP.BACKUP (the failsafe backup I made you create
@@ earlier in the script).
@@
@@ .:....1....:....2....:....3....:....4....:....5....:....6....:....7....:
@@
@@ The end result should be a game which, during a game restart, processes
@@ "all startup commands" in the earliest possible queue cycle that such a
@@ single action can occur. God is granted five (5) initial queue cycles
@@ during startup, in which it is allowed the unique privilege of freely
@@ cramming stuff into the queue at will, before anyone else's @startup is
@@ processed. This code attempts to use a single @dolist to get as much
@@ 'stuff' into the queue as early as possible.
@@
@@ ALSO NOTE: This code is not restricted only to #1/startup. It can be
@@ used in anything's @startup, or in @aconnect, or any other place you
@@ need to process several commands in sequence.
@@ ------------------------------------------------------------------------
@@ .:....1....:....2....:....3....:....4....:....5....:....6....:....7....:
@@ ========================================================================

Credits

  • 2007/01/11 - Concept originated with Trispis @ M*U*S*H.
  • 2007/01/11 - Design and implementation issues were tweaked and resolved with some help from Javelin and Mike @ M*U*S*H.

1.0.1 ~cron

@@ ========================================================================
@@ .:....1....:....2....:....3....:....4....:....5....:....6....:....7....:
@@ ------------------------------------------------------------------------
@@ WARPED      ~~~~~~~~~~~~~~~~                                           ~
@@        ~~~~~~~~~        ~~~~~~~~~              WARPEDcore             ~~
@@     ~~~~~~                    ~~~~~~              ~cron             ~~~
@@   ~~~~          Adoption          ~~~~         200601110b         ~~~~
@@  ~~~              Date              ~~~~~~                    ~~~~~~
@@ ~~             2007.01.11              ~~~~~~~~~        ~~~~~~~~~
@@ ~                                           ~~~~~~~~~~~~~~~~        core
@@ ------------------------------------------------------------------------
@@ .:....1....:....2....:....3....:....4....:....5....:....6....:....7....:
@@ ========================================================================

@@ .:....1....:....2....:....3....:....4....:....5....:....6....:....7....:
@@
@@ LEGAL
@@
@@ This material is released under the terms of the
@@ WARPEDcore Softcode and Documentation License (WSDL).
@@ For details, see: http://community.pennmush.org
@@
@@ USE AT YOUR OWN RISK.
@@
@@ Copyright 2007, The WARPEDcore Project
@@
@@ .:....1....:....2....:....3....:....4....:....5....:....6....:....7....:
@@
@@ SYSTEM REQUIREMENTS
@@
@@ * PennMUSH version 1.7.4p21 or newer.
@@
@@ .:....1....:....2....:....3....:....4....:....5....:....6....:....7....:
@@
@@ The 'cut' line.
@@
@@ It is safe to remove everything above the following line, before quoting
@@ this script into your MUSH.
@@
@@ ========================================================================
@@ . . . . C . . . u . . . t . . . . . . H . . . e . . . r . . . e . . . .
@@ ========================================================================
@@ .:....1....:....2....:....3....:....4....:....5....:....6....:....7....:
@@ ------------------------------------------------------------------------
@@
@@ create ~cron
@@
@create ~cron
@set ~cron=NO_COMMAND
@describe ~cron=WARPEDcore~cron
@@
@@ .:....1....:....2....:....3....:....4....:....5....:....6....:....7....:
@@
@@ legal reference and version
@@
&~`legal ~cron=http://community.pennmush.org
@@
&~`version ~cron=200701110b
@@
@@ ========================================================================
@@ .:....1....:....2....:....3....:....4....:....5....:....6....:....7....:
@@ ------------------------------------------------------------------------
@@
@@ data
@@
@@ .:....1....:....2....:....3....:....4....:....5....:....6....:....7....:
@@
@@ variables: configurable.
@@
@@ documentation is provided.
@@
&CONF`INTERVAL ~cron=300
&NOTE`CONF`INTERVAL ~cron=This value represents the frequency of emits in a number of SECONDS. Note, setting this to anything other than an appropriate multiple of sixty (60) will have very screwy results. Recommended values are the following: 60 300 600 900 1200 1800 3600 (1m 5m 10m 15m 20m 30m and 60m, respectively). Default: 300 (5m)
@@
@@ ========================================================================
@@ .:....1....:....2....:....3....:....4....:....5....:....6....:....7....:
@@ ------------------------------------------------------------------------
@@
@@ the code.
@@
@@ .:....1....:....2....:....3....:....4....:....5....:....6....:....7....:
@@
@@ the loop.
@@
@@ fix this so that the emit is caculated before the final wait length.
@@
@STARTUP ~cron=@wait/until [cemit(~, if(gt(sub(secs(),convtime(starttime())),10),Re-)Started., 1)][setr(s, mul(setr(i, v(CONF`INTERVAL)), inc(div(secs(), %qi))))]=@tr me/TRIG`CRON`LOOP=%qs
@@
&NOTE`STARTUP ~cron=triggers TRIG.CRON.LOOP to start the cron
@@
@@
&TRIG`CRON`LOOP ~cron=@wait/until [cemit(~, ufun(UFUN`CEMIT,%0), 1)][setr(s, mul(setr(i, v(CONF`INTERVAL)), inc(div(secs(), %qi))))]=@tr me/TRIG`CRON`LOOP=%qs
@@
&NOTE`TRIG`CRON`LOOP ~cron=this cemits cron message and reinitiates loop.
@@
@@ .:....1....:....2....:....3....:....4....:....5....:....6....:....7....:
@@
@@ the functions
@@
&UFUN`CEMIT ~cron=[u(UFUN`TZ)][@@(UFUN`TZ sets and returns %qz - the timezone offset based on system configuration)]~%0~[u(UFUN`ETIMESTRING, %0)][@@(UFUN`ETIMESTRING sets and returns %qt - the enhanced time string value for %0)][if(hasattrval(me/UFUN`IC),~[u(UFUN`IC, %0)])][@@(does whatever you write UFUN`IC to do)]
@@
&NOTE`UFUN`CEMIT ~cron=this calculates, arranges, and returns the message for the cron cemit, using the subsequent UFUN.* attribs. %0 is the secs() value of the current emit sent to all subsequent functions.
@@
@@
&UFUN`TZ ~cron=[setr(z, div(sub(secs(), convtime(utctime())), 3600))]
@@
&NOTE`UFUN`TZ ~cron=determines sets %qz to the timezone offset in hours, based on your system's configuration.
@@
@@
&UFUN`ETIMESTRING ~cron=[setq(t, convsecs(%0))][inc(div(dec(elements(%qt, 3)), 7))][@@(<-- this calculates N for 'Nth <Weekday> of the month')][if(not(strmatch(elements(%qt, 2), elements(convsecs(add(%0, lmath(mul,60 60 24 7))), 2))), .0)][@@(<-- this appends '.0' to the previously calculated 'N' if and only if this is also the 'last <Weekday> of the month')] %qt
@@
&NOTE`UFUN`ETIMESTRING ~cron=sets %qt to the timestring value for %0 and emits %qt preceded by the <N[.0]> enhancement.
@@
@@
&UFUN`IC ~cron=
@@
&NOTE`UFUN`IC ~cron=write this for your IC cron data. it is sent %qs - the UTSECS value of current emit .
@@
@@ .:....1....:....2....:....3....:....4....:....5....:....6....:....7....:
@@
@@ create the cron broadcast channel and configure its locks on the ~cron.
@@
@chan/add ~=object player quiet
@@
@dolist join speak see hide mod=@clock/## ~=@[num(~cron)]
@dolist Join Speak See Hide Mod=@lock/user:Chan##Lock ~cron=LOCK`CHAN`[ucstr(##)]/1
@@
@@
&LOCK`CHAN`JOIN ~cron=cor(orflags(owner(%#), Wr), not(t(member(iter(cwho(~), owner(%i0)), owner(%#)))), u(LOCK`CHAN`JOIN.CUSTOM))
@@
&NOTE`LOCK`CHAN`JOIN ~cron=join-locks the channel to wizards and royalty, mortal players who don't already have an object on channel, and whatever you write in LOCK`CHAN`JOIN.CUSTOM
@@
&LOCK`CHAN`JOIN.CUSTOM ~cron=0
@@
&NOTE`LOCK`CHAN`JOIN.CUSTOM ~cron=write your own truth value test here.
@@
@@
&LOCK`CHAN`SPEAK ~cron=strmatch(%#, num(me))
@@
@@
&LOCK`CHAN`SEE ~cron=1
@@
@@
&LOCK`CHAN`HIDE ~cron=strmatch(%#, num(me))
@@
@@
&LOCK`CHAN`MOD ~cron=0
@@
@@
@chan/on ~=~cron
@@
@@ ========================================================================
@@ .:....1....:....2....:....3....:....4....:....5....:....6....:....7....:
@@ ------------------------------------------------------------------------
@@
@@ Help
@@
@@ .:....1....:....2....:....3....:....4....:....5....:....6....:....7....:
@@
@@ Help files
@@
&HELP`CRON ~cron=%r<~> <TZ>~<SECS>~<ETIMESTRING>~<IC>%r%r [ljust(<~>,12)] this is the channel name.%r [ljust(<TZ>,10)] TimeZone offset in hours>%r [ljust(<SECS>,12)] secs() of the current emit%r [ljust(<ETIMESTRING>,12)] includes <#wkday> and <time()> of current emit%r [ljust(<IC>,10)] includes whatever is custom written by the game gods%r%rexample...%r%r<~> -6 1067209500~4.0 Sun Oct 26 17:05:00 2003~<IC stuff>%r%rSee also the +help on: ic_time%r
@@
&HELP`IC_TIME ~cron=%rthe <IC> section of the ~cron includes whatever softcoded "IC time" data your local wizards have configured for this portion.%r%r[get(me/note`ufun`cron`ic)]
@@
@@
@@ The following regexp listen patterns were contributed by Mike @ M*U*S*H
@@ for some common listen intervals. Although it's not necessary to use
@@ regexp listen patterns, it can be very useful especially if you wanted
@@ to combine a few of the effects (e.g., opening a secret exit only
@@ on the third Wednesday of the month at precisely midnight).
@@
@@ In each one,
@@ %1 is <TZ~SECS>
@@ %2 is the <N>th Weekday of the month
@@ %3 is the Weekday itself,
@@ %4 the month,
@@ %5 the Day of the Month,
@@ %6 the HH,
@@ %7 the MM,
@@ %8 the SS,
@@ %9 the YYYY
@@ (%0 is the entire com message)
@@ if all the individual %<1-9> registers aren't needed, you can of course
@@ write shorter code.
@@
@@ These are untested, but I think they should work, with the caveat that
@@ if you ever broadcast at intervals of less than one minute,
@@ things will get nasty.
@@
@@ .:....1....:....2....:....3....:....4....:....5....:....6....:....7....:
@@
@@ &1M foo=^^<~> (.+)~(.|.\.0) (...) (...) (..) (..):(..):(..) (....)$:blah
@@ &2M foo=^^<~> (.+)~(.|.\.0) (...) (...) (..) (..):(.[02468]):(..) (....)$:blah
@@ &5M foo=^^<~> (.+)~(.|.\.0) (...) (...) (..) (..):(.[05]):(..) (....)$:blah
@@ &10M foo=^^<~> (.+)~(.|.\.0) (...) (...) (..) (..):(.0):(..) (....)$:blah
@@ &15M foo=^^<~> (.+)~(.|.\.0) (...) (...) (..) (..):(00|15|30|45):(..) (....)$:blah
@@ &20M foo=^^<~> (.+)~(.|.\.0) (...) (...) (..) (..):([024]0):(..) (....)$:blah
@@ &30M foo=^^<~> (.+)~(.|.\.0) (...) (...) (..) (..):([03]0):(..) (....)$:blah
@@ &1H foo=^^<~> (.+)~(.|.\.0) (...) (...) (..) (..):(00):(..) (....)$:blah
@@ &2H foo=^^<~> (.+)~(.|.\.0) (...) (...) (..) (.[02468]):(00):(..) (....)$:blah
@@ &3H foo=^^<~> (.+)~(.|.\.0) (...) (...) (..) (00|03|06|09|12|15|18|21):(00):(..) (....)$:blah
@@ &4H foo=^^<~> (.+)~(.|.\.0) (...) (...) (..) (00|04|08|12|16|20):(00):(..) (....)$:blah
@@ &6H foo=^^<~> (.+)~(.|.\.0) (...) (...) (..) (00|06|12|18):(00):(..) (....)$:blah
@@ &8H foo=^^<~> (.+)~(.|.\.0) (...) (...) (..) (00|08|16):(00):(..) (....)$:blah
@@ &12H foo=^^<~> (.+)~(.|.\.0) (...) (...) (..) (00|12):(00):(..) (....)$:blah
@@ &24H foo=^^<~> (.+)~(.|.\.0) (...) (...) (..) (00):(00):(..) (....)$:blah
@@
@@ ========================================================================
@@ .:....1....:....2....:....3....:....4....:....5....:....6....:....7....:
@@ ------------------------------------------------------------------------
@@
@@ activate
@@
@restart ~cron
@@
@@ The End.

Credits

  • 2007/01/11 - This code is based on a chat-based broadcast-cron on M*U*S*H. I'm assuming that was written by Javelin, but have seen no documentation either way. This is a clean-room version of that style system - It is all original code written by Trispis @ M*U*S*H who has never seen the code which operates the system installed by Javelin on M*U*S*H. The development origin this specific package is documented in a MUDtoberfest/ITBG presentation available from the mush.pennmush.org website
  • 2007/01/11 - Efficiency tweaks and other suggestions contributed by Mike @ M*U*S*H

1.1 - Contributions and Development

This section is where user contributions will be run through the paces as they are considered for inclusion in the official release versions. Each and every line of code in the WARPEDcore will start its life here. This section is where MOST of the activity of this entire book SHOULD take place.

At the most basic explanation (as I am presently understanding this book format), the procedure should work something like this...

  • To contribute a module for consideration, use the 'create content' option on your account to create a 'book page' parented to THIS page (The WARPEDcore/The Code/Unofficial Contributions). It will go through the moderation process to be added as a page in the book. Then, it will be publicly evaluated and/or otherwise abused in discussion and tweaking via 'edits' and 'replies' (see below). And, eventually, will be considered for inclusion in the official release (at which time, it would be appropriately moved thereto).
  • To submit a patch or tweak, use the 'edit' tab (just below the title of this page) and include a comment in the 'log' window at the bottom, explaining what you did. It, too, will go through the moderation process before being approved for inclusion (it might also be a good idea to start out with a discussion thread, see below)
  • To make a suggestion or request (i.e., you know something is needed, but are uncertain if you'd be able to code it right, or whatever) or to otherwise discuss or comment upon existing code submissions, use the 'reply' option.

NOTE: Just because a contribution isn't immediately considered for inclusion in the official release does not necessarily mean it's been rejected therefrom. I suspect many contributions will go through a very long period of 'not quite ready'-ness, for whatever reason (maybe the core isn't really ready to deal with the larger implications of adding some specific module - whatever). Point being: don't be discouraged if your really cool idea version 42.b5 just hangs out here for a while in the 'debug, comment, and abuse' phase.

1.1.0 ~reboot


@@ ========================================================================
@@ .:....1....:....2....:....3....:....4....:....5....:....6....:....7....:
@@ ------------------------------------------------------------------------
@@ WARPED      ~~~~~~~~~~~~~~~~                                           ~
@@        ~~~~~~~~~        ~~~~~~~~~              WARPEDcore             ~~
@@     ~~~~~~                    ~~~~~~             ~reboot            ~~~
@@   ~~~~          Adoption          ~~~~         200609250b         ~~~~
@@  ~~~              Date              ~~~~~~                    ~~~~~~
@@ ~~             2006.09.25              ~~~~~~~~~        ~~~~~~~~~
@@ ~                                           ~~~~~~~~~~~~~~~~        core
@@ ------------------------------------------------------------------------
@@ .:....1....:....2....:....3....:....4....:....5....:....6....:....7....:
@@ ========================================================================

1.1.1 ~cron


@@ ========================================================================
@@ .:....1....:....2....:....3....:....4....:....5....:....6....:....7....:
@@ ------------------------------------------------------------------------
@@
@@ WARPEDcore~cron Version 20070107a1
@@
@@ ------------------------------------------------------------------------
@@ .:....1....:....2....:....3....:....4....:....5....:....6....:....7....:
@@ ========================================================================
@@ .:....1....:....2....:....3....:....4....:....5....:....6....:....7....:
@@
@@ LEGAL
@@
@@ This material is released under the terms of the
@@ WARPEDcore Softcode and Documentation License (WSDL).
@@ For details, see: http://community.pennmush.org
@@
@@ USE AT YOUR OWN RISK.
@@
@@ Copyright 2007, The WARPEDcore Project
@@
@@ .:....1....:....2....:....3....:....4....:....5....:....6....:....7....:
@@
@@ SYSTEM REQUIREMENTS
@@
@@ * PennMUSH version 1.7.4p21 or newer.
@@
@@ .:....1....:....2....:....3....:....4....:....5....:....6....:....7....:
@@
@@ The 'cut' line.
@@
@@ It is safe to remove everything above the following line, before quoting
@@ this script into your MUSH.
@@
@@ ========================================================================
@@ . . . . C . . . u . . . t . . . . . . H . . . e . . . r . . . e . . . .
@@ ========================================================================
@@ .:....1....:....2....:....3....:....4....:....5....:....6....:....7....:
@@ ------------------------------------------------------------------------
@@
@@ create ~cron
@@
@create ~cron
@set ~cron=NO_COMMAND
@describe ~cron=WARPEDcore~cron
@@
@@ .:....1....:....2....:....3....:....4....:....5....:....6....:....7....:
@@
@@ legal reference and version
@@
&~`legal ~cron=http://community.pennmush.org
@@
&~`version ~cron=20070107a1
@@
@@ ========================================================================
@@ .:....1....:....2....:....3....:....4....:....5....:....6....:....7....:
@@ ------------------------------------------------------------------------
@@
@@ data
@@
@@ .:....1....:....2....:....3....:....4....:....5....:....6....:....7....:
@@
@@ variables: configurable.
@@
@@ documentation is provided.
@@
&CONF`INTERVAL ~cron=300
&NOTE`CONF`INTERVAL ~cron=This value represents the frequency of emits in a number of SECONDS. Note, setting this to anything other than an appropriate multiple of sixty (60) will have very screwy results. Recommended values are the following: 60 300 600 900 1200 1800 3600 (1m 5m 10m 15m 20m 30m and 60m, respectively). Default: 300 (5m)
@@
@@ ========================================================================
@@ .:....1....:....2....:....3....:....4....:....5....:....6....:....7....:
@@ ------------------------------------------------------------------------
@@
@@ the code.
@@
@@ .:....1....:....2....:....3....:....4....:....5....:....6....:....7....:
@@
@@ the loop.
@@
@@ fix this so that the emit is caculated before the final wait length.
@@
@STARTUP ~cron=@wait/until [cemit(~, if(gt(sub(secs(),convtime(starttime())),10),Re-)Started., 1)][setr(s, mul(setr(i, v(CONF`INTERVAL)), inc(div(secs(), %qi))))]=@tr me/TRIG`CRON`LOOP=%qs
@@
&NOTE`STARTUP ~cron=triggers TRIG.CRON.LOOP to start the cron
@@
@@
&TRIG`CRON`LOOP ~cron=@wait/until [cemit(~, ufun(UFUN`CEMIT,%0), 1)][setr(s, mul(setr(i, v(CONF`INTERVAL)), inc(div(secs(), %qi))))]=@tr me/TRIG`CRON`LOOP=%qs
@@
&NOTE`TRIG`CRON`LOOP ~cron=this cemits cron message and reinitiates loop.
@@
@@ .:....1....:....2....:....3....:....4....:....5....:....6....:....7....:
@@
@@ the functions
@@
&UFUN`CEMIT ~cron=[u(UFUN`TZ)][@@(UFUN`TZ sets and returns %qz - the timezone offset based on system configuration)]~%0~[u(UFUN`ETIMESTRING, %0)][@@(UFUN`ETIMESTRING sets and returns %qt - the enhanced time string value for %0)][if(hasattrval(me/UFUN`IC),~[u(UFUN`IC, %0)])][@@(does whatever you write UFUN`IC to do)]
@@
&NOTE`UFUN`CEMIT ~cron=this calculates, arranges, and returns the message for the cron cemit, using the subsequent UFUN.* attribs. %0 is the secs() value of the current emit sent to all subsequent functions.
@@
@@
&UFUN`TZ ~cron=[setr(z, div(sub(secs(), convtime(utctime())), 3600))]
@@
&NOTE`UFUN`TZ ~cron=determines sets %qz to the timezone offset in hours, based on your system's configuration.
@@
@@
&UFUN`ETIMESTRING ~cron=[setq(t, convsecs(%0))][inc(div(dec(elements(%qt, 3)), 7))][@@(<-- this calculates N for 'Nth <Weekday> of the month')][if(not(strmatch(elements(%qt, 2), elements(convsecs(add(%0, lmath(mul,60 60 24 7))), 2))), .0)][@@(<-- this appends '.0' to the previously calculated 'N' if and only if this is also the 'last <Weekday> of the month')] %qt
@@
&NOTE`UFUN`ETIMESTRING ~cron=sets %qt to the timestring value for %0 and emits %qt preceded by the <N[.0]> enhancement.
@@
@@
&UFUN`IC ~cron=
@@
&NOTE`UFUN`IC ~cron=write this for your IC cron data. it is sent %qs - the UTSECS value of current emit .
@@
@@ .:....1....:....2....:....3....:....4....:....5....:....6....:....7....:
@@
@@ create the cron broadcast channel and configure its locks on the ~cron.
@@
@chan/add ~=object player quiet
@@
@dolist join speak see hide mod=@clock/## ~=@[num(~cron)]
@dolist Join Speak See Hide Mod=@lock/user:Chan##Lock ~cron=LOCK`CHAN`[ucstr(##)]/1
@@
@@
&LOCK`CHAN`JOIN ~cron=cor(orflags(owner(%#), Wr), not(t(member(iter(cwho(~), owner(%i0)), owner(%#)))), u(LOCK`CHAN`JOIN.CUSTOM))
@@
&NOTE`LOCK`CHAN`JOIN ~cron=join-locks the channel to wizards and royalty, mortal players who don't already have an object on channel, and whatever you write in LOCK`CHAN`JOIN.CUSTOM
@@
&LOCK`CHAN`JOIN.CUSTOM ~cron=0
@@
&NOTE`LOCK`CHAN`JOIN.CUSTOM ~cron=write your own truth value test here.
@@
@@
&LOCK`CHAN`SPEAK ~cron=strmatch(%#, num(me))
@@
@@
&LOCK`CHAN`SEE ~cron=1
@@
@@
&LOCK`CHAN`HIDE ~cron=strmatch(%#, num(me))
@@
@@
&LOCK`CHAN`MOD ~cron=0
@@
@@
@chan/on ~=~cron
@@
@@ ========================================================================
@@ .:....1....:....2....:....3....:....4....:....5....:....6....:....7....:
@@ ------------------------------------------------------------------------
@@
@@ Help
@@
@@ .:....1....:....2....:....3....:....4....:....5....:....6....:....7....:
@@
@@ Help files
@@
&HELP`CRON ~cron=%r<~> <TZ>~<SECS>~<ETIMESTRING>~<IC>%r%r [ljust(<~>,12)] this is the channel name.%r [ljust(<TZ>,10)] TimeZone offset in hours>%r [ljust(<SECS>,12)] secs() of the current emit%r [ljust(<ETIMESTRING>,12)] includes <#wkday> and <time()> of current emit%r [ljust(<IC>,10)] includes whatever is custom written by the game gods%r%rexample...%r%r<~> -6 1067209500~4.0 Sun Oct 26 17:05:00 2003~<IC stuff>%r%rSee also the +help on: ic_time%r
@@
&HELP`IC_TIME ~cron=%rthe <IC> section of the ~cron includes whatever softcoded "IC time" data your local wizards have configured for this portion.%r%r[get(me/note`ufun`cron`ic)]
@@
@@
@@ The following regexp listen patterns were contributed by Mike @ M*U*S*H
@@ for some common listen intervals. Although it's not necessary to use
@@ regexp listen patterns, it can be very useful especially if you wanted
@@ to combine a few of the effects (e.g., opening a secret exit only
@@ on the third Wednesday of the month at precisely midnight).
@@
@@ In each one,
@@ %1 is <TZ~SECS>
@@ %2 is the <N>th Weekday of the month
@@ %3 is the Weekday itself,
@@ %4 the month,
@@ %5 the Day of the Month,
@@ %6 the HH,
@@ %7 the MM,
@@ %8 the SS,
@@ %9 the YYYY
@@ (%0 is the entire com message)
@@ if all the individual %<1-9> registers aren't needed, you can of course
@@ write shorter code.
@@
@@ These are untested, but I think they should work, with the caveat that
@@ if you ever broadcast at intervals of less than one minute,
@@ things will get nasty.
@@
@@ .:....1....:....2....:....3....:....4....:....5....:....6....:....7....:
@@
@@ &1M foo=^^<~> (.+)~(.|.\.0) (...) (...) (..) (..):(..):(..) (....)$:blah
@@ &2M foo=^^<~> (.+)~(.|.\.0) (...) (...) (..) (..):(.[02468]):(..) (....)$:blah
@@ &5M foo=^^<~> (.+)~(.|.\.0) (...) (...) (..) (..):(.[05]):(..) (....)$:blah
@@ &10M foo=^^<~> (.+)~(.|.\.0) (...) (...) (..) (..):(.0):(..) (....)$:blah
@@ &15M foo=^^<~> (.+)~(.|.\.0) (...) (...) (..) (..):(00|15|30|45):(..) (....)$:blah
@@ &20M foo=^^<~> (.+)~(.|.\.0) (...) (...) (..) (..):([024]0):(..) (....)$:blah
@@ &30M foo=^^<~> (.+)~(.|.\.0) (...) (...) (..) (..):([03]0):(..) (....)$:blah
@@ &1H foo=^^<~> (.+)~(.|.\.0) (...) (...) (..) (..):(00):(..) (....)$:blah
@@ &2H foo=^^<~> (.+)~(.|.\.0) (...) (...) (..) (.[02468]):(00):(..) (....)$:blah
@@ &3H foo=^^<~> (.+)~(.|.\.0) (...) (...) (..) (00|03|06|09|12|15|18|21):(00):(..) (....)$:blah
@@ &4H foo=^^<~> (.+)~(.|.\.0) (...) (...) (..) (00|04|08|12|16|20):(00):(..) (....)$:blah
@@ &6H foo=^^<~> (.+)~(.|.\.0) (...) (...) (..) (00|06|12|18):(00):(..) (....)$:blah
@@ &8H foo=^^<~> (.+)~(.|.\.0) (...) (...) (..) (00|08|16):(00):(..) (....)$:blah
@@ &12H foo=^^<~> (.+)~(.|.\.0) (...) (...) (..) (00|12):(00):(..) (....)$:blah
@@ &24H foo=^^<~> (.+)~(.|.\.0) (...) (...) (..) (00):(00):(..) (....)$:blah
@@
@@ ========================================================================
@@ .:....1....:....2....:....3....:....4....:....5....:....6....:....7....:
@@ ------------------------------------------------------------------------
@@
@@ activate
@@
@restart ~cron
@@
@@ The End.

1.1.2 ~config

Below is a list of 'to do' items.

1. Get and maintain plain vanilla default master list (i.e., set up a new PennMUSH "out of the box" and separate the code for setting up defaults in &DATA`<category>`<item>`DEFAULT attributes).

KNOWN BUG: the do-options code, as written, generates a category called 'parameters'.
Mike pages: If you just stick setdiff(<foo>,@config parameters,|) in (where <foo> is the textentries(help,@config %0*,|) I believe) that should fix that bit.

KNOWN BUG: the 'tiny' category doesn't get a description set.

KNOWN ISSUE: Haven't yet finished the /diff switch for two reasons:
1. time
2. have only tested this on M*U*S*H (haven't ever done a plain vanilla, per the 'to do' above).

Here's the code to generate all of the data (not yet separated per 'vanilla' above).


@@
&CMND.DO-OPTIONS [v(~)]=$do-options:@pemit %#=Doing options.[null(u(list-options))]
@@
&list-options [v(~)]=localize(setq(0,,1,,2,,3,0,4,0,5,0)[null(iter(sort(textentries(help, @config %0*,|),,|), if(isint(right(%i0, 1)), setq(5, 0), if(%q3, u(save-option, %q2, %q0))[switch(inum(0), 1, , u(save-category, %q0, %q1))][setq(3, 0, 2, , 0, rest(%i0), 5, 1)])[setq(4, 1)][iter(textfile(help, %i0), switch(setr(9, squish(%i0)), , if(%q3,u(save-option, %q2, %q0)[setq(3, 0, 2, )]), *=*:*, switch(1, %q3, u(save-option, %q2, %q0))[setq(2, %q9, 3, 1)], switch(1, %q4, if(%q5, setq(1, %q9))[setq(4,0)], %q3, setq(2, %q2 %q9))), %r, %b)], |, %b))])
@@
&save-option [v(~)]=set(me, DATA`%1`[first(%0, =)]`DEFAULT:[config(first(%0, =))])[set(me, DATA`%1`[first(%0, =)]`TYPE:[before(after(%0, <), >)])][set(me, DATA`%1`[first(%0, =)]:[squish(after(%0, :))])]
@@
&save-category [v(~)]=set(me,DATA`%0:%1)
@@
&credit-options [v(~)]=code for generating all of the attributes and contents originally written by Mike @ M*U*S*H with attribute name adaptations by Trispis @ c.p.o.
@@

And here's the display code, as it presently exists


@@
&cmnd`config [v(~)]=$~config:@pemit %#=u(UFUN`DISP)
@@
&cmnd`config.diff [v(~)]=$~config/diff:@pemit %#=u(UFUN`DISP`DIFF)
@@
&cmnd`config.list_x [v(~)]=$~config/list *:@pemit %#=ifelse(setr(e, u(UFUN`ERRCK`CATY, %0)), %qe, u(UFUN`DISP`HEADER)[u(UFUN`DISP`CATY, %0)][u(UFUN`DISP`FOOTER)])
@@
&cmnd`config.show_x [v(~)]=$~config/show *:@pemit %#=ifelse(setr(e, u(UFUN`ERRCK`ITEM, %0)), %qe, u(UFUN`DISP`HEADER)[u(UFUN`DISP`ITEM,%0)][u(UFUN`DISP`FOOTER)])
@@
&ufun`disp [v(~)]=[u(UFUN`DISP`HEADER)][u(UFUN`DISP`SYNTAX)][iter(setr(l, lattr(me/DATA`))[setq(w, lmath(max, iter(%ql, strlen(last(%i0, `)))))], [align(%qw [sub(width(%#), sub(%qw, 2))], setr(c, lcstr(last(%i0, `))), v(%i0))], %b, %r)][u(UFUN`DISP`FOOTER)]
@@
&ufun`disp`diff [v(~)]=null(iter(config(), switch(v(lattr(me/DATA`*`%i0`DEFAULT)), config(%i0), setq(d, %qd %i0), #-*, setq(e, %qe %i0), setq(o, %qo %i0))))%rDiffering values: %qd%r%rErrors: %qe%r%rOther differences: %qo%r
@@
&ufun`disp`caty [v(~)]=Config Category: %0%rDescription: [v(DATA`%0)]%r[setq(n, lmath(max, iter(setr(l, iter(lattr(me/DATA`%0`), lcstr(last(%i0,`)))), inc(strlen(%i0)))))][table(%ql, %qn, width(%#))]
@@
&ufun`disp`item [v(~)]=ljust(Config Item: %0, setr(w, div(width(%#), 2)))Config Type: [v(%qi`type)]%r%rDescription: [v(%qi)]%r%r[ljust(Default Setting: [v(%qi`DEFAULT)], %qw)]Current Setting: [config(%0)]
@@
&ufun`errck`caty [v(~)]=ifelse(or(not(dec(words(%0))), hasattr(me, DATA`%0)), ,Unknown category: %0)
@@
&ufun`errck`item [v(~)]=ifelse(or(words(setr(i, lattr(me/DATA`*`%0))), not(dec(words(%0)))), , Unknown config item: %0)
@@
&ufun`disp`header [v(~)]=-[center(- WARPEDcore~config -, sub(width(%#), 6), =)]-%r
@@
&ufun`disp`footer [v(~)]=%r-[setr(f, repeat(=, div(sub(width(%#), 3), 2)))]-%qf-
@@
&~`legal [v(~)]=WARPED~core Softcode and Documentation License - http://community.pennmush.org
@@

PIGLet

PIGLet pieces.

It will be interesting to watch the differences between these two file types.

~let()


@@ ========================================================================
@@ .:....1....:....2....:....3....:....4....:....5....:....6....:....7....:
@@ ========================================================================
@@ DISCLAIMER: Use at your own risk.
@@ This script is intended for the Pennmush server.
@@ Guaranteed to break if used in Rhost or MUX.
@@ See license at: http://community.pennmush.org/node/343
@@ ========================================================================
@@ .:....1....:....2....:....3....:....4....:....5....:....6....:....7....:
@@ ------------------------------------------------------------------------
@@ Announcement
@@
th ~> Script started.
@@
@@ ========================================================================
@@ .:....1....:....2....:....3....:....4....:....5....:....6....:....7....:
@@ ------------------------------------------------------------------------
@@ UPDATE: To update an existing installation, set the following line to
@@ your let() function's #dbref. Otherwise, let it set a blank attribute to
@@ begin a fresh installation (i.e., leave it alone).
@@
&~ me=
@@
@@ Setting the above line is all you need to do. Make sure you did it
@@ and that you did it the way you wanted. No further changes needed.
@@
@@ ------------------------------------------------------------------------
@@ .:....1....:....2....:....3....:....4....:....5....:....6....:....7....:
@@ ------------------------------------------------------------------------
@@ Update/Creation Announcement and Implementation...
@@
th ~> [ifelse(isdbref(v(~)), Updating, Installing[attrib_set(me/~, create(~let function))][attrib_set(v(~)/DATA, v(~))])]: [name(v(~))]...
@@
@@
@@ ------------------------------------------------------------------------
@@ .:....1....:....2....:....3....:....4....:....5....:....6....:....7....:
@@ ------------------------------------------------------------------------
@@ Library
@@
th ~> [ifelse(dec(words(lparent(v(~)))), Checking, Creating [name(parent(v(~), setr(0, create(Font Library 1))))][attrib_set(%q0/describe, name(%q0))])]
@@
@@
@@ ------------------------------------------------------------------------
@@ .:....1....:....2....:....3....:....4....:....5....:....6....:....7....:
@@ ------------------------------------------------------------------------
@@ Preparation
@@
@@ ========================================================================
@@ .:....1....:....2....:....3....:....4....:....5....:....6....:....7....:
@@ ------------------------------------------------------------------------
@@ Credits.
@@
&CRED`COPYRIGHT [v(~)]=© Copyright 2007, Chuc McGuire
&CRED`LICENSE [v(~)]=WARPEDcore Softcode and Documentation License, http://community.pennmush.org/node/343
@@
@set [v(~)]=DATA`ANSIORDS:[iter(h H u U i I x X r R g G y Y b B m M c C w W, ord(%i0))]
@@
@@ Tweak ~let() with no args so that it lists installed fonts after the #dbref.
@@
@@ ~let()
@@ ~let(<font[:<ansi>]>, <string>)
@@
&UFUN`~LET [v(~)]=localize(ifelse(nor(words(%0), words(%1)), %! [iter(lattrp(me/FONT`), after(%i0, `))], switch(1, t(words(setr(e, u(UFUN`ERCK`FONT, setr(f, first(%0, :)))))), %qe, t(words(setr(e, u(UFUN`ERCK`STRING, setr(s, %1))))), %qe, setq(a, u(UFUN`ESET`ANSI, rest(%0, :)))[u(UFUN`DISP, %qf, %qa, %qs)])))
@@
&UFUN`DISP [v(~)]=map(UFUN`DISP2, lnum(1, words(v(FONT`%qf`032), |)), %b, %r)
&UFUN`DISP2 [v(~)]=setq(0, %0)[foreach(UFUN`DISP3, %qs)]
&UFUN`DISP3 [v(~)]=map(UFUN`DISP4, elements(v(FONT`%qf`[rjust(ord(%0), 3, 0)]), %q0, |), %b, )
&UFUN`DISP4 [v(~)]=ansi(%qa[first(%0, \, )], chr(rest(%0, \, )))
@@
@@
@@ &~letlen()
@@
&UFUN`~LETLEN [v(~)]=localize(switch(1, t(words(setr(e, u(UFUN`ERCK`FONT, setr(f, first(%0, :)))))), %qe, t(words(setr(e, u(UFUN`ERCK`STRING, setr(s, %1))))), %qe, lmath(add, foreach(#lambda/words(first(v(FONT`%qf`\[rjust(ord(\%0), 3, 0)\]), |))\%b, %qs))))
@@
&UFUN`ERCK`FONT [v(~)]=ifelse(hasattrp(me, FONT`%qf), , u(UFUN`EMSG-1, %qf))
@@
&UFUN`ERCK`STRING [v(~)]=localize(foreach(#lambda/\[ifelse(hasattrp(me, FONT`%qf`\[rjust(ord(\%0), 3, 0)\]), , setq(e, \%qe \%0))\], %0)[if(words(%qe), u(UFUN`EMSG-2, %qf, %qe))
@@
&UFUN`ESET`ANSI [v(~)]=foreach(#lambda/if(member(v(DATA`ANSIORDS), ord(\%0)), \%0), %0)
@@
&UFUN`EMSG-1 [v(~)]=#-1 No such font: %0
@@
&UFUN`EMSG-2 [v(~)]=#-2 Unsupported character(s) in font %0: %1
@@
@@ ========================================================================
@@ .:....1....:....2....:....3....:....4....:....5....:....6....:....7....:
@@ ------------------------------------------------------------------------
@@
&HELP`~LET [v(~)]=%r~let()%r~let(<font\[:<ansi>\]>, <string>)%r%rwith no arguments returns the #dbref of the ~let function object, followed by a list of all installed fonts.%r%rif <font> (optional :<ansi>) and <string> are provided, it returns one of the following...%r%r#-1 if <font> does not exist.%r#-2 if there are characters in <string> which aren't supported in <font>%ror, <string> in <font> with optional <ansi> applied.%r%rFor example, see: +help ~let2
@@
&HELP`~let2 [v(~)]=%rExample: think ~let(isometricsm:bh, M U S H)%r[~let(isometricsm:bh, M U S H)]%r
@@
&HELP`~letlen [v(~)]=%r~letlen(<font>, <string>)%r%rreturns the actual screen width of <string> displayed in <font>, or the following errors%r%r#-1 if <font> does not exist.%r#-2 if there are characters in <string> which aren't supported in <font>%r
@@
@@ ========================================================================
@@ .:....1....:....2....:....3....:....4....:....5....:....6....:....7....:
@@ ------------------------------------------------------------------------
@@
@@ From Javelin: add the following to a wiz object's @startup
@@
@@ @function ~let=<#dbref>, ufun`~let
@@ @function ~letlen=<#dbref>, ufun`~letlen
@@