Brainiac Behavior Engine User's Guide

About Brainiac Behavior Engine

*

Contact Info

*

License

*

High Concept of Brainiac Behavior Engine

*

Getting Started: Basics Of The Brainiac Behavior Engine

*

Basic Entities

*

Core And ItemScores Structures

*

Brainiac Conventions

*

Linking Brainiac Behavior Engine To Your Application

*

Requirements

*

Using Brainiac BE

*

Visual C++ Notes

*

Getting Started With The Brainiac Data Manager

*

1. The Basics

*

2. Setting A New Database

*

3. Building Behavior Patterns

*

Behavior Pattern 1: Killing in the Name Of...

*

Behavior Pattern 2: Robbery

*

Behavior Pattern 3: Conspiracy

*

Brainiac Native Verbal Interaction

*

Programmer's Reference

*

Goal And Criteria

*

Action

*

Strategy

*

Agent

*

EventsRegistry

*

PersonalLog

*

Non-Member Functions

*

About Brainiac Behavior Engine

Brainiac Behavior Engine (or Brainiac BE) is a highly customizable state-of-the-art AI engine; it is primarily designed for creating computer strategy / adventure / role-playing games (CRPGs) that feature lifelike behavior on the part of computer-controlled characters. Brainiac BE is virtually weightless so far as maintenance is concerned, can be tweaked in every possible direction, and is more advanced than any functionality that could be created from scripts. The list below mentions only a few of the Brainiac capabilities:

- Intelligent and reasoned responses to player actions by any computer controlled characters.

- Character actions are dependant on state of mind and practical considerations.

- Characters themselves are not static or merely reactive. They will pursue their own interests and independently assign themselves goals with or without player actions.

- Brainiac BE includes a groundbreaking model of verbal interaction. No more painstakingly scripted multi-choice conversations! In Brainiac, conversation has become the use of verbal actions; a powerful tool for enabling non-linear plots.

- Flexibility. The game designer defines character actions, goals, strategies and mindsets. The Brainiac BE data management utility makes this process easy -- no programming skills are required! Beyond the designer's imagination, there are no limits at all.

Brainiac BE uses a simple and effective object oriented model to simulate character decision-making processes at a high level.

Copyright © 1999 Twilight Minds

Contact Info

Send your comments, requests and proposals to:

Email:

bbe_support@twilightminds.com

bbe@twilightminds.com

Twilight Minds homepage:

http://www.twilightminds.com

License

TWILIGHT MINDS BRAINIAC BEHAVIOR ENGINE (BBE) PUBLIC LICENSE

Version 1.0

PREAMBLE

Please read this license carefully before using the Twilight Minds'

Brainiac Behavior Engine (BBE). By downloading and using

BBE, you are agreeing to be bound by the terms of this license.

If you do not or cannot agree to the terms of this License, do not

download or use BBE.

This license is intended to make the BBE source code available to

everyone who wants the opportunity to use it or contribute to this

Twilight Minds project. Note that BBE is a commercial product.

It is not in the public domain, nor is it "freeware" or "shareware".

By making the source code available, the Twilight Minds Design

Group is not giving it away nor abandoning any right of ownership.

By using BBE you agree to be bound by the spirit and the terms of

this license.

This license permits you to use BBE to create and sell products.

You may also redistribute BBE. You may also make modifications

to the BBE source code and distribute them too.

If you modify the BBE source, excerpt any portion of it, or if

you use a modified version of the engine source, you must make your

source code available for others to use under the same terms that

we have granted you. This guarantees that modifications to BBE will

be available to everyone and the best modifications can become part

of any official Twilight Minds release. Your source code must be

released concurrent with releasing any executable built with BBE.

If you do not wish to make your source code available you must

obtain a separate license from the Twilight Minds Design Group.

If you use any original unmodified Twilight Minds-built BBE binaries

there is no requirement for you to make your source code available.

You must display the original unmodified Twilight Minds animated logo

as the first logo on startup of your product, demo or application.

You must also prominently display the Twilight Minds logo on any

marketing materials, advertising or packaging of your product.

These terms are good for the community because they make source code

available to everyone and encourage the sharing of improvements. They

are good for Twilight Minds because some companies will opt to not

share their source and will prefer to pay to license the engine instead.

These kinds of licenses will help to fund future Twilight Minds

development and subsidize the free licenses that many people will enjoy.

1. DEFINITIONS

1.1. ``Contributor'' means each entity that creates or contributes to

the creation of Modifications.

1.2. ``Contributor Version'' means the combination of the Original

Code, prior Modifications used by a Contributor, and the

Modifications made by that particular Contributor.

1.3. ``Covered Code'' means the Original Code or Modifications or

the combination of the Original Code and Modifications, in each case

including portions thereof, and any Source Code which duplicates,

enhances, modifies or replaces functionality of the Covered Code as

defined in Exhibit B.

1.4. ``Electronic Distribution Mechanism'' means a mechanism

generally accepted in the software development community for the

electronic transfer of data.

1.5. ``Twilight Minds'' means Twilight Minds Design Group, a

partnership.

1.6. ``Executable'' means Covered Code in any form other than

Source Code.

1.7. ``Larger Work'' means a work which combines Covered Code

or portions thereof with code not governed by the terms of this

License.

1.8. ``License'' means this document.

1.9. ``Modifications'' means any addition to or deletion from the

substance or structure of either the Original Code or any previous

Modifications. When Covered Code is released as a series of files, a

Modification is:

A. Any addition to or deletion from the contents of a file

containing Original Code or previous Modifications.

B. Any new file that contains any part of the Original Code

or previous Modifications.

1.10. ``Original Code'' means Source Code of computer software

code which is described in the Source Code notice required by

Exhibit A as Original Code, and which, at the time of its release

under this License is not already Covered Code governed by this

License.

1.11. ``Source Code'' means the preferred form of the Covered Code

for making modifications to it, including all modules it contains, plus

any associated interface definition files, scripts used to control

compilation and installation of an Executable, or a list of source code

differential comparisons against either the Original Code or another

well known, available Covered Code of the Contributor's choice. The

Source Code can be in a compressed or archival form, provided the

appropriate decompression or de-archiving software is widely

available for no charge.

1.12. ``You'' means an individual or a entity exercising rights

under, and complying with all of the terms of, this License or a future

version of this License issued under Section 7.1. For legal entities,

``You'' includes any entity which controls, is controlled by, or is

under common control with You. For purposes of this definition,

``control'' means (a) the power, direct or indirect, to cause the

direction or management of such entity, whether by contract or

otherwise, or (b) ownership of fifty percent (50%) or more of the

outstanding shares or beneficial ownership of such entity.

2. SOURCE CODE LICENSE

2.1. The Twilight Minds Grant.

Twilight Minds hereby grants You a world-wide, fully paid, royalty-free,

non-exclusive license, subject to third party intellectual property claims:

(a) to use, reproduce, modify, display, perform, sublicense and

distribute the Original Code (or portions thereof) with or without

Modifications, or as part of a Larger Work; and

(b) under patents now or hereafter owned or controlled by

Twilight Minds, to make, have made, use and sell (``Utilize'') the

Original Code (or portions thereof), but solely to the extent that

any such patent is reasonably necessary to enable You to Utilize

the Original Code (or portions thereof) and not to any greater

extent that may be necessary to Utilize further Modifications or

combinations.

2.2. Contributor Grant.

Each Contributor hereby grants You a world-wide, fully paid,

royalty-free, non-exclusive license, subject to third party intellectual

property claims:

(a) to use, reproduce, modify, display, perform, sublicense and

distribute the Modifications created by such Contributor (or

portions thereof) either on an unmodified basis, with other

Modifications, as Covered Code or as part of a Larger Work; and

(b) under patents now or hereafter owned or controlled by

Contributor, to Utilize the Contributor Version (or portions

thereof), but solely to the extent that any such patent is

reasonably necessary to enable You to Utilize the Contributor

Version (or portions thereof), and not to any greater extent that

may be necessary to Utilize further Modifications or

combinations.

2.3. Your Grant.

You hereby grant to Twilight Minds a world-wide, fully paid,

royalty-free, non-exclusive license, subject to third party intellectual

property claims:

(a) to use, reproduce, modify, display, perform, sublicense and

distribute the Modifications created by You (or portions thereof)

either on an unmodified basis, with other Modifications, as

Covered Code or as part of a Larger Work; and

(b) under patents now or hereafter owned or controlled by You,

to Utilize the Modifications (or portions thereof), but solely to

the extent that any such patent is reasonably necessary to enable

Twilight Minds to Utilize the Modifications (or portions thereof), and not

to any greater extent that may be necessary to Utilize further

Modifications or combinations.

3. DISTRIBUTION OBLIGATIONS

3.1. Application of License to You.

The Modifications which You create or to which You contribute are

governed by the terms of this License, including without limitation

Section 2.2. The Source Code version of Covered Code may be

distributed only under the terms of this License or a future version of

this License released under Section 7.1, and You must include a copy

of this License with every copy of the Source Code You distribute.

You may not offer or impose any terms on any Source Code version

that alters or restricts the applicable version of this License or the

recipients' rights hereunder. However, You may include an additional

document offering the additional rights described in Section 3.6.

3.2. Application of License to Twilight Minds.

(a) Other Products.

Twilight Minds may include Covered Code in products other than

BBE without such additional products becoming subject to

the terms of this License, and may license such additional

products on different terms from those contained in this License.

(b) Other Licenses.

Twilight Minds may license the Source Code including Modifications

incorporated therein, without such additional products becoming

subject to the terms of this License, and may license such

additional products on different terms from those contained in

this License.

(c) Other Releases.

Twilight Minds may create new releases of BBE without such

releases becoming subject to the terms of this License.

3.3. Availability of Source Code.

Any Modification which You create or to which You contribute must

be made available in Source Code form under the terms of this

License either on the same media as an Executable version or via an

accepted Electronic Distribution Mechanism to anyone to whom you

made an Executable version available; and if made available via

Electronic Distribution Mechanism, must remain available for at least

twelve (12) months after the date it initially became available, or at

least six (6) months after a subsequent version of that particular

Modification has been made available to such recipients. You are

responsible for ensuring that the Source Code version remains

available even if the Electronic Distribution Mechanism is maintained

by a third party. Furthermore, the Source Code to the Modifications

You create or contribute must be delivered in fully compilable form

using commonly available tools. If the tools used to compile the

Source Code are not commonly available You must also include the

tools, in Source Code and Executable forms, as part of the

Modifications.

3.4. Description of Modifications.

You must cause all Covered Code to which you contribute to contain

a file documenting the changes You made to create that Covered

Code and the date of any change. You must include a prominent

statement that the Modification is derived, directly or indirectly, from

Original Code provided by Twilight Minds in (a) the Source Code, and

(b) in any notice in an Executable version or related documentation in

which You describe the origin or ownership of the Covered Code.

3.5. Intellectual Property Matters

(a) Third Party Claims.

If You have knowledge that a party claims an intellectual

property right in particular functionality or code (or its utilization

under this License), you must include a text file with the source

code distribution titled ``LEGAL'' which describes the claim and

the party making the claim in sufficient detail that a recipient will

know whom to contact. If you obtain such knowledge after You

make Your Modification available as described in Section 3.3,

You shall promptly modify the LEGAL file in all copies You

make available thereafter and shall take other steps (such as

notifying appropriate mailing lists or newsgroups) reasonably

calculated to inform those who received the Covered Code that

new knowledge has been obtained.

(b) Contributor APIs.

If Your Modification is an application programming interface

and You own or control patents which are reasonably necessary

to implement that API, you must also include this information in

the LEGAL file.

3.6. Required Notices.

You must duplicate the notice in Exhibit A in each file of the Source

Code, and this License in any documentation for the Source Code,

where You describe recipients' rights relating to Covered Code. If

You created one or more Modification(s), You may add your name as

a Contributor to the notice described in Exhibit A. If it is not

possible to put such notice in a particular Source Code file due to its

structure, then you must include such notice in a location (such as a

relevant directory file) where a user would be likely to look for such a

notice. You may choose to offer, and to charge a fee for, warranty,

support, indemnity or liability obligations to one or more recipients

of Covered Code. However, You may do so only on Your own

behalf, and not on behalf of Twilight Minds or any Contributor. You must

make it absolutely clear that any such warranty, support, indemnity or

liability obligation is offered by You alone, and You hereby agree to

indemnify Twilight Minds and every Contributor for any liability incurred

by Twilight Minds or such Contributor as a result of warranty, support,

indemnity or liability terms You offer.

3.7. Distribof Executable Versions.

You may distribute Covered Code in Executable form only if the

requirements of Section 3.1-3.6 have been met for that Covered

Code, and if You include a notice stating that the Source Code

version of the Covered Code is available under the terms of this

License, including a description of how and where You have fulfilled

the obligations of Section 3.3. The notice must be conspicuously

included in any notice in an Executable version, related

documentation or collateral in which You describe recipients' rights

relating to the Covered Code. You may distribute the Executable

version of Covered Code under a license of Your choice, which may

contain terms different from this License, provided that You are in

compliance with the terms of this License and that the license for the

Executable version does not attempt to limit or alter the recipient's

rights in the Source Code version from the rights set forth in this

License. If You distribute the Executable version under a different

license You must make it absolutely clear that any terms which differ

from this License are offered by You alone, not by Twilight Minds or any

Contributor. You hereby agree to indemnify Twilight Minds and every

Contributor for any liability incurred by Twilight Minds or such

Contributor as a result of any such terms You offer.

3.8. Larger Works.

You may create a Larger Work by combining Covered Code with

other code not governed by the terms of this License and distribute

the Larger Work as a single product. In such a case, You must make

sure the requirements of this License are fulfilled for the Covered

Code.

4. RESTRICTIONS

4.1. You agree to:

(a) display the original, unmodified Twilight Minds animated logo

as the first logo on startup of your product, demo or application;

(b) prominently display the Twilight Minds logo on any marketing

materials, advertising or packaging of your product, demo or

application;

(c) distribute the Covered Code to third parties who agree to be

bound by these terms and conditions;

(d) make reasonable efforts to discontinue distribution of the Covered

Code upon Twilight Minds' release of an update, upgrade or new version of

the Covered Code and to make reasonable efforts to distribute such

updates, upgrades or new versions to your customers who have

received the Covered Code herein;

(e) be solely responsible for any update or support obligation or other

liability which may arise from your distribution of the Covered Code.

4.2. You may not:

(a) remove, alter, obscure, or modify in any way the appearance or

operation of the Twilight Minds logo;

(b) copy the Covered Code, in whole or in part, except as provided in

this License;

(c) make any statement that your product is "certified," or that its

performance is guaranteed, by Twilight Minds.

5. INABILITY TO COMPLY DUE TO STATUTE OR

REGULATION

If it is impossible for You to comply with any of the terms of this

License with respect to some or all of the Covered Code due to

statute or regulation then You must: (a) comply with the terms of this

License to the maximum extent possible; and (b) describe the

limitations and the code they affect. Such description must be

included in the LEGAL file described in Section 3.5 and must be

included with all distributions of the Source Code. Except to the

extent prohibited by statute or regulation, such description must be

