Because we're not always wizards and some things are just easy to do and ought to be done. (And some of us have too much caffeine in our bloodstreams and need a break from RL code.)
// BEFORE YOU DO ANY OF THIS:
@lock me=me
// If you don't know why, don't use this code.
// The automatic idler: After 15m puts you in a "hey I might be idle" state. After 30-60m (unless you have it turned off), takes you to the "yep I'm idle" state. After 6 hours, even if you have it set to keep you awake, runs the "I'm idle" commands. When you reconnect, it automatically remembers your STAY-awake/asleep state, but still fires your awake-actions anyway and marks you "awake". The idea was to have a single "aconnect" that fires when you "wake up" as well as when you connect. This is for games that just let people sit on them for all time, becoming idle and then unidle but never again firing the @aconnect unless someone got disconnected.
// Commands: +wake; +sleep; +stay/a*;
// Function: Interval
// Input: me, *name, #dbref, or a time in seconds (for example, the time a post was made).
// Output: Converts given seconds-ago or person's idle time into human-readable text. Returns only the top 2 significant intervals (weeks, days, hours, minutes, seconds).
&f.interval me=if(t(setr(0, extract(squish(trim(strcat(setq(I, sub(secs(), if(isnum(%0), %0, sub(secs(), idle(%0))))), setq(W, div(%qI, 604800)), if(gt(%qW, 0), setq(I, sub(%qI, mul(%qW, 604800)))), setq(D, div(%qI, 86400)), if(gt(%qD, 0), setq(I, sub(%qI, mul(%qD, 86400)))), setq(H, div(%qI, 3600)), if(gt(%qH, 0), setq(I, sub(%qI, mul(%qH, 3600)))), setq(M, div(%qI, 60)), if(gt(%qM, 0), setq(I, sub(%qI, mul(%qM, 60)))), setq(S, %qI), if(t(%qW), %qWw)|, if(t(%qD), %qDd)|, if(t(%qH), %qHh)|, if(t(%qM), %qMm)|, if(t(%qS), %qSs)), b, |), |), 1, 2, |, %b))), %q0, 0s)
// th ulocal(me/f.interval, me)
// th ulocal(me/f.interval, *idleperson)
// th ulocal(me/f.interval, sub(secs(), 102))
// th ulocal(me/f.interval, sub(secs(), 400002))
// th ulocal(me/f.interval, startsecs())
&state-sleep me=1
&stay-asleep me=0
&awake-actions me=+watch; +bbscan; +wantrp/on;
&asleep-actions me=+wantrp/off;
&min-idle-before-promised-sleep me=900
&max-idle-before-sleep me=1800
&max-idle-before-forced-sleep me=21600
&idle-check-interval me=1700
&msg-idle-but-awake me=I've been idle for [ulocal(me/f.interval, me)] but I swear I'm here. It might take me a few minutes to respond.
&msg-very-idle me=I've been idle for [ulocal(me/f.interval, me)] so I'm probably AFK.
&msg-idling-soon me=I've been idle for [u(me/f.interval, me)] so I could be AFK or just typing a really long pose.
&tr-wake me=@switch/first v(state-sleep)=0, {@trigger/quiet me/awake-actions; @set/quiet me=state-sleep:1;};
&tr-sleep me=@switch/first v(state-sleep)=1, {th Getting sleepy.;@trigger/quiet me/asleep-actions; @set/quiet me=state-sleep:0;};
&tr-wakeorsleep me=@switch/first or(eq(v(stay-asleep), 0), gte(idle(me), v(max-idle-before-forced-sleep)))=1,{ @switch/first gte(idle(me), v(max-idle-before-sleep))=1, { @trigger/quiet me/tr-sleep; }, { @trigger/quiet me/tr-wake; }; }
&tr-wait-wakeorsleep me=@trigger/quiet me/tr-wakeorsleep; @wait v(idle-check-interval)=@trigger/quiet me/tr-wait-wakeorsleep;
@idle me=case(1, gt(idle(me), v(max-idle-before-sleep)), case(and(v(stay-asleep), v(state-sleep)), 1, u(me/msg-idle-but-awake), u(me/msg-very-idle)), gt(idle(me), v(min-idle-before-promised-sleep)), u(me/msg-idling-soon),)
@aconnect me=@set/quiet me=state-sleep:0[setq(S, v(stay-asleep))]; @set/quiet me=stay-asleep:0; @wait 5=@trigger/quiet me/tr-wait-wakeorsleep; @wait 6=@set/quiet me=stay-asleep:%qS;
&CMD-WAKE me=$+wake:@switch/first v(state-sleep)=0, { @trigger/quiet me/tr-wake; },{ th You're already awake.; }
&CMD-SLEEP me=$+sleep:@switch/first v(state-sleep)=1, { @trigger/quiet me/tr-sleep; },{ th You're already asleep.; }
&cmd-stay me=$+stay/a*:@set/quiet me=stay-asleep:[not(v(stay-asleep))];th case(v(stay-asleep), 1, Staying, Letting fate decide if you stay) [case(v(state-sleep), 1, awake, asleep)].
// Below is random stuff that I have written over the years to make RP less painful on games that aren't all coded up to my "standards" so to speak.
// +msg: remembers the last person/people you texted with +msg and makes it so you can just type +msg <stuff> and it'll go to them.
&CMD-+MSG me=$+msg *:@switch/first %0=*=*, {@set/quiet me=last-msg:[first(%0, =)]; @force me=+txt %0; }, { @force me=+txt [v(last-msg)]=%0; }
// On my player bits, I often forget if I'm a wizbit or not. This catches my "+job"s and turns them into "+myjob"s. You need the no_parse or your formatting gets eaten when you +job/add <#>=<formatted stuff>.
&CMD-+JOB me=$+job*:@force me=+myjob%0
@set me/cmd-+job=no_parse
Does anyone else have anything useful they stick on their PC bits? I might want to steal your code.
Edit: because I called the attr 'stay-asleep', not 'stay-sleep'. And because those idle messages were getting spammy so I sectioned them out.