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 |