sufficiently detailed for a recipient of ordinary skill to be able to

understand it.

6. APPLICATION OF THIS LICENSE

This License applies to code to which Twilight Minds has attached the

notice in Exhibit A, and to related Covered Code.

7. VERSIONS OF THE LICENSE

7.1. New Versions.

Twilight Minds may publish revised and/or new versions of the License

from time to time. Each version will be given a distinguishing version

number.

7.2. Effect of New Versions.

Once Covered Code has been published under a particular version of

the License, You may always continue to use it under the terms of

that version. You may also choose to use such Covered Code under

the terms of any subsequent version of the License published by

Twilight Minds. No one other than Twilight Minds has the right to modify

the terms applicable to Covered Code created under this License.

8. DISCLAIMER OF WARRANTY

COVERED CODE IS PROVIDED UNDER THIS LICENSE ON

AN ``AS IS'' BASIS, WITHOUT WARRANTY OF ANY KIND,

EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT

LIMITATION, WARRANTIES THAT THE COVERED CODE IS

FREE OF DEFECTS, MERCHANTABLE, FIT FOR A

PARTICULAR PURPOSE OR NON-INFRINGING. THE ENTIRE

RISK AS TO THE QUALITY AND PERFORMANCE OF THE

COVERED CODE IS WITH YOU. SHOULD ANY COVERED

CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT

TWILIGHT MINDS OR ANY OTHER CONTRIBUTOR) ASSUME THE

COST OF ANY NECESSARY SERVICING, REPAIR OR

CORRECTION. THIS DISCLAIMER OF WARRANTY

CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO

USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER

EXCEPT UNDER THIS DISCLAIMER.

9. TERMINATION

This License and the rights granted hereunder will terminate

automatically if You fail to comply with terms herein and fail to cure

such breach within 30 days of becoming aware of the breach. All

sublicenses to the Covered Code which are properly granted shall

survive any termination of this License. Provisions which, by their

nature, must remain in effect beyond the termination of this License

shall survive.

10. LIMITATION OF LIABILITY

UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL

THEORY, WHETHER TORT (INCLUDING NEGLIGENCE),

CONTRACT, OR OTHERWISE, SHALL TWILIGHT MINDS, ANY

OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED

CODE, OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE

LIABLE TO YOU OR ANY OTHER PERSON FOR ANY

INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL

DAMAGES OF ANY CHARACTER INCLUDING, WITHOUT

LIMITATION, DAMAGES FOR LOSS OF GOODWILL, WORK

STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR

ANY AND ALL OTHER COMMERCIAL DAMAGES OR

LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN

INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS

LIMITATION OF LIABILITY SHALL NOT APPLY TO

LIABILITY FOR DEATH OR PERSONAL INJURY RESULTING

FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT

APPLICABLE LAW PROHIBITS SUCH LIMITATION. SOME

JURISDICTIONS DO NOT ALLOW THE EXCLUSION OR

LIMITATION OF INCIDENTAL OR CONSEQUENTIAL

DAMAGES, SO THAT EXCLUSION AND LIMITATION MAY

NOT APPLY TO YOU.

INDEMNIFICATION: YOU SHALL INDEMNIFY, HOLD

HARMLESS, AND DEFEND TWILIGHT MINDS AND ITS

SUPPLIERS FROM AND AGAINST ANY CLAIMS OR LAWSUITS,

INCLUDING ATTORNEY'S FEES, THAT ARISE OR RESULT

FROM YOUR USE OR DISTRIBUTION OF ANY PRODUCT

INCORPORATING THE COVERED CODE IN WHOLE OR IN

PART.

11. U.S. GOVERNMENT END USERS

The Covered Code is a ``commercial item,'' as that term is defined in

48 C.F.R. 2.101 (Oct. 1995), consisting of ``commercial computer

software'' and ``commercial computer software documentation,'' as

such terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with

48 C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4

(June 1995), all U.S. Government End Users acquire Covered Code

with only those rights set forth herein.

12. MISCELLANEOUS

This License represents the complete agreement concerning subject

matter hereof. If any provision of this License is held to be

unenforceable, such provision shall be reformed only to the extent

necessary to make it enforceable. This License is governed by the

laws of the State of Texas and the United States, including patent and

copyright laws. Any claim arising out of this License will be brought

in Harris County, Texas.

The application of the United Nations Convention on Contracts for

the International Sale of Goods is expressly excluded. Any law or

regulation which provides that the language of a contract shall be

construed against the drafter shall not apply to this License.

13. RESPONSIBILITY FOR CLAIMS

Except in cases where another Contributor has failed to comply with

Section 3.5, You are responsible for damages arising, directly or

indirectly, out of Your utilization of rights under this License, based

on the number of copies of Covered Code you made available, the

revenues you received from utilizing such rights, and other re

factors. You agree to work with affected parties to distribute

responsibility on an equitable basis.

EXHIBIT A.

``The contents of this file are subject to the Twilight Minds Brainiac

Behavior Engine (BBE) Public License Version 1.0 (the

"License"); you may not use this file except

in compliance with the License. You may obtain a copy of the

License at http://www.twilightminds.com/tmBBElicense.txt.

Software distributed under the License is distributed on an "AS IS"

basis, WITHOUT WARRANTY OF ANY KIND, either express or

implied. See the License for the specific language governing rights

and limitations under the License.

The Original Code is BBE, released November 29, 1999.

Copyright (C) 1999 Twilight Minds Design Group All Rights

Reserved.

Contributor(s): ______________________________________.''

EXHIBIT B.

Functionality of the Covered Code includes:

(a) Handling AI-specific processes;

(b) Storing, loading and managing the binary data;

High Concept of Brainiac Behavior Engine

The three basic conceptual units of behavior used in Brainiac BE are Goals, Actions and Strategies. As in real life, characters set Goals and then search for suitable Strategies to obtain these Goals.

A Strategy consists of one or more Actions; if a character evaluates the Actions making up a Strategy to have a reasonably chance of success (and to be morally acceptable), the Strategy will be adopted and the Actions scheduled. For example, every character might want to acquire a given expensive item. Some characters might be able to purchase the item, while others might be able to steal the item. Most characters will not find a suitable and morally acceptable Strategy and will put the whole issue to one side. (At least, this is the way it should be to prevent unwanted hyperactivity on the part of your characters. The level of activity is -- of course -- configurable through your own settings).

Characters will attempt Actions on every "environment change" (that is, when a character leaves, disappears, changes state, arrives or appears). In the debugger, Actions are executed continuously because there are no other tasks.

Every Action and Strategy includes an Objective. The Objective is a character targeted by this particular Action. A Strategy Objective is not necessarily the Objective of every Action that is a part of that Strategy (you can look at the examples, such as conspiracy or assassination, using the Brainiac BE Data Manager).

A Criteria Id must be specified in order to choose an Objective. A Criteria is set of limits defining, as you might expect, criteria for the potential Objective. Technically, Criteria records are stored in a Goal file, as both use the same format and are conceptually close. Flags and limitations also exist in connection with Actions, such as conditional loops in case of failure and referenced Objectives.

An important point to take note of is the difference between Goals and Strategies. A Goal is a morally independent state that a character might want to achieve. For example, neither stealing nor buying an item is a Goal. Both are Strategies for acquiring this item. To determine the real Goal, consider an alternate Strategy that leads to the same end state.

Getting Started: Basics Of The Brainiac Behavior Engine

Basic Entities

The figure below shows the hierarchy of the basic Brainiac entities. The Agent entity contains a Strategy entity, which consists of several Actions. Strategy has a Goal. All the entities use Core structure, which contains the most important attributes of the Agent.

The Brainiac concept is simple and intuitive; you should soon get the hang of it. All processes start with a motivation, which is defined by a Goal structure. Once an Agent has decided that it wants to pursue a Goal, the process of selecting a Strategy begins. The Strategy that is adopted will be the one that best fits the Agent's profile and that appears the easiest to accomplish. The Agent then schedules Actions within the Strategy for execution. Goals, Strategies and Actions are defined in the Brainiac Data Manager during the design process.

The cornerstone structure in Brainiac is called Core. It contains the most elementary and univeral Agent features. Core is recognized and used by all Brainaic classes and most non-member functions.

Core And ItemScores Structures

The Core structure contains basic and universal Agent attributes. A similar structure exists for inventory items and is called ItemScores. The ItemScores structure contains a subset of the Attributes included in Core; these being Meanness, Foreignness, Wealth, Beauty and Personality. In addition, a current Owner ID is specified.

typedef struct _Core {

AlignmentType alType;

percentage Wickedness;

percentage Anarchy;

percentage InitialAttitude;

percentage AttitudeChangeUnit;

percentage SuddenChange;

percentage LieProbability;

//Impression values - [1] means "true social"; [0] -

// "seemed social"

percentage Meanness[2], Wealth[2], Beauty;

percentage Foreignness;

percentage Intelligence[2], Courage;

short UserDefined[3];

ID attId;

Attitude *attPersonal; //tree of personal attitudes

_Core *LastAccessedBy;

unsigned char CurrentEnvironment;

ID LastTargettedInAction, LastCommittedAction;

BOOL Dead;

} Core;

typedef struct {

ID ItemID;

ID Owner;

percentage Wickedness;

percentage Anarchy;

percentage Meanness, Foreignness, Wealth, Beauty, Personality;

percentage Influence;

//0 to 100 - percentage of influence on the

//overall Impression

BOOL CanBeDivided;

unsigned short UserDefined[3];

} ItemScores;

The agent stats used in Core / ItemScores structures are:

- Wickedness
(measure of evil). If negative, assumed "good". The higher this score, the more wicked the agent / the action. Valid values are -100..100.

- Anarchy
(measure of chaos). If negative, assumed "lawful". The higher this score, the more chaotic the agent / the action. Valid values are -100..100.

- Attitude
- the lower the value, the worse the attitude. Valid values are -100..100.

- Attitude Change Unit
is the least possible change of attitude, different for every agent

- Sudden Change Probability
is probability of sudden unexplained random change in agent's moral profile which will enable him / her to accomplish an action s / he would normally avoid (like stealing for lawful person). Valid scores are 0..100.

- Combat Overall
, or Meanness - the overall combat capability for agent or inventory item, including dexterity, strength, and all the other attributes. For agents, this score is an array of two parts: seemed[0] and real[1]. Valid scores are 0..100.

- Wealth
- the overall financial status for agent or inventory item. Just like Combat Overall, this score is an array of seemed[0] and real[1] wealth (for agents only). Valid scores are 0..100.

- Intelligence
- the overall agent's mental abilities, including the evaluating ability. For inventory items, this score shows just how "smart" the item looks. For agents only, this score is an array of seemed[0] and real[1] intelligence.

- Beauty
- appearance for a agent or an inventory item.

- Social Group
/ Foreignness - used to mark belongevity to a social group.

- Courage
/ Morale - current agent's spirit strength and ability to handle difficult choices.

Other attributes are:

- alType
- alignment (mindset) type constant / ID for custom mindset

- InitialAttitude
- neutral, uninfluenced attitude toward a total stranger

- attId
- unique ID given by the system to the Agent. Not recommended to modify

- attPersonal
- pointer to the attitudes' tree (not recommended to use directly). See Non-Member Functions for functions manipulating the attitude tree

- LieProbability
is currently unused

- LastAccessedBy
- pointer to the Core of the agent who last initiated action aimed at the structure's owner

- CurrentEnvironment
- nature of the action last aimed at the structure's owner: HOSTILE / NEUTRAL / FRIENDLY

- LastTargettedInAction
- ID of the action last aimed at the structure's owner

- LastCommittedAction
- ID of the last committed action

- Dead
- if the agent is permanently inactive (dead)

- UserDefined
- array of 3 cells for user-defivalues

- CanBeDivided
(ItemScores) - if the inventory item is dividable. Used for value comparisons

- Influence
(ItemScores) - the inventory item's influence on the overall agent's appearance (in per cents).

- Owner
(ItemScores) - the inventory item's owner's unique ID

- ItemID
(ItemScores) - the inventory item ID inside the inventory

Brainiac Conventions

- Initiator
- the Agent who accomplishes an Action or Strategy

- Objective
/ Subject - an Agent or inventory item targetted by an Action or Strategy. Every Action or Strategy has free slots for both an Objective person and an Objective inventory item. Note that even if an item is targetted, an Agent (owner of the item, living or dead) still must be specified.

- Evaluator
- an Agent making a decision; examining a stranger, appraising a deal or thinking about completing a request.

- Scanned
- an Agent being examined.

- Action
is the basic unit in Brainiac. It is a single action, executed by an Initiator and targetting an Objective.

- Goal
is an Agent's motivation to act. It might be the desire to acquire an item or practically any other urge.

- Strategy
is a way of achieving a Goal. Strategies are made up of Actions. Technically, a Strategy is a single-linked list, but special flags enable conditional branching and even looping. The Objective of every Action in the Strategy is not necessarily the Strategy Objective. Other Agents are usually used for intermediate purposes, and in most strategies this is an essential feature: when hiring an assassin, you just cannot hire the mark, after all.

- TAC
, or Target Assignment Criterion - criterion ID for the Objective of an Action. It defines what kind of Agents are suitable to be the Action Objective. Once the Initiator encounters an Agent that suits the criterion, it assigns this Agent. Criteria records are stored in the Goals file, because Goals are actually criteria for starting a Strategy.

- Action Function
/ Callback Function - a function which is automatically called upon Action execution. The function is, actually, an Action implementation. The Brainiac callback function receives a void pointer and returns an integer. If a non-zero value is returned, Brainiac assumes that the action succeeded.

Linking Brainiac Behavior Engine To Your Application

Requirements

Windows '95 or better

Any Win32-supporting C++ IDE or compiler

Using Brainiac BE

You will have to complete a number of tasks in order to make use of Brainiac in conjunction with your application:

1) Link BBE.LIB to your project. Include the BRAINIAC.H header file in the module that will make use of Brainiac functions.

2) When generating your characters or other computer-controlled entities, ensure that an Agent object is defined for each one.

3) You must call the InitActionLib() non-member function when loading your application and the FreeLibLists() non-member function when exiting it.

4) Optionally (but it is recommended), you may prepare functions that assemble an array of pointers to all Agent objects, and an array of arrays containing pointers to their inventory items.

5) When a character or entity enters or departs the currently considered game location (an "environment change") you must call the Agent::Scan() function for every Agent present at that game location.

6) You must call the Agent::ExecuteNextAction() method when you want a character or entity to act. The best timing is probably for Agents to actat each environment change. In that case, agents who failed in an action won't attempt to needlessly execute the action again (possibly leading the abandonment of their strategy).

Visual C++ Notes

To work with Brainiac BE in a Visual C++ IDE, you will have to perform the following tasks:

1) In Tools/Options/Directories, add the BRAINIAC.H header file to the "Library files" directory list.

2) Add Visual C++ BBE.LIB to your project. This can be done in Project/Settings/Link.

Getting Started With The Brainiac Data Manager

1. The Basics

