// cas_repeatspeech
// Listener script: repeat what the PC says and optionally route it.

    void SpeakFrom(object oWho, string sSpeak)
    {
        if (!GetIsObjectValid(oWho)) return;
        DelayCommand(0.1f, AssignCommand(oWho, ActionSpeakString(sSpeak)));
    }


void main()
{
    // Make sure we're in "listening" mode (harmless if already on).
    if (!GetIsListening(OBJECT_SELF))
    {
        SetListening(OBJECT_SELF, TRUE);
    }

    // Capture who spoke and what they said.
    object oPC   = GetPCChatSpeaker();      // Assumes your custom core exposes this here.
    string sText = GetPCChatMessage();      // Full text of the player's message.

    if (!GetIsObjectValid(oPC)) return;
    if (sText == "") return;

    // Routing hint from the listener.
    string sSendTo = GetLocalString(OBJECT_SELF, "sSEND_TO");

    // Helper: speak from a given object after a short delay.
    // Using ActionSpeakString queues it on the object; AssignCommand targets it.
    void SpeakFrom(object oWho, string sSpeak)
    {
        if (!GetIsObjectValid(oWho)) return;
        DelayCommand(0.1f, AssignCommand(oWho, ActionSpeakString(sSpeak)));
    }

    // Try routing based on sSEND_TO.
    if (sSendTo == "FROM_HOLE")
    {
        object oArea = GetArea(OBJECT_SELF);
        object oT = GetObjectByTag("CAS_FROM_HOLE");
        // Ensure it's in the same area
        int i = 1;
        while (GetIsObjectValid(oT) && GetArea(oT) != oArea)
        {
            oT = GetObjectByTag("CAS_FROM_HOLE", i);
            i++;
        }

        if (GetIsObjectValid(oT))
        {
            SpeakFrom(oT, sText);
            return;
        }
        // Fallback to self if not found
        SpeakFrom(OBJECT_SELF, sText);
        return;
    }
    else if (sSendTo == "INTO_HOLE")
    {
        object oArea = GetArea(OBJECT_SELF);
        object oT = GetObjectByTag("CAS_INTO_HOLE");
        int i = 1;
        while (GetIsObjectValid(oT) && GetArea(oT) != oArea)
        {
            oT = GetObjectByTag("CAS_INTO_HOLE", i);
            i++;
        }

        if (GetIsObjectValid(oT))
        {
            SpeakFrom(oT, sText);
            return;
        }
        // Fallback to self if not found
        SpeakFrom(OBJECT_SELF, sText);
        return;
    }

    // Default: listener repeats the PC.
    SpeakFrom(OBJECT_SELF, sText);
}
