Man mentation
From LSWiki
Synopsis
Ain Soph enables the handling of game functionality actuated by in-character mental processes; e.g. a helm which projects flames when you think a command word, a gem that heals you when you visualize a caduceus.
Files
/mod/character/mind.c /lib/thought.h /daemon/command/character/believe.c /daemon/command/character/concentrate.c /daemon/command/character/disbelieve.c /daemon/command/character/imagine.c /daemon/command/character/subvocalize.c /daemon/command/character/think.c /daemon/command/character/visualize.c /daemon/command/character/will.c
Description
The mentation mechanism enables wizards to implement character abilities which are actuated by thought processes. Many items and organizations add various capabilities to players by using add_action() to create arbitrary command structures. Many of these capabilities are better handled through speech or thought actuation; this system covers the latter.
Thought-actuated events, or simply "thoughts", are created using the function add_thought(), which exists in all living objects. Its syntax is as follows:
mapping add_thought(mixed tag, string arg, int flags, int activity, closure fcan, closure fdo);
'tag' is a string or array of strings which the thought 'keys' on, or 0 to key on any string. For example, if you wanted your thought to activate when someone thought of trees, you might send a value of "trees" for 'tag'. If you wanted it to activate when they thought of either trees or bushes, you could send ({ "trees", "bushes" }). It's recommended that both specific and less specific tags be provided; e.g. you could have a power key on both "visualize a triangle" and "visualize a point-up silver triangle", possibly triggering somewhat different versions of the power. This allows the possibility of ambiguity with other powers which also involve the visualization of triangles, but also lets characters who wish to be careful in their use of thought-actuated powers avoid trouble.
'arg' can be used for thoughts which take arguments, e.g. if you wanted people to be able to do "concentrate on harming <target>". In that case you would pass "%s" as 'arg', meaning a string argument following the tag value. You can also use "%d", meaning an integer argument following the tag value.
'flags' indicates the types of mentation which the thought will key on. These are defined by the macros in /lib/thought.h, and are:
TF_Believe thought confirming the reality of a thing or idea TF_Concentrate concentration on an concept TF_Disbelieve thought denying the reality of a thing or idea TF_Feel thought expressing an emotion TF_Imagine thought about a sensory impression, real or constructed TF_Subvocalize mind-internal verbalization, "thinking words" TF_Think thinking about a concept, like concentrate but less intensive TF_Visualize thought about a visual sensory impression, real or constructed TF_Will thought oriented toward a desired effect
You can send one of these flags as your 'flags' value to key only on that type, send several joined by bitwise ORs (e.g. TF_Think|TF_Will), or use the macro TF_Any to key on any mentation type. Note that the mentation types have different default activity costs ('concentrate' takes more time thank 'think', for example) and different conditional requirements (you cannot 'concentrate' while berserk).
'activity' is the activity cost of actuating this thought. Only the highest activity cost from all thoughts triggered at once is used. If no triggered thoughts specify an activity cost, the activity cost will be the default value for the type of mentation used (in general, 2 for think, feel, subvocalize and will, 15 for the rest).
'fcan' is the function checked for whether the thought can be actuated. It is passed the following arguments:
object who The person performing the mentation. mixed val The value obtained for the thought's arguments, if any. string what The string value given by the player to the mentation command; e.g. for both "think about beer" and "visualize beer", this value will be "beer". int total The total number of thoughts which are having their 'fcan' functions checked for this mentation event, including this one. int type The appropriate thought.h macro for the type of mentation actually being performed.
The return value from the 'fcan' closure may be:
1 Success; allow the thought to be actuated. 0 Failure; do not actuate this thought. a string Failure; do not actuate this thought. The string returned will be shown to the person performing the mentation, as an error message. an array Success; allow the thought to be actuated. Pass the array given to the 'fdo' function. a mapping Success; allow the thought to be actuated. Pass the mapping given to the 'fdo' function. an error descriptor Failure; do nto actuate this thought. The message in the error descriptor returned will be shown to the person performing the mentation, as an error message.
'fdo' is the function called when the thought has been successfully cleared for actuation; all actual game effects should be contained in this function, while status checks and so forth should be contained in the 'fcan' function. It is passed the following arguments:
object who The person performing the mentation. mixed val The value obtained for the thought's arguments, if any. mixed inf If 'fcan' returned an array or mapping value, this is it. string what The string value given by the player to the mentation command; e.g. for both "think about beer" and "visualize beer", this value will be "beer". int total The total number of thoughts which have had their 'fcan' functions checked and are now being actuated via 'fdo' functions, including this one. int type The appropriate thought.h macro for the type of mentation actually being performed.
Example of setting up a thought:
thought = character->add_thought( ({ "a triangle", "a point-up silver triangle", }), 0, TF_Visualize, 0, #'can_use_healing_power, #'do_use_healing_power );
The return value of add_thought() is a mapping which contains the thought information as used internally by mind.c. You should not change the data in this mapping. What you should do with it is store it for when you want to remove the thought from the character, which is done like so:
character->remove_thought(thought);
where 'thought' is the mapping passed back to you by add_thought().