Roger Firth's IF pages | ![]() |
InfAct -- about Inform NPCs | ![]() |
![]() |
This casual chatting with your NPC is all very well, but it's a bit, well, passive. There are times when you'd like to have him do as he's told.
The conventional way of getting an NPC to perform some action on your bidding is to use a form like USHER, GO EAST. The NPC's orders property is designed to handle this.
Object usher "gentleman usher" cloakroom
with name 'usher' 'gentleman' 'gentle' 'man',
description "The usher is smartly uniformed.",
orders [;
Go:
"~Sorry - I mustn't leave the cloakroom.~";
Take:
if (noun ~= cloak) "~Thank you, but no.~";
move cloak to hook; give cloak ~worn;
"~I'll just hang it on here for you.~";
Drop:
move noun to location;
print_ret (The) self, " drops ", (the) noun, " on the floor.";
Give:
move noun to second;
print_ret (The) self, " hands over ", (the) noun, ".";
NotUnderstood:
"~Pardon?~";
default:
"~I think not.~";
],
has animate male;
|
This code is really a bit too simplistic; for example, there ought to be a check that the usher is actually holding the object before he Drops or Gives it. (The Library doesn't do much validation here; ensuring sensible behaviour is down to you.) However, for our purposes, it's enough to support a little give and take.
>USHER,TAKE THE CLOAK "I'll just hang it on here for you." >INVENTORY You are carrying nothing. >USHER,DROP THE CLOAK The gentleman usher drops the velvet cloak on the floor. >ASK USHER FOR THE CLOAK The gentleman usher hands over the velvet cloak. |
If your NPC doesn't have an orders property, or has one which returns false, then the library passes the order to the life property. This is only for compatibility with older games; you're recommended always to deal with orders by providing a comprehensive orders property.
The useful package AskTellOrder.h extends the library syntax to encompass orders like ASK USHER TO TAKE THE CLOAK or TELL USHER TO DROP THE CLOAK. Cleverly, it does this by modifying the input buffer so that these two orders become USHER,TAKE THE CLOAK and USHER,DROP THE CLOAK; all you need do is Include the package.
>ASK USHER TO TAKE THE CLOAK "I'll just hang it on here for you." >TELL USHER TO DROP THE CLOAK The gentleman usher drops the velvet cloak on the floor. >USHER,GIVE ME THE CLOAK The gentleman usher hands over the velvet cloak. |
A natural extension of the orders syntax outlined here is the handling of questions: USHER, WHAT|WHERE|WHO IS A|THE ... One approach to this follows that suggested for conversational topics on a previous segment:
Object Queries "conversational queries";
Object -> q_cloak with name 'handsome' 'dark' 'black' 'velvet' 'cloak';
Object -> q_opera with name 'opera' 'show' 'performance';
Object -> q_time with name 'time';
Object -> q_bar with name 'bar';
Object -> q_foyer with name 'foyer';
[ QueryScope; switch(scope_stage) {
1: rfalse;
2: ScopeWithin(Queries); rtrue;
3: "At the moment, even the simplest questions are confusing.";
} ];
[ WhatIsSub; "You seem to be talking to yourself."; ];
[ WhereIsSub; "You seem to be talking to yourelf."; ];
Verb 'what' 'who'
* 'is'/'are' scope=QueryScope -> WhatIs;
Verb 'where'
* 'is'/'are' scope=QueryScope -> WhereIs;
|
With the query objects and the grammar in place, the orders handlers are straightforward:
Object usher "gentleman usher" cloakroom
with name 'usher' 'gentleman' 'gentle' 'man',
description "The usher is smartly uniformed.",
orders [;
|
Look at the WhoWhat.h package for further ideas.
In the last segment, we take off the brakes.