Useful code on player bit



  • 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. :D

    Edit: because I called the attr 'stay-asleep', not 'stay-sleep'. :P And because those idle messages were getting spammy so I sectioned them out.


  • Coder

    You probably want to put a @lock/use on yourself as well.



  • Yeah. Not sure why games don't do that on their default player object. I haven't seen a situation in which anyone wanted their code to work on everyone in the same room with them. o.O

    I'm sort of surprised no one else has a stack of useful stuff they stick on their player bits by default. I can't be the only one who does this and I've been doing it for years - custom descers (basically a thing to list descs and swap between them), note-to-self type code... heck, I even threw an entire dice roller onto myself on one game that didn't have one. (It was dirt-simple but worked for what I needed it for.)

    Anybody? Anyone? Bueller?



  • @melpomene said in Useful code on player bit:

    I'm sort of surprised no one else has a stack of useful stuff they stick on their player bits by default

    We do. Though at least in my case it's an ugly bastard of a hydra that is a conglomeration of coughcough years worth of 'tweaking', so it's definitely not worth sharing.


  • Coder

    @melpomene I have a few things that I wrote myself, but mostly the things I want to see in a game... well. I started doing MUSHcode so I could put them into the game. So, any game I'm a coder on, my fun player stuff is on the game. I do think game owners and coders should be putting in more features, especially when they're very easy to implement.

    That said, I started playing on Arx, where you can do no soft code. I sort of worked myself out of needing it.

    Now, I think the only player-side code I use is on SFMux, though it's @Cobaltasaurus 's and I just @parent'd an object to her code. It's +mwhere (my where) to replace the game's +where, which neither of us could read.

    Oh and I was typing I just remembered this... my +friend+ code! It allows you to add friends, then see if they're online and where they're at. Example:

    -------------------------[Friend Finder LITE v0.8729]-------------------------
    Name                          Conn      Idle           Location            
    Lily ().......................Offline...-----..........Quiet Room..........
    Milo (LD).....................Offline...-----..........SM1: Milo's Place - 
    Jacey (jc)....................Offline...-----..........SM1: Jacey's Place -
    Race (RV).....................Online....48m 3s.........NV1: Patio - Wake Ho
    -----------------------------------by skew------------------------------------
    

    Here's the code. Works on MUX.

    &CMD.FRIEND.ADD me=$+friend/add *:@assert t( pmatch( %0 ))=@pemit %#=[FRIEND] '%0' does not return to a valid player.;@pemit %#=[FRIEND] You add [name(*%0)] to your personal FRIEND list.;&dat.friendlist %#=[setunion(u(%#/dat.friendlist), pmatch( %0 ))]
    
    &CMD.FRIEND.DEL me=$+friend/del *:@pemit %#=[FRIEND] You remove [name( *%0 )] to your personal FRIEND list.;&dat.friendlist %#=[setdiff(u(%#/dat.friendlist),pmatch( %0 ))]
    
    &CMD.FRIEND.WHO me=$+friend:@pemit %#=strcat( center(ansi( r, [, h, Friend Finder LITE v0.8729, r, ] ),78, -),%r,ljust( Name, 30), ljust( Conn, 10), ljust( Idle, 15), ljust( Location, 20),%r,iter( u(%#/dat.friendlist),strcat( ljust( strcat( name(##), %b, %(, %ch%cx, get( ##/alias ), %cn, %) ),30,.),ljust(ifelse(gt(conn(##),0),Online,Offline),10,.),ljust(ifelse(gt(conn(##),0),exptime(idle(##)), ----- ),15,.),ljust( name( loc( ##)), 20,.)), ,%r),%r,center( by skew,78,- ))
    

  • Coder

    @melpomene said in Useful code on player bit:

    I'm sort of surprised no one else has a stack of useful stuff they stick on their player bits by default. I can't be the only one who does this and I've been doing it for years - custom descers (basically a thing to list descs and swap between them), note-to-self type code... heck, I even threw an entire dice roller onto myself on one game that didn't have one. (It was dirt-simple but worked for what I needed it for.)

    Not really, no. I tend to build that kind of stuff in as globals on my games, so I've never needed to have player-specific utilities. Ares has most (if not all) of this stuff built in - afk indications, friends lists, dice roller, outfits system. I'm curious to know what other little utilities people have, though, to see if there are any gaps. Because like Arx (as @skew mentioned), Ares doesn't allow player utility code.


  • Coder

    @faraday

    • A verbose +txt system,
    • a poseorder that makes noise when it's your turn to pose
    • +repose with line breaks in it and can be easily cleared
    • a +watch system that not only notifies of log on/off, but also lists out things like idle times (and maybe the person's location),
    • commands that allow + or not (ex, +txt or txt) (this makes stuff mobile-friendly)

    I think that's all I got right now.


  • Coder

    @skew said in Useful code on player bit:

    a poseorder that makes noise when it's your turn to pose

    You mean, like, literally noise using the ANSI beep?


  • Coder

    @faraday said in Useful code on player bit:

    @skew said in Useful code on player bit:

    a poseorder that makes noise when it's your turn to pose

    You mean, like, literally noise using the ANSI beep?

    Literal, actual noise coming out of my computer speakers. The reason I picked up MUing (all of 5 years ago) is because I can do it while doing other things. Watching TV, washing dishes, even pushing my kid in the swing. When it BEEPS to alert me it's my turn, it's priceless.

    Some people do not like +poseorder that shows who turn it is in the room. They feel it puts pressure on people who go slower, or enforces a "turn order" when they'd prefer more free-flow pose-when-you-have-something-to-day... in this case, the alternative is do a +poseorder/fixed # command. After X people pose (including just 1), it alerts me.

    Need to implement that in my own code. But, yes. ANSI beep. BEEP!


  • Coder

    @skew Understandable, though you could also set up a trigger in the client to beep at you when the code says "It's your turn to pose." pose/fixed is a neat idea though.


  • Coder

    @faraday Unless your client doesn't support that. Potato doesn't, best I know. The "next best thing" is to beg staff to create something like +beeptest. So my client can send that when it detects the "Your pose next" emit.

    So, yes. Please let Ares let me have sound. Please.


  • Coder

    @skew said in Useful code on player bit:

    So, yes. Please let Ares let me have sound. Please.

    I added a beep command (coming in the next patch) so you can trigger that from your client for whatever events you wish. Though, interestingly, none of the Mac clients I tried seem to even respect the beep at all. (Not even the beep on PennMUSH.) But it's there, at least, for clients that support it.


  • Coder

    @faraday My Atlantis beeps all the livelong day. I think you just need to turn it on as it defaults to off.

    And thank you! Beep beep!