The Generic Swinging Weapon

  1. Editing Properties and Verbs
  2. Programming
  3. Forks and Tasks

Even though I’m going to leave the majority of programming instruction to the official manual, I’m a firm believer that you can never have too many examples. This is Valhalla. Lots of gods with short tempers. We will have swords, staves, and hammers coming out of (and into) our ears. Let's make a generic swinging weapon to base them all on.

@create $thing named generic swinging weapon,swinger

@describe swinger as "a nondescript weapon of untold power; be careful with it: you might knock someone's eye out!

We need a verb of some sort so that we can hit people with it. What are the possibilities?

hit Jack with sword

strike Thor with staff

There is a big problem with both of these. Remember the order of searching? The MOO is going to look at Jack and Thor (the direct objects) before it looks at sword or staff. If I bother them too much, they’ll create a swing verb on themselves:

@verb me:"Hit Strike" any with this

@edit me:Hit

"player:tell("You miss.");

"player.location:announce($string_utils:pronoun_subs("%N strikes at %d with %p %i. %D dodges nimbly, and %n strikes the ground, leaving %r embarrassed and revealing %p utter incompetence."));

compile

done

Since the MOO will get to this verb before it gets to ours, whenever we try to hit or strike Thor, we'll see:

You miss.

And everyone else will see:

Balder strikes at Thor with his staff. Thor dodges nimbly, and Balder strikes the ground, leaving himself embarrassed and revealing his utter incompetence.

Do we really want that? How about, since this is a generic swinging weapon:

swing staff at Thor

Okay.

@verb swinger:swing this at any

@edit swinger:swing

The @verb creates the verb ‘swing’ on ‘swinger’. And then @edit allows us to edit it, and add instructions:

"if (valid(iobj))

If the player typed a valid object—something that exists—do the rest of this. Otherwise, Valhalla will jump down to the ‘else’ a couple lines down.

"player:tell("You hit ",iobj.name," with your ",this.name,".");

"player.location:announce_all_but({player,iobj}, $string_utils:pronoun_sub("%N hits %i with %p %d. It is a crushing blow."));

Here, we first tell the player who swung the weapon that the weapon (‘this.name’) hit the target (‘iobj.name’). ‘Name’ in each case is a property of the object referred to by ‘this’ and ‘iobj’. You refer to object properties with object.property. Tell is a verb that exists on player. We use it by typing player:tell. Announce_all_but is a verb that exists on the room that the player is in. We know the room because it is in the player’s property location. So, player.location:announce_all_but uses that verb. First, Valhalla interprets ‘player.location’, and then looks for the verb announce_all_but on that location. This is how we refer to verbs: object:verb(information for the verb).

Then, we tell everybody in the room—except the player, who we already told, and the target (‘iobj’), who we’ll tell in a moment—the same thing. Notice that we also call the pronoun_sub verb to interpret all those ‘%’ things. The pronoun_sub verb is on an object called $string_utils.

"if ($object_utils:has_callable_verb(iobj,"tell"))

"iobj:tell($string_utils:pronoun_sub("%N swings %p %d at you and deals an ugly wound. Good lord, %i, are you going to stand for that?"));

"endif

Here’s a complete if statement. If the target (‘iobj’) has a verb that we can use called ‘tell’, Valhalla will use the verb after the if statement and before the endif statement. In this case, it tells the iobj that it has been hit by the player swinging the weapon.

"else

"player:tell("I don't see any ",iobjstr," here. Feeling a little troubled?");

"player.location:announce($string_utils:pronoun_sub("%N appears to be developing an interesting rapport with %p %d"));

"endif

This else and endif belong to the first ‘if’ at the beginning of this verb. The part between the else and the endif here will only be used if the if (valid(iobj)) comes back and says “no, the player didn’t refer to a valid object.” In other words, the MOO uses the first part (between the if and the else) if the statement valid(iobj) is ‘true’; else it uses the second part (between the else and the endif).

And what we’ve decided to do is, first, tell the player that we couldn’t find any ‘iobjstr’ to swing at, and, second, announce to everyone in the room that the player is doing something strange. Iobjstr is the text after the first preposition. It’s like iobj, except that it’s text instead of an object number. Announce is a verb that all rooms have, and it tells everyone in the room—except for the player who called the verb—whatever we put between the parentheses. In this case, that the player “appears to be developing an interesting rapport with” a generic weapon.

compile

Compile tells the MOO to check the verb for errors, and then save the verb so that it can be used. You must compile your verbs before what you typed can be used.

done

Done returns you to wherever you were before you started editing the verb.

@chparent staff to swinger

Balder already created a staff in order to demonstrate creating objects. The @chparent command makes that staff a child of swinger, as if Balder had originally created it with @create swinger named staff. The staff now can do anything that a generic weapon can.

swing staff at Captain Video

You swing the staff at Captain Video

Everyone else (except Captain Video) sees:

Balder hits Captain Video with his staff. It is a crushing blow.

And Captain Video sees:

Balder swings his staff at you and deals an ugly wound. Good lord, Captain Video, are you going to stand for that?

Now, this isn’t really that interesting of a generic. You can @create all the staves, swords, and maces you want, they’ll still all “hit” and “deal ugly wounds”. At the end of this section, I’ll show you a better form of generic, that includes messages—properties that the owner can change, like all of the messages we fooled around with in Advanced Building.

The Advantages of Being Object-Oriented