Brainiac characters operate using three tools: Goals, Actions and Strategies. A Goal defines a desired end result, such as winning a game or getting rich. A Strategy is made up of a chain of possible Actions that can be undertaken in order to attain a Goal. In the case of getting rich, a Strategy could be made up of Actions revolving around theft, trading, playing the stock market, or any one of a hundred other tactics.

If character A meets with character B and B satisfies all of the criteria contained in one of A's Goal records, then A will attempt to pick a Strategy which:

a) Serves to accomplish this Goal, and

b) Suits character A's temperament and that A believes is possible to accomplish

If character A finds such a Strategy, it will be scheduled for execution. The execution of Actions within a Strategy may branch and loop, but individual Actions are generally fairly straightforward.

2. Setting A New Database

To start a new database, delete all of the files in the Brainiac directory using the ".db" extension. (Note that the default database is also stored in Default.zip. Keeping backup files often saves later grief.) Only one database can be used by the Database Manager at one time, but the files for other databases can of course be stored elsewhere.

3. Building Behavior Patterns

Let's build a few behavior patterns, advancing from simple events to more complex examples. We'll start with everyone's favorite, the Lethal Attack.

Behavior Pattern 1: Killing in the Name Of...

1.1 The Goal

The first step is in building a behavior pattern is always to analyze the desired sequence of events in order to determine the Goal. In this case, it couldn't be more straightforward: you would like one character to attempt to kill another character. Obviously, the Goal of the attacking character should be to kill the Objective character (remember that the Objective character is the target of an Action or a Strategy). Now you can load the Brainiac Data Manager and take the following steps:

1) Open the Database menu and select Goals... to view the Goals Table.

2) Click on the Insert button.

If you deleted all files with ".db" extensions, there will be no Goals in the Goal table. After clicking "Insert," you should now be looking at the Goal/Criterion update window.

3) Enter a description of the Goal in the "Description" field. For this Goal, we could use "killing out of enmity."

Now why would a character want to kill someone else? There are always plenty of reasons available, more is the pity, but we shall choose the most obvious: personal hatred. "Personal hatred" translates to Brainiacese as "the evaluator's attitude to the target ranges from -100 to -75." (These limits are not strict, however. Attitudes range from -100 to 100 -- the higher the better. You can play with your own settings and give your characters choleric or phlegmatic temperaments).

4) Select the Attitude Limits tab.

Do you see the number "129" everywhere? It means that a given slot is unused.

5) Now enter the following values on the "Evaluator's To Target" attitude line: Low = -100, High = -75.

A green check should appear, meaning that the Attitude slot is now being used. Press Enter to save changes, or click the OK button. What...it wouldn't close! Apparently, we forgot something. This would be the Importance field in the General tab, which is selected now. Importance comes into play when a character has to choose between two different Goals, one of which has already triggered a Strategy. Importance can take any value from one to ten, where ten is most important.

6) Enter "9" in the Importance field.

7) Click the OK button to save the Goal.

The Goal will now appear in the Goals Table. You can further edit the Goal by double-clicking on its line in the Goal Table, or by clicking the "Change" button.

1.2 The Strategy

Now that we have set up our Goal, we must create an accompanying Strategy. Note that a Strategy is really just a set of Actions and a few accompanying attributes.

1) Open the Database menu and select Strategies... to open the Strategies table.

2) Click on the Insert button.

You should now be looking at a window entitled "Update the StrategFile." Let's first identify this strategy:

3) Enter "lethal attack" (as suitable description as any) in the Name field.

4) Enter "tutorial: lethal attack" in the Description field.

The next step is to link our new Strategy to a Goal. You can either type the Goal numeric ID into the Goal field yourself or select a Goal from the Goals table:

5) Place the cursor in the Goal field and press F2 key or right click the mouse.

You should now see the same Goals table as before, but with the useful addition of the Select button. (Note that in this mode you can still branch off to add, edit or delete Goals). To link the Strategy to our Goal, do the following:

6) Highlight the "killing out of enmity" Goal (by clicking on it, or using the arrow keys) and press Select.

The Goals Table will vanish, and you should see that the Goal field in the Strategies window now contains the correct Goal ID and name.

1.3 The Actions

Now that our Strategy has a Goal, it's time to place Actions. As it happens, this Strategy only has the one Action: a straightforward attack. Let's add it this:

7) Click on the Append button.

(Notice that it's "Append," and not "Insert." New Actions will always be appended to the end of this list). You should now be looking at a window labeled "Browse the Actions File"). As before, we can add, change or delete entries in any such table in this lookup mode as well as in the regular mode.

8) Click on the Insert Button.

The Insert button is used to add a new Action record to the Actions file, and will pop up the "Update the Actions File" window.

9) Type "attack" in the Name field of the Update window.

10) Switch the Action Type to Vital using the radio button.

Setting an Action as "Vital" will turn on all the checking routines which deal with "matters of life and death." Next, we should set the other aspects of the new Action. Minimum Intelligence is first: this is the Intelligence level that a character must possess in order to initiate this Action.

11) Set Minimum Intelligence to 1; it doesn't require much in the way of brainpower to hit someone.

Let's look at Attitude Change next. The Objective character's attitude towards the character who initiated this Action will change by this amount after the Action was accomplished. Here we must give a value which will switch the kindest man on earth into a hostile state of mind; -90 is more than enough.

12) Set Attitude Change to -90.

Required Courage is -- not surprisingly -- the Courage required to initiate this Action when the initiating character and the Objective character are about even in their overall combat abilities. On the scale from 1 to 10 we should give it about an 8.

13) Set Courage to 8.

The value entered for Difficulty is used to evaluate the overall Strategy Difficulty parameter. This value prioritizes the selection of Strategies, the assumption being that characters will try easier methods (lower Difficulty numbers) first. Violence is -- hopefully -- one of the last resorts, so we shall assign Difficulty a value 30 (on a scale 1 to 100).

14) Set Difficulty to 30.

Wickedness and Anarchy are measures of the evil and chaos, respectively, inherent to this Action if the Objective character is a totally neutral towards the initiating character. On a scale of 1 to 100, this Action should rate around 75 for Wickedness and 50 for Anarchy.

15) Enter 75 in the Wickedness field.

16) Enter 50 in the Anarchy field.

The "Attitude From" and "To" fields restrict this Action to a certain emotional state, where the initiating character's Attitude towards the Objective character is within the specified range. On the assumption that most people will not attempt to kill their friends, we shall set this range from -100 to 10 (out of a total range of -100 to 100, where -100 is absolute hatred).

17) Enter -100 in the "Attitude From" field and -10 in the "To" field.

That would be that! We've finished defining the Action, but before going on we should explain the two function-related fields. These are for programmers who wish to code their own Actions. The "Function Module ID" field should contain the ID number of the run-time module (a DLL or EXE) that holds the function used to handle this Action. (The ID is given in the run-time modules table.) The "Function Label" field should contain the export pattern (typically contained in a .DEF file) of the function.

18) Hit the Enter key or click the OK button to save your changes.

You should now be back to the Actions table, in the lookup mode. We now need to select this Action for our Strategy.

19) Click on the Select button.

The Action will now be added to the list in the "Update The Strategies File" window.

18) Hit the Enter key or click the OK button to save this Strategy.

Congratulations! You have just created your first simple Brainiac behavior pattern.

Behavior Pattern 2: Robbery

2.1 The Goal

Robbery is more sophisticated behavior pattern than the crude attack of the previous example. We should analyze it first: it would seem fairly obvious that the Goal of a robbery is usually to acquire an item (often money).

Item acquisition is a special case among Goals in Brainiac, as it has a variable Importance. When the Attributes of a potential Objective character are evaluated to see if a Goal should be triggered, that character's inventory is checked for items that -- in the opinion of the initiating character -- are valuable (not only in financial aspect). If the item acquisition Goal matches, then the Importance attribute is assigned based on the value of the items held by the Objective character.

The item acquisition Goal record should not hold any criteria. On the other hand, it must include a condition which is always false, such as 10 < Courage < 1, used in the demonstration database). All this serves to prevent the accidental triggering of Strategies while an inventory is checked. It is natural to ask, why do we need this record at all? The answer is simple: Strategies use the Goal as a primary key in the database. To distinguish Strategies that aim to acquire an item, such Strategies must be linked to the item acquisition Goal.

Do not forget that if you are going to prepare a new database from scratch, you must redirect the item acquisition Goal ID to point to your record. This is done by calling the SetGoalItemAcquisitionID() function. By default, the inventory scanning loop synchronizes to Goal record 1.

2.2 The Strategy

We'll use a simple and fairly crude plan. The initiating character (robber) will first attempt to intimidate the Objective character (victim); the robber will demand the item and threaten to attack the victim if the demand is not met. The Strategy will end successfully if the threat succeeds. If the threat fails to intimidate the victim, the robber will attack. After the victim is dead, the robber will acquire the item. Note that this plan contains a simple branching statement revolving around the success or failure of the threat.

1) Call up the Strategies table, click on the Insert button.

We are now back to the "Update the Strategies File" window. Hopefully this is all looking more familiar by now. Next, you can breeze through setting up the Strategy:

2) Type "robbery" in the name field and "tutorial: robbery" in the description field.

3) Set the Goal ID field to "item acquisition" by right-clicking on the field and selecting from the Goals Table.

2.3 The Actions

It is now time to define the Actions that make up the robbery Strategy. You should still be looking at the "Update the Strategies File" window:

1) Click the Append button to call up the Actions table.

2) Click the Insert button to create a new Action.

Our first task here is to define the threat portion of the Strategy.

3) Enter "threat" in the Action name field.

4) Set the Action Type to "Verbal."

You will also need to set the following values: Minimum Intelligence = 8, Attitude Change = -8, Required Courage = 7, Difficulty = 3, Wickedness = 10, Anarchy = 0 and Attitude from -100 to 40. Remember that these values apply only to this Action -- not to the Strategy as a whole.Robbery is fairly antisocial, but threatening someone is not as undesirable an act in and of itself.

5) Click the OK button or press the Enter key to save the changes to the Action

6) Press the Select button to add the newly created "threat" Action to the Strategy list.

Verbal Actions (Actions involving speech) are typically associated with Content Actions. When making a Verbal Action -- a deal proposal, request or threat -- Content Actions are proposed within the context of the Verbal Action. The Brainiac convention is to firstly describe the initiating character's verbally proposed Action ("me"), then the Objective characters proposed response ("you"). In our current Strategy, the verbal action on the part of the robber is -- more or less -- "give me that item or I will attack you!" The robber (initiating Character) is proposing both an attack and that the victim (Objective character) hand over the item. By the Brainiac rules, therefore, we must first add "attack" and secondly add "give item" as Content Actions.

7) Make sure that the "threat" Action is highlighted.

8) Click on the enabled "Append This Verbal Action Content" checkbox.

This important checkbox is at the bottom of the window; it is enabled only if the last Verbal Action is highlighted in the Action list. (As "threat" is the only Action present, the checkbox should be enabled).

9) Click on the Append button to bring up the Actions window.

10) Highlight the "attack" action and click on the Select button.

This will take you back to the Strategy window. You should see "attack" added to the list as 1A, and the Action name is bound by quotes. This is a visual reminder to show that this is a Content Action. We should now define the "give item" Action.

11) Return to the Actions screen as before -- making sure that "threat" is highlighted and the checkbox on.

12) Click on Insert to add a new Action.

Fill out our new Action as follows: type "give item" in the name field, switch the Action type to Mechanic, set Minimum Intelligence = 1, Required Courage = 1 and Difficulty = 1. For all intents and purposes, these 1's mean a practical absence of requirements for this Action. The other fields are left at their default values.

13) Press the Enter key or click the OK button to save this Action.

14) Click on the Select button in the Actions window to add this Action to your Strategy.

This should be appended in the same way as "attack," but as Action 1B. Now that we have added the two allowed Content Actions to the "threat" Verbal Action, the "Append This Verbal Action Content" checkbox will be unchecked and disabled. Recall that the Strategy must end if the threat succeeds.

15) Highlight the "threat" action.

16) Click on the "Target And Conditional Branch..." button.

This will pop up a window that contains a fair amount of frightening stuff. For the moment, however, our interest is in the checkbox at the bottom -- "End Strategy If This Action Succeeded".

17) Check the "End Strategy If This Action Succeeded" checkbox.

18) Click on the OK button.

This will set up the necessary condition that will end the Strategy on the success of the "threat" Action. Now we can add the last parts of this Strategy.

19) Use the Append button and the Actions window to add the "attack" action to the list.

20) Click on the Append button again.

The last step in this Strategy is to take the item. We will therefore need to create a "take item" Action.

21) Click on the Insert button to create a new Action.

Fill in the Action fields as follows: type "take item" in the name field, switch the action type to Mechanic and enter the same values as you did for the "give item" Action. (These were Minimum Intelligence = 1, Required Courage = 1 and Difficulty = 1).

22) Press the Enter key or click on the OK button to save your changes.

23) Click the Select button to add this final Action to the list.

Phew! Looks like we're done here. You should save the Strategy:

24) Hit the Enter key or click on the OK button to save this Strategy.

Notice that in setting up the robbery Strategy you have at least touched upon the creation of Verbal Actions, Content Actions and a simple branching of Actions within Strategies.

Behavior Pattern 3: Conspiracy

3.1 The Goal

A conspiracy scenario, like the first sample behavior pattern, revolves around an initiating character who wants to kill the Objective character. In this case, however, the initiating character is unable to successfully accomplish an attack alone. The initiating character will then find a potential assassin, telling the potential assassin that the Objective character attacked someone that the potential assassin likes. The initiating character will then ask the potential assassin to attack the Objective character.

The Strategy and Actions in this example will be a little more complex that in the previous examples; you'll learn to assign immediate and reference criteria, and how to use advanced branching. By way of contrast, the Goal is easy. This Strategy is (yet another) one of the ways to dispose of someone, so the Goal is "killing out of enmity." Conveniently, we have already defined this Goal in the first example.

3.2 The Strategy

We shall quickly set up the parameters of the Strategy:

1) Call up the Strategies table.

2) Click on the Insert button to create a new Strategy.

3) Right-click on the Goal ID field and select "killing out of enmity" from the Goals Table.

4) Type "conspiracy" in the name field and "tutorial: conspiracy" in the brief description field.

3.3 The Actions

We are now ready to start on the Actions that make up this Strategy.

1) Click on the Append button.

2) Click the Insert button in Actions File window.

You should now be looking at the "Update the Actions File" window. We are going to define the "statement" Verbal Action:

3) Enter "statement" in the name field.

4) Switch the action type to Verbal.

"Statement" is a neutral Action that requires at least a little native intelligence to carry out. We shall set the following values: Minimal Intelligence = 6, Difficulty = 3, Required Courage = 3 and Attitude from -65 to 100 (this last because it is a little hard to make a statement while apoplectic with anger).

5) Hit the Enter key or click on the OK button to save the changes.

6) Click the Select button to add this Action to your Strategy.

Now we must define the Content Actions for the "statement" content.

7) Highlight the "statement" Action in the list.

8) Check the "Append This Verbal Action Content" checkbox.

9) Click the Append button.

We need to choose a Content Action. The statement we are going to define here will run along the lines of "this person attacked that person!"

10) Select the "attack" action to add it to the list as 1A.

