---+ Object Movement
From a programmer's point of view, movement can be more complex than you might think. The core details are in [manual's section on movement], but things are more complicated than just that, in <nop>HellMOO.
==$exit:invoke([who])==. Once an exit is identified as the one a player wants to (or is being made to) go through, invoke is called, which queues the Move action for that player, and the other members of that player's party if he/she has one. (see ProgActions). If the player is busy moving already, the exit's name is queued, otherwise, the exit's object number is queued as the target of the action.
==$actions.move:_start==. If the action's target is a string, check for the exit with that name, and if it isn't there stop the player's queue. Otherwise: check to see if the player is too weighted down to move. If not, check to see if the player's fighting anyone and if there's smoke where the player is. Check the player's dodge vs his opponent's senses if there's smoke -- certain values let him escape faster. If the check is failed, or there is no smoke and there are opponents, wait 5 seconds before passing =exit:try_me(who, 1)= to =this:_finish=. If there are no opponents at all or the check was made, pass that same value much faster (0 - 1.5 seconds, plus =exit:speed(who)=).
==$exit:try_me==(OBJ who [, INT silent]). make sure that =who= is in the same location as the exit. check =this:allows(who)=.
==$exit:allows==(OBJ who). make sure that both =this.otherside= and =this.otherside.location= are valid. if =this.passable=, return =this.otherside.location:acceptable(who)=, otherwise return 0.
==$exit:acceptable==(OBJ who). return 1.
==$exit:try_me== (from above). if =this:allows(who)= is false, announce the problem to the room, and return =E_PERM=. otherwise, if =!silent=, announce the =leave_msg= and return 1.
==$actions.move:_finish==. if the target of this action is a string, find the object number of the exit referred to. if the passed value (from =exit:try_me=) was 1, then check how many people are fighting and how strong they are, and check this vs the player's reflexes. if the check fails, so does the move, but if the check is successful or there are no opponents, call =exit:move(who)=.
==$exit:move==(OBJ what). Make sure player is in the same location as the exit. If =this:allows(what)=, call =what:moveto(this:dest_for(what))=.
==$exit:dest_for==(OBJ what). If =this.otherside= is valid, return =this.otherside.location=.
==$creature:moveto==(OBJ where). first, =pass(@args)=.
==$thing:moveto==(OBJ where). return =move(this, where)=.
==move -> $room:accept==(OBJ what). return 1, all things are acceptable at this point.
==move -> $room:exitfunc==(OBJ what). remove =what= from the lists of occupants of furniture in the room, of covering creatures (see ProgActionsCover), if it is an exit remove it from the exits list, update =this.tracks= (see ProgTracking), make sure =what.posture= is "standing" and disengage =what= from combat. Then return 1.
==move -> $room:enterfunc==(OBJ what). If =what= is a player, show them the description of the room. If it's an exit, add it to the exits list. If it is any creature (includes players), update =this.tracks= (again, see ProgTracking), infect it with any biohazards that are in =this.biohazards=, and update furniture occupant lists if necessary.
==$creature:moveto== (from above). Broadcast the Move action in the old location of =this=. (see ProgEvents). call =this:enter_room(where)=.
==$creature:enter_room==(). If =this.hunting= and the object =this= is hunting is here, engage them in a fight.
==$creature:moveto== (from above). Broadcast the Arrive action in the new location of =this=. (again see ProgEvents). return what =pass(@args)= returned.
==$exit:move== (from way up there). If the move was successful (the location of =what= has changed), accumulate smoke if there is any, otherwise announce the departure of =what= with =oleave_msg=. Announce the arrival of =what= in its new location using its =arrive_msg=. Update last usage times on =this= and =this.otherside=. Update =what='s thirst and stress values, if applicable, and then return 1. Return 0 if the move was not successful.
==$actions.move:_finish== (from way up top). _Finally_, the player has moved into another room. Return the value of =exit:move(who)=.
This is only, actually, the most simple of movements, and it becomes much more complicated with locks and such.
-- Main.BlackLite - 28 Nov 2004