Let’s make a present for Thor. First, we need to complete one more thing on the generic swinging weapon. We need to make it fertile.

@chmod swinger to +f

This adds ‘fertility’ to the swinger. Until an object is fertile, only the owner can make children from it. Anyone can make children from a fertile object. Now that swinger is fertile, anyone in Valhalla can @create swingers named whatever they want.

@create swinger named "Thor's Hammer",hammer,Mjolnir

Now, as anyone who reads comics—I mean, studied Norse mythology—knows, Thor’s Hammer is not your average weapon. One of its biggest properties is that it returns to Thor after Thor throws it.

Right now, Thor’s hammer can be ‘thrown’ just like any other object. It’s a $thing, and all $things have a throw verb which allows them to be thrown. Because Valhalla is object-oriented, we can override the basic throw verb with our own:

@show hammer:throw

Object #98 does not define that verb, but its ancestor #5 does.

#5:"dr*op th*row"

Owner: Thor (#2)

Permissions: rxd

Direct Object: this

Preposition: none

Indirect Object: none

I use the @show command to find out what the exact syntax for throw is. If I don’t copy it exactly, my ‘throw’ may not override all instances that players will use.

@verb hammer:th*row" this none none

@edit hammer:throw

"if (player != this.owner)

"pass(@args);

"else

"player:tell("You fling the ",dobjstr," across the sky.");

"player.location:announce(player.name," flings ",player.pp," ",dobjstr," out of sight!");

"player.location:announce("The ",dobjstr," flips back around and returns to ",player.name,".");

"player:tell("Your ",dobjstr," returns to your grasp.");

"endif

compile

done

The important thing to look at here is the pass(@args); verb. This passes the sentence to the parent verb. If anyone other than the hammer’s owner throws the hammer, it throws normally. If the owner (Thor) throws it, we take control and send out our special messages. By passing control on to the parent verb when we do want the hammer to be thrown normally, we don’t have to worry about what goes on in throwing an object, and, if the administrators ever improve their ‘throw’ verb, our own ‘throw’ verb will reflect these improvements.

Also, the original ‘throw’ verb is combined with drop. We didn’t override drop at all, so if Thor drops his hammer, it won’t return to him.

If you have any other questions about the statements in this verb, see the LambdaMOO Programmer's Manual, available at all fine virtual bookstores.

A Better Generic Swinging Weapon

@create $thing named generic swinging weapon:generic swinging weapon,swinger

@describe swinger as "a nondescript weapon of untold power; be careful with it: you might knock someone's eye out!"

@prop swinger."swing_msg" "You &hit %i with your %d, &wounds."

@prop swinger.tswing_msg "%N &ohits you with %p %d, &wounds. &tcomment"

@prop swinger.oswing_msg "%N &ohits %i with %p %d, &wounds."

@prop swinger.wounds_msg "dealing a deadly wound"

@prop swinger.no_target_msg "I don't see any %i here. Feeling a little troubled?"

@prop swinger.ono_target_msg "%N appears to be developing an interesting rapport with %p %d."

@prop swinger.hit_msg "hit"

@prop swinger.ohits_msg "hits"

@prop swinger.tcomment_msg "Good Lord, %i, are you going to stand for this?"

@prop swinger.help_msg ""

@notedit swinger.help_msg

"The generic swinging weapon has the following messages:

" tswing: What the target sees when the weapon is swung.

" swing: What the swinger sees when the weapon is swung.

" oswing: What others see when the weapon is swung.

" no_target: What the swinger sees when the weapon is swung at a target that doesn't exist.

" ono_target: What others see when the weapon is swung at a target that doesn't exist.

"

"In addition, the following 'ampersand' substitutions can be placed in the above messages:

" &wounds: Should be set to the kind of wounds the weapon does as a phrase: "dealing a deadly wound"

" &hit: What the weapon does when it hits as the swinger sees it: "hit"

" &ohit: What the weapon does when it hits as others see it: "hits"

" &tcomment: An extra comment for the target. Should be a complete sentence. "Good Lord, %i, are you going to stand for this?"

"

"For the current state of the above messages, use the @messages verb.

"

"Remember to be careful what you do with this thing! We don't want any ownerless eyeballs floating around Valhalla.

@verb swinger:swing this at any

@program swinger:swing

if (valid(iobj))

player:tell($string_utils:pronoun_sub(this:hitting_sub(this.swing_msg)));

player.location:announce_all_but({player, iobj}, $string_utils:pronoun_sub(this:hitting_sub(this.oswing_msg)));

if ($object_utils:has_callable_verb(iobj, "tell"))

iobj:tell($string_utils:pronoun_sub(this:hitting_sub(this.tswing_msg)));

endif

else

player:tell($string_utils:pronoun_sub(this:hitting_sub(this.no_target_msg)));

player.location:announce($string_utils:pronoun_sub(this:hitting_sub(this.ono_target_msg)));

endif

.

@verb swinger:hitting_sub this none this

@program swinger:hitting_sub

The_Message = args[1];

Substitute_List = {{"&hit", this.hit_msg}, {"&ohits", this.ohits_msg}, {"&wounds", this.wounds_msg}, {"&tcomment", this.tcomment_msg}};

Munged_Message = $string_utils:substitute(The_Message, Substitute_List);

return Munged_Message;

  1. Editing Properties and Verbs
  2. Programming
  3. Forks and Tasks