11) Now click on the Append button again.

12) Click on the Dummy button to add a "dummy" action to the list as 1B.

Here, the first Content Action associated with the "statement" Action is all that is needed to describe the statement made by an initiating character. Statements support only one Action per statement. There can be no default initiating character in the statement; "dummy" Actions are used to point to the initiating character. So far we have been doing just fine with the default targets, but in this case some changes must be made to the targets of the statement Action and its Content Actions.

The statement, the first Action in this Strategy, is made to a potential assassin and not to the Strategy Objective character (the victim). We need to translate this targeting of a specific Action within the Strategy into Brainiacese:

13) Highlight the "statement" Action.

14) Click on the "Target And Conditional Branch..." button.

You should now be looking at the Target Assignment window. What is needed here is an "immediate" target criteria; that is, a target character who will be selected immediately before this Action executes. In order to make this work, we will first need to declare that we are using an immediate target. Secondly, we must define the criteria by which such an immediate target will be selected.

15)Make sure the "Immediate Target Criteria..." checkbox is selected.

16) Right click in the criteria field to bring up the Criteria Table.

We don't need to use an inventory-related criteria here:

17) Make sure the Common radio button is selected.

18) Click on the Insert button to add a new criteria record.

What to choose in the Goal/Criteria Update window? It would be logical to select a potential assassin capable of killing the intended victim.

19) Enter "potential assassin" in the Description field.

20) Switch "Criteria Limiting Values and Action Flag's Type" to "Relative to strategy objective."

21) Go to the Target Criterion Limits tab.

22) Assign limits of 1 to 100 to Meanness (Combat Ability).

23) Click on the Enter button to save the newly created criteria record.

Note that by changing the "Criteria Limiting Values..." selected radio button like this, we are comparing the abilities of the potential assassin and the victim (who is the Strategy Objective character).

24) Highlight the new criteria in the Criteria Table.

25) Click on the Select button to assign this criteria to the Action that you're currently editing.

Having assigned the immediate target criteria for the potential assassin, we are now done with the Target Assignment window.

26) Click on the OK button or press the Enter key to return to the Strategy window.

We are not done with the statement Action yet; we must still edit the target of the "attack" Content Action. The statement Action in its entirety runs something along the lines of "hey! Mr. Potential Assassin! Mr. Victim attacked Mr. Friend Of Potential Assassin!" We have already dealt with the "hey! Mr. Potential Assassin!" part by setting the immediate target criteria for the statement action. Now we must sort out the targets involved in the second part. In Brainiacese, the second part of the statement (the "attack" Content Action) can be read as "the Strategy Objective character attacked a friend of the Action 1 Objective character!"

27) Highlight the "attack" Content Action.

28) Click on the "Target And Conditional Branch..." button again.

29) Make sure "Immediate Target Criteria..." is selected in the Target Assignment window.

30) Right click in the "Immediate Target Criteria..." entry field to bring up the Criteria Table.

31) Click on the Insert button to create a new Criteria record.

In this new criteria we will be defining the sort of character that will be a "friend of the Action 1 Objective character."

32) Enter "Friend of Act 1 Obj" in the Description field.

33) Go to the Attitude Limits tab.

34) Enter "1" in the Referenced Action field.

We would like the potential assassin's attitude should be friendly or better; enter 75 and 100 in the "Ref. Action Objective's To Target" from and to fields respectively.

35) Hit the Enter key or click on the OK button to save the changes.

36) Highlight the new criteria record in the Criteria Table.

37) Click on the Select button to assign the criteria to the Action being edited.

38) Select the "Not In Strategy" radio button in the Target Assignment window.

39) Press the Enter key or click on the OK button to save your changes.

We are now done with the "attack" Content Action. What about the "dummy" Content Action that is used to hold the character who initiated the reported Action? The initiating character is the Strategy objective character by default; which is to say the victim. In this case, we don't need to change the default setting.

Onwards! We have completed the first part of this Strategy, but there is more to come. The second part is a request made to the potential assassin to attack the victim.

40) Click on the Append button in the "Update the Strategies File" window.

41) Click on the Insert button in the "Browse the Actions File" to create a new Action.

42) Enter "request" in the name field, and switch the Action Type to "Verbal."

We shall set the following values for a request Verbal Action: Minimum Intelligence = 5, Difficulty = 3, Required Courage = 3 and an Attitude range of -30 to 100.

43) Press the Enter key or click on the OK button to save the new Action.

44) Make sure that the request Action is highlighted.

45) Click on the Select button to add the "request" Action to the list.

You can now add the Content Actions to the request Verbal Action. In this case, the first and second content Actions will be the same as those contained by the statement Verbal Action; "attack" and "dummy" Actions respectively. Don't forget to check the "Append This Verbal Action Content" checkbox before adding the Content Actions to the request Action. Once this is done, we must ensure that these new Actions have the correct targets.

46) Highlight the "request" Action and click the "Target And Conditional Branch..." button.

The request has to be made to the same character as the statement Verbal Action was; in Brainiacese, this means that the Objective character for both Actions is one and the same. Telling Brainiac to do this is fairly simple:

47) Select the "Get Target From Action..." radio button in the Target Assignment window.

48) Enter "1" in the "Get Target From Action..." entry field.

That will instruct Brainiac to assign the same Objective character to the request Action as was used for Action 1 (the statement).

While we are here, we should also consider the matter of failure. What if the potential assassin refuses to attack the victim? A solution to this problem would be for the character initiating the Strategy to find another potential assassin. To set this behavior in motion, we can implement a simple loop in the strategy:

49) Enter "1" in the "If Unable, Go To Action..." field.

What could be more simple than that? This will instruct Brainiac to return to Action 1 (the statement) should the request fail.

50) Press the Enter key or click the OK button to save the changes.

The last step is to consider the targeting of the request Content Actions. Fortunately, we don't need to alter the Objective character of the "attack" Content Action; the default is the Strategy Objective character (the victim). However, the character doing the attacking should be the potential assassin singled out as the Objective character in Action 1. Recall that the "dummy" Content Action Objective character is the one who should be performing the requested "attack" Action, and the default here is the character who is initiating the Strategy. We will have to change this:

51) Highlight "dummy" Action 2B and click on the "Target And Conditional Branch..." button.

52) Select the "Get Target From Action..." radio button in the Target Assignment window.

53) Enter "1" in the "Get Target From Action..." entry field.

54) Press the Enter key or click the OK button to save the changes.

Are we there yet? Almost. To be able to correctly select candidate potential assassins for Action 1, we must restrict these candidates to those characters not listed in the Strategy. This will raise our chances of finding a candidate, although there is a chance of repetitive choices.

55) Highlight "statement" Action 1 and click on the "Target And Conditional Branch..." button.

56) Switch the Restrictions radio button to "Not Strategy Objective."

57) Press the Enter key or click the OK button to save the changes.

58) Press the Enter key or click the OK button again to save the Strategy.

That's it! You just created a fairly complex strategy, while learning about advanced branching and immediate and reference criteria.

Brainiac Native Verbal Interaction

For now, Brainiac BE supports five verbal Actions: Deal, Request, Statement, Tease and Threat. These Actions allow for more than it might seems first, and end-user programmers can add their own verbal Actions to the list.

Deal

Deal is a generic commercial Action ("trade offer" is used in the Brainiac BE Data Manager to set constraints for Deal). A Deal can be divided into two parts: the proposed Action and the requested Action. If either of the two Actions has a non-NULL pointer to an inventory item, the item is evaluated instead of used in an Action. This means that Deal can descrinearly every basic form of transaction; paying for a service, exchanging or buying items and exchanging services, to name a few. The evaluation of a Deal Action is also influenced by

the attitudes of the Dealing characters.

Request

Request is as universal as Deal, but it contains only one Action -- the requested Action. In other words, a Request it is the same as a Deal, but without a proposed Action.

Statement

A Statement reports an Action (only one Action for the moment) to another character. Why bother? Well, take a look at the conspiracy example for the use of a Statement to manipulate another character. A Statement can be either true or a lie. It can describe events that happened in the past, are happening now, or that can happen in the future.

The character receiving a Statement (the Statement Objective) will evaluate the reported Action and the reporting character. If the information is believed, attitudes may change.

In Brainiac BE, the reported Action is first defined in the Data Manager ("A"). The target of this Action defines the reported Action initiator. The second Action ("B") must be present, but only to define the reported Action Initiator. It is advisable to use the "dummy" Action, just to prevent confusion.

(All verbal actions by definition containing only one content Action, are defined in A-B, content Action - initiator holder fashion).

Tease

Tease does not provide much functionality. It just makes use of a small function for generating insults by comparing personal characteristics. For example, a physically strong character could call a weaker opponent "wimp," while a smarter character would refer to a dumber target as "idiot," and so on. Insults are sorted by the difference in abilities -- that is, the greatest difference comes first.

Threat

Threat resembles Deal in many aspects, except that both Actions are viewed as undesirable by the Objective character. The aim is to make the Objective character consider alternate Strategies to prevent the "proposed" Action on the part of the threatening character.

Programmer's Reference

Goal And Criteria

Goal is the motivation of an agent to do something. To start accomplishing tasks aimed at another agent, the potential initiator agent must find a goal definition record suitable for potential target. Criteria is, technically, goal record where importance attribute is 0 (N/A), but it is used for another purpose - to seek intermediate action objectives in strategy.

Goal structure contains merely goal ID and its basic importance before possible modifications. The full definition is

typedef struct {

ID Itself; //goal ID

percentage Importance; //basic goal importance

} Goal;

The full definition structure contains all the limiting values and the brief description.

struct _GoalDefNode {

Goal goal;

char Descr[26];

Core LoReqs, HiReqs; //limiting values structures

unsigned char CompType,

/*comparison type:

COMP_ABS (0) = absolute (target)

COMP_REL2EVAL (1) = relative to evaluator

COMP_REL2SOBJ (2) = relative to objective

COMP_REL2LINI (3) = relative to initiator

COMP_ABS_EVAL (4) = absolute (evaluator)*/

AttDir, //unused for now

IdFlag1; /*special ID flag:

FL1_LASTINIT (1) = for last action initiator

FL1_LASTOBJ (2) = for last action objective*/

ID IdFlag2; //special Action ID for ID flag

ID UserDefAttID; //user-defined attitude ID

ID AttRefAct; //referenced action ID (for the corresponding //attitude value)

ID IncGoalID; //included goal ID, for recoursive definitions

struct _GoalDefNode *next; //pointer to next node in the list

};

typedef struct _GoalDefNode* GoalDefNodeP;

Action

Action is, as it sounds, a single action with defined Initiator and Objective, and optional ObjectiveItem. If ObjectiveItem pointer is not NULL, it is assumed that the action is inventory-oriented.

Properties (public only):

BOOL SkipChecks

Description

- If TRUE, there will be no checks on action execution. The action will be executed in any case

Methods (public only):

Action::Action();

Description:

- Default constructor

Parameters:

- None

Return values:

- None

Action::Action(Action *InitBy);

Description:

- Constructor by another Action

Parameters:

- Action *InitBy - Action object whose attributes will be copied, including all the targets

Return values:

- None

Action::Action(ActionType aType, percentage BasicDiffArg, percentage BasicWickArg,

percentage BasicAnarArg, percentage MinIntArg, percentage ReqCouArg,

percentage BasicAttitudeChangeArg, ID ActionIDArg, percentage MinAttArg,

percentage MaxAttArg, int (*ActionFnArg)(void*));

Description:

- Constructor by basic attributes

Parameters:

- ActionType aType - action type: VERBAL / COMMERCIAL / MECHANIC / VITAL / other

- percentage BasicDiffArg - basic difficulty / priority points

- percentage BasicWickArg - basic wickedness points

- percentage BasicAnarArg - basic anarchy points

- percentage MinIntArg - minimum intelligence points

- percentage ReqCouArg - required courage

- percentage BasicAttitudeChangeArg - basic attitude change points

- ID ActionIDArg - unique action definition ID

- percentage MinAttArg - minumum attitude limit

- percentage MaxAttArg - maxumum attitude limit

- int (*ActionFnArg)(void*) - function to call on execution

Return values:

- None

Action::~Action()

Description:

- Default destructor

Parameters:

- None

Return values:

- None

void Action::Init(ActionType aType, percentage BasicDiffArg, percentage BasicWickArg,

percentage BasicAnarArg, percentage MinIntArg, percentage ReqCouArg,

percentage BasicAttitudeChangeArg, ID ActionIDArg, percentage MinAttArg,

percentage MaxAttArg, int (*ActionFnArg)(void*));

Description:

- Initialize Action object by basic attributes

Parameters:

- ActionType aType - action type: VERBAL / COMMERCIAL / MECHANIC / VITAL / other

- percentage BasicDiffArg - basic difficulty / priority points

- percentage BasicWickArg - basic wickedness points

- percentage BasicAnarArg - basic anarchy points

- percentage MinIntArg - minimum intelligence points

- percentage ReqCouArg - required courage

- percentage BasicAttitudeChangeArg - basic attitude change points

- ID ActionIDArg - unique action definition ID

- percentage MinAttArg - minumum attitude limit

- percentage MaxAttArg - maxumum attitude limit

- int (*ActionFnArg)(void*) - function to call on execution

Return values:

- None

void Action::Init(Action *InitBy);

Description:

- Initialize Action object by another Action

Parameters:

- Action *InitBy - Action object whose attributes will be copied, including all the targets

Return values:

- None

void Action::SetActionFn(int (*)(void*)ActionFnArg);

Description:

- Assign pointer to function to be called on execution

Parameters:

- int (*)(void*)ActionFnArg - pointer to function to be called on execution. The function must return an integer and use one pointer to any type as parameter

Return values:

- None

void Action::InitTargets(Core *InitiatorArg = NULL, Core *ObjectiveArg = NULL,

ItemScores *ObjectiveItemArg = NULL);

Description:

- Assign pointer to function to be called on execution. If a parameter(s) is (are) NULL, it is omitted (the attribute remains unchanged).

Parameters:

- Core *InitiatorArg - pointer to Initiator's Core

- Core *ObjectiveArg - pointer to Objective's Core

- ItemScores *ObjectiveItemArg - pointer to objective item's ItemScores structure

Return values:

- None

void Action::ResetTargets();

Description:

- Assign NULL to Initiator, Objective, and ObjectiveItem pointers

Parameters:

- None

Return values:

- None

Core *Action::GetInitiator();

Description:

- Getter function for Initiator. Return value is the pointer to Initiator Core structure.

Parameters:

- None

Return values:

- None

Core *Action::GetObjective();

Description:

- Getter function for Objective. Return value is the pointer to Objective Core structure.

Parameters:

- None

Return values:

- None

ItemScores *Action::GetObjItem();

Description:

- Getter function for ObjectiveItem. Return value is the pointer to ObjectiveItem ItemScores structure.

Parameters:

- None

Return values:

- None

Action *Action::GetReported1Ptr();

Description:

- Getter function for Reported1 action pointer - optverbal content action. Return value is the pointer to Reported1.

Parameters:

- None

Return values:

- None

Action *Action::GetReported2Ptr();

Description:

