Man message
From LSWiki
Revision as of 10:23, 11 June 2007 (edit) Laine (Talk | contribs) (→Files) ← Previous diff |
Current revision (16:26, 7 October 2017) (edit) Chaos (Talk | contribs) (→EXAMPLES) |
||
Line 1: | Line 1: | ||
- | '''man message''' | + | '''message - advanced multipurpose messaging protocol''' |
- | message - basic multipurpose messaging protocol | + | |
==SYNOPSIS== | ==SYNOPSIS== | ||
- | varargs void message(mixed array list, object array exclude, | + | void message(mixed spec); |
- | object array define, function filter); | + | varargs void message(mixed array msg, object array exclude, |
+ | object array targets, closure filter); | ||
- | ==Files== | + | ==FILES== |
- | /mod/basic/messaging.c | + | /mod/basic/messaging.c |
- | /mod/character/commands.c | + | /def/descriptor/message.c |
+ | /lib/descriptors/message.h | ||
+ | /lib/msg.h | ||
==DESCRIPTION== | ==DESCRIPTION== | ||
- | The function message() provides a multipurpose, flexible, expandible | + | The function message() provides a multipurpose, flexible, expandable |
- | protocol for delivery of a point-of-view oriented event message to a | + | protocol for delivery of a point-of-view oriented event message to a |
- | selection of targets. It should be called in the object which the | + | selection of targets. It should be called in the object which the |
- | message should "originate" from; this is somewhat arbitrary, but allows | + | message should "originate" from; this is somewhat arbitrary, but allows |
- | certain convenient shorthand notations to be used. This object will | + | certain convenient shorthand notations to be used. This object will |
- | henceforth be referred to as the originator. | + | henceforth be referred to as the originator. |
- | The first argument to message(), 'list', is an array of various values | + | ===Descriptor=== |
- | which define the message to be delivered. The second argument, which | + | In its basic form, the first argument to message() is a message |
- | is optional, defines an array of objects which should be excluded from | + | descriptor specification, as defined by /def/descriptor/message.c. |
- | receiving the message. The third argument, also optional, allows | + | |
- | explicit definition of a list of objects which should receive the | + | |
- | message. The default for this is the contents of the originator's | + | |
- | environment plus the environment itself, unless the originator has the | + | |
- | invisibility flag Invis_Actions, in which case the default is all | + | |
- | object variables present in 'list'. The fourth argument can be used | + | |
- | to specify a function which all those to whom the message would normally | + | |
- | be sent should be filtered through (i.e. they will not receive the | + | |
- | message if the function returns 0 when called with them as argument). | + | |
- | message() operates by broadcasting the 'list' in array form to all its | + | ====Message_Content==== |
- | targets through the function receive_message(). In each individual | + | The core of the message, an array of various values that |
- | target, the various elements of the list are converted to the appropriate | + | define the message to be delivered. This is the only field |
- | representational string and concatenated; i.e. an object configured as | + | that is required; all others are optional. If an array is |
- | a ring might be converted to "brass ring" or "ring of warmth" according | + | sent as the message specification, it will be interpreted |
- | to whether the target recognizes it for what it is. | + | as a Message_Content field (rather than each element of the |
+ | array being interpreted as a different descriptor field). | ||
- | An element of a list may be: | + | ====Message_Exclude==== |
+ | May be used to specify exclusion of objects from receiving the | ||
+ | message. This can be a closure (which will be called with the | ||
+ | object in question as argument), an object (that specific object | ||
+ | should be excluded), an array (objects in the array should be | ||
+ | excluded), or a mapping (objects that exist as keys in the array | ||
+ | should be excluded). Flags like Message_Flag_Exclude_Source | ||
+ | should be preferred to this option, if they are applicable to | ||
+ | your situation. | ||
- | Zero | + | ====Message_Targets==== |
- | This will be replaced with the originator and evaluated as per | + | May be used to specify explicitly what objects should receive the |
- | an object. | + | message, rather than relying on the default behavior (see below). |
+ | This can be an object (meaning only that object should receive the | ||
+ | message; normally there are better ways of doing this, such as | ||
+ | passing the message to display() in that object) or an array of | ||
+ | objects (specifying the objects to send to). | ||
- | A string | + | The default set of objects to receive a message is the contents of |
- | The string will be used as-is in the final message. | + | the originator's environment, plus the environment itself, unless |
+ | the originator has the invisibility flag Invis_Actions, in which | ||
+ | case the default is all object variables present at any level in | ||
+ | Message_Content. | ||
- | An object | + | ====Message_Filter==== |
- | The object will be converted to a string identifier based on the | + | May be used to define a filter that can determine whether a |
- | object's query_name(); an article (a, an, or the) will be applied | + | given object should receive the message. This can be a closure |
- | if appropriate. | + | call descriptor or condition descriptor (which will be called with |
+ | the object in question as argument), an object (meaning only that | ||
+ | object should receive the message; normally there are better ways | ||
+ | of doing this), an array (only objects in the array should receive | ||
+ | the message), or a mapping (only objects that exist as keys in the | ||
+ | mapping should receive the message). | ||
- | A function pointer | + | ====Message_Flags==== |
- | The function pointer will be evaluated with no arguments passed. It | + | May be used to specify flags that affect the message system's |
- | is expected to return a string; failure to do so will cause errors. | + | behavior for this message. The list is beyond this document's |
+ | scope at present. | ||
- | A nonzero integer | + | ====Message_Senses==== |
- | The integer will be interpreted as a control code to affect | + | May be used to specify sensory flags that constitute the senses |
- | subsequent list elements. Valid control codes are: | + | that must be operational in order to perceive the message, such |
- | 'a' Apply a() to the following element. | + | as Message_Sense_Visual. |
- | 'c' Apply capitalize() to the following element. | + | ====Message_Alternate==== |
+ | May be used to specify an alternate message that may be delivered | ||
+ | if the main message cannot be delivered due to Message_Senses. | ||
+ | This is a complete message descriptor in itself. | ||
- | 'j' Join together the following two elements without inserting | + | ===Backwards Compatibility=== |
- | a space between them. | + | Alternately, the backward-compatibility four-argument form may be |
+ | used. In this case, the first argument specifies Message_Content, the | ||
+ | second specifies Message_Exclude, the third Message_Targets, and the | ||
+ | fourth Message_Filter. | ||
- | 'n' Ignore this element, as if it were not present. (Useful | + | ===Message Interpretation=== |
- | in condition construction of messages.) | + | message() operates by broadcasting the message descriptor to all its |
+ | targets through the function receive_message(). In each individual | ||
+ | target, the various elements of the message are converted to the | ||
+ | appropriate representational string and joined together; i.e. an object | ||
+ | configured as a ring might be converted to "brass ring" or "ring of | ||
+ | warmth" according to how the target recognizes it. | ||
- | 'p' Apply pluralize() to the following element. | + | '''An element of a list may be:''' |
- | 's' Apply singularize() to the following element. | + | :* Zero |
+ | :This will be replaced with the originator and evaluated as per an object. | ||
- | 'w' Apply capitalize_words() to the following element. | + | :* A string |
+ | :The string will be used as-is in the final message. | ||
- | An array | + | :*An object |
- | The array must contain either two or three elements, the first of | + | :The object will be converted to a string identifier based on the |
- | which must be a string or an integer. The second and third elements | + | :object's query_name(); an article (a, an, or the) or possessive (your) |
- | may be an object, a string, an array, or 0; 0 will be converted to the | + | :will be applied if appropriate. |
- | originator. | + | |
- | If the first element is a string, it will be treated as a verb being | + | :*A closure |
- | performed by the second element, which should be an object or an array | + | :The closure will be evaluated with no arguments passed. It is |
- | of objects. | + | :expected to return a string or zero (zero will be interpreted |
+ | :as a no-op); failure to do so will cause errors. | ||
- | If the first element is an integer, it will be interpreted as a special | + | :*A nonzero integer |
- | command code based on its character value, according to the following | + | :**The integer will be interpreted as a special code, usually a control code that affects subsequent list elements. Valid codes are as follows. The raw form is to the left, readability macro from msg.h to the right. |
- | table: | + | 'a' Msg_Ctl_A_Next |
+ | Apply a() to the following element. | ||
+ | 'b' Msg_Ctl_Sentence_Break | ||
+ | Interpret a sentence break at the current position, including applying terminal punctuation to the preceding word (if there is any and Message_Flag_Suppress_Punctuation is not on), Capitalizing the following word (unless Messsage_Flag_Suppress_Capitalization is on), and causing there to be two spaces between the sentences. This is not needed at the end of the message; it's for when you need to have a sentence break inside the message. (Please also consider issuing two separate messages instead of doing this.) | ||
+ | 'c' Msg_Ctl_Capitalize_Next | ||
+ | Apply capitalize() to the following element. | ||
+ | 'i' Msg_Ctl_Interpolate_Next | ||
+ | If the following element is an array, and is not a call, description, message, abstract item, identity, or manipulator descriptor, interpolate it into the message as if it had been added to the message array rather than embedded in it. 'i' will also work if the following element is a closure or call descriptor that returns an array. (Array contents of description descriptors are always interpolated.) | ||
+ | 'j' Msg_Ctl_Join_Next | ||
+ | Join together the following two elements without inserting a space between them. | ||
+ | 'n' Msg_Ctl_No_Op | ||
+ | Ignore this element, as if it were not present; useful in conditional construction of messages. Embedding an empty string achieves the same effect. | ||
+ | 'p' Msg_Ctl_Pluralize_Next | ||
+ | Apply pluralize() to the following element. | ||
+ | 's' Msg_Ctl_Singularize_Next | ||
+ | Apply singularize() to the following element. | ||
+ | 'v' Msg_Viewer | ||
+ | Indicates the viewer. In basic message construction, this would be the same as using 0. Some contexts of message use, such as descriptions, process zeroes into references to the object described, however. Using 'v' allows messages defined in these contexts to refer to the eventual viewer. | ||
+ | 'w' Msg_Ctl_Capitalize_Words_Next | ||
+ | Apply capitalize_words() to the following element. | ||
- | ({ 'a', obj }) "an orc" | + | :*An array |
+ | ::The array must contain either two or three elements, the first of which must be a string or an integer. The second and third elements may be an object, a string, an array, or 0; 0 will be converted to the originator. | ||
- | The second element will be affected as by the function a(); | + | ::If the first element is a string, it will be treated as a verb being performed by the second element, which should be an object or an array of objects. So ({ "beep", 0 }) specifies that the message originator is "beeping"; the originator will see "beep", others will see "beeps". If you are using msg.h readability macros, you can write this as Msg_Verb("beep", 0). |
- | i.e. ({ 'a', autonomon }) will be converted into a string | + | |
- | along the lines of "an orc", "a troll", or "Bob" | + | |
- | ({ 'c', obj }) "orc" | + | ::As a special case related to the 'v' / Msg_Viewer code above, if any array element after the first is 'v', it will be converted to the viewer. This serves the same purpose as the 'v' code outside of arrays. |
- | The race of the second element, which must be an object, as | + | ::If the first element is an integer, it will be interpreted as a special command code based on its character value, according to the following table. For each entry, its readability macro form from msg.h is listed on the line following the "raw" form. |
- | apparent to the viewer. If the second element has no race, | + | |
- | "object" will be produced. | + | |
- | ({ 'd', room, "north" }) "north" / "from the south" | + | ({ 'a', obj }) "an orc" |
+ | Msg_A(obj) | ||
+ | |||
+ | The second element will be affected as by the function a(); | ||
+ | i.e. ({ 'a', autonomon }) will be converted into a string | ||
+ | along the lines of "an orc", "a troll", or "Bob" | ||
- | Third element expressed as a direction originating within | + | ({ 'b', obj, limbs }) "head, left arm and hands" |
- | the second element; i.e. ({ 'd', room, "north" }) will | + | Msg_Limbs(obj) |
- | produce "north" for those in 'room' and "from the south" | + | |
- | for those elsewhere. | + | A description of one or more limbs, indicated by array of indices, |
+ | of the second element, as they appear to the viewer. This | ||
+ | description is obtained from query_limbs_description(). If a | ||
+ | fourth element is supplied, it will be used as message listing | ||
+ | flags, the only one of which is relevant to the context is | ||
+ | Message_Listing_Flag_Combat_Limb_Name. Note: this is provided | ||
+ | strictly for the case where you need to describe a set of limbs | ||
+ | without a proximate indication of who they belong to. If something | ||
+ | like "his head" or "Bob's head" is what you're looking for, use | ||
+ | 'r' or 's', below. | ||
- | ({ 'e', obj }) "an orc" / "the orc" | + | ({ 'c', obj }) "orc" |
+ | Msg_Race(obj) | ||
+ | |||
+ | The race of the second element, which must be an object, as | ||
+ | apparent to the viewer. If the second element has no race, | ||
+ | "object" will be produced. | ||
- | Second element affected as by one() | + | ({ 'd', room, Direction_North }) "north" / "from the south" |
+ | Msg_Direction(room, Direction_North) | ||
+ | |||
+ | Third element expressed as a direction originating within | ||
+ | the second element; i.e. ({ 'd', room, "north" }) will | ||
+ | produce "north" for those in 'room' and "from the south" | ||
+ | for those elsewhere. | ||
- | ({ 'i', list }) "a sword, an axe and a shield" | + | ({ 'e', obj }) "a sword" / "the sword" / "your sword" |
- | ({ 'i', list, "or" }) "a sword, an axe or a shield" | + | Msg_Article_Pron(obj) |
+ | |||
+ | Second element affected as by one(), unless it is not near the | ||
+ | viewer, in which case it is affected as by a(), or it is in the | ||
+ | viewer's inventory, in which case it is affected as by article() | ||
+ | with a second argument of "your" | ||
- | Array-listing form of the second element, which must be an | + | ({ 'f', obj }) "a sword" / "the sword" |
- | array. Any objects will be converted to strings and list_array() | + | Msg_Article(obj) |
- | will be applied to the result. If a third element is supplied, | + | |
- | this will become the conjunction used by list_array(). | + | Second element affected as by one(), unless it is not near the |
+ | viewer, in which case it is affected as by a() | ||
- | ({ 'l', obj }) "himself" / "herself" / "yourself" | + | ({ 'h', list }) "a sword, an axe and a shield" |
+ | ({ 'h', list, "or" }) "a sword, an axe or a shield" | ||
+ | Msg_Unique_List(list) | ||
+ | |||
+ | Unique array-listing form of the second element, which must be an | ||
+ | array. Any objects will be converted to strings, duplicates will | ||
+ | be eliminated, and list_array() will be applied to the result. If | ||
+ | a third element is supplied, this will become the conjunction used | ||
+ | by list_array(). If a fourth element is supplied, it will be used | ||
+ | as identity query flags for resolving the names of the list | ||
+ | elements. | ||
- | Reflexive pronoun of the second element (himself, herself, | + | ({ 'i', list }) "a sword, a sword, an axe and a shield" |
- | yourself, etc) | + | ({ 'i', list, "or" }) "a sword, a sword, an axe or a shield" |
+ | Msg_Indiv_List(list) | ||
+ | Msg_Indiv_List(list, "or") | ||
+ | |||
+ | Array-listing form of the second element, which must be an | ||
+ | array. Any objects will be converted to strings and list_array() | ||
+ | will be applied to the result. If a third element is supplied, | ||
+ | this will become the conjunction used by list_array(). If a fourth | ||
+ | element is supplied, it will be used as identity query flags for | ||
+ | resolving the names of the list elements. If a fifth element is | ||
+ | supplied, it will be interpreted as message listing flags. | ||
- | ({ 'm', obj }) "his" / "hers" / "yours" | + | ({ 'j', list }) "a couple of swords, an axe and a shield" |
+ | Msg_Group_List(list) | ||
+ | |||
+ | Item-listing form of the second element, which must be an | ||
+ | array. /daemon/item_listing's functionality will be will be | ||
+ | applied to the list. If a third element is supplied, it will be | ||
+ | used as identity query flags for resolving the names of the list | ||
+ | elements. If a fourth element is supplied, it will be used as | ||
+ | listing flags; Listing_Flag_Include_Viewer is always turned on. | ||
- | Possessive-objective pronoun of the second element (his, hers, | + | ({ 'l', obj }) "himself" / "herself" / "yourself" |
- | yours, etc) | + | Msg_Refl_Pron(obj) |
+ | |||
+ | Reflexive pronoun of the second element (himself, herself, | ||
+ | yourself, etc) | ||
- | ({ 'n', obj }) "orc" | + | ({ 'm', obj }) "his" / "hers" / "yours" |
+ | Msg_Poss_Adj_Pron(obj) | ||
+ | |||
+ | Possessive-adjective pronoun of the second element (his, hers, | ||
+ | yours, etc) | ||
- | The literal name of the second element, i.e. "orc", "troll", "Bob" | + | ({ 'n', obj }) "orc" |
+ | Msg_Name(obj) | ||
+ | |||
+ | The literal name of the second element, i.e. "orc", "troll", "Bob" | ||
- | ({ 'o', obj }) "him" / "her" / "it" / "them" / "you" | + | ({ 'N', obj }) "orc" |
- | ({ 'o', obj, True }) "him" / "her" / "that" / "those" / "you" | + | Msg_Conv_Name(obj) |
+ | |||
+ | The conversational name of the second element, i.e. "anthrope", | ||
+ | "human", "Bob" | ||
- | Objective pronoun of the second element (him, her, etc). If | + | ({ 'o', obj }) "him" / "her" / "it" / "them" / "you" |
- | a third element of True is given, the objective indicative pronoun | + | ({ 'o', obj, Identity_Query_Flag_Indicative_Case }) |
- | ('that' rather than 'it', 'those' rather than 'them') is used. | + | "him" / "her" / "that" / "those" / "you" |
+ | Msg_Obj_Pron(obj) | ||
+ | Msg_Obj_Pron(obj, Identity_Query_Flag_Indicative_Case) | ||
+ | |||
+ | Objective pronoun of the second element (him, her, etc). The | ||
+ | third element may contain identity query flags; if they include | ||
+ | Identity_Query_Flag_Indicative_Case, the objective indicative | ||
+ | pronoun ('that' rather than 'it', 'those' rather than 'them') is | ||
+ | used. | ||
- | ({ 'p', obj }) "he" / "she" / "it" / "they" / "you" | + | ({ 'p', obj }) "he" / "she" / "it" / "they" / "you" |
- | ({ 'p', obj, True }) "he" / "she" / "that" / "those" / "you" | + | ({ 'p', obj, Identity_Query_Flag_Indicative_Case }) |
+ | "he" / "she" / "that" / "those" / "you" | ||
+ | Msg_Subj_Pron(obj) | ||
+ | Msg_Subj_Pron(obj, Identity_Query_Flag_Indicative_Case) | ||
+ | |||
+ | Subjective pronoun of the second element (he, she, etc). The | ||
+ | third element may contain identity query flags; if they include | ||
+ | Identity_Query_Flag_Indicative_Case, the subjective indicative | ||
+ | pronoun ('that' rather than 'it', 'those' rather than 'they') | ||
+ | is used. | ||
- | Subjective pronoun of the second element (he, she, etc). If | + | ({ 'q', obj }) "his" / "her" / "your" |
- | a third element of True is given, the subjective indicative | + | Msg_Poss_Pron(obj) |
- | pronoun ('that' rather than 'it', 'those' rather than 'they') | + | |
- | is used. | + | Possessive pronoun of the second element (his, her, etc). This |
+ | is ALMOST NEVER appropriate to use; use 'r' instead whenever | ||
+ | possible. | ||
- | ({ 'q', obj }) "his" / "her" / "your" | + | ({ 'r', who, obj }) "his sword" / "your knife" |
+ | ({ 'r', who, list }) "his sword and knife" | ||
+ | Msg_Pron_Has(who, obj) | ||
+ | Msg_Pron_Has(who, list) | ||
+ | |||
+ | Indefinite possessive form of the third element with respect | ||
+ | to the second element; i.e. ({ 'r', 0, weapon }) will produce | ||
+ | "his sword", "her knife", "Heavensfire", etc. The third element | ||
+ | may be a string, an object, or an array of strings and/or objects | ||
+ | and/or limb indices of 'who' (limb indices will be converted to a | ||
+ | summary list of the appropriate limb names using the function | ||
+ | query_limbs_description()). A fourth element, if supplied, will be | ||
+ | used as message listing flags (cf. /def/descriptor/message.c). | ||
+ | If a fifth element is supplied, it will be used as identity query | ||
+ | flags (cf. /def/descriptor/identity.c). | ||
- | Possessive pronoun of the second element (his, her, etc). Use | + | ({ 's', who, obj }) "the orc's sword" / "your knife" |
- | 'r' instead of 'q' whenever possible. | + | ({ 's', who, list }) "the orc's sword and knife" |
+ | Msg_Name_Has(who, obj) | ||
+ | Msg_Name_Has(who, list) | ||
+ | |||
+ | Definite possessive form of the third element with respect to | ||
+ | the second element; i.e. ({ 's', 0, weapon }) will produce "the | ||
+ | troll's sword", "Bob's knife", "Stormbringer", etc. The third | ||
+ | element may be a string, an object, or an array of strings and/or | ||
+ | objects and/or limb indices (as with 'r' above). If a fourth element | ||
+ | is supplied, it will be used as message listing flags | ||
+ | (cf. /def/descriptor/message.c). A fifth element, if supplied, will | ||
+ | be used as identity query flags (cf. /def/descriptor/identity.c). | ||
+ | |||
+ | In a very special-case behavior, if 's' is used and the third | ||
+ | element is entirely proper-named so that the second element's name | ||
+ | does not appear, this causes the next non-reflexive pronoun in the | ||
+ | message that refers to the second element to display a name; this | ||
+ | means that a 'm' or 'q' will be treated as a 'u', an 'o' or 'p' | ||
+ | will be treated as a 'e', and a 'r' will be treated as a 's'. | ||
- | ({ 'r', who, obj }) "his sword" / "your knife" | + | ({ 't', obj }) "the orc" |
- | ({ 'r', who, list }) "his sword and knife" | + | Msg_The(obj) |
+ | |||
+ | Second element affected as if by the() | ||
+ | ({ 'u', obj }) "the orc's" / "your" | ||
+ | Msg_Defn_Poss(obj) | ||
+ | |||
+ | Definite possessive form of the second element, i.e. ({ 'u', 0 }) | ||
+ | will produce "your" or "Bob's" or "the orc's". If a third element | ||
+ | is provided, it will be used as identity query flags. This is | ||
+ | ALMOST NEVER appropriate to use; use 's' instead of 'u' whenever | ||
+ | possible. | ||
- | Indefinite possessive form of the third element with respect | + | ({ 'v', obj }) "this" / "these" |
- | to the second element; i.e. ({ 'r', 0, weapon }) will produce | + | Msg_Indic_Pron(obj) |
- | "his sword", "her knife", "Heavensfire", etc. The third element | + | |
- | may be a string, an object, or an array of strings and/or objects. | + | Indicative pronoun of the second element (this, these). |
- | ({ 's', who, obj }) "the orc's sword" / "your knife" | + | ({ 'w', obj }) "orc" / "orc 2" |
- | ({ 's', who, list }) "the orc's sword and knife" | + | Msg_Which(obj) |
+ | |||
+ | Second element affected as if by which(), with the message's | ||
+ | observer used as which()'s observer argument. If a third element | ||
+ | is supplied, it is used as the 'name' argument to which(). If | ||
+ | a fourth element is supplied, it is used as the 'flags' argument | ||
+ | to which(). If a fifth element is supplied, it is used as the | ||
+ | 'context' argument to which(). | ||
- | Definite possessive form of the third element with respect to | + | ({ 'x', obj }) "male" / "female" |
- | the second element; i.e. ({ 's', 0, weapon }) will produce "the | + | Msg_Sex(obj) |
- | troll's sword", "Bob's knife", "Stormbringer", etc. The third | + | |
- | element may be a string, an object, or an array of strings and/or | + | The sex of the second element as apparent to the viewer, i.e. |
- | objects. In a very special-case behavior, if 's' is used and | + | ({ 'x', person }) will produce "male", "female", "neuter", etc. |
- | the third element is entirely proper-named so that the second | + | If the second element's sex is indeterminate to the viewer, |
- | element's name does not appear, this causes the next non-reflexive | + | nothing will be produced. If a third element is provided, it |
- | pronoun in the message that refers to the second element to display | + | is expected to be a string and will be appended (with a space |
- | a name; this means that a 'm' or 'q' will be treated as a 'u', an | + | in between) to the sex name if and only if one is displayed. |
- | 'o' or 'p' will be treated as a 'e', and a 'r' will be treated as | + | Most often, the results desired with this are better obtained |
- | a 's'. | + | using 'c' with the 'include sex' flag enabled. |
- | ({ 't', obj }) "the orc" | + | ({ 'z', obj, "forme", "foryou" }) "forme" / "foryou" |
+ | Msg_Self_Other(obj, "forme", "foryou") | ||
+ | |||
+ | Uses the third or fourth element depending on the viewer, i.e. | ||
+ | ({ 'z', 0, "you", "this" }) will produce "you" if the viewer | ||
+ | matches the originator of the message, otherwise "this". | ||
- | Second element affected as if by the() | + | ({ 'X', ({ ... })}) |
+ | Msg_Expand(({ ... })) | ||
+ | |||
+ | Expands the array specified into the outer message. So | ||
+ | ({ ({ 'X', ({ "foo" }) has the same effect as ({ "foo" }). | ||
+ | If this doesn't make any sense to you, it probably doesn't | ||
+ | need to; it exists to support some difficult cases that lib | ||
+ | developers run into. | ||
- | ({ 'u', obj }) "the orc's" / "your" | + | Once converted to strings locally, the elements of the list are normally |
+ | concatenated with a single space inserted between each pair. The space | ||
+ | will not be inserted, however, before any list element which begins with | ||
+ | one of the characters ,;:.!? for purposes of consistency. | ||
- | Definite possessive form of the second element, i.e. ({ 'u', 0 }) | + | It is expected that support for language interpretation and other |
- | will produce "your" or "Bob's" or "the orc's". Use 's' instead of | + | functions will be added into the messaging code. |
- | 'u' whenever possible. | + | |
- | ({ 'w', obj }) "orc" / "orc 2" | + | ==EXAMPLES== |
+ | To send a message of an orc bowing to an ogre (represented by the | ||
+ | object variables 'orc' and 'ogre' respectively): | ||
- | Second element affected as if by which() | + | orc->message(([ |
+ | Message_Content : ({ | ||
+ | 0, ({ "bow", 0 }), "to", ogre, | ||
+ | }), | ||
+ | Message_Senses : Message_Sense_Visual | Message_Sense_Kinesthetic_For_Source, | ||
+ | ])); | ||
- | ({ 'x', obj }) "male" / "female" | + | // msg.h version |
+ | orc->message(([ | ||
+ | Message_Content : ({ | ||
+ | 0, Msg_Verb("bow"), "to", ogre, | ||
+ | }), | ||
+ | Message_Senses : Message_Sense_Visual | Message_Sense_Kinesthetic_For_Source, | ||
+ | ])); | ||
- | The sex of the second element as apparent to the viewer, i.e. | + | The orc will see "You bow to the ogre.\n", the ogre will see |
- | ({ 'x', person }) will produce "male", "female", "neuter", etc. | + | "The orc bows to you.\n", and others present will see "The orc bbows to the ogre.\n". |
- | If the second element's sex is indeterminate to the viewer, | + | |
- | nothing will be produced. | + | |
- | ({ 'z', obj, "forme", "foryou" }) "forme" / "foryou" | + | For a sword to send a message that it leaps toward its target: |
- | + | ||
- | Uses the third or fourth element depending on the viewer, i.e. | + | |
- | ({ 'z', 0, "you", "this" }) will produce "you" if the viewer | + | |
- | matches the originator of the message, otherwise "this". | + | |
- | + | ||
- | Once converted to strings locally, the elements of the list are normally | + | |
- | concatenated with a single space inserted between each pair. The space | + | |
- | will not be inserted, however, before any list element which begins with | + | |
- | one of the characters ,;:.!? for purposes of consistency. | + | |
- | + | ||
- | It is expected that support for language interpretation and other | + | |
- | functions will be added into the messaging code. | + | |
- | + | ||
- | ==EXAMPLES== | + | |
- | To send a message of an orc bowing to an ogre (represented by the | + | |
- | object variables 'orc' and 'ogre' respectively): | + | |
- | orc->message(({ | + | wielder->message(([ |
- | 0, ({ "bow", 0 }), "to", ogre, | + | Message_Content : ({ |
- | })); | + | ({ 's', 0, this_object() }), ({ "leap", this_object() }), |
+ | "toward", target, | ||
+ | }), | ||
+ | Message_Senses : Message_Sense_Visual | Message_Sense_Kinesthetic_For_Source | Message_Sense_Tactile_For_Participants, | ||
+ | ])); | ||
- | The orc will see "You bow to the ogre.\n", the ogre will see | + | // msg.h version |
- | "The orc bows to you.\n", and others present will see "The orc | + | wielder->message(([ |
- | bows to the ogre.\n". | + | Message_Content : ({ |
+ | Msg_Name_Has(0, this_object()), Msg_Verb("leap", this_object()), | ||
+ | "toward", target, | ||
+ | }), | ||
+ | Message_Senses : Message_Sense_Visual | Message_Sense_Kinesthetic_For_Source | Message_Sense_Tactile_For_Participants, | ||
+ | ])); | ||
- | For a sword to send a message that it leaps toward its target: | + | For 'bob' to wiggle his ears: |
- | wielder->message(({ | + | bob->message(([ |
- | ({ 's', 0, this_object() }), ({ "leap", this_object() }), | + | Message_Content : ({ |
- | "toward", target, | + | 0, ({ "wiggle", 0 }), ({ 'r', 0, "ears" }), |
- | })); | + | }), |
+ | Message_Senses : Message_Sense_Visual | Message_Sense_Kinesthetic_For_Source, | ||
+ | ])); | ||
- | For 'bob' to wiggle his ears: | + | // msg.h version |
+ | bob->message(([ | ||
+ | Message_Content : ({ | ||
+ | 0, Msg_Verb("wiggle", 0), Msg_Pron_Has(0, "ears"), | ||
+ | }), | ||
+ | Message_Senses : Message_Sense_Visual | Message_Sense_Kinesthetic_For_Source, | ||
+ | ])); | ||
- | bob->message(({ | + | For 'larry' to run into 'moe', shoving him into 'curly': |
- | 0, ({ "wiggle", 0 }), ({ 'r', 0, "ears" }), | + | |
- | })); | + | |
- | For 'larry' to run into 'moe', shoving him into 'curly': | + | larry->message(([ |
+ | Message_Content : ({ | ||
+ | 0, ({ "run", 0 }), "into", moe, ", shoving", | ||
+ | ({ 'o', moe }), "into", curly, | ||
+ | }), | ||
+ | Message_Senses : Message_Sense_Visual | Message_Sense_Kinesthetic_For_Source | Message_Sense_Tactile_For_Participants, | ||
+ | ])); | ||
- | larry->message(({ | + | // msg.h version |
- | 0, ({ "run", 0 }), "into", moe, ", shoving", | + | larry->message(([ |
- | ({ 'o', moe }), "into", curly, | + | Message_Content : ({ |
- | })); | + | 0, Msg_Verb("run", 0), "into", moe, ", shoving", |
+ | Msg_Obj_Pron(moe), "into", curly, | ||
+ | }), | ||
+ | Message_Senses : Message_Sense_Visual | Message_Sense_Kinesthetic_For_Source | Message_Sense_Tactile_For_Participants, | ||
+ | ])); | ||
==HISTORICAL== | ==HISTORICAL== | ||
- | The original message() function had a four-argument form which could only | + | The original message() function had a four-argument form which could only |
- | handle different messages for one target and which had no facility for | + | handle different messages for one target and which had no facility for |
- | subjective recognition of objects. Its functionality was once supported | + | subjective recognition of objects. Its functionality was once supported |
- | for backward compatibility, but this is no longer the case. | + | for backward compatibility, but this is no longer the case. |
==SEE ALSO== | ==SEE ALSO== | ||
- | identify(mechanisms), third_person(efun) | + | [[man identify|identify(mechanisms)]], [[man third person|third_person(efun)]] |
Current revision
message - advanced multipurpose messaging protocol
Contents |
SYNOPSIS
void message(mixed spec); varargs void message(mixed array msg, object array exclude, object array targets, closure filter);
FILES
/mod/basic/messaging.c /def/descriptor/message.c /lib/descriptors/message.h /lib/msg.h
DESCRIPTION
The function message() provides a multipurpose, flexible, expandable protocol for delivery of a point-of-view oriented event message to a selection of targets. It should be called in the object which the message should "originate" from; this is somewhat arbitrary, but allows certain convenient shorthand notations to be used. This object will henceforth be referred to as the originator.
Descriptor
In its basic form, the first argument to message() is a message descriptor specification, as defined by /def/descriptor/message.c.
Message_Content
The core of the message, an array of various values that define the message to be delivered. This is the only field that is required; all others are optional. If an array is sent as the message specification, it will be interpreted as a Message_Content field (rather than each element of the array being interpreted as a different descriptor field).
Message_Exclude
May be used to specify exclusion of objects from receiving the message. This can be a closure (which will be called with the object in question as argument), an object (that specific object should be excluded), an array (objects in the array should be excluded), or a mapping (objects that exist as keys in the array should be excluded). Flags like Message_Flag_Exclude_Source should be preferred to this option, if they are applicable to your situation.
Message_Targets
May be used to specify explicitly what objects should receive the message, rather than relying on the default behavior (see below). This can be an object (meaning only that object should receive the message; normally there are better ways of doing this, such as passing the message to display() in that object) or an array of objects (specifying the objects to send to).
The default set of objects to receive a message is the contents of the originator's environment, plus the environment itself, unless the originator has the invisibility flag Invis_Actions, in which case the default is all object variables present at any level in Message_Content.
Message_Filter
May be used to define a filter that can determine whether a given object should receive the message. This can be a closure call descriptor or condition descriptor (which will be called with the object in question as argument), an object (meaning only that object should receive the message; normally there are better ways of doing this), an array (only objects in the array should receive the message), or a mapping (only objects that exist as keys in the mapping should receive the message).
Message_Flags
May be used to specify flags that affect the message system's behavior for this message. The list is beyond this document's scope at present.
Message_Senses
May be used to specify sensory flags that constitute the senses that must be operational in order to perceive the message, such as Message_Sense_Visual.
Message_Alternate
May be used to specify an alternate message that may be delivered if the main message cannot be delivered due to Message_Senses. This is a complete message descriptor in itself.
Backwards Compatibility
Alternately, the backward-compatibility four-argument form may be used. In this case, the first argument specifies Message_Content, the second specifies Message_Exclude, the third Message_Targets, and the fourth Message_Filter.
Message Interpretation
message() operates by broadcasting the message descriptor to all its targets through the function receive_message(). In each individual target, the various elements of the message are converted to the appropriate representational string and joined together; i.e. an object configured as a ring might be converted to "brass ring" or "ring of warmth" according to how the target recognizes it.
An element of a list may be:
- Zero
- This will be replaced with the originator and evaluated as per an object.
- A string
- The string will be used as-is in the final message.
- An object
- The object will be converted to a string identifier based on the
- object's query_name(); an article (a, an, or the) or possessive (your)
- will be applied if appropriate.
- A closure
- The closure will be evaluated with no arguments passed. It is
- expected to return a string or zero (zero will be interpreted
- as a no-op); failure to do so will cause errors.
- A nonzero integer
- The integer will be interpreted as a special code, usually a control code that affects subsequent list elements. Valid codes are as follows. The raw form is to the left, readability macro from msg.h to the right.
- A nonzero integer
'a' Msg_Ctl_A_Next Apply a() to the following element. 'b' Msg_Ctl_Sentence_Break Interpret a sentence break at the current position, including applying terminal punctuation to the preceding word (if there is any and Message_Flag_Suppress_Punctuation is not on), Capitalizing the following word (unless Messsage_Flag_Suppress_Capitalization is on), and causing there to be two spaces between the sentences. This is not needed at the end of the message; it's for when you need to have a sentence break inside the message. (Please also consider issuing two separate messages instead of doing this.) 'c' Msg_Ctl_Capitalize_Next Apply capitalize() to the following element. 'i' Msg_Ctl_Interpolate_Next If the following element is an array, and is not a call, description, message, abstract item, identity, or manipulator descriptor, interpolate it into the message as if it had been added to the message array rather than embedded in it. 'i' will also work if the following element is a closure or call descriptor that returns an array. (Array contents of description descriptors are always interpolated.) 'j' Msg_Ctl_Join_Next Join together the following two elements without inserting a space between them. 'n' Msg_Ctl_No_Op Ignore this element, as if it were not present; useful in conditional construction of messages. Embedding an empty string achieves the same effect. 'p' Msg_Ctl_Pluralize_Next Apply pluralize() to the following element. 's' Msg_Ctl_Singularize_Next Apply singularize() to the following element. 'v' Msg_Viewer Indicates the viewer. In basic message construction, this would be the same as using 0. Some contexts of message use, such as descriptions, process zeroes into references to the object described, however. Using 'v' allows messages defined in these contexts to refer to the eventual viewer. 'w' Msg_Ctl_Capitalize_Words_Next Apply capitalize_words() to the following element.
- An array
- The array must contain either two or three elements, the first of which must be a string or an integer. The second and third elements may be an object, a string, an array, or 0; 0 will be converted to the originator.
- If the first element is a string, it will be treated as a verb being performed by the second element, which should be an object or an array of objects. So ({ "beep", 0 }) specifies that the message originator is "beeping"; the originator will see "beep", others will see "beeps". If you are using msg.h readability macros, you can write this as Msg_Verb("beep", 0).
- As a special case related to the 'v' / Msg_Viewer code above, if any array element after the first is 'v', it will be converted to the viewer. This serves the same purpose as the 'v' code outside of arrays.
- If the first element is an integer, it will be interpreted as a special command code based on its character value, according to the following table. For each entry, its readability macro form from msg.h is listed on the line following the "raw" form.
({ 'a', obj }) "an orc" Msg_A(obj) The second element will be affected as by the function a(); i.e. ({ 'a', autonomon }) will be converted into a string along the lines of "an orc", "a troll", or "Bob"
({ 'b', obj, limbs }) "head, left arm and hands" Msg_Limbs(obj) A description of one or more limbs, indicated by array of indices, of the second element, as they appear to the viewer. This description is obtained from query_limbs_description(). If a fourth element is supplied, it will be used as message listing flags, the only one of which is relevant to the context is Message_Listing_Flag_Combat_Limb_Name. Note: this is provided strictly for the case where you need to describe a set of limbs without a proximate indication of who they belong to. If something like "his head" or "Bob's head" is what you're looking for, use 'r' or 's', below.
({ 'c', obj }) "orc" Msg_Race(obj) The race of the second element, which must be an object, as apparent to the viewer. If the second element has no race, "object" will be produced.
({ 'd', room, Direction_North }) "north" / "from the south" Msg_Direction(room, Direction_North) Third element expressed as a direction originating within the second element; i.e. ({ 'd', room, "north" }) will produce "north" for those in 'room' and "from the south" for those elsewhere.
({ 'e', obj }) "a sword" / "the sword" / "your sword" Msg_Article_Pron(obj) Second element affected as by one(), unless it is not near the viewer, in which case it is affected as by a(), or it is in the viewer's inventory, in which case it is affected as by article() with a second argument of "your"
({ 'f', obj }) "a sword" / "the sword" Msg_Article(obj) Second element affected as by one(), unless it is not near the viewer, in which case it is affected as by a()
({ 'h', list }) "a sword, an axe and a shield" ({ 'h', list, "or" }) "a sword, an axe or a shield" Msg_Unique_List(list) Unique array-listing form of the second element, which must be an array. Any objects will be converted to strings, duplicates will be eliminated, and list_array() will be applied to the result. If a third element is supplied, this will become the conjunction used by list_array(). If a fourth element is supplied, it will be used as identity query flags for resolving the names of the list elements.
({ 'i', list }) "a sword, a sword, an axe and a shield" ({ 'i', list, "or" }) "a sword, a sword, an axe or a shield" Msg_Indiv_List(list) Msg_Indiv_List(list, "or") Array-listing form of the second element, which must be an array. Any objects will be converted to strings and list_array() will be applied to the result. If a third element is supplied, this will become the conjunction used by list_array(). If a fourth element is supplied, it will be used as identity query flags for resolving the names of the list elements. If a fifth element is supplied, it will be interpreted as message listing flags.
({ 'j', list }) "a couple of swords, an axe and a shield" Msg_Group_List(list) Item-listing form of the second element, which must be an array. /daemon/item_listing's functionality will be will be applied to the list. If a third element is supplied, it will be used as identity query flags for resolving the names of the list elements. If a fourth element is supplied, it will be used as listing flags; Listing_Flag_Include_Viewer is always turned on.
({ 'l', obj }) "himself" / "herself" / "yourself" Msg_Refl_Pron(obj) Reflexive pronoun of the second element (himself, herself, yourself, etc)
({ 'm', obj }) "his" / "hers" / "yours" Msg_Poss_Adj_Pron(obj) Possessive-adjective pronoun of the second element (his, hers, yours, etc)
({ 'n', obj }) "orc" Msg_Name(obj) The literal name of the second element, i.e. "orc", "troll", "Bob"
({ 'N', obj }) "orc" Msg_Conv_Name(obj) The conversational name of the second element, i.e. "anthrope", "human", "Bob"
({ 'o', obj }) "him" / "her" / "it" / "them" / "you" ({ 'o', obj, Identity_Query_Flag_Indicative_Case }) "him" / "her" / "that" / "those" / "you" Msg_Obj_Pron(obj) Msg_Obj_Pron(obj, Identity_Query_Flag_Indicative_Case) Objective pronoun of the second element (him, her, etc). The third element may contain identity query flags; if they include Identity_Query_Flag_Indicative_Case, the objective indicative pronoun ('that' rather than 'it', 'those' rather than 'them') is used.
({ 'p', obj }) "he" / "she" / "it" / "they" / "you" ({ 'p', obj, Identity_Query_Flag_Indicative_Case }) "he" / "she" / "that" / "those" / "you" Msg_Subj_Pron(obj) Msg_Subj_Pron(obj, Identity_Query_Flag_Indicative_Case) Subjective pronoun of the second element (he, she, etc). The third element may contain identity query flags; if they include Identity_Query_Flag_Indicative_Case, the subjective indicative pronoun ('that' rather than 'it', 'those' rather than 'they') is used.
({ 'q', obj }) "his" / "her" / "your" Msg_Poss_Pron(obj) Possessive pronoun of the second element (his, her, etc). This is ALMOST NEVER appropriate to use; use 'r' instead whenever possible.
({ 'r', who, obj }) "his sword" / "your knife" ({ 'r', who, list }) "his sword and knife" Msg_Pron_Has(who, obj) Msg_Pron_Has(who, list) Indefinite possessive form of the third element with respect to the second element; i.e. ({ 'r', 0, weapon }) will produce "his sword", "her knife", "Heavensfire", etc. The third element may be a string, an object, or an array of strings and/or objects and/or limb indices of 'who' (limb indices will be converted to a summary list of the appropriate limb names using the function query_limbs_description()). A fourth element, if supplied, will be used as message listing flags (cf. /def/descriptor/message.c). If a fifth element is supplied, it will be used as identity query flags (cf. /def/descriptor/identity.c).
({ 's', who, obj }) "the orc's sword" / "your knife" ({ 's', who, list }) "the orc's sword and knife" Msg_Name_Has(who, obj) Msg_Name_Has(who, list) Definite possessive form of the third element with respect to the second element; i.e. ({ 's', 0, weapon }) will produce "the troll's sword", "Bob's knife", "Stormbringer", etc. The third element may be a string, an object, or an array of strings and/or objects and/or limb indices (as with 'r' above). If a fourth element is supplied, it will be used as message listing flags (cf. /def/descriptor/message.c). A fifth element, if supplied, will be used as identity query flags (cf. /def/descriptor/identity.c). In a very special-case behavior, if 's' is used and the third element is entirely proper-named so that the second element's name does not appear, this causes the next non-reflexive pronoun in the message that refers to the second element to display a name; this means that a 'm' or 'q' will be treated as a 'u', an 'o' or 'p' will be treated as a 'e', and a 'r' will be treated as a 's'.
({ 't', obj }) "the orc" Msg_The(obj) Second element affected as if by the()
({ 'u', obj }) "the orc's" / "your" Msg_Defn_Poss(obj) Definite possessive form of the second element, i.e. ({ 'u', 0 }) will produce "your" or "Bob's" or "the orc's". If a third element is provided, it will be used as identity query flags. This is ALMOST NEVER appropriate to use; use 's' instead of 'u' whenever possible.
({ 'v', obj }) "this" / "these" Msg_Indic_Pron(obj) Indicative pronoun of the second element (this, these).
({ 'w', obj }) "orc" / "orc 2" Msg_Which(obj) Second element affected as if by which(), with the message's observer used as which()'s observer argument. If a third element is supplied, it is used as the 'name' argument to which(). If a fourth element is supplied, it is used as the 'flags' argument to which(). If a fifth element is supplied, it is used as the 'context' argument to which().
({ 'x', obj }) "male" / "female" Msg_Sex(obj) The sex of the second element as apparent to the viewer, i.e. ({ 'x', person }) will produce "male", "female", "neuter", etc. If the second element's sex is indeterminate to the viewer, nothing will be produced. If a third element is provided, it is expected to be a string and will be appended (with a space in between) to the sex name if and only if one is displayed. Most often, the results desired with this are better obtained using 'c' with the 'include sex' flag enabled.
({ 'z', obj, "forme", "foryou" }) "forme" / "foryou" Msg_Self_Other(obj, "forme", "foryou") Uses the third or fourth element depending on the viewer, i.e. ({ 'z', 0, "you", "this" }) will produce "you" if the viewer matches the originator of the message, otherwise "this".
({ 'X', ({ ... })}) Msg_Expand(({ ... })) Expands the array specified into the outer message. So ({ ({ 'X', ({ "foo" }) has the same effect as ({ "foo" }). If this doesn't make any sense to you, it probably doesn't need to; it exists to support some difficult cases that lib developers run into.
Once converted to strings locally, the elements of the list are normally concatenated with a single space inserted between each pair. The space will not be inserted, however, before any list element which begins with one of the characters ,;:.!? for purposes of consistency.
It is expected that support for language interpretation and other functions will be added into the messaging code.
EXAMPLES
To send a message of an orc bowing to an ogre (represented by the object variables 'orc' and 'ogre' respectively):
orc->message(([ Message_Content : ({ 0, ({ "bow", 0 }), "to", ogre, }), Message_Senses : Message_Sense_Visual | Message_Sense_Kinesthetic_For_Source, ]));
// msg.h version orc->message(([ Message_Content : ({ 0, Msg_Verb("bow"), "to", ogre, }), Message_Senses : Message_Sense_Visual | Message_Sense_Kinesthetic_For_Source, ]));
The orc will see "You bow to the ogre.\n", the ogre will see "The orc bows to you.\n", and others present will see "The orc bbows to the ogre.\n".
For a sword to send a message that it leaps toward its target:
wielder->message(([ Message_Content : ({ ({ 's', 0, this_object() }), ({ "leap", this_object() }), "toward", target, }), Message_Senses : Message_Sense_Visual | Message_Sense_Kinesthetic_For_Source | Message_Sense_Tactile_For_Participants, ]));
// msg.h version wielder->message(([ Message_Content : ({ Msg_Name_Has(0, this_object()), Msg_Verb("leap", this_object()), "toward", target, }), Message_Senses : Message_Sense_Visual | Message_Sense_Kinesthetic_For_Source | Message_Sense_Tactile_For_Participants, ]));
For 'bob' to wiggle his ears:
bob->message(([ Message_Content : ({ 0, ({ "wiggle", 0 }), ({ 'r', 0, "ears" }), }), Message_Senses : Message_Sense_Visual | Message_Sense_Kinesthetic_For_Source, ]));
// msg.h version bob->message(([ Message_Content : ({ 0, Msg_Verb("wiggle", 0), Msg_Pron_Has(0, "ears"), }), Message_Senses : Message_Sense_Visual | Message_Sense_Kinesthetic_For_Source, ]));
For 'larry' to run into 'moe', shoving him into 'curly':
larry->message(([ Message_Content : ({ 0, ({ "run", 0 }), "into", moe, ", shoving", ({ 'o', moe }), "into", curly, }), Message_Senses : Message_Sense_Visual | Message_Sense_Kinesthetic_For_Source | Message_Sense_Tactile_For_Participants, ]));
// msg.h version larry->message(([ Message_Content : ({ 0, Msg_Verb("run", 0), "into", moe, ", shoving", Msg_Obj_Pron(moe), "into", curly, }), Message_Senses : Message_Sense_Visual | Message_Sense_Kinesthetic_For_Source | Message_Sense_Tactile_For_Participants, ]));
HISTORICAL
The original message() function had a four-argument form which could only handle different messages for one target and which had no facility for subjective recognition of objects. Its functionality was once supported for backward compatibility, but this is no longer the case.