[...]

 

generic furniture, $furniture

the furniture object needs much better messages (as I didn't work out how to store the multitude of sit/stand/lean/rest/sleep in/on/beside/etc messages, much less shifting [lean -> stand, rest -> sleep, &c] messages), 'cause right now it generates a generic message that doesn't refer to existing stance.

this also needs better display: players using when looking at furniture aren't listed.

maybe also incorporate the .squeeze & other shifting/next to/shoving/fall actions from yudJ's exceptionally social furniture?

this ALSO needs to mess w/ player actions (when sleeping can't use non-@* commands aside from 'wake'; when sitting can't move, close doors; etc), but that's more of a general embodiment issue.


$xplayer.stance (r)
stores the current body position of $xplayer (this should be on generic embodied object)
$xplayer.furniture (r)
stores the current furniture and preposition that $xplayer is interacting with, or {#-1, ""} if not interacting with any furniture (this should be on generic embodied object)
$xplayer:moveto (tnt rxd)
overridden to :set_stance to standing before moving around
$xplayer:set_stance (tnt rxd)
{stance, ?furn = #-1, ?prep = ""} = args;, sets $xplayer's stance and optional furniture interaction. (this should be on generic embodied object)
$xplayer:stance_action (tnt rxd)
{old, new} = args;, returns a message for $you:say_action to display for room when $xplayer's stance changes from <old> to <new> (this should be on generic embodied object... and probably rewritten to put data on properties, not in the code.)
$xplayer:"sit stand lean rest sleep lie" (none none none rd)
verbs for a player $xplayer, to change stance without furniture interaction.
$xplayer:wake (any none none rd)
verb for a player $xplayer, to change stance.
$xplayer:last_huh (tnt rxd)
Helpful messages on how to use the "sit stand lean rest sleep lie" verb.
$xplayer:look_self (tnt rxd)
Overridden to display player's pose & alertness.

$furniture.valid_actions
looks like {{"sit", {"on"}}, {"rest", {"on"}}, {"sleep", {"on"}}}
$furniture.capacity
$furniture.users
$furniture:drop_user
$furniture:"g*et ta*ke"
overridden to be un-pick-upable when things are interacting with it.
$furniture:"sit stand lean rest sleep lie" (any any any rd)
$furniture:_check_users
$furniture:look_self
needs to be overridden to list players using when looked at.

$detailed_room:tell_contents
overridden to display players using furniture in room

@prop $xplayer.stance "stand" r @prop $xplayer.furniture {#-1, ""} r @verb $xplayer:"sit stand lean rest sleep lie" none none none rd @program $xplayer:sit if (this.stance != verb || `this.furniture[1] != #-1 ! E_RANGE => 0') oldstance = this.stance; player:set_stance(verb); $you:say_action(this:stance_action(oldstance, verb)); else player:tell("You're already doing that."); endif . @verb $xplayer:wake any none none rd @program $xplayer:wake if (dobjstr && dobjstr != "up") this:my_explain_syntax(caller, verb, args); return; endif if (this.stance != "sleep") player:tell("You're not sleeping!"); else player:set_stance("stand"); $you:say_action(this:stance_action("sleep", "stand")); endif . @verb $xplayer:my_explain_syntax tnt @program $xplayer:my_explain_syntax {caller, verb, ?args = {}, ?msg = ""} = args; r = 0; if (verb == "wake") player:tell("Try this instead: wake [up]."); r = 1; endif if(msg) player:tell(msg); r = 1; endif return r; . @verb $xplayer:stance_action tnt @program $xplayer:stance_action ":stance_action(<old stance>, <new stance>)"; ""; "what <player> does when stance changes from <old> to <new>"; {old, new} = args; if (old == "sleep") if (new == "sit") return "%N %<wakes> up and %<pulls> %r into a sitting position."; elseif (new == "stand") return "%N %<wakes> and %<stands> up."; elseif (new == "lean") return "%N %<wakes> up and %<leans> over."; elseif (new == "rest") return "%N %<wakes> up, but %<remains> resting."; elseif (new == "lie") return "%N %<wakes> up."; else return ""; endif else if (new == "sit") return "%N %<sits> down."; elseif (new == "stand") return "%N %<stands> up."; elseif (new == "lean") return "%N %<leans> over."; elseif (new == "rest") return "%N %<slumps> down on the ground and %<rests>."; elseif (new == "lie") return "%N %<lies/lie> down on the ground."; else return "%N %<curls> up on the ground and %<dozes> off."; endif endif . @verb $xplayer:set_stance tnt @program $xplayer:set_stance if (player != this) return E_PERM; endif {stance, ?furniture = #-1, ?prep = ""} = args; this.stance = stance; if (length(this.furniture) == 2 && `valid(this.furniture[1]) ! E_TYPE => 0') `this.furniture[1]:drop_user(this) ! ANY'; endif if (furniture != #-1 && prep) "add this to furn using list?"; this.furniture = {furniture, prep}; else this.furniture = {#-1, ""}; endif . @verb $xplayer:moveto tnt @program $xplayer:moveto this:set_stance("stand"); pass(@args); . stand -> "awake" sit -> "sitting [down | {on} {furniture}]" lean -> "leaning [over | {on} {furniture}]" rest -> "resting [{on} {furniture}]" lie -> "lying [down | {on} {furniture}]" sleep -> "sleeping [{on} {furniture}]" @verb $xplayer:look_self tnt rxd @program $xplayer:look_self player:tell(this:titlec()); desc = this:description(); if (desc) player:tell_lines(desc); else player:tell("You see nothing special."); endif stance = tostr(this.stance == "lie" ? "ly" | this.stance, this.stance == "sit" ? "ting" | "ing"); stance = stance == "standing" ? "awake" | stance; furniture = this.furniture[1] != #-1 && $recycler:valid(this.furniture[1]) ? tostr(this.furniture[2], " ", this.furniture[1]:title()) | ""; furniture = furniture ? furniture | {"", "down", "down", "over"}[1 + (stance in {"sitting", "lying", "leaning"})]; if (!(this in connected_players())) player:tell($gender_utils:pronoun_sub(tostr("%{:He} %{!is} sleeping deeply", (furniture ? " " + furniture | ""), "."), this)); elseif (this.stance == "sleep") player:tell($gender_utils:pronoun_sub(tostr("%{:He} %{!is} sleeping", (furniture ? " " + furniture | ""), "."), this)); elseif ((idle = idle_seconds(this) < 60)) player:tell($gender_utils:pronoun_sub(tostr("%{:He} %{!is} ", stance, (furniture ? " " + furniture | ""), " and %{!looks} alert."), this)); else time = $string_utils:from_seconds(idle); player:tell($gender_utils:pronoun_sub(tostr("%{:He} %{!is} ", stance, (furniture ? " " + furniture | ""), ", but %{!has} been staring off into space for ", time, "."), this)); endif . @create $thing called "generic furniture",furniture @chmod furniture +rf @prop furniture.valid_actions {} @prop furniture.capacity 0 @prop furniture.users {} @verb furniture:drop_user tnt rxd @program furniture:drop_user user = args[1]; this.users = setremove(this.users, user); . @verb furniture:"g*et ta*ke" this none none rxd @program furniture:get if (this.users) player:tell("You can't pick that up; there are people on it."); else pass(@args); endif . @verb furniture:"sit stand lean rest sleep lie" any any any rd @program $furniture:sit actions = $list_utils:assoc(verb, this.valid_actions); if (player.location != this.location) player:tell("I don't see that here."); return; endif if(prepstr) prepstr = $code_utils:short_prep(prepstr); elseif (!prepstr && actions) try prepstr = actions[2][1]; except (E_RANGE) "malformed actions list-- verb with no preps"; player:tell("You can't ", verb, " on that."); return; endtry endif this:_check_users(); if (actions == {} || (actions && !(prepstr in actions[2]))) if(!prepstr) prepstr = "on"; endif player:tell("You can't ", verb, " ", prepstr, " that."); return; elseif (!this:is_unlocked_for(player)) player:tell("You can't use that."); return; elseif (length(this.users) >= this.capacity) player:tell("You can't fit there."); return; elseif (player in this.users && `player.stance == verb && player.furniture[2] == prepstr ! E_PROPNF => 0') player:tell("You're already doing that."); return; endif player:set_stance(verb, this, prepstr); this.users = setadd(this.users, player); $you:say_action(tostr("%N %<", verb == "lie" ? "lies/lie" | verb + "s", "> ", prepstr, " ", this:title(), ".")); . @verb furniture:_check_users tnt @program furniture:_check_users ":_check_users()"; ""; "Goes through the list of current users and checks to see if 1) they're in the same room as the furniture and 2) they're using this furniture. If not, the furniture silently drops them from the users list. This is run right before anyone tries to use the furniture."; ""; "(this is needed because despite my best efforts, certain things still send the furniture state into disarray-- most notably, a wizard using the furniture [since $wiz:moveto is very direct] or someone disconnecting into Limbo while using the furniture-- at which point the user will continue taking up a capacity slot.)"; for u in (this.users) if(u.location != this.location || `u.furniture[1] != this ! E_PROPNF, E_RANGE => 1') this:drop_user(u); endif endfor . "(this is "generic detailed room") @program $detailed_room:tell_contents {contents, ctype} = args; if (!this.dark && contents != {} && ctype == 4) players = things = {}; for x in (contents) if (is_player(x)) players = {@players, x}; else things = {@things, x}; endif endfor if (!this.integrate) for t in (things) if ($object_utils:has_readable_property(t, "look_msg")) player:tell($string_utils:pronoun_sub(t.look_msg, player, t, this)); else player:tell("You see ", t:title(), " here."); endif if ($object_utils:isa(t, $furniture) && (d = $set_utils:intersection({player, @players}, t.users))) "ideally, this shouldn't need the player if/else block, and players who have the same stance & prep should be grouped together w/ $string_utils:title_list (along w/ player if so)."; for p in (d) if(p == player) player:tell($string_utils:pronoun_sub(tostr(" %N %<is/are> ", p.stance == "lie" ? "ly" | p.stance, p.stance == "sit" ? "ting " | "ing ", p.furniture[2], " it."), $you, t)); else player:tell($string_utils:pronoun_sub(tostr(" %N %<is/are> here, ", p.stance == "lie" ? "ly" | p.stance, p.stance == "sit" ? "ting " | "ing ", p.furniture[2], " %t."), p, t)); endif endfor players = $set_utils:difference(players, t.users); endif endfor endif for p in (players) player:tell($string_utils:pronoun_sub(tostr("%N %<is/are> ", p.stance == "lie" ? "ly" | p.stance, (p.stance == "sit" ? "ting" | "ing"), " here."), p)); endfor else pass(@args); endif . --- "huh integration for things like 'sit down' or moving onto objects that don't exist @verb $xplayer:last_huh tnt rxd @program $xplayer:last_huh {verb, args} = args; if (verb in {"sit", "stand", "lie", "lean", "rest", "sleep"}) $xplayer_huh:(verb)(@args); return 1; else return 0; endif . $xplayer_huh:"sit stand" tnt rxd if