- Getter function for Reported2 action pointer - optional verbal content action. Return value is the pointer to Reported2.

Parameters:

- None

Return values:

- None

void Action::SetReported1(Action *Reported1Arg);

Description:

- Setter function for Reported1 action pointer. The Action object pointed by the parameter is duplicated to Reported1 attribute, so you don't have to worry about deleting this pointer.

Parameters:

- Action *Reported1Arg

Return values:

- None

void Action::SetReported2(Action *Reported2Arg);

Description:

- Setter function for Reported2 action pointer. The Action object pointed by the parameter is duplicated to Reported2 attribute, so you don't have to worry about deleting this pointer.

Parameters:

- Action *Reported2Arg

Return values:

- None

void Action::InitScores(ActionType aType, percentage BasicDiffArg, percentage BasicWickArg,

percentage BasicAnarArg, percentage MinIntArg,

percentage ReqCouArg, percentage BasicAttitudeChangeArg,

percentage MinAttArg, percentage MaxAttArg);

Description:

- Initialize Action object by basic attributes, excluding function pointer

Parameters:

- ActionType aType - action type: VERBAL / COMMERCIAL / MECHANIC / VITAL / other

- percentage BasicDiffArg - basic difficulty / priority points

- percentage BasicWickArg - basic wickedness points

- percentage BasicAnarArg - basic anarchy points

- percentage MinIntArg - minimum intelligence points

- percentage ReqCouArg - required courage

- percentage BasicAttitudeChangeArg - basic attitude change in ACUs

- ID ActionIDArg - unique action definition ID

- percentage MinAttArg - minumum attitude limit

- percentage MaxAttArg - maxumum attitude limit

Return values:

- None

void Action::ResetScores();

Description:

- Resets all the score attributes to 0

Parameters:

- None

Return values:

- None

void Action::GetActualScores(percentage& ActualDiffArg, percentage& ActualWickArg,

percentage& ActualAnarArg, percentage& ActualAttChg);

Description:

- Getter method assigning the actual attribute values to the given parameters

Parameters:

- percentage& ActualDiffArg - parameter that will receive actual difference / priority

- percentage& ActualWickArg - parameter that will receive actual wickedness score

- percentage& ActualAnarArg - parameter that will receive actual anarchy score

- percentage& ActualAttChg - parameter that will receive actual attitude change in ACUs

Return values:

- None

void Action::GetBasicScores(percentage& BasicDiffArg, percentage& BasicWickArg,

percentage& BasicAnarArg, percentage& BasicAttChg);

Description:

- Getter method assigning the basic attribute values to the given parameters

Parameters:

- percentage& BasicDiffArg - parameter that will receive basic difference / priority

- percentage& BasicWickArg - parameter that will receive basic wickedness score

- percentage& BasicAnarArg - parameter that will receive basic anarchy score

- percentage& BasicAttChg - parameter that will receive basic attitude change in ACUs

Return values:

- None

void Action::GetSolidScores(percentage& MinIntArg, percentage& ReqCouArg);

Description:

- Getter method assigning the attribute values to the given parameters

Parameters:

- percentage& MinIntArg - parameter that will receive minimal intelligence value

- percentage& ReqCouArg - parameter that will receive required courage value

Return values:

- None

void Action::GetAttitudeLimits(percentage& LoAttArg, percentage&HiAttArg);

Description:

- Getter method assigning the attitude limits values to the given parameters

Parameters:

- percentage& LoAttArg - parameter that will receive the lower limit attitude

- percentage& HiAttArg - parameter that will receive the upper limit attitude

Return values:

- None

ActionType Action::GetType();

Description:

- Getter method returning the action type: VERBAL / COMMERCIAL / MECHANIC / VITAL / UNDEFINED

Parameters:

- None

Return values:

- action type: VERBAL / COMMERCIAL / MECHANIC / VITAL / UNDEFINED

ActionError Action::Execute(void* vpArg, BOOL CheckMode = FALSE, unsigned char UseTrue = 0, percentage NeutralSideMeanness = 0);

Description:

- The most important method in the class. After all the needed checks (if SkipChecks is FALSE), it calls the user-defined function and updates all the needed scores in Initiator and Objective Core structures, if not in CheckMode. If the user-defined function returned any non-zero value, the action succeeded. In CheckMode, the method is set to investigate for the possibility of real execution, and find out the reason of failure, if any.

Parameters:

- void* vpArg - user-defined parameters to the executed user function

- BOOL CheckMode - is the action executed or merely being checked for the possibility of execution

- unsigned char UseTrue - encoded value containing bit-level flags determining which values the checks should operate with, the Real or the Seemed ones. The mapping is the following:

bit 0 = Meanness

bit 1 = Wealth

bit 2 = Intelligence

- percentage NeutralSideMeanness = 0 - is used only in VITAL actions. This parameter is used to define the combat overall of everyone except the Initiator and the Objective. By default, Agent methods calling this method calculate and assign correct NeutralSideMeanness according to the given population. If you call Action::Execute method manually (not recommended) and don't want NeutralSideMeanness to be considered, omit this parameter or assign a zero.

Return values:

- ACTION_NOT_PRIMED - one or more of the necessary attributes is invalid

- PAST_FAILURE - there was an unsuccessful attempt to execute this action before. The action will not be executed

- LO_INT - the Initiator lacks intelligence to execute the action

- TOO_FOREIGN - the Objective is too foreign to the Initiator (foreignness check failed)

- HI_ATT - the Initiator's attitude to the Objective is higher than the allowed upper limit

- LO_ATT - the Initiator's attitude to the Objective is higher than the allowed lower limit

- HI_WICK - the Initiator is too evil to commit the action

- LO_WICK - the Initiator is too good to commit the action

- HI_ANA - the Initiator is too chaotic to commit the action

- LO_ANA - the Initiator is too lawful to commit the action

- BAD_COMBAT_ODDS - the Initiator "thinks" his/her odds in combat vs. the Objective are too low

- LO_COU - the Initiator doesn't have the needed courage to execute the action

- ACTION_FAILURE - action failed (user-defined function returned zero)

- ACTION_SUCCESS - action executed successfully

BOOL Action::IsReady();

Description:

- Getter method written for debugging purposes returning whether all the attributes are ready for the action execution

Parameters:

- None

Return values:

- TRUE if the Action is ready for execution, FALSE otherwise

ID Action::GetID();

Description:

- Getter method returning the action definition record ID

Parameters:

- None

Return values:

- Action definition record ID

void Action::SetTargetAssignmentCriteria(unsigned char TACArg);

Description:

- Setter method assigning the given parameter to the TargetAssignmentCriterion attribute

Parameters:

- unsigned char TACArg - TargetAssignmentCriterion (TAC) ID to assign

Return values:

- Action definition record ID

void Action::SetRefTAC(unsigned char RefTACArg);

Description:

- Setter method assigning the given parameter to the ReferencedTAC attribute. ReferencedTAC (target brought from another action) is used to hold restriction flags, when normal TargetAssignmentCriterion is not zero.

Parameters:

- unsigned char RefTACArg - referenced TAC to assign

Return values:

- None

void Action::SetFailureGoto(unsigned char ActionOrder);

Description:

- Setter method assigning the given parameter to the FailureGoto attribute. Strategy NextAction pointer is moves there if the action fails. The count starts from 1 (not 0, to prevent confusions!).

Parameter:

- unsigned char ActionOrder - referenced TAC to assign

Return values:

- None

unsigned char Action::GetTargetAssignmentCriteria();

Description:

- Getter method returning the TargetAssignmentCriteria attribute

Parameters:

- None

Return values:

- "Immediate" target assignment criteria ID; if none, 0 is returned.

unsigned cAction::GetRefTAC();

Description:

- Getter method returning the ReferencedTAC attribute

Parameters:

- None

Return values:

- Referenced TargetAssignmentCriteria (that is, order of the Action to use Objective from). If "immediate" TargetAssignmentCriteria is a non-zero value, referenced TargetAssignmentCriteria typically holds Objective restrictions (ALL_BUT_SELF / NOT_STR_OBJ / NOT_LISTED_IN_STR / SELF_ONLY).

unsigned char Action::GetFailureGoto();

Description:

- Getter method returning the FailureGoto attribute (action to go to if failed)

Parameters:

- None

Return values:

- Order of the Action to branch to if the current Action fails / cannot be executed

percentage Action::GetDealValue();

Description:

- Getter method returning the action value from the Initiator's point of view. If an ObjectiveItem is specified, its value is returned

Parameters:

- None

Return values:

- Value of the current deal, in Wealth points

unsigned short Action::FillSaveBuffer(BYTE* bpBuffer);

Description:

- Encode the object contents to the given buffer. Return value: number of bytes allocated

Parameters:

- BYTE* bpBuffer - buffer to use

Return values:

- Number of bytes allocated

void Action::RestoreFromBuffer(BYTE *bpBuffer, Core **Population, unsigned short nPopLen,

ItemPtrArr* ipapAllInventories, unsigned short *nAllInvLens);

Description:

- Restore object from buffer containing encoded information.

Parameters:

- BYTE *bpBuffer - buffer containing encoded information

- Core **Population - array of pointers to all the Core structures in the current location

- unsigned short nPopLen - number of members in Population array

- ItemPtrArr* ipapAllInventories - array of ItemScores pointers' arrays containing all the inventories

- unsigned short *nAllInvLens - array of ItemScores pointers' arrays' lengths. The overall length of this array is assumed to be equal to nPopLen.

Return values:

- None

Strategy

Strategy is a way to achieve a certain goal via series of Actions. Brainiac strategies contain only single-linked straightforward list of Actions, but the class is able to manage strategies involving conditional branching and looping. Strategies, as well as Actions, are managed automatically by Agent class - normally, you don't have to call Strategy methods explicitly.

Properties:

- There are no public properties in Strategy class

Methods (public):

Strategy::Strategy();

Description:

- Default constructor

Parameters:

- None

Strategy::Strategy(Goal argGoal, ID argID);

Description:

- Constructor by Goal and ID

Parameters:

- Goal argGoal - Goal to be initialized with

- ID argID - Strategy definition record ID

Return values:

- None

Strategy::~Strategy();

Description:

- Destructor

Parameters:

- None

Return values:

- None

void Strategy::Init(Goal argGoal);

Description:

- Initialize Strategy object by Goal

Parameters:

- Goal argGoal - Goal to be initialized with

Return values:

- None

void Strategy::Init(Goal argGoal, ID argID);

Description:

- Initialize Strategy object by Goal and ID

Parameters:

- Goal argGoal - Goal to be initialized with

- ID argID - Strategy definition record ID

Return values:

- None

ActionError Strategy::ExecuteNextAction(void *vpArg, unsigned char UseTrue = 0, percentage NeutralSideMeanness = 0);

Description:

- Method which calls the NextAction Execute method. Return values: the same as in Action::Execute method

Parameters:

- void* vpArg - user-defined parameters to the executed user function

- BOOL CheckMode - is the Action executed or merely being checked for the possibility of execution

- unsigned char UseTrue - encoded value containing bit-level flags determining which values the checks should operate with, the Real or the Seemed ones. The mapping is the following:

bit 0 = Combat Ability (Meanness)

bit 1 = Wealth

bit 2 = Intelligence

- percentage NeutralSideMeanness = 0 - is used only in VITAL Actions. This parameter is used to define the combat overall of everyone except the Initiator and the Objective. By default, Agent methods calling this method calculate and assign correct NeutralSideMeanness according to the given population. If you call Action::Execute method manually (not recommended) and don't want NeutralSideMeanness to be considered, omit this parameter or assign a zero.

Return values:

- ACTION_NOT_PRIMED - one or more of the necessary attributes is invalid

- PAST_FAILURE - there was an unsuccessful attempt to execute this Action before. The Action will not be executed

- LO_INT - the Initiator lacks intelligence to execute the Action

- TOO_FOREIGN - the Objective is too foreign to the Initiator (foreignness check failed)

- HI_ATT - the Initiator's attitude to the Objective is higher than the allowed upper limit

- LO_ATT - the Initiator's attitude to the Objective is higher than the allowed lower limit

- HI_WICK - the Initiator is too evil to commit the Action

- LO_WICK - the Initiator is too good to commit the Action

- HI_ANA - the Initiator is too chaotic to commit the Action

- LO_ANA - the Initiator is too lawful to commit the Action

- BAD_COMBAT_ODDS - the Initiator "thinks" his/her odds in combat vs. the Objective are too low

- LO_COU - the Initiator doesn't have the needed courage to execute the Action

- ACTION_FAILURE - Action failed (user-defined function returned zero)

- ACTION_SUCCESS - Action executed successfully

Action *Strategy::GetNextAction();

Description:

- Getter method that returns pointer to the Action that will be executed next. If no such Action is present, the method returns NULL.

Parameters:

- None

Return values:

- Pointer to the Action which is going to be executed. If no such Action is present, NULL is returned

percentage Strategy::GetNextActionOrder();

Description:

- Getter method that returns order of the Action that will be executed next. If no such Action is present, the method returns 0.

Parameters:

- None

Return values:

- Order of the Action that will be executed next. If no Action is scheduled, 0 is returned.

Action *Strategy::GetLastAction();

Description:

- Getter method that returns pointer to the last executed Action. If the Strategy is at its first Action, the method returns NULL.

Parameters:

- None

Return values:

- Pointer to the Action which was executed last in the current Strategy. If the Strategy is at its first Action, NULL is returned

percentage Strategy::GetLastActionOrder();

Description:

- Getter method that returns order of the last executed Action.

Parameters:

- None

Return values:

- Order of the Action that was executed last in the current Strategy. If the Strategy is at its first Action, 0 is returned

void Strategy::UpdateNextActionTargets(Core *argInitiator,

Core *argObjective, ItemScores *argItem);

Description:

- Setter method that assigns targets to the next Action

Parameters:

- Core *argInitiator - Initiator pointer to Core structure to assign

- Core *argObjective - Objective pointer to Core structure to assign

- ItemScores *argItem - Objective Item pointer to Core structure to assign

Return values:

- None

BOOL Strategy::AppendAction(Action* apToAppend);

Description:

- Method that attaches a new Action to the end of the Actions' linked list.

Parameters:

- Action* apToAppend - Action object to attach to the end of the list

Return values:

- TRUE if the new Action was successfully attached, FALSE otherwise

Action Strategy::DelAction();

Description:

- Method that deletes the last Action in the list.

Parameters:

- None

Return values:

- Copy of the deleted Action object.

ActionNodeP Strategy::FindAction(unsigned char ActionOrder);

Description:

- Find the Action of the specified order in the list.

Parameters:

- unsigned char ActionOrder - Action to find

Return values:

- Pointer to the node containing the requested Action. If none found, NULL is returned.

ActionNodeP Strategy::GetActionList();

Description:

- Getter method that returns pointer to the linked list of Actions.

Parameters:

- None

Return values:

- Pointer to the list of Actions. If the list is empty, NULL is returned

void Strategy::SetGoal(Goal argGoal);

Description:

- Setter method that assigns Goal to the Strategy.

Parameters:

- None

Return values:

- None

Goal Strategy::GetGoal();

Description:

