

//:: Purpose:         Have a placeable "speak" when a trigger is touched.
//::
//:: Instructions:    Put down a trigger, and assign this script "cas_shatemple" on the OnEnter event of the script.
//::                  Assign the following variables:
//::
//::                  - int nMaxLines = the maximum number of "lines" on the placeable. This will tell it what number to stop at when randomly searching or speaking "in order"
//::                  - float fTimeBetweenText = the delay between lines of text being speaking. This is in seconds.
//::                  - float fMaximumTimeBeforeIReset = There is a timer on the trigger to prevent multiple people from triggering the event and spamming the dialogue box with text. This is in seconds.
//::                  - string sSpeakingPlaceable = The Tag of the Placeable you want to speak. Make sure this is UNIQUE.
//::                  - int bSpeakInOrder = 0 = random, 1= in order.
//::                  - string SpeakTextX = Assigned to the placeable, this tells the script what text to "speak." PUT THIS ON THE PLACEABLE YOU WANT TO SPEAK, NOT THE TRIGGER. X the number.

//Placeable and Trigger related constants
const string SPEAK_TEXT_VARNAME_PREFIX = "SpeakText";
const string SPEAK_PLACEABLE_TAG_VARNAME = "sSpeakingPlaceable";
const string MAX_LINES_VARNAME = "nMaxLines";
const string AM_ACTIVATED_FLAG_VARNAME = "AmIActivated";
const string SPEAK_IN_ORDER_FLAG_VARNAME = "bSpeakInOrder";
const string TIME_BETWEEN_TEXT_VARNAME = "fTimeBetweenText";
const float COOLDOWN_TIME = 180.0f; // Cooldown time in seconds (3 minutes)

// Function to reset trigger activation state
void ResetTriggerActivation(object oTrigger) {
    SetLocalInt(oTrigger, AM_ACTIVATED_FLAG_VARNAME, FALSE);
}

// Function to speak a line from the placeable
void SpeakLine(object oCodex, int nMaxLines, int bSpeakInOrder, int nCurrentLine) {
    int nLine;
    string sVariableName, sLine;

    if(bSpeakInOrder == 1) {
        // Stop speaking if the last line has been reached
        if(nCurrentLine > nMaxLines) {
            return;
        }
        nLine = nCurrentLine;
    } else {
        nLine = Random(nMaxLines) + 1; // Random line
    }

    sVariableName = SPEAK_TEXT_VARNAME_PREFIX + IntToString(nLine);
    sLine = GetLocalString(oCodex, sVariableName);

    if(sLine != "") {
        AssignCommand(oCodex, SpeakString(sLine));
    }

    // Prepare for the next line
    if(bSpeakInOrder == 1) {
        nLine = nCurrentLine + 1; // Increment for the next line

        float fTimeBetweenText = GetLocalFloat(OBJECT_SELF, TIME_BETWEEN_TEXT_VARNAME);
        DelayCommand(fTimeBetweenText, SpeakLine(oCodex, nMaxLines, bSpeakInOrder, nLine));
    }
}

void main() {
    object oTrigger = OBJECT_SELF;
    object oCodex;
    int nMaxLines, bSpeakInOrder;
    string sSpeakingPlaceable = GetLocalString(oTrigger, SPEAK_PLACEABLE_TAG_VARNAME);

    // Check if the placeable is specified and if the trigger is already activated
    if(sSpeakingPlaceable == "" || GetLocalInt(oTrigger, AM_ACTIVATED_FLAG_VARNAME) == TRUE)
        return;

    // Set the trigger as activated
    SetLocalInt(oTrigger, AM_ACTIVATED_FLAG_VARNAME, TRUE);

    oCodex = GetNearestObjectByTag(sSpeakingPlaceable, oTrigger);
    nMaxLines = GetLocalInt(oTrigger, MAX_LINES_VARNAME);
    if (nMaxLines <= 0) return; // Invalid number of lines

    bSpeakInOrder = GetLocalInt(oTrigger, SPEAK_IN_ORDER_FLAG_VARNAME);

    SpeakLine(oCodex, nMaxLines, bSpeakInOrder, 1); // Start from the first line

    // Reset trigger after the cooldown time
    DelayCommand(COOLDOWN_TIME, ResetTriggerActivation(oTrigger));
}
