Generic Wandering Automaton (#502)
(an instance of Generic Automaton made by Zon)
     You see a homeless, nomadic robot. Its memory circuits were affected by being stored too close to a television set and may now be seen roaming about shouting "Exterminate! Exterminate!".
Go to location of this object, wooden box.
HELP MANUAL:
     The Generic Wandering Automaton is a wandering version of the Generic Automaton,
which is described below. A child of the Generic Wandering Automaton will randomly
wander from room to room, unless it has been interacted with during its last cycle
(see @setcycle below).
     
     Commands to Generic Wandering Automata:
     
     @start
      This causes the automaton to begin wandering. It will pick a random exit in the
room it is currently in and take it every 120 seconds (the default). If someone
has interacted with the automaton during that 120 seconds (or the time set by @setcycle),
it will not take an exit.
     
     @stop
      This causes the automaton to stop wandering.
     
     @setcycle to
      This sets the move interval of the automaton
     
     shoo
      This cause the automaton to leave the current location and not
      to come back for a while.
     
     Programming note:
      The ways_out property of the Generic Wandering Automaton contains
     a list of exit names that the automaton will try to use when leaving
     a room. By modifying this, and giving the exits in a particular area
     matching names, the area of movement of the automaton can be constrained.
     
     Also note that the act verb may be overridden to periodically perform some action,
other than or in addition to moving the 'bot around.
     ------------------------------------------------------------------------
     
     Help for Generic Automaton
     
     The Generic Automaton is an easy-to-program robot which responds to simple commands.
It can have multiple MOODS, each one of which has a different description and set
of RESPONSES. Commands trigger an announced response and can also trigger a TRANSITION
to another mood. For example, a trivial robot might be made as follows:
     
      @create #192 named robot
      @describe robot as "A crash-test dummy."
      @setresponse robot with hug,kiss: pets the Generic Wandering Automaton. It smiles.
      @setresponse robot with hit,kick: pets the Generic Wandering Automaton. It frowns.
     
     The pattern pet will be substituted with the verb name, and pets will be substituted
with the third-person form of the verb. So, if Calkins types "kiss robot" or "hit
robot", we will see:
     
      Calkins kisses the robot. It smiles.
      Calkins hits the robot. It smiles.
     
     This trivial automaton has only one mood (called "initial"), but things don't really
get interesting until multiple moods are created. Moods and transitions between
moods form a sort of MENTAL LANDSCAPE or personality which other players can explore,
somewhat like rooms and exits. To make a new mood (or switch to an existing mood),
use @setmood. For example, we can make our trivial robot slightly more interesting:
     
      @setmood robot to initial
      @transition robot with hit,kick:angry
      @setmood robot to angry
      @describe robot as "A very angry test dummy."
      @setresponse robot with hug,kiss: pets the Generic Wandering Automaton. It relaxes.
      @transition robot with hug,kiss:initial
      @setresponse robot with hit,kick: pets the Generic Wandering Automaton. It pets
visitor!
     
     Now kicking the robot will make it mad, and when it's mad it will react more violently
to being kicked again. Kissing or hugging it will calm it down (transition to initial
mood). If an automaton is left alone in a room, it automatically returns to the
"initial" mood, if it has one.
     
     To design an automaton think of what moods or states it should have. Pick a set of
basic commands to trigger responses and mood transitions. Draw a TRANSITION DIAGRAM!
Complex automatons have over a dozen moods and are impossible to design without
making a diagram. Here is the diagram of a three-mood stray dog:
     
      +-------<---------------<---------------+
      | |
      feed +---+ V +-->--+ +---+ |
      pet | | | | pet | | | kick |
      \ V | \ V pet \ V |
      HAPPY---+ INITIAL<---<---ANGRY------>----+
      | ^ | | ^ ^ feed
      | | feed | | kick | |
      | +---<-----<--+ +--->----+ |
      +------->------->------->------->---+
      kick
     
     Besides setting responses and transitions, you can use @rminputs to erase a response
and @actions to review the programming of a given mood. @rmmoods will erase
whole moods, and @cpmood will copy the responses and transisions of another mood
to the current mood (sometimes a convenient starting point for a mood that is similar).
Once the basic logic of an automaton is finished, @alias can be used to beef up
the number of verbs the robot will respond to:
     
      @alias robot with slug,punch,slap=hit
     
     Aliases apply to all moods, but are overridden by any set responses in any particular
mood. Useful tip: if you are using @notedit, beware that the automaton will return
to its "initial" mood when you depart to the note editor. So it is a good idea to
be carrying the robot while you are programming it.
VERB SOURCE CODE:
find_exits:
"find_exits() -- return a list of exit object numbers that are valid for the bot
to take from the current room. If the bot doesn't set ways_out, those exits are
the obvious_exits() - 'banned exits'. Otherwise, they are the exits named by ways_out
- 'banned exits'. ";
exits = {};
room = this:this_room();
if (this.ways_out != {})
for name in (this.ways_out)
exit = room:match_exit(name);
if ((valid(exit) && (!(exit in exits))) && (!this:banned(exit.dest)))
exits = listappend(exits, exit);
endif
endfor
else
obvious_exits = room:obvious_exits();
for exit in (obvious_exits)
if (valid(exit) && (!this:banned(exit.dest)))
exits = listappend(exits, exit);
endif
endfor
endif
return exits;
.
act_loop:
if (!this.stopped)
fork (0)
this:act();
suspend(this.act_interval);
this:act_loop();
endfork
endif
.
act:
"act(): the repeating action of the automaton goes here. It can be a movement, as
here, or be overridden to do some other repeating action";
if (this.should_act && ($object_utils:has_property(this.location, "exits") || is_player(this.location)))
exits = this:find_exits();
if (length(exits))
destination = exits[random(length(exits))];
destination:move(this);
endif
else
this.should_act = 1;
endif
.
@start:
if (player != this.owner)
player:tell("Only the owner of ", this.name, " can start it.");
return;
endif
if (this.stopped)
player:tell(this.name, " is now running.");
this.stopped = 0;
this.should_act = 1;
this:act_loop();
else
player:tell(this.name, " is already running.");
endif
.
@stop:
if (player != this.owner)
player:tell("Only the owner of ", this.name, " can stop it.");
return;
endif
if (this.stopped)
player:tell(this.name, " is already stopped.");
else
this.stopped = 1;
player:tell(this.name, " is now stopped.");
endif
.
accept_input:
"accept_input(): this keeps the Wandering automaton from walking off (acting), if
it has recently accepted input";
this.should_act = 0;
return pass(@args);
.
@setc*ycle:
if (player != this.owner)
player:tell("Only the owner of ", this.name, " can set its cycle time");
return;
endif
cycletime = tonum(iobjstr);
if (cycletime < 30)
player:tell("Cycle times must be greater than 30 seconds.");
return;
endif
this.act_interval = cycletime;
player:tell("Cycle time of ", this.name, " set to ", cycletime, " seconds ");
.
shoo:
current_room = this:this_room();
if (this.stopped)
player:tell(this.name, " isn't wandering, so can't be shoo'ed away.");
return;
endif
if (current_room in this.banned_rooms)
player:tell(this.name, " has already been shoo'ed away from ", current_room.name);
else
this.banned_rooms = setadd(this.banned_rooms, current_room);
this.ban_times = setadd(this.ban_times, time());
player:tell("You shoo ", this.name, " away from ", current_room.name, " for a
while.");
current_room:announce(player.name, " shoo's ", this.name, " away from ", current_room.name,
" for a while.");
this.should_act = 1;
this:act();
this.should_act = 0;
endif
.
banned:
"Boolean banned(room object #) -- is the room in the banned list?";
position = args[1] in this.banned_rooms;
if (position == 0)
return 0;
endif
"if the bots ban interval has expired, delete ban info and return 0, else return
1";
if ((time() - this.ban_times[position]) > this.ban_interval)
this.banned_rooms = listdelete(this.banned_rooms, position);
this.ban_times = listdelete(this.ban_times, position);
return 0;
else
return 1;
endif
.
this_room:
"is someone holding the wanderer?";
if (is_player(this.location))
return this.location.location;
else
return this.location;
endif
.
PROPERTY DATA:
      ways_out
      should_act
      stopped
      act_interval
      ban_times
      banned_rooms
      ban_interval
CHILDREN:
robot Strays mangy cat Generic Speaking Wandering Automaton brown goat Jeweled Scorpion lithe and winsome Afsheeni Breast Implants Hugo emma Lancelot
|