- Getter method that returns the Strategy Goal.

Parameters:

- None

Return values:

- Actual Strategy Goal, including actual (not basic!) importance

void Stra::SetObjective(Core *argObj);

Description:

- Setter method that assigns the Strategy Objective.

Parameters:

- Core *argObj - Objective Core structure pointer to assign

Return values:

- None

Core *Strategy::GetObjective();

Description:

- Getter method that returns pointer the Strategy Objective Core

Parameters:

- None

Return values:

- Pointer the Strategy Objective Core

void Strategy::SetObjItem(ItemScores *argItem);

Description:

- Setter method that assigns the Strategy ObjectiveItem.

Parameters:

- Core *argItem - Objective ItemScores structure pointer to assign

Return values:

- None

ItemScores *Strategy::GetObjItem();

Description:

- Getter method that returns the Strategy ObjectiveItem.

Parameters:

- None

Return values:

- Pointer the Strategy ObjectiveItem

percentage Strategy::GetImportance();

Description:

- Getter method that returns the Strategy actual (not basic) Importance.

Parameters:

- None

Return values:

- Strategy actual (not basic) Importance

void Strategy::CalcScores(percentage AdditionalImportanceModification = 0);

Description:

- Compute the total scores for the current Strategy based on the included Actions

Parameters:

- percentage AdditionalImportanceModification - user override for Strategy importance

Return values:

- None

void Strategy::FreeActionList();

Description:

- Delete all the Actions in the list. Reset all the list pointers (NextAction and LastAction).

Parameters:

- None

Return values:

- None

BOOL Strategy::PossibilityCheck();

Description:

- Check for the possibility of Strategy execution by executing all the Actions in CheckMode.

Parameters:

- None

Return values:

- TRUE if the Strategy is possible, FALSE if one or more of the Actions failed the check

void Strategy::End();

Description:

- End current Strategy deleting all the Actions and resetting all the pointer. Warning: Strategy::End() method is NOT called in Strategy destructor. It is called in Agent class for embedded Strategy objects, so if you're not working through Agent, it is your responsibility to free memory.

Parameters:

- None

Return values:

- None

ID Strategy::GetID();

Description:

- Getter method that returns the Strategy definition record ID.

Parameters:

- None

Return values:

- Strategy definition record ID

void Strategy::SetNextActionAddress(ActionNodeP pActionNode);

Description:

- Setter method that explicitly assigns the next Action to be executed

Parameters:

- ActionNodeP pActionNode - next Action node pointer to assign

Return values:

- None

void Strategy::SetLastActionAddress(ActionNodeP pActionNode);

Description:

- Setter method that explicitly assigns the last Action pointer

Parameters:

- ActionNodeP pActionNode - last Action node pointer to assign

Return values:

- None

void Strategy::SkipNextAction(BOOL ForceFailure = FALSE);

Description:

- Make Strategy to skip to next Action without performing the current.

Parameters:

- BOOL ForceFailure - if FALSE or omitted, the Action that is skipped is assumed to succeed. Otherwise, it is assumed that the Action failed. If needed, conditional branching is performed.

Return values:

- None

BOOL Strategy::IsListed(ID ToCheck);

Description:

- Check if the Agent with the specified ID is listed somewhere in the Strategy - as Initiator or Objective or the Strategy or one of the Actions

Parameters:

- ID ToCheck - Core ID to check

Return values:

- TRUE if the ID is found, FALSE otherwise

unsigned short Strategy::FillSaveBuffer(BYTE *bpBuffer);

Description:

- Encode Strategy object, including all the Actions, into the given buffer

Parameters:

- BYTE *bpBuffer - pointer to buffer to use

Return values:

- Number of bytes allocated

void Strategy::RestoreFromBuffer(BYTE *bpBuffer, Core **Population, unsigned short nPopLen,

ItemPtrArr* ipapAllInventories, unsigned short *nAllInvLens);

Description:

- Decode Strategy object, including all the Actions, using the given buffer and the arrays containing info about the current population.

Parameters:

- BYTE *bpBuffer - buffer containing encoded information

- Core **Population - array of pointers to all the Core structures in the current location

- unsigned short nPopLen - number of members in Population array

- ItemPtrArr* ipapAllInventories - array of ItemScores pointers' arrays (sorry, couldn't make it easier!) containing all the inventories

- unsigned short *nAllInvLens - array of ItemScores pointers' arrays' lengths. The overall length of this array is assumed to be equal to nPopLen.

Return values:

- None

void Strategy::OverrideActionList(ActionNodeP pActionNode);

Description:

- Assign the given pointer to the Actions linked list. Warning: the old list is not deleted as this method is intended to be low-level service function.

Parameters:

- ActionNodeP pActionNode - pointer to the Actions list to assign

Return values:

- None

void Strategy::ResetAllActionTargets();

Description:

- Reset targets in all Actions in the list (not the Strategy targets) to NULL.

Parameters:

- None

Return values:

- None

void Strategy::ReturnToLastAction();

Description:

- Get back to the last executed Action. That is, the Action which will be executed next, is the last one executed.

Parameters:

- None

Return values:

- None

Agent

Agent is the implementation of the central Brainiac concept - autonomous agent acting and deciding by itself, scheduling and executing actions.

Properties (public only):

unsigned char FailuresCount;

- Counter for consequent failures in the last action. If after ExecuteNextAction this counter exceeds global maximum failures value (see Non-member functions) and no FailureGoto specified in this action, the strategy is aborted and strategy failure is registered, if using History feature.

unsigned char LoopFailuresCount;

- Counter for consequent failures in the last strategy loop. If after ExecuteNextAction this counter exceeds global maximum failures value (see Non-member functions), the strategy is aborted and strategy failure is registered, if using History feature.

static unsigned short AutoNumber;

- Autoincrementing value providing unique ID for every Agent object. There should be no problem if you increase it, but DO NOT decrease it or you'll have duplicate IDs which may cause unpredictable results.

Strategy CurrentStrategy;

- Agent's current strategy. If the Agent has no active Strategy at the moment, CurrentStrategy's goal ID is GOAL_NONE (which is 0), and, of course, the actions list is empty.

Methods (public only):

Agent::Agent();

Description:

- Default constructor

Parameters:

- None

Return values:

- None

Agent::Agent(percentage WickednessArg, percentage AnarchyArg);

Description:

- Constructor by the 2 parameters defining the Agent's belongevity to a certain mindset from the internal tables.

Parameters:

- percentage WickednessArg - measure of evil. If negative, assumed good

- percentage AnarchyArg - measure of chaos. If negative, assumed lawful

Return values:

- None

Agent::~Agent();

Description:

- Destructor

Parameters:

- None

Return values:

- None

void Agent::Init(percentage WickednessArg = 0, percentage AnarchyArg = 0);

Description:

- Initialize by the 2 parameters defining the Agent's belongevity to a certain mindset from the internal tables.

Parameters:

- percentage WickednessArg - measure of evil. If negative, assumed good

- percentage AnarchyArg - measure of chaos. If negative, assumed lawful

Return values:

- None

void Agent::SetImpression(percentage argMeanness, percentage argWealth,

percentage argBeauty, percentage argIntelligence, percentage argForeignness,

BOOL UseTrue = FALSE);

Description:

- Setter method for Impression values: CombatOverall (Meanness), Wealth, Beauty, Intelligence, and Foreignness (belongevity to social group), SEEMED or TRUE.

Parameters:

- percentage argMeanness - combat overall

- percentage argWealth - overall wealth points

- percentage argBeauty - beauty points

- percentage argIntelligence - intelligence points

- percentage argForeignness - belongevity to social group (-100..100)

- BOOL UseTrue - values type, SEEMED (0) or TRUE (1)

Return values:

- None

void Agent::SetSolidScores(percentage argIntel, percentage argCourage);

Description:

- Setter method for intelligence and courage

Parameters:

- percentage argIntel - intelligence

- percentage argCourage - courage

Return values:

- None

void Agent::GetImpression(percentage& argMeanness, perc& argWealth,

percentage& argBeauty, percentage& argIntelligence, percentage& argForeignness,

BOOL UseTrue = FALSE);

Description:

- Getter method for Impression values: CombatOverall (Meanness), Wealth, Beauty, Intelligence, and Foreignness (belongevity to social group), SEEMED or TRUE. The values are returned via referenced parameters.

Parameters:

- percentage argMeanness - combat overall

- percentage argWealth - overall wealth points

- percentage argBeauty - beauty points

- percentage argIntelligence - intelligence points

- percentage argForeignness - belongevity to social group (-100..100)

- BOOL UseTrue - values type, SEEMED (0) or TRUE (1)

Return values:

- None

void Agent::GetSolidScores(percentage& argIntel, percentage& argCourage);

Description:

- Getter method for intelligence and courage which are returned via referenced parameters

Parameters:

- percentage argIntel - intelligence

- percentage argCourage - courage

percentage Agent::InitialAttitudeModification(const Core& OtherAgent,unsigned char UseWhich = 0);

Description:

- Calculate the modification of initial attitude to the given Agent

Parameters:

- Core& OtherAgent - Core structure of the agent being evaluated

- unsigned char UseWhich - encoded value defining which Impression values will be evaluated

Return values:

- Modification of initial attitude to the given Agent

const AlignmentType Agent::GetAlType();

Description:

- Getter method for Agent's mindset ID.

Parameters:

- None

Return values:

- Mindset ID

char* Agent::GetAlName();

Description:

- Getter method for Agent's mindset name.

Parameters:

- None

Return values:

- Mindset name

ID Agent::GetID();

Description:

- Getter method for Agent's unique ID.

Parameters:

- None

Return values:

- Agent's unique ID

percentage Agent::ItemAcquisitionImportance(ItemScores &ToEvaluate);

Description:

- Calculate and return importance of an inventory item acquisition for this agent

Parameters:

- None

Return values:

- Importance of the given inventory item acquisition for the current Agent

BOOL Agent::Scan(Agent *paScanned,ItemPtrArr Items, unsigned short ItemArrayLen,

ID ScanGoalItselfArg = GOAL_NONE);

Description:

- Scan another agent for possible strategy engagement / action target assignment.

Parameters:

- Agent *paScanned - scanned (examined) Agent entity

- ItemPtrArr Items - scanned agent inventory array

- unsigned short ItemArrayLen - scanned agent inventory array length

- ID ScanGoalItselfArg - goal record ID of the scan goal, if any (if omitted, assumed GOAL_NONE). The ID can be also criterion record, but then the method functions in criterion mode (no Strategy is attempted to adopt).

Return values:

- TRUE if a Strategy was launched, or the Agent is suitable for the argument Goal (ScanGoalItselfArg) if it's not GOAL_NONE, FALSE otherwise

BOOL Agent::ScanForCriterion(Agent *paScanned,

ItemPtrArr Items, unsigned short ItemArrayLen, GoalDefNodeP gp);

Description:

- Scan another agent for action target assignment only (criterion check).

Parameters:

- Agent *paScanned - scanned (examined) Agent entity

- ItemPtrArr Items - scanned agent inventory array

- unsigned short ItemArrayLen - scanned agent inventory array length

- GoalDefNodeP gp - criterion record

Return values:

- TRUE if the Agent is suitable for the argument criteria

long Agent::FindCriterionMatch(Agent **Candidates,unsigned short nCandArrLen,

ItemPtrArr *Items,unsigned short *ItemArrayLen,

ID ScanGoal = GOAL_NONE, percentage PassedRestrict = -1);

Description:

- Find agent matching a criterion in the given population.

Parameters:

- Agent **Candidates - population of agents to select from

- unsigned short nCandArrLen - candidates array length

- ItemPtrArr *Items - array of inventory items pointers' arrays

- unsigned short *ItemArrayLen - length of array of inventory items pointers' arrays

- ID ScanGoal - goal of scan / search

- percentage PassedRestrict - restrictions of identity:

ALL_BUT_SELF - usual restriction. Allows scan of all Agents but self.

NOT_STR_OBJ - this restriction disallows self and strategy objective agent

NOT_LISTED_IN_STR - this restriction disallows self and everyone already listed in strategy (initiators, objectives, verbal action content objectives, etc.)

SELF_ONLY - this restriction exists only for picking inventory items owned by the scanning agent ("self").

Note: Even SELF_ONLY restriction doesn't provide automatic selection. Restrictions serve only to restrict.

Return values:

- Number of the first suitable agent. If none found, -1 returned.

BOOL Agent::AssignTargetForNextAction(Agent**Population = NULL,unsigned short nPopLen = 0,

ItemPtrArr* ipapAllInventories = NULL,unsigned short *nInvSizes = 0);

Description:

- Attempt to find agents suitable to be the next action's targets, and prime the next action with these targets, if successful. Return values: TRUE if succeeded, FALSE if failed.

Parameters:

- Agent **Population - population of agents to select from

- unsigned short nPopLen - population size

- ItemPtrArr* ipapAllInventories - array of pointers' arrays containing all the inventories

- unsigned short *nInvSizes - sizes of these arrays. The length of this array must be nPopLen.

Return values:

- TRUE if a target was found for the next Action, FALSE otherwise

BOOL Agent::AssignTargetsForAction(Action *actpToAssign,

Agent**Population = NULL,unsigned short nPopLen = 0,

ItemPtrArr* ipapAllInventories = NULL,unsigned short *nInvSizes = 0,

Strategy *strpToUse = NULL);

Description:

- Attempt to find agents suitable to be the specified action's targets, and prime this action with these targets, if successful. Return values: TRUE if succeeded, FALSE if failed.

Parameters:

- Action *actpToAssign - action to assign targets to

- Agent **Population - population of agents to select from

- unsigned short nPopLen - population size

- ItemPtrArr* ipapAllInventories - array of pointers' arrays containing all the inventories

- unsigned short *nInvSizes - sizes of these arrays. The length of this array must be nPopLen.

- Strategy *strpToUse - alternate strategy to use

Return values:

- TRUE if a target was found for the given Action, FALSE otherwise

ActionError Agent::ExecuteNextAction(void *vpArg, Agent**Population = NULL,unsigned short nPopLen = 0,ItemPtrArr* ipapAllInventories = NULL,unsigned short *nInvSizes = 0);

Description:

- Execute the next action scheduled to be executed, completing al the needed checks, assignments (like AssignTargetsForNextAction), and conditional branching, if needed. It is strongly recommended to use this method and not lower-level equivalents to execute next action.

Parameters:

- void *vpArg - user-defined argument for the user function called upon the action execution

- Agent**Population - population of agents to select from

- unsigned short nPopLen - population size

- ItemPtrArr* ipapAllInventories - array of pointers' arrays containing all the inventories

- unsigned short *nInvSizes - sizes of these arrays. The length of this array must be nPopLen.

Return values:

- ACTION_NOT_PRIMED - one or more of the necessary attributes is invalid

- PAST_FAILURE - there was an unsuccessful attempt to execute this action before. The action will not be executed

- LO_INT - the Initiator lacks intelligence to execute the action

- TOO_FOREIGN - the Objective is too foreign to the Initiator (foreignness check failed)

- HI_ATT - the Initiator's attitude to the Objective is higher than the allowed upper limit

- LO_ATT - the Initiator's attitude to the Objective is higher than the allowed lower limit

