Version 4 of Reactable Quips by Michael Martin begins here.

"A table-based approach to NPC conversation chains, as well as allowing rules to fire on lines of conversation."

[Version 4: Cleanups for indexing.  Rule ordering bugfix.  Removed redundant rules.  Permit current quip to change in a "before quipping" rule.  Reset the number understood when necessary to duck a parser issue.  Add a specification for quips.  Removed ugly hacks to make parser asides work right in versions of Inform predating version 4S08.]
[Version 3: Replaced parentheses with brackets where appropriate, as is traditional for parser asides.  Removed the "wait silently" action by using conditional "understand" statements instead -- this produces sensible error messages in all circumstances as of version 3T38 of Inform 7.  Expanded documentation to show how default ask and tell quips can be individually universally redefined.  ]
[Version 2: Modified "if index is the noun" to "if index is the number understood" to compensate for Inform 7's improved type checking in 3R85.  Improved the output of REPEAT, and added RECAP as a synonym.]
[Version 1: Initial release.]

Section 1 - Quips

A quip is a kind of value.  The quips are defined by the Table of Quip Texts.  The specification of quip is "Represents a line or exchange of dialogue, which may be linked to other quips via followups or linked to ask or tell responses."

The current quip is a quip that varies.  The current quip is quip_null.
The pertinent quip is a quip that varies.  The pertinent quip is quip_null.

A person has a quip called default ask quip. The default ask quip of a person is usually quip_null.
A person has a quip called default tell quip. The default tell quip of a person is usually quip_dtell.

Quipping is an activity.

The last for quipping rule (this is the basic quipping rule): say "[quiptext of the current quip][paragraph break]";

To deliver the (q - quip) quip:
  change the current quip to q;
  carry out the quipping activity;
  let rq_index be 0;
  repeat through Table of Quip Followups begin;
    if the current quip is the quip entry begin;
      increase rq_index by 1;
      say "[bracket][rq_index][close bracket] [option entry][line break]";
    end if;
  end repeat;
  if rq_index is not 0 begin;
    change the pertinent quip to the current quip;
    change the number understood to 0;
  otherwise;
    change the pertinent quip to quip_null;
  end if.

Requesting a recap is an action out of world applying to nothing.  Understand "repetir" or "repite" as requesting a recap when the pertinent quip is not quip_null.

Carry out requesting a recap (this is the perform recap rule):
  let rq_index be 0;
  repeat through Table of Quip Followups begin;
    if the quip entry is the pertinent quip begin;
      increase rq_index by 1;
      if rq_index is 1, say "Las opciones disponibles son:[paragraph break]";
      say "[bracket][rq_index][close bracket] [option entry][line break]";
    end if;
  end repeat;
  if rq_index is 0 then say "[bracket]No hay respuestas disponibles.[close bracket][paragraph break]".

Responding with is an action applying to one number.
Understand "[number]" as responding with when the pertinent quip is not quip_null.

[This rule Can't Run, as the Understand commands stand..]
[Carry out responding with when the pertinent quip is quip_null (this is the can't talk out of conversations rule): 
  say "[bracket]BUG: Responded despite there being no conversation options available![close bracket]".]

[Likewise, this test is redundant.]
Carry out responding with [when the pertinent quip is not quip_null] (this is the perform responding rule):
  let rq_index be 0;
  repeat through Table of Quip Followups begin;
    if the quip entry is the pertinent quip begin;
      increase rq_index by 1;
      if rq_index is the number understood begin;
          deliver the result entry quip;
          rule succeeds;
      end if;
    end if;
  end repeat;
  say "[bracket]Respuestas validas de rango 1-[rq_index].  Teclea REPETIR para volver a listar respuestas.[close bracket][paragraph break]".

Instead of doing something other than requesting a recap or responding with when the pertinent quip is not quip_null (this is the force conversation rule):
   say "[bracket]Necesito alguna reacción para continuar la escena. Introduce un número, o teclea REPETIR para ver la lista de opciones.[close bracket][paragraph break]" instead.

A procedural rule: move the force conversation rule to before the before rules.
A procedural rule when the pertinent quip is not quip_null: ignore the turn sequence.

Section 2 - Hitword-based conversation

Instead of asking someone about something: 
    repeat through Table of Ask Results
    begin;
        if the noun is the NPC entry begin;
        if the topic understood includes topic entry
        begin;
            deliver the result entry quip;
            rule succeeds; 
        end if; end if;
    end repeat; 
    if the noun is a person begin;
        say "[quiptext of the default ask quip of the noun][paragraph break]"; 
        rule succeeds; 
    end if;
    say "[bracket]BUG: Managed to talk to [a noun], who is not a person![close bracket]".

Telling someone about something is reactable quips speech.
Answering someone that something is reactable quips speech.

Instead of reactable quips speech: 
    repeat through Table of Tell Results
    begin; 
        if the noun is the NPC entry begin;
        if the topic understood includes topic entry
        begin;
            deliver the result entry quip;
            rule succeeds; 
        end if; end if;
    end repeat; 
    if the noun is a person begin;
        say "[quiptext of the default tell quip of the noun][paragraph break]"; 
        rule succeeds; 
    end if;
    say "[bracket]BUG: Managed to talk to [a noun], who is not a person![close bracket][paragraph break]"

Section 3 - Quip Tables

Table of Quip Texts
quip		quiptext
quip_null	"You can't think of anything to say on that topic."
quip_dtell	"You can't think of anything to say on that topic."

Table of Quip Followups
quip		option		result
a quip		text		a quip

Table of Ask Results
NPC		topic		result
a person		a topic		a quip

Table of Tell Results
NPC		topic		result
a person		a topic		a quip

Reactable Quips ends here.

---- DOCUMENTATION ----

Reactable Quips provides a table-driven conversation system for NPCs that allows a mixture of traditional ask/tell and menu-based systems.  The intended model is that under normal circumstances, the player character may initiate conversation by asking or telling an NPC about a topic.  That NPC will then respond.  However, NPCs may occasionally say or do things that demand or imply some kind of reaction from the PC -- the player must then choose some option off a menu to characterize the reaction.

Regardless of the intended model, it is quite possible to use the extension to implement a pure ask/tell system.

The most fundamental concept in the extension is the "quip".  Quips are values, not things; they are used to index into the quip tables.

Thus, the one task we must always perform is filling in the Table of Quip Texts.  A default table is provided by the extension, so you will need to continue the table in your own code:

	Table of Quip Texts (continued)
	quip	quiptext
	greeting	"'Why, hello there!'"
	discuss weather	"'Looks like rain, or my name isn't George Washington.'"
	standoff	"'What's it to you, Mac?'"

We then (if we are using the ask/tell model) use the Table of Ask Results and Table of Tell Results to attach quips to NPCs and topics.  The topics may be patterns, much like understanding commands as actions are.  However, the library will match against any text that contains the topic (much like Example 233: "Complimentary Peanuts").  The results are quips.

	Table of Ask Results (continued)
	NPC	topic	result
	Bob	"weather" or "nice day"	discuss weather

	Table of Tell Results (continued)
	NPC	topic	result
	Bob	"hi/hello"	greeting

People have a "default ask quip" and "default tell quip" that can be used to give a generic response to unknown topics.  This defaults to the first two quips in the table, which are predefined to "You can't think of anything to say on that topic."  If you wish to universally redefine either of these, you may do so by redefining them as follows:

	change the quiptext entry of row 1 of the Table of Quip Texts to "This is the new default response to asking a person about an unknown topic."
	change the quiptext entry of row 2 of the Table of Quip Texts to "This is the new default response to telling a person about or answering them that an unknown topic."

We can also script quip delivery:

	Instead of examining Bob, deliver the greeting quip.

Quips can be attached to rules; however, quips aren't things, and so can't be treated as "something" or "anything."  Instead, we use rulebooks associated with the quipping activity:

	Before quipping when the current quip is greeting: say "You walk up and say hello."

Quips may require a reaction.  Possible responses (and the quips those responses lead to) are stored in the Table of Quip Followups:

	Table of Quip Followups (continued)
	quip	option	result
	greeting	"Make small talk"	discuss weather
	greeting	"Get down to business"	standoff

If a quip is in the table of quip followups, the game will not progress until a choice has been made.  If a quip does not appear in the table of quip followups, then after delivering the quip, normal gameplay resumes.

Example: ** When Injokes Collide - Matching important words in a phrase, or matching complete phrases, and reacting to quips with rules.

Note that in some versions of Inform 7, this code may not work if you simply cut and paste it out of the Documentation window; the tables will not render properly in the Source window.  Copy it out of the actual Documentation file instead.

	"When Injokes Collide"
	
	Include Reactable Quips by Michael Martin.
	
	Use American dialect, the serial comma, and no scoring.
	
	Horace's House is a room.  A man called Horace is here.  "Your eccentric neighbor Horace is here, with a T-shirt that says 'TELL ME ABOUT YOURSELF.'"
	
	Table of Quip Texts (continued)
	quip			quiptext
	suggest monkeys		"'That's nice, I suppose.  But have I told you how awesome monkeys are?  You should ask me about monkeys!'"
	yay monkeys		"'Monkeys are awesome!  Anyone with [italic type]any[roman type] sense loves monkeys.  Did you know?  It was humans who unleashed Zero Wing on an unsuspecting universe.'"
	hate aybabtu		"Horace unleashes an unearthly howl.  restar'AIIIEEEEE!  NO!  Speak of it not!  Never again!  Hate you forever!  Die die die!!!!'[paragraph break]He leaps for your throat, wrestles you to the ground, and pummels the 	consciousness out of you.  Death will follow soon enough..."
	apes ok			"'They're OK, I guess, but they're not nearly as great as monkeys.'"
	humans lousy		"'Humans in general are vastly inferior to monkeys.'"
	kindred spirit		"'Finally!  A kindred spirit!  My quest is finally over.  Take this briefcase as a token of my appreciation.'[paragraph break]He hands you a briefcase full of solid gold Krugerrands."
	speciesist		"'Oh, you're just speciesist like the rest of them.'"
	
	Table of Quip Followups (continued)
	quip			option			result
	humans lousy		"Fervently agree"		kindred spirit
	humans lousy		"Shrug indifferently"	speciesist
	
	Table of Ask Results (continued)
	NPC		topic						result
	Horace		"monkeys"					yay monkeys
	Horace		"lemurs/apes/gibbons/orangutans/bonobos/gorillas"	apes ok
	Horace		"humans/people/me/you/myself/yourself"		humans lousy
	Horace		"All his/her/your base" or "All his/her/your base are belong to us/you/me" or "AYBABTU"	hate aybabtu
	
	Table of Tell Results (continued)
	NPC		topic		result
	Horace		"self/me/myself"	suggest monkeys
	
	After quipping when the current quip is hate aybabtu: end the game saying "You have no chance to survive make your time".
	After quipping when the current quip is kindred spirit: end the game in victory.
	
	test winning with "ask horace about people / 3 / 1".
	
	test me with "tell horace about myself / ask horace about how awesome monkeys are / ask horace about humans / go east / repeat / 2 / ask horace about gibbons / ask horace about all his base".
