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