- HI_WICK - the Initiator is too evil to commit the action

- LO_WICK - the Initiator is too good to commit the action

- HI_ANA - the Initiator is too chaotic to commit the action

- LO_ANA - the Initiator is too lawful to commit the action

- BAD_COMBAT_ODDS - the Initiator "thinks" his/her odds in combat vs. the Objective are too low

- LO_COU - the Initiator doesn't have the needed courage to execute the action

- ACTION_FAILURE - action failed (user-defined function returned zero)

- ACTION_SUCCESS - action executed successfully

BOOL Agent::CalcResponse(Action& actInitial);

Description:

- Initiate response to an executed action, if needed. Alter agent's personal attitude to the initiator, if applicable.

Parameters:

- Action& actIniti- action to respond to

Return values:

- TRUE if a Strategy was initiated in response, FALSE otherwise

percentage Agent::AttitudeToItem(ItemScores& ToEvaluate);

Description:

- Calculate agent's attitude to the parameter inventory item.

Parameters:

- ItemScores& ToEvaluate - item being evaluated

Return values:

- Attitude to the given item

BOOL Agent::PrimeAllActionTargets(Strategy *strToPrime);

Description:

- Checks for theoretical possibility of finding targets for actions in strategy (if SoloAssumption mode is off), or just assigns dummy targets to all the action targets (if SoloAssumption mode is on). All of these are typically done not for execution, but rather for running precise PossibilityCheck.

Parameters:

- Strategy *strToPrime - pointer to Strategy to prime actions in

Return values:

- TRUE if all the Actions were successfully primed, FALSE otherwise

Core Agent::GetCore() const;

Description:

- Getter method returning the agent's Core structure.

Parameters:

- None

Return values:

- The Agent's Core structure

Core *Agent::GetCoreAddress();

Description:

- Getter method returning pointer to the agent's Core structure.

Parameters:

- None

Return values:

- Pointer to the Agent's Core structure

void Agent::SetCore(Core & argCore);

Description:

- Setter method assigning the agent's Core structure

Parameters:

- Core& argCore - Core structure to assign

Return values:

- None

Core Agent::GetOriginalCore() const;

Description:

- Getter method returning the agent's "Original Core" structure.

Parameters:

- None

Return values:

- The Agent's original Core structure

void Agent::SetOriginalCore(Core &argCore);

Description:

- Setter method assigning the agent's "Original Core" structure

Parameters:

- Core& argCore - Core structure to assign

Return values:

- None

void Agent::ResetFromOriginal();

Description:

- Resets the current Core structure to the "constant" Original Core structure.

Parameters:

- None

Return values:

- None

void Agent::UpdateOriginalCore();

Description:

- The opposite of ResetFromOriginal: resets the original Core structure to the current Core structure.

Parameters:

- None

Return values:

- None

BOOL Agent::CreateNewAttitude(Core &ToAdd);

Description:

- Create new attutude in the attitudes tree, assigning the calculated attitude for this agent.

Parameters:

- Core& ToAdd - Core structure of the agent to create new attitude to

Return values:

- TRUE if the node was added successfully (there was no such attitude node before), and FALSE otherwise

percentage Agent::AttitudeTo(Core &ToGet);

Description:

- Return (SEEMED or TRUE, according to the UseTrueAttitude property) attitude to the agent whose Core is passed as parameter.

Parameters:

- Core& ToGet - Core structure of the agent to get attitude to

Return values:

- Attitude to the agent whose Core is passed as parameter

percentage Agent::AttitudeTo(ID ToGet);

Description:

- Return (SEEMED or TRUE, according to the UseTrueAttitude property) attitude to the agent whose ID is passed as parameter.

Parameters:

- ID ToGet - ID of the agent to get attitude to

Return values:

- Attitude to the agent whose ID is passed as parameter

BOOL Agent::SetAttitudeTo(ID ToSet, percentage NewAttitude,

unsigned char WhichOne = BOTH);

Description:

- Set attitude for the passed ID

Parameters:

- ID ToSet - ID of the agent to set attitude to

- percentage NewAttitude - the attitude to set

- unsigned char WhichOne - which attitude to set, SEEMED, TRUE, or BOTH

Return values:

- TRUE if the attitude was successfully set, FALSE otherwise

BOOL Agent::IsNewStrategyMoreImportant(Strategy& NewStrategy);

Description:

- Checks if CurrentStrategy can be aborted in favor of NewStrategy, based on the actual Importance

Parameters:

- Strategy& NewStrategy - strategy to compare to

Return values:

- TRUE if the new Strategy is more important, FALSE otherwise

BOOL Agent::IsNewStrategyMoreImportant(percentage NewStrategyImportance);

Description:

- Checks if CurrentStrategy can be aborted in favor of a new strategy, based on the actual Importance compared to the passed NewStrategyImportance

Parameters:

