---------------------------
Conversations with Hawkwind
---------------------------

The conversations with Hawkwind are handled by a function starting at offset 0xcb14 in avatar.exe.

Hawkwind's dialog is stored in avatar.exe at offset 0x123e9, as a sequence of 0-terminated strings.
The last string is terminated by two 0's.

The offsets of most strings are hard-coded into avatar.exe.
But when you ask Hawkwind about one of the virtues, the game looks up his answer in a table.
This table is located right behind Hawkwind's dialog, at offset 0x13187 in avatar.exe.

The Hawkwind dialog function, translated into C:

-----
Notes
-----
The newline character is 0xa.

------
Tables
------
unsigned char* virtueNames[] = {
    "honesty",
    "compassion",
    "valor",
    "justice",
    "sacrifice",
    "honor",
    "spirituality",
    "humility"
}

/* unsigned word = 2 bytes */
typedef unsigned word[8] virtueLevelRange;
virtueLevelRange virtueTable[5]; /* at offset 0x13187 in avatar.exe */

---------------------
Conversation function
---------------------
void talkToHawkwind() {
    unsigned char *playerInput;
    int firstQuestion = 1;
    int contConv = 1; /* continue convesation flag */
    int i;
    unsigned byte virtueLevel;

    if ((getStatus(0) == 'G') || (getStatus(0) == 'P')) {
        /* Hawkwind welcomes the Avatar */
        printString(0x3d1d);
        printPCName(0);
        printString(0x3d29);

        while (contConv) {
            if (firstQuestion) {
                printString(0x3d95);
                firstQuestion = 0;
            }
            else printString(0x3dc3);

            playerInput = getPlayerInput();
            if (strcmp(playerInput,"none") == 0) contConv = 0;
            if (strcmp(playerInput,"bye") == 0) contConv = 0;
            if (strcmp(playerInput,"") == 0) contConv = 0;

            if (contConv) {
                /* did the player ask about one of the virtues? */
                i = 0;
                while ((strcmp(playerInput,virtueNames[i]) != 0) && (i < 8)) i++;
                if (i == 8) printString(0x3dfc) /* not a subject for enlightenment */
                else {
                    virtueLevel = getVirtueLevel(virtue);
                    if (virtueLevel == 0) printString(0x3e30) /* partial Avatar */
                    else if (virtueLevel < 0x14) printString(virtueTable[0][virtue])
                    else if (virtueLevel < 0x28) printString(virtueTable[1][virtue])
                    else if (virtueLevel < 0x3c) printString(virtueTable[2][virtue])
                    else if (virtueLevel < 0x63) printString(virtueTable[3][virtue])
                    else {
                        /* virtue level >= 0x63 */
                        printString(virtueTable[4][virtue]);
                        printString(0x3e8a); /* go to the shrine and meditate for 3 cycles */
                    }
                }
            }
            else printString(0x3ebc); /* goodbye message */
        }
    }
    else {
        /* Hawkwind: "I will only speak with the Avatar" */
        printString(0x3cd9);
        printPCName(0);
        printString(0x3d00);
        printPCName(0);
        printString(0x3d0f);
    }
}

-------------------
Auxiliary functions
-------------------
/* Return 'G','P','S' or 'D' */
char getStatus(int pcNumber);

/* Print the 0-terminated string stored at (ofs + 0xf27b) in avatar.exe */
void printString(long ofs);

/*
 * Print the name of the specified PC.
 * PC's are numbered 0-7.
 * A PC's number depends on the current party order.
 * The Avatar is always #0, because he can't change position.
 */
void printPCName(int pcNumber);

/* Read a string */
unsigned char* getPlayerInput();
