// cas_repeatspeech
// Listens for PC chat, confirms, then repeats or routes the message.

void SpeakDelayed(object oWho, string sMsg, float fDelay)
{
    if (!GetIsObjectValid(oWho) || sMsg == "") return;
    DelayCommand(fDelay, AssignCommand(oWho, SpeakString(sMsg)));
}

object GetFirstInSameAreaByTag(string sTag, object oRef)
{
    object oArea = GetArea(oRef);
    object oT = GetObjectByTag(sTag);
    int i = 1;
    while (GetIsObjectValid(oT) && GetArea(oT) != oArea)
    {
        oT = GetObjectByTag(sTag, i);
        i++;
    }
    if (GetIsObjectValid(oT) && GetArea(oT) == oArea) return oT;
    return OBJECT_INVALID;
}

void main()
{
    // Ensure we're actually listening.
    if (!GetIsListening(OBJECT_SELF))
    {
        SetListening(OBJECT_SELF, TRUE);
    }

    object oPC   = GetPCChatSpeaker();
    string sText = GetPCChatMessage();
    if (!GetIsObjectValid(oPC)) return;
    if (sText == "") return;

    // Immediate confirmation from the listener.
    SpeakDelayed(OBJECT_SELF, "I heard " + sText, 0.1f);

    // Route or echo the original text.
    string sSendTo = GetLocalString(OBJECT_SELF, "sSEND_TO");

    if (sSendTo == "FROM_HOLE")
    {
        object oTarget = GetFirstInSameAreaByTag("CAS_FROM_HOLE", OBJECT_SELF);
        if (GetIsObjectValid(oTarget))
        {
            SpeakDelayed(oTarget, sText, 0.1f);
        }
        else
        {
            // Fallback to listener if no target in area.
            SpeakDelayed(OBJECT_SELF, sText, 0.1f);
        }
        return;
    }
    else if (sSendTo == "INTO_HOLE")
    {
        object oTarget = GetFirstInSameAreaByTag("CAS_INTO_HOLE", OBJECT_SELF);
        if (GetIsObjectValid(oTarget))
        {
            SpeakDelayed(oTarget, sText, 0.1f);
        }
        else
        {
            SpeakDelayed(OBJECT_SELF, sText, 0.1f);
        }
        return;
    }

    // Default: listener repeats it as well.
    SpeakDelayed(OBJECT_SELF, sText, 0.1f);
}