- percentage NewStrategyImportance - new strategy importance (obvious, isn't it?)

Return values:

- TRUE if the new Strategy is more important, FALSE otherwise

void Agent::SetSeemed_TrueToggles(BOOL UseTrueMeanness,

BOOL UseTrueWealth, BOOL UseTrueIntelligence,

BOOL argUseTrueAttitude);

Description:

- Setter method for the flags defining which value is used, TRUE or SEEMED

Parameters:

- BOOL UseTrueMeanness - usage of TRUE (not SEEMED) combat overall (meanness)

- BOOL UseTrueWealth - usage of TRUE (not SEEMED) wealth

- BOOL UseTrueIntelligence - usage of TRUE (not SEEMED) intelligence

- BOOL argUseTrueAttitude - usage of TRUE (not SEEMED) attitudes

Return values:

- None

BOOL Agent::IsDead();

Description:

- Returns whether the agent is dead (permanently inactive)

Parameters:

- None

Return values:

- TRUE if the Agent is dead, FALSE otherwise

void Agent::Die();

Description:

- Switches the agents' state to permanently inactive (dead)

Parameters:

- None

Return values:

- None

BOOL Agent::AdoptStrategyFromOneAction(Action *ToBeExecuted,

unsigned char NewImportance);

Description:

- Create a custom undefined strategy containing only one function passed as parameter, and assign it to CurrentStrategy, if importance allows. Return value: TRUE if succeded, FALSE if failed.

Parameters:

- Action *ToBeExecuted - the action to execute within the custom strategy

- unsigned char NewImportance - importance of the custom strategy

Return values:

- TRUE if the new Strategy was successfully created and adopted by the Agent, FALSE otherwise

unsigned short Agent::VerifyCriteria(GoalDefNodeP gpCrit, Core *bsChk,

ItemPtrArr ipaInventory = NULL, unsigned short nInvSize = 0);

Description:

- Verify if the checked Core structure fits in the named criterion limits. If the criterion is an inventory item criterion, all the inventory items are scanned until the first one suitable.

Parameters:

- GoalDefNodeP gpCrit - criterion record pointer

- Core *bsChk - Core structure to check

- ItemPtrArr ipaInventory - inventory items' pointers' array

- unsigned short nInvSize - ipaInventory size

Return values:

- if criterion is for item: 0 if failed to find a suitable item in the agent's inventory, item's index in the array + 1 otherwise (for example, for item No. 0 the return value will be 1)

- if criterion is for agent entity: 0 if failed, 1 if succeeded.

BOOL Agent::IsStrategyStillRelevant(Agent **Candidates,unsigned short nCandArrLen,

ItemPtrArr* Items,

unsigned short *ItemArrayLen);

Description:

- Check if the current strategy objective still suits the criterion which made the current agent to engage this strategy. It is a good idea to run this check before every lower level ExecuteNextAction (and Agent::ExecuteNextAction method does it), if you use such, to ensure the strategy still has the point (examples of "losing the point": the person who has the targetted item, was robbed and this item gone).

Parameters:

- Agent **Candidates - population of agents to select from

- unsigned short nCandArrLen - candidates array length

- ItemPtrArr *Items - array of inventory items pointers' arrays

- unsigned short *ItemArrayLen - length of array of inventory items pointers' arrays

Return values:

- TRUE if the current Strategy is still relevant to the Agent, FALSE otherwise

BOOL Agent::PickStrategy(Goal StrGoal, Core *pbsObj, ItemScores *pisObj = NULL);

Description:

- Attempt to search and adopt the easiest possible strategy for the current agent for the specified goal, running PossibilityCheck, etc.

Parameters:

- Goal StrGoal - goal to pick strategy for

- Core *pbsObj - pointer to the potential objective's Core structure

- ItemScores *pisObj - pointer to the potential item objective's ItemScores (if there is an item targetted)

Return value:

- TRUE if a Strategy was found suitable, FALSE otherwise

void Agent::SetAttitudesRoot(Attitude *TreeRoot, BOOL bDoNotDelele = FALSE);

Description:

- Override the current attitudes tree - assign a new one.

Parameters:

- Attitude *TreeRoot - new attitudes tree root to assign

- BOOL bDoNotDelele - whether the present attitude tree should be deleted. The default is "Yes, delete the tree"

Return values:

- None

void Agent::FillCritAttitudesArray(percepAtt[],Core *bsChk, GoalDefNodeP gp);

Description:

- Fills the passed array with attitudes needed for comparison with the criterion record

Parameters:

- percentage pAtt[] - array to fill (currently 7 is maximum filled cells)

- Core *bsChk - pointer to the checked agent's Core structure

- GoalDefNodeP gp - the criterion to use

Return values:

- None

unsigned short Agent::FillSaveBuffer(BYTE *pbBuffer);

Description:

- Encodes the object's contents, including attitudes tree, Strategy and all the Actions inside it, into the passed buffer. Return value: number of bytes allocated

Parameters:

- BYTE *pbBuffer - buffer to fill with the encoded contents

Return values:

- Number of bytes allocated

void Agent::RestoreFromBufferStep1(BYTE *pbBuffer,unsigned short nBufLen);

Description:

- Step one of restoring an Agent object from the encoded buffer. Why two steps? Because we cannot assume that the unique attId's will be the same if you generate these characters in the same order and quantity.That's why first we must restore all their scores, including IDs, and then recover all the pointers through these IDs.

Parameters:

- BYTE *pbBuffer - buffer containing the encoded Agent object contents

- unsigned short nBufLen - buffer length

Return values:

- None

void Agent::RestoreFromBufferStep2(BYTE *pbBuffer,unsigned short nBufLen,

Agent** papPopulation, unsigned short nPopSize,

ItemPtrArr* ipapItems, unsigned short *npInvSizes);

Description:

- Step two of restoring an Agent object from the encoded buffer. It involves relinking the lost pointers to the proper attributes.

Parameters:

- BYTE *pbBuffer - buffer containing the encoded Agent object contents

- unsigned short nBufLen - buffer length

- Agent** papPopulation - current population of agents

- unsigned short nPopSize - current population size

- ItemPtrArr* ipapItems - population of agents' inventory items

- unsigned short *npInvSizes - length of the inventory items array

Return values:

- None

percentage Agent::CalcNeutralSideMeanness(Agent **pbspPopulation,

unsigned short nPopSize, Action *actToExecute);

Description:

- Calculate combat overall for the neutral side, which is neither initiator nor objective. Needed for MeannessCheck, when SoloExecution mode is off (FALSE).

Parameters:

- Agent **pbspPopulation - current population of agents

- unsigned short nPopSize - current population size

- Action *actToExecute - action to be executed. Must be primed

Return values:

- Neutral side total combat ability

unsigned char Agent::GetTrueStatsByte();

Description:

- Getter method that returns the encoded value containing bit-level flags, which Impression values and attitude will be used, SEEMED or TRUE ones.

Parameters:

- None

Return values:

- True / seemed toggles bitmap

BOOL Agent::WasStrategyFailure(Strategy *ToCheck);

Description:

- Check if the passed strategy was attempted to execute in the past by this agent and failed

Parameters:

- Strategy *ToCheck - strategy to check for past failures

Return values:

- TRUE if the current Strategy was once adopted and failed, FALSE otherwise

EventsRegistry

EventsRegistry class primarily stores failed strategies and actions in order to prevent agents from making the same mistakes twice. Besides, it can be also used to store completed events to keep track - like promise or scheduled part of a deal that must be completed. If UseHistory flag is FALSE, the built-in EventsRegistry object managed by the system is inactive. EventsRegistry uses EventEntry structure which is listed below:

typedef struct{

ID EventID;

ID ObjectiveID;

ID ObjItemID;

ID *Witnesses;

unsigned short WitnessesQty;

EventType _Type;

} EventEntry;

Properties (public):

None

Methods (public):

EventsRegistry::EventsRegistry();

Description:

- Default constructor

Parameters:

- None

Return values:

- None

EventsRegistry::~EventsRegistry();

Description:

- Default destructor

Parameters:

- None

Return values:

- None

void EventsRegistry::Register(ID InitiID,ID EvID,ID ObjID,ID ObjItID, EventType eType);

Description:

- Register an event, allocating the needed entries, adding a new personal log section, if needed. It is strongly recommended to use this method and not lower-level ones.

Parameters:

- ID InitiID - event initiator's ID

- ID EvID - event definition record ID (action or strategy)

- ID ObjID - event objective ID

- ID ObjItID - event objective item ID (if any)

- EventType eType - event type. For now, the following are supported:

ACTION_PROMISE

ACTION_FAILURE

STRATEGY_FAILURE

Return values:

- None

BOOL EventsRegistry::IsEventRegistered(ID InitiID,ID EvID,ID ObjID,ID ObjItID,EventType eType);

Description:

- Check if the passed event is registered

Parameters:

- ID InitiID - event initiator's ID

- ID EvID - event definition record ID (action or strategy)

- ID ObjID - event objective ID

- ID ObjItID - event objective item ID (if any)

- EventType eType - event type. For now, the following are supported:

ACTION_PROMISE

ACTION_FAILURE

STRATEGY_FAILURE

Return values:

- TRUE if the event registered, FALSE otherwise

EventEntry *EventsRegistry::GetEventEntry(ID InitiID,ID EvID,ID ObjID,ID ObjItID,EventType eType);

Description:

- Find the passed event and return pointer to the proper EventEntry, if found.

Parameters:

- ID InitiID - event initiator's ID

- ID EvID - event definition record ID (action or strategy)

- ID ObjID - event objective ID

- ID ObjItID - event objective item ID (if any)

- EventType eType - event type. For now, the following are supported:

ACTION_PROMISE

ACTION_FAILURE

STRATEGY_FAILURE

Return values:

- Pointer to the proper EventEntry. If no event is found, NULL is returned.

void EventsRegistry::Unregister(ID InitiID,ID EvID,ID ObjID,ID ObjItID,EventType eType);

Description:

- Remove the passed event from events registry.

Parameters:

- ID InitiID - event initiator's ID

- ID EvID - event definition record ID (action or strategy)

- ID ObjID - event objective ID

- ID ObjItID - event objective item ID (if any)

- EventType eType - event type. For now, the following are supported:

ACTION_PROMISE

ACTION_FAILURE

STRATEGY_FAILURE

Return values:

- None

void EventsRegistry::Clear();

Description:

- Clear the registry, removing all the events.

Parameters:

- None

Return values:

- None

PersonalLog

PersonalLog class is a personal entry of EventsRegistry. The latter stores events by initiator.

Properties (public):

unsigned short MaxLogLen

- Maximum number of entries in the personal log

Methods (public):

PersonalLog::PersonalLog();

Parameters:

- None

Description:

- Default constructor

Return values:

- None

PersonalLog::~PersonalLog();

Parameters:

- None

Description:

- Default destructor

Return values:

- None

BOOL PersonalLog::ReallocLog(int nNewLen);

Parameters:

- int nNewLen - new number of entries

Description:

- reallocate memory by the given number of entries

Return values:

- TRUE if reallocation was successful, FALSE otherwise

void PersonalLog::SetInitiatorID(ID NewInitiatorID);

Parameters:

- ID NewInitiatorID - ID to set

Description:

- set the given ID to the PersonalLog

Return values:

- None

ID PersonalLog::GetInitiatorID();

Parameters:

- none

Description:

- return initiator ID

Return values:

- Initiator ID

int PersonalLog::GetEventIndex(ID EvID, ID Obj, ID ObjItem, EventType eType);

Parameters:

- ID EvID - event (action / strategy) definition node ID

- ID Obj - objective ID

- ID ObjItem - objective item ID

- EventType eType - event type: ACTION_FAILURE / STRATEGY_FAILURE / etc.

Description:

- locate the given event and return its index

Return values:

- Event index in the personal log; if none found, -1 is returned

BOOL PersonalLog::WasEventWitness(ID EvID, ID Obj, ID ObjItem, EventType eType);

Parameters:

- ID EvID - event (action / strategy) definition node ID

- ID Obj - objective ID

- ID ObjItem - objective item ID

- EventType eType - event type: ACTION_FAILURE / STRATEGY_FAILURE / etc.

- ID Witness - ID to check

Description:

- check if the given ID is present in the witnesses list of the given event

Return values:

- TRUE if the given ID is present in the witnesses list of the given event, FALSE otherwise

int PersonalLog::GetPromiseIndex(ID EvID, ID Obj, ID ObjItem);

Description:

- shortcut to GetEventIndex when the event is ACTION_PROMISE

Parameters:

- ID EvID - event (action / strategy) definition node ID

- ID Obj - objective ID

- ID ObjItem - objective item ID

Return values:

- Index of the given promise recorded under the given attributes

int PersonalLog::GetFailedActionIndex(ID EvID, ID Obj, ID ObjItem);

Description:

- shortcut to GetEventIndex when the event is ACTION_FAILURE

Parameters:

- ID EvID - event (action / strategy) definition node ID

- ID Obj - objective ID

- ID ObjItem - objective item ID

Return values:

- Index of the failed Action recorded under the given attributes

int PersonalLog::GetFailedStrategyIndex(ID EvID, ID Obj, ID ObjItem);

Description:

- shortcut to GetEventIndex when the event is STRATEGY_FAILURE

Parameters:

- ID EvID - event (action / strategy) definition node ID

- ID Obj - objective ID

- ID ObjItem - objective item ID

Return values:

- Index of the failed Strategy recorded under the given attributes

EventEntry *PersonalLog::GetEvent(unsigned short nIndex);

Description:

- get pointer to event by the given index

Parameters:

- unsigned short nIndex - index of the event

Return values:

- Pointer to the EventEntry using the given index. If none, NULL is returned

void PersonalLog::SetEvent(ID EvID, ID Obj, ID ObjItem, EventType eType, unsigned short nIndex);

Description:

- set event attributes by the given index

Parameters:

- ID EvID - event (action / strategy) definition node ID

- ID Obj - objective ID

- ID ObjItem - objective item ID

- EventType eType - event type: ACTION_FAILURE / STRATEGY_FAILURE / etc.

- unsigned short nIndex - index of the event

Return values:

- None

EventEntry *PersonalLog::AddEvent(ID EvID, ID Obj, ID ObjItem, EventType eType, unsigned short nIndex);

Description:

- add event to the PersonalLog

Parameters:

- ID EvID - event (action / strategy) definition node ID

- ID Obj - objective ID

- ID ObjItem - objective item ID

- EventType eType - event type: ACTION_FAILURE / STRATEGY_FAILURE / etc.

- unsigned short nIndex - index of the event

Return values:

- Pointer to the added EventEntry

void PersonalLog::RemoveEvent(ID EvID, ID Obj, ID ObjItem, EventType eType, unsigned short nIndex);

Description:

- remove event from the PersonalLog

Parameters:

- ID EvID - event (action / strategy) definition node ID

- ID Obj - objective ID

- ID ObjItem - objective item ID

- EventType eType - event type: ACTION_FAILURE / STRATEGY_FAILURE / etc.

- unsigned short nIndex - index of the event

Return values:

- None

void PersonalLog::DisconnectPointer();

Description:

- Remove the link between the attribute pointers to the allocated buffers

Parameters:

- None

Return values:

- None

Non-Member Functions

GoalDefNodeP GetGoalNode(ID GoalNodeID);

Description:

- Get goal definition record by the passed ID.

Parameters:

- ID GoalNodeID - goal record ID to get

Return values:

- Pointer to the Goal record. If none found, NULL is returned.

ActionDefNodeP GetActionNode(ID ActionNodeID);

Description:

- Get action definition record by the passed ID. Return value: pointer to the record. If none found, NULL is returned.

Parameters:

- ID ActionNodeID - action record ID to get

Return values:

- Pointer to the Action record. If none found, NULL is returned.

StrategyDefNodeP GetStrategyNode(ID StrategyNodeID);

Description:

- Get strategy definition record by the passed ID. Return value: pointer to the record. If none found, NULL is returned.

Parameters:

- ID StrategyNodeID - strategy record ID to get

Return values:

- Pointer to the Strategy record. If none found, NULL is returned.

percentage GetAttitude(ID AgentID, Attitude * AttTreeRoot, BOOL GetSEEMED = TRUE);

Description:

- Retrieve agent-specific attitude.

Parameters:

- ID AgentID - attitude ID to retrieve

- Attitude * AttTreeRoot - pointer to the attitude tree root to search

- BOOL GetSEEMED - whether to retrieve SEEMED or TRUE attitude

Return values:

- Requested attitude value. If the passed ID doesn't exist in the attitude tree, ERROR_PERCENTAGE (-127) is returned

BOOL AddAttitude(ID AgentID, percentage BothAttitudesValue, Attitude **AttTreeRoot);

Description:

- Adds a new attitude node according to the passed values. If node with the passed ID already existed before, no new node is added.

Parameters:

- ID AgentID - attitude ID to add

- percentage BothAttitudesValue - value to set. The value will be assigned to both SEEMED and TRUE attitudes

- Attitude **AttTreeRoot - attitude root

Return values:

- TRUE if the attitude value(s) were successfully added, FALSE otherwise

BOOL ModifyAttitude(ID AgentID, short ValueModifyBy, Attitude *AttTreeRoot,

unsigned char WhichOne = BOTH);

Description:

- Modify existing attitude node according to the passed values. If no node with the passed ID is found, the function fails.

Parameters:

- ID AgentID - attitude ID to modify

- short ValueModifyBy - value to modify by

- Attitude *AttTreeRoot - attitude tree root

- unsigned char WhichOne - which attitude to modify: SEEMED, TRUE, or BOTH

Return values:

- TRUE if the attitude value(s) were found and successfully modified, FALSE otherwise

BOOL UpdateAttitude(ID AgentID, percentage ValueToSet, Attitude **AttTreeRoot, unsigned char WhichOne = BOTH);

Description:

- Add / modify attitude node according to the passed values. The function fails only if memory allocation failed or the tree has invalid structure.

Parameters:

- ID AgentID - attitude ID to update

- percentage ValueToSet - value to assign to the attituide(s)

- Attitude **AttTreeRoot - attitudes tree root

- unsigned char WhichOne - which attitude to modify: SEEMED, TRUE, or BOTH

Return values:

- TRUE if the attitude value(s) were successfully added / modified, FALSE otherwise

void DelAttitudeTree(Attitude **AttTreeRoot);

Description:

- Discard all the attitude tree, assigning NULL to the AttTreeRoot

Parameters:

- Attitude **AttTreeRoot - attitudes tree root

Return values:

- None

Attitude *CopyAttitudeTree(Attitude*AttTreeRoot);

Description:

- Obtain a copy of attitude tree pointed by AttTreeRoot

Parameters:

- Attitude*AttTreeRoot - attitudes tree root

Return values:

- Pointer to the newly created attitude tree

void Attitudes2String(Attitude *AttTreeRoot, char *szReceiveBuffer);

Description:

- Debugging-purpose function dumping all the attitudes info to a character string

Parameters:

- Attitude *AttTreeRoot - attitudes tree root

- char *szReceiveBuffer - buffer to dump the attitude info to

Return values:

- None

BOOL InitActionLib((int(*)(void*))DefaultUserActionFunction);

Description:

- Initialize Brainiac libraries, internal lists, tables, etc. This function must be run before using Brainiac.

Parameters:

- ((int(*)(void*))DefaultUserActionFunction - default user function which is called on action execution when the ActionFunction is undefined (NULL). If DefaultUserActionFunction is NULL, then no function is called upon action execution with undefined ActionFunction

Return values:

- TRUE if Brainiac was properly initialized, FALSE otherwise.

void FreeLibLists();

Description:

- Free memory after Brainiac libraries and internal lists. Call this function before exiting your program

Parameters:

- None

Return values:

- None

percentage PersonalEvaluate(Action& ToEvaluate, Core& Evaluator);

Description:

- Calculate and return the commercial value of the passed action to the evaluator, in Wealth points. If the action involves items exchange, the item's value is returned. The function supports 3rd party evaluation (that is, when the evaluator is neither initiator nor objective).

Parameters:

- Action& ToEvaluate - action to evaluate

- Core& Evaluator - evaluator's Core structure

Return values:

- Commercial value, in Wealth points, of the next Action, according to the evaluator

long PersonalAttitude2Action(Action& ToEvaluate, Core &Evaluator,

BOOL bSetAtt = TRUE);

Description:

- Calculate and return the evaluator's attitude to the passed action. Note that attitude is not the same as commercial value, so this function is different from PersonalEvaluate. The function supports 3rd party evaluation (that is, when the evaluator is neither initiator nor objective).

Parameters:

- Action& ToEvaluate - action to evaluate

- Core &Evaluator - evaluator's Core structure

- BOOL bSetAtt - whether to update the evaluator's attitude to the action initaccording to the calculated value

Return values:

- Evaluator's attitude to the given Action

unsigned short BSFillSaveBuffer(Core ToSave, BYTE *pbBuffer);

Description:

- Encode the passed Core structure to buffer. Return value: number of bytes allocated.

Parameters:

- Core ToSave - Core structure to save

- BYTE *pbBuffer - buffer to save into

Return values:

- Number of bytes allocated

Core *FindBSAddress(ID ToFind, Core **Population,unsigned short nPopSize);

Description:

- Locate Core structure by ID. Return value: pointer to the Core structure. If none found, NULL is returned.

Parameters:

- ID ToFind - ID of the Core structure to find (what else?)

- Core **Population - pointers to all the agents' Core structures

- unsigned short nPopSize - population size

Return values:

- Pointer to the Core structure with the matching ID. If none found, NULL is returned

ItemScores *FindItemAddress(ID ItemID,ID OwnerID,

unsigned short nPopSize,ItemPtrArr* ipapAllInventories,

unsigned short* nInvSizes);

Description:

- Locate ItemScores structure. Return value: pointer to the Core structure. If not found, NULL is returned.

Parameters:

- ID ItemID - item ID

- ID OwnerID - item owner's ID

- unsigned short nPopSize - population of agents size

- ItemPtrArr* ipapAllInventories - ItemScores pointers' arrays' array

- unsigned short* nInvSizes - sizes of all the inventories

Return values:

- Pointer to the ItemScores with the matching IDs. If none found, NULL is returned.

void BSRestoreFromBufferStep1(BYTE *pbBuffer, unsigned short nBufLen, Core* ToRestore);

Description:

- Step one of restoring Core structure from the passed buffer.

Parameters:

- BYTE *pbBuffer - buffer containing encoded Core structure

- unsigned short nBufLen - buffer length

- Core* ToRestore - Core structure to restore

Return values:

- None

void BSRestoreFromBufferStep2(Core *ToRestore,Core **Population, unsigned short nPopSize);

Description:

- Step two of restoring Core structure from the passed buffer.

Parameters:

- Core *ToRestore - Core structure to restore

- Core **Population - pointers to all the agents' Core structures

- unsigned short nPopSize - population size

Return values:

- None

void SetDynamicTACAssumptionPopulation(Agent** Population, unsigned short nPopSize, ItemPtrArr*AllInventories, unsigned short *nInvSizes);

Description:

- Set "sample population" used for dynamic target assignment criterion assumptions. English: bunch of agents which will be used to check if there are candidates for an action that requires target assignment immediately before the execution. This function is called on ExecuteNextAction, if current dynamic TAC assumption population is NULL. That is, you normally don't have to bother about it, unless you changing you locations rapidly and destroy all the agents every time. Then, you have to call this function explicitly. NOTE: dynamic TAC assumption population feature is not used if SoloAssumptionMode is on (TRUE).

Parameters:

- Agent** Population - pointers to all the agents' Core structures

- unsigned short nPopSize - population size

- ItemPtrArr* ipapAllInventories - ItemScores pointers' arrays' array

- unsigned short* nInvSizes - sizes of all the inventories

Return values:

- None

void FreeDynamicTACAssumptionPopulation();

Description:

- Free memory taken by dynamic TAC assumption population

Parameters:

- None

Return values:

- None

void SetSoloAssumptionMode(BOOL NewSoloAssumptionMode);

Description:

- Turns SoloAssumptionMode on / off.

Parameters:

- BOOL NewSoloAssumptionMode - new setting for SoloAssumptionMode

Return values:

- None

void SetSoloActionMode(BOOL NewSoloActionMode);

Description:

- Turn SoloActionMode on / off

Parameters:

- BOOL NewSoloActionMode - new setting for SoloActionMode

Return values:

- None

void SetSuddenChangeUse(BOOL NewSuddenChangeUse);

Description:

- Turn SuddenChangeUse on / off

Parameters:

- BOOL NewSuddenChangeUse - new setting for SuddenChangeUse

Return values:

- None

void SetHistoryUse(BOOL NewHistoryUse);

Description:

- Turn usage of events registry (history) on / off, respectively disabling or enabling backtracking

Parameters:

- BOOL NewHistoryUse - new setting for HistoryUse

Return values:

- None

void SetMaxFailures(unsigned short NewMaxFailures);

Description:

- Set number of failures before aborting a strategy

Parameters:

- unsigned short NewMaxFailures - new setting for number of failures before aborting a strategy

Return values:

- None

void ClearHistory();

Description:

- Discard all the registered events - everybody's memory is cleared.

Parameters:

- None

Return values:

- None

void SetGoalItemAcquisitionID();

Description:

- Set new item acquisition node

Parameters:

- ID idNewAcquisitionGoal - new item acquisition node ID

Return values:

- None