Generic Automaton (#192)(an instance of generic thing made by Calkins)     You see a perfect copy of Rotwang's art-deco robot from _Metropolis_. Go to location of this object, wooden box. HELP MANUAL:      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: heckles the Generic Automaton. It smiles.       @setresponse robot with hit,kick: heckles the Generic Automaton. It frowns.            The pattern heckle will be substituted with the verb name, and heckles 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: heckles the Generic Automaton. It relaxes.       @transition robot with hug,kiss:initial       @setresponse robot with hit,kick: heckles the Generic Automaton. It heckles 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 VERB SOURCE CODE: bonk kick kiss feed pet harass annoy punch hit cuddle hug kill tip pay buy slap bind tie cuff flirt chat smile wink grin goose molest grab tickle wrestle massage strip fondle unbind dress play proposition attack fight handcuff untie uncuff release talk caress undress club wake wave heckle fuck suck blow pinch squeeze twist boo screw lick stroke speak whisper drugs drug slug unveil veil strike touch hiss with scare threaten grope rim french sigh laugh giggle smirk chuckle snicker love like adore comfort look peer mock ignore poke milk fellate swallow unzip open-fly-for kneel lick-my-ass lick-my-feet blow-me lick-my-fuck THIS-SHOULD-NOT-BE-A-VERB-ON-#192 polish fuel tease surrender bore whack sock rub burnish shine calm stupefy provoke bother bug hassle joke insult dis tweak beg plead submit bow sodomize bugger hump mount fill oil slam smack capitulate praise flatter pacify worship respect mercy slurp hold nuzzle grovel whimper pat feel finger glare whine pout on off worshop squash pester crush step stomp woo seduce court sobs smiles sings push sing eat hum growl curse scowl tempt rob beat swat belt shtup knee bully to make dance kic soothe whisper_to murmur_to pets huge bite spank pull tail call scold yell injure:
if ((player.location != this.location) && (player != this.location))
player:tell("You aren't close enough to ", verb, " ", this.name, ".");
return;
endif
if (!this:accept_input(verb))
player:tell(this.name, " doesn't respond to that.");
endif
.
@setm*ood:
if (player == this.owner)
if (this:create_state(iobjstr))
player:tell("New mood created.");
endif
this:change_state(iobjstr);
player:tell(this.name, " is now ", iobjstr, ".");
this:look_self();
else
player:tell(E_PERM);
endif
.
@moods:
if (player == this.owner)
player:tell(this.name, "'s moods are ", $string_utils:print(this.states));
else
player:tell("Only the owner of ", this.name, " can list the moods.");
endif
.
@act*ions:
if (player != this.owner)
player:tell("You may not do that.");
return;
endif
player:tell("In ", this.state, " mood, ", this.name, " does:");
if (this.input)
for i in (this.input)
n = i in this.input;
player:tell(i, ": ", player.name, this.response[n]);
player:tell(" and then has mood ", this.transition[n]);
endfor
else
player:tell("Nothing.");
endif
.
audience:
if ($object_utils:connected(this.location))
return 1;
else
for c in (this.location.contents)
if ($object_utils:connected(c))
return 1;
endif
endfor
endif
return 0;
.
change_state:
if (caller != this)
return E_PERM;
endif
if ((new = args[1] in this.states) && ((old = this.state in this.states) != new))
if (old)
this.descriptions[old] = this.description;
this.inputs[old] = this.input;
this.responses[old] = this.response;
this.transitions[old] = this.transition;
endif
this.state = this.states[new];
this:set_description(this.descriptions[new]);
this.input = this.inputs[new];
this.response = this.responses[new];
this.transition = this.transitions[new];
endif
.
tell:
if (!this:audience())
this:change_state("initial");
endif
.
@rmi*nputs:
if (player != this.owner)
player:tell("You may not remove inputs form this.");
return;
endif
del = $string_utils:explode(strsub(dobjstr, ",", " "));
for i in (del)
if (n = i in this.input)
this.input = listdelete(this.input, n);
this.response = listdelete(this.response, n);
this.transition = listdelete(this.transition, n);
endif
endfor
player:tell(this.name, " now can respond to ", $string_utils:print(this.input));
.
@rmmoods:
if (player != this.owner)
player:tell("You may not remove moods form this.");
return;
endif
del = $string_utils:explode(strsub(dobjstr, ",", " "));
for i in (del)
if (n = i in this.states)
this.inputs = listdelete(this.inputs, n);
this.responses = listdelete(this.responses, n);
this.transitions = listdelete(this.transitions, n);
this.descriptions = listdelete(this.descriptions, n);
this.states = listdelete(this.states, n);
endif
endfor
player:tell(this.name, " now has states: ", $string_utils:print(this.states));
if (!(this.state in this.states))
if (this.states)
this:change_state(this.states[1]);
player:tell(this.name, " is now in ", this.state, " mood.");
else
this.state = 0;
this.input = {};
this.response = {};
this.transition = {};
player:tell(this.name, " has no moods now.");
endif
endif
.
@setr*esponse:
if (player != this.owner)
player:tell("You may not set the responses of this.");
return;
endif
if (i = index(iobjstr, ":"))
cmdstr = iobjstr[1..i - 1];
resp = iobjstr[i + 1..length(iobjstr)];
else
player:tell("Try @setr
@trans*ition:
if (player != this.owner)
player:tell("You may not set the transitions of this.");
return;
endif
if (i = index(iobjstr, ":"))
cmdstr = iobjstr[1..i - 1];
trans = iobjstr[i + 1..length(iobjstr)];
else
player:tell("Try @trans
install_inputs:
if (caller != this)
return E_PERM;
endif
new = {};
for i in (args[1])
if (!(i in this.input))
new = {@new, i};
endif
endfor
if (new)
this:new_verb(new);
this.input = {@this.input, @new};
for i in (new)
this.response = {@this.response, " responds to " + i};
this.transition = {@this.transition, this.state};
endfor
endif
return 1;
.
subst_verb:
s = args[1];
v = args[2];
lv = length(v);
if (v[lv] in {"s", "x", "o", "u", "i"})
vs = v + "es";
elseif ((lv >= 2) && (v[lv - 1..lv] in {"ch", "sh"}))
vs = v + "es";
elseif ((lv >= 2) && (v[lv - 1..lv] in {"ay", "ey", "oy", "uy"}))
vs = v + "s";
elseif (v[lv] == "y")
vs = v[1..lv - 1] + "ies";
elseif (i = v in {"be", "have"})
vs = {"is", "has"}[i];
else
vs = v + "s";
endif
s = strsub(s, "%vs", vs);
return strsub(s, "%v", v);
.
create_state:
mood = args[1];
if ((mood in this.states) || (caller != this))
return E_PERM;
else
this.states = {@this.states, mood};
this.descriptions = {@this.descriptions, this.description};
this.inputs = {@this.inputs, {}};
this.responses = {@this.responses, {}};
this.transitions = {@this.transitions, {}};
return mood;
endif
.
@cpmood:
if (player != this.owner)
player:tell(E_PERM);
return;
endif
if (this.input)
player:tell("The current state, ", this.state, " is not empty. Do an @rmmoods
and @setmood if you really want to overwrite it with a @cpmood.");
return;
endif
if (i = iobjstr in this.states)
this.input = this.inputs[i];
this.response = this.responses[i];
this.transition = this.transitions[i];
for it in [1..length(this.transition)]
if (this.transition[it] == this.states[i])
this.transition[it] = this.state;
endif
endfor
this:set_description(this.descriptions[i]);
player:tell(iobjstr, " mood copied to ", this.state, ".");
this:look_self();
else
player:tell(this.name, " doesn't have a mood of ", iobjstr, ".");
endif
.
look_self:
if (this.title_msg)
player:tell($string_utils:pronoun_sub(this.title_msg));
endif
pass(@args);
if (this.append_msg)
player:tell($string_utils:pronoun_sub(this.append_msg));
endif
.
@alias:
if (player != this.owner)
player:tell(E_PERM);
return;
endif
if (i = index(iobjstr, "="))
dststr = iobjstr[1..i - 1];
src = iobjstr[i + 1..length(iobjstr)];
else
player:tell("Usage: @alias
new_verb:
if (caller != this)
return E_PERM;
endif
new = args[1];
info = verb_info(#192, "bonk");
bonks = $string_utils:explode(info[3]);
for i in (new)
if (index(i, " ") || ($object_utils:has_verb(this, i) && (!(i in bonks))))
return 0;
endif
endfor
bonks = $list_utils:remove_duplicates({@bonks, @new});
info = listset(info, $string_utils:from_list(bonks, " "), 3);
set_verb_info(#192, "bonk", info);
.
accept_input:
input = args[1];
if (input in this.input)
cmd = input;
elseif (i = input in this.alias_names)
cmd = this.alias_values[i];
else
cmd = "huh";
endif
if (i = cmd in this.input)
resp = player.name + this.response[i];
resp = $string_utils:pronoun_sub(this:subst_verb(resp, input));
this.location:announce_all(resp);
this:change_state(this.transition[i]);
if (this.autolook_msg == "ON")
this:look_self();
endif
return 1;
else
return 0;
endif
.
PROPERTY DATA:       states       state       descriptions       input       response       transition       inputs       responses       transitions       help_msg       append_msg       title_msg       autolook_msg       alias_names       alias_values CHILDREN: the monkey Sal Caveman love slave Mazakeen sailor The Table Of Doom Generic Wandering Automaton Luce Aurora statue Generic Interzone Boy Grim Reaper Tattooed Lady Snake Charmer Snake L The Savior Holy Mother Kathleen |