//::///////////////////////////////////////////////
//:: Librairie - Gestion du chat
//:: LIB_CHAT_MANAGE
//:://////////////////////////////////////////////
/*
 Cette librairie contient toutes les fonctions utiles pour le chat
*/
//:://////////////////////////////////////////////
//:: Created By: Léa Andersteen
//:://////////////////////////////////////////////
#include "lib_char_manage" 
#include "lib_lang_manage" 
#include "lib_lang_trans" 
#include "lib_chat_emote" 
#include "nwnx_funcs"
#include "nwnx_funcsext" 
#include "x2_inc_switches"
#include "x0_i0_stringlib"
#include "dmfi_string_inc"
#include "dmfi_plchlishk_i"
#include "dmfi_db_inc"
#include "dmfi_plychat_inc"
const int COMMAND_CHAT_NOT_FOUND = 0;
const int COMMAND_CHAT_DNAME_RENAME = 1;
const int COMMAND_CHAT_CHAR_SAVE = 2;
const int COMMAND_CHAT_SPEAK_LANG = 3;
//COMMANDE LANGUES
//COMMANDE CHAT DMFI
const int COMMAND_CHAT_EMOTE = 10; //*
const int COMMAND_CHAT_DMFI_CMD = 11;//.
const int COMMAND_CHAT_SPEAK_SELECT_LANG = 12;//[
const int COMMAND_CHAT_MODULE_CMD = 13;//!
//DEBUG COMMANDES
//CONFIGURATION PERSONNAGE
const int DEBUG_COMMAND_CHAT_CHAR_SET_SUBRACE = 101;
const int DEBUG_COMMAND_CHAT_CHAR_GET_SUBRACE = 102;
const int DEBUG_COMMAND_CHAT_CHAR_SET_GOD = 103;
const int DEBUG_COMMAND_CHAT_CHAR_GET_GOD = 104;
const int DEBUG_COMMAND_CHAT_CHAR_SET_REGION = 105;
const int DEBUG_COMMAND_CHAT_CHAR_GET_REGION = 106;
const int DEBUG_COMMAND_CHAT_CHAR_GRANT_LANGUE = 107;
const int DEBUG_COMMAND_CHAT_CHAR_REMOVE_LANGUE = 108;
int isCommandChatFound(string chatText);
int getCommandChatFound(string chatText);
string getParameterCommandChatFound(string chatText);
void executeCommandChat(object oPC,int commandChat, string param1);
void enregistrementDerniereParole(object oPC,string chatTest);
//DMFI 
int isChannelAudible( int nVolume);
void traitementCanauxDMFI(int nVolume,object oShouter);
/*
IMPLEMENTATION
*/
int isCommandChatFound(string chatText)
{
    int positionCharSpecial = FindSubString(chatText, "!");
    return  (positionCharSpecial>-1);
}
int getCommandChatFound(string chatText)
{
    string commandeFound;
    int positionCharSpecial = FindSubString(chatText, " ");
    if (positionCharSpecial>0)
        commandeFound = GetStringLeft(chatText,positionCharSpecial);
    else 
        commandeFound=chatText;
    if (commandeFound=="!nommer")
        return COMMAND_CHAT_DNAME_RENAME;
    if (commandeFound=="!save")
        return COMMAND_CHAT_CHAR_SAVE;
    if (commandeFound=="!gregion")
        return DEBUG_COMMAND_CHAT_CHAR_GET_REGION;
    if (commandeFound=="!sregion")
        return DEBUG_COMMAND_CHAT_CHAR_SET_REGION;
    if (commandeFound=="!speak")
        return COMMAND_CHAT_SPEAK_LANG;
    if (commandeFound=="!add_langue")
        return DEBUG_COMMAND_CHAT_CHAR_GRANT_LANGUE;
        if (commandeFound=="!remove_langue")
        return DEBUG_COMMAND_CHAT_CHAR_REMOVE_LANGUE;
    
    return 0;
}
string getParameterCommandChatFound(string chatText)
{
    string paramFound;
    int positionCharSpecial = FindSubString(chatText, " ");
    paramFound = GetStringLeft(chatText,positionCharSpecial);
    return GetSubString(chatText,positionCharSpecial+1,GetStringLength(chatText)-positionCharSpecial-1);
}
void executeCommandChat(object oPC,int commandChat, string param1)
{
    switch (commandChat)
    {
        case COMMAND_CHAT_DNAME_RENAME:renommerPJ(oPC,param1);
        break;
        case COMMAND_CHAT_CHAR_SAVE:sauvegarderPersoPROXY(oPC);
                                    sauvegarderPersoDB(oPC);
        break;
        case DEBUG_COMMAND_CHAT_CHAR_GET_REGION:getPCRegionOrigine(oPC);
        break;
        case DEBUG_COMMAND_CHAT_CHAR_SET_REGION:setPCRegionOrigine(oPC,StringToInt(param1));
        break;
        
        case COMMAND_CHAT_SPEAK_LANG:setActiveLangage(oPC,param1);
        break;
        case DEBUG_COMMAND_CHAT_CHAR_GRANT_LANGUE:addLangueParlee(oPC,getCodeLangue(param1));
        break;
        case DEBUG_COMMAND_CHAT_CHAR_REMOVE_LANGUE:removeLangueParlee(oPC,getCodeLangue(param1));
        break;
        
        
        
    }
}
void setDerniereParole(object oPC,string chatText)
{
    SetLocalString(oPC,"lastWordSaid",chatText);
}
string getDerniereParole(object oPC)
{
    return GetLocalString(oPC,"lastWordSaid");
    
}
int isChannelAudible( int nVolume)
{
 if ((nVolume == TALKVOLUME_TALK && DMFI_LISTEN_ON_CHANNEL_TALK) ||
            (nVolume == TALKVOLUME_SILENT_SHOUT && DMFI_LISTEN_ON_CHANNEL_DM) ||
            (nVolume == TALKVOLUME_WHISPER && DMFI_LISTEN_ON_CHANNEL_WHISPER) ||
            (nVolume == TALKVOLUME_PARTY && DMFI_LISTEN_ON_CHANNEL_PARTY) ||
            (nVolume == TALKVOLUME_SHOUT && DMFI_LISTEN_ON_CHANNEL_SHOUT))
        return 1;
        else 
        return 0;
}
void traitementCanauxDMFI(int nVolume,object oShouter)
{
        object oMod = GetModule();
        int nHooks = GetLocalArrayUpperBound(oMod, DMFI_CHATHOOK_HANDLE_ARRAYNAME);
        int iHook;
        int bInvoke;
        string sChatHandlerScript;
        int maskChannels;
        // int bListenAll;
        object oRunner;
        int bAutoRemove;
        int bDirtyList = FALSE;
    
    for (iHook = nHooks; iHook > 0; iHook--) // reverse-order execution, last hook gets first dibs
    {
        maskChannels = GetLocalArrayInt(oMod, DMFI_CHATHOOK_CHANNELS_ARRAYNAME, iHook);
        if (((1 << nVolume) & maskChannels) != 0) // right channel
        {
            bInvoke = FALSE;
            if (GetLocalArrayInt(oMod, DMFI_CHATHOOK_LISTENALL_ARRAYNAME, iHook) != FALSE)
            {
                bInvoke = TRUE;
            }
            else
            {
                object oDesiredSpeaker = GetLocalArrayObject(oMod, DMFI_CHATHOOK_SPEAKER_ARRAYNAME, iHook);
                if (oShouter == oDesiredSpeaker) bInvoke = TRUE;
            }
            if (bInvoke) // right speaker
            {
                sChatHandlerScript = GetLocalArrayString(oMod, DMFI_CHATHOOK_SCRIPT_ARRAYNAME, iHook);
                oRunner = GetLocalArrayObject(oMod, DMFI_CHATHOOK_RUNNER_ARRAYNAME, iHook);
                ExecuteScript(sChatHandlerScript, oRunner);
                bAutoRemove = GetLocalArrayInt(oMod, DMFI_CHATHOOK_AUTOREMOVE_ARRAYNAME, iHook);
                if (bAutoRemove)
                {
                    bDirtyList = TRUE;
                    SetLocalArrayInt(oMod, DMFI_CHATHOOK_HANDLE_ARRAYNAME, iHook, 0);
                }
            }
        }
    }
    if (bDirtyList) DMFI_ChatHookRemove(0);
    }
string ParseEmote(string sEmote, object oPC)
{
    // see if PC has muted their own emotes
    if (GetLocalInt(oPC, "hls_emotemute") != 0) return sEmote;
    DeleteLocalInt(oPC, "dmfi_univ_int");
    object oRightHand = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND,oPC);
    object oLeftHand =  GetItemInSlot(INVENTORY_SLOT_LEFTHAND,oPC);
    string sLCEmote;
    int rollDMFIIntercepted = 0;
    int emoteDMFIIntercepted=0;
    if (GetStringLeft(sEmote, 1) == "*")
    {
        sLCEmote=GetStringLowerCase(sEmote);
        int positionFirstSpace    =    FindSubString(sEmote," ",1); //-1 si rien trouvé
        int positionSecondEndChar =FindSubString(sEmote,"*",1);
        int positionFirstSeparator = FindSubString(sEmote,";",1); // on peut taper ceci: *sit; s'assoie par terre*
        if (positionFirstSpace> - 1)
            sLCEmote=GetStringLeft(sEmote,positionFirstSpace); // supression de tout ce qu'il y a appres le premier espace espace inclus
            
        if (positionSecondEndChar> - 1)
            sLCEmote=GetStringLeft(sLCEmote,positionSecondEndChar); //supression de tout ce qu'il y a apres la deuxieme *
            
        if (positionFirstSeparator> - 1)
            {
            sLCEmote=GetStringLeft(sLCEmote,positionFirstSeparator); //supression de tout ce qu'il y a apres le premier ;
            }
            
    }
    sendMessageAuPJ(oPC,1,"Emote:["+sLCEmote+"]");
    int iSit;
    object oArea;
    object oChair;
    // morderon - rewrote from here to end for better text case handling
    //*emote* rolls
    if ((FindSubString(sLCEmote, "strength") != -1))
        SetLocalInt(oPC, "dmfi_univ_int", 61);
    else if ((FindSubString(sLCEmote, "dexterity") != -1))
        SetLocalInt(oPC, "dmfi_univ_int", 62);
    else if ((FindSubString(sLCEmote, "constitution") != -1))
        SetLocalInt(oPC, "dmfi_univ_int", 63);
    else if ((FindSubString(sLCEmote, "intelligence") != -1))
        SetLocalInt(oPC, "dmfi_univ_int", 64);
    else if ((FindSubString(sLCEmote, "wisdom") != -1))
        SetLocalInt(oPC, "dmfi_univ_int", 65);
    else if ((FindSubString(sLCEmote, "charisma") != -1))
        SetLocalInt(oPC, "dmfi_univ_int", 66);
    else if ((FindSubString(sLCEmote, "fortitude") != -1))
        SetLocalInt(oPC, "dmfi_univ_int", 67);
    else if ((FindSubString(sLCEmote, "reflex") != -1))
        SetLocalInt(oPC, "dmfi_univ_int", 68);
    else if ((FindSubString(sLCEmote, "will*") != -1))
        SetLocalInt(oPC, "dmfi_univ_int", 69);
    else if ((FindSubString(sLCEmote, "animal empathy") != -1))
        SetLocalInt(oPC, "dmfi_univ_int", 71);
    else if ((FindSubString(sLCEmote, "appraise") != -1))
        SetLocalInt(oPC, "dmfi_univ_int", 72);
    else if ((FindSubString(sLCEmote, "bluff") != -1))
        SetLocalInt(oPC, "dmfi_univ_int", 73);
    else if ((FindSubString(sLCEmote, "concentration") != -1))
        SetLocalInt(oPC, "dmfi_univ_int", 74);
    else if ((FindSubString(sLCEmote, "craft armor") != -1))
        SetLocalInt(oPC, "dmfi_univ_int", 75);
    else if ((FindSubString(sLCEmote, "craft trap") != -1))
        SetLocalInt(oPC, "dmfi_univ_int", 76);
    else if ((FindSubString(sLCEmote, "craft weapon") != -1))
        SetLocalInt(oPC, "dmfi_univ_int", 77);
    else if ((FindSubString(sLCEmote, "disable trap") != -1))
        SetLocalInt(oPC, "dmfi_univ_int", 78);
    else if ((FindSubString(sLCEmote, "discipline") != -1))
        SetLocalInt(oPC, "dmfi_univ_int", 79);
    else if ((FindSubString(sLCEmote, "heal") != -1))
        SetLocalInt(oPC, "dmfi_univ_int", 81);
    else if ((FindSubString(sLCEmote, "hide") != -1))
        SetLocalInt(oPC, "dmfi_univ_int", 82);
    else if ((FindSubString(sLCEmote, "intimidate") != -1))
        SetLocalInt(oPC, "dmfi_univ_int", 83);
    else if ((FindSubString(sLCEmote, "listen") != -1))
        SetLocalInt(oPC, "dmfi_univ_int", 84);
    else if ((FindSubString(sLCEmote, "lore") != -1))
        SetLocalInt(oPC, "dmfi_univ_int", 85);
    else if ((FindSubString(sLCEmote, "move silently") != -1))
        SetLocalInt(oPC, "dmfi_univ_int", 86);
    else if ((FindSubString(sLCEmote, "open lock") != -1))
        SetLocalInt(oPC, "dmfi_univ_int", 87);
    else if ((FindSubString(sLCEmote, "parry*") != -1))
        SetLocalInt(oPC, "dmfi_univ_int", 88);
    else if ((FindSubString(sLCEmote, "perform") != -1))
        SetLocalInt(oPC, "dmfi_univ_int", 89);
    else if ((FindSubString(sLCEmote, "persuade") != -1))
        SetLocalInt(oPC, "dmfi_univ_int", 91);
    else if ((FindSubString(sLCEmote, "pick pocket") != -1))
        SetLocalInt(oPC, "dmfi_univ_int", 92);
    else if ((FindSubString(sLCEmote, "search") != -1))
        SetLocalInt(oPC, "dmfi_univ_int", 93);
    else if ((FindSubString(sLCEmote, "set trap") != -1))
        SetLocalInt(oPC, "dmfi_univ_int", 94);
    else if ((FindSubString(sLCEmote, "spellcraft") != -1))
        SetLocalInt(oPC, "dmfi_univ_int", 95);
    else if ((FindSubString(sLCEmote, "spot") != -1))
        SetLocalInt(oPC, "dmfi_univ_int", 96);
    else if ((FindSubString(sLCEmote, "taunt") != -1))
        SetLocalInt(oPC, "dmfi_univ_int", 97);
    else if ((FindSubString(sLCEmote, "tumble") != -1))
        SetLocalInt(oPC, "dmfi_univ_int", 98);
    else if ((FindSubString(sLCEmote, "use magic device") != -1))
        SetLocalInt(oPC, "dmfi_univ_int", 99);
    else if ((FindSubString(sLCEmote, "ride") != -1))
        SetLocalInt(oPC, "dmfi_univ_int", 90);
    if (GetLocalInt(oPC, "dmfi_univ_int"))
    {
        SetLocalString(oPC, "dmfi_univ_conv", "pc_dicebag");
        rollDMFIIntercepted=1;
        ExecuteScript("dmfi_execute", oPC);
    }
    //*emote*
    if (FindSubString(GetStringLowerCase(sLCEmote), "*bows") != -1 ||
        FindSubString(GetStringLowerCase(sLCEmote), " bows") != -1 ||
        FindSubString(GetStringLowerCase(sLCEmote), "curtsey") != -1)
        {AssignCommand(oPC, PlayAnimation(ANIMATION_FIREFORGET_BOW, 1.0));emoteDMFIIntercepted=1;}
    else if (FindSubString(GetStringLowerCase(sLCEmote), "drink") != -1 ||
             FindSubString(GetStringLowerCase(sLCEmote), "sips") != -1)
        {AssignCommand(oPC, PlayAnimation(ANIMATION_FIREFORGET_DRINK, 1.0));emoteDMFIIntercepted=1;}
    else if (FindSubString(GetStringLowerCase(sLCEmote), "drinks") != -1 &&
             FindSubString(GetStringLowerCase(sLCEmote), "sits") != -1)
    {
        AssignCommand(oPC, ActionPlayAnimation( ANIMATION_LOOPING_SIT_CROSS, 1.0, 99999.0f));
        DelayCommand(1.0f, AssignCommand(oPC, PlayAnimation( ANIMATION_FIREFORGET_DRINK, 1.0)));
        DelayCommand(3.0f, AssignCommand(oPC, PlayAnimation( ANIMATION_LOOPING_SIT_CROSS, 1.0, 99999.0)));
        emoteDMFIIntercepted=1;
    }
    else if (FindSubString(GetStringLowerCase(sLCEmote), "reads") != -1 &&
             FindSubString(GetStringLowerCase(sLCEmote), "sits") != -1)
    {
        AssignCommand(oPC, ActionPlayAnimation( ANIMATION_LOOPING_SIT_CROSS, 1.0, 99999.0f));
        DelayCommand(1.0f, AssignCommand(oPC, PlayAnimation( ANIMATION_FIREFORGET_READ, 1.0)));
        DelayCommand(3.0f, AssignCommand(oPC, PlayAnimation( ANIMATION_LOOPING_SIT_CROSS, 1.0, 99999.0)));
        emoteDMFIIntercepted=1;
    }
    else if (FindSubString(GetStringLowerCase(sLCEmote), "sit")!= -1)
    {
        AssignCommand(oPC, ActionPlayAnimation( ANIMATION_LOOPING_SIT_CROSS, 1.0, 99999.0f));
        emoteDMFIIntercepted=1;
    }
    else if (FindSubString(GetStringLowerCase(sLCEmote), "greet")!= -1 ||
             FindSubString(GetStringLowerCase(sLCEmote), "wave") != -1)
        {AssignCommand(oPC, PlayAnimation(ANIMATION_FIREFORGET_GREETING, 1.0));emoteDMFIIntercepted=1;}
    else if (FindSubString(GetStringLowerCase(sLCEmote), "yawn")!= -1 ||
             FindSubString(GetStringLowerCase(sLCEmote), "stretch") != -1 ||
             FindSubString(GetStringLowerCase(sLCEmote), "bored") != -1)
        {AssignCommand(oPC, PlayAnimation(ANIMATION_FIREFORGET_PAUSE_BORED, 1.0));emoteDMFIIntercepted=1;}
    else if (FindSubString(GetStringLowerCase(sLCEmote), "scratch")!= -1)
    {
        AssignCommand(oPC,ActionUnequipItem(oRightHand));
        AssignCommand(oPC,ActionUnequipItem(oLeftHand));
        AssignCommand(oPC, PlayAnimation(ANIMATION_FIREFORGET_PAUSE_SCRATCH_HEAD, 1.0));
        emoteDMFIIntercepted=1;
    }
    else if (FindSubString(GetStringLowerCase(sLCEmote), "reads")!= -1 ||
             FindSubString(GetStringLowerCase(sLCEmote), " reads")!= -1||
             FindSubString(GetStringLowerCase(sLCEmote), "read")!= -1)
        {AssignCommand(oPC, PlayAnimation(ANIMATION_FIREFORGET_READ, 1.0));emoteDMFIIntercepted=1;}
    else if (FindSubString(GetStringLowerCase(sLCEmote), "salute")!= -1)
    {
        AssignCommand(oPC,ActionUnequipItem(oRightHand));
        AssignCommand(oPC,ActionUnequipItem(oLeftHand));
        AssignCommand(oPC, PlayAnimation(ANIMATION_FIREFORGET_SALUTE, 1.0));
        emoteDMFIIntercepted=1;
    }
    else if (FindSubString(GetStringLowerCase(sLCEmote), "steal")!= -1 ||
             FindSubString(GetStringLowerCase(sLCEmote), "swipe") != -1)
        {AssignCommand(oPC, PlayAnimation(ANIMATION_FIREFORGET_STEAL, 1.0));emoteDMFIIntercepted=1;}
    else if (FindSubString(GetStringLowerCase(sLCEmote), "taunt")!= -1 ||
             FindSubString(GetStringLowerCase(sLCEmote), "mock") != -1)
    {
        PlayVoiceChat(VOICE_CHAT_TAUNT, oPC);
        AssignCommand(oPC, PlayAnimation(ANIMATION_FIREFORGET_TAUNT, 1.0));
        emoteDMFIIntercepted=1;
    }
    else if ((FindSubString(GetStringLowerCase(sLCEmote), "smokes") != -1)||
             (FindSubString(GetStringLowerCase(sLCEmote), "smoke") != -1))
    {
        SmokePipe(oPC);
        emoteDMFIIntercepted=1;
    }
    else if (FindSubString(GetStringLowerCase(sLCEmote), "cheer ")!= -1 ||
             FindSubString(GetStringLowerCase(sLCEmote), "cheer")!= -1)
    {
        PlayVoiceChat(VOICE_CHAT_CHEER, oPC);
        AssignCommand(oPC, PlayAnimation(ANIMATION_FIREFORGET_VICTORY1, 1.0));
        emoteDMFIIntercepted=1;
    }
    else if (FindSubString(GetStringLowerCase(sLCEmote), "hooray")!= -1)
    {
        PlayVoiceChat(VOICE_CHAT_CHEER, oPC);
        AssignCommand(oPC, PlayAnimation(ANIMATION_FIREFORGET_VICTORY2, 1.0));
        emoteDMFIIntercepted=1;
    }
    else if (FindSubString(GetStringLowerCase(sLCEmote), "celebrate")!= -1)
    {
        PlayVoiceChat(VOICE_CHAT_CHEER, oPC);
        AssignCommand(oPC, PlayAnimation(ANIMATION_FIREFORGET_VICTORY3, 1.0));
        emoteDMFIIntercepted=1;
    }
    else if (FindSubString(GetStringLowerCase(sLCEmote), "giggle")!= -1 && GetGender(oPC) == GENDER_FEMALE)
       { AssignCommand(oPC, PlaySound("vs_fshaldrf_haha"));emoteDMFIIntercepted=1;}
    else if (FindSubString(GetStringLowerCase(sLCEmote), "flop")!= -1 ||
             FindSubString(GetStringLowerCase(sLCEmote), "prone")!= -1)
        {AssignCommand(oPC, ActionPlayAnimation(ANIMATION_LOOPING_DEAD_FRONT, 1.0, 99999.0));emoteDMFIIntercepted=1;}
    else if (FindSubString(GetStringLowerCase(sLCEmote), "bends")!= -1 ||
             FindSubString(GetStringLowerCase(sLCEmote), "stoop")!= -1)
        {AssignCommand(oPC, ActionPlayAnimation(ANIMATION_LOOPING_GET_LOW, 1.0, 99999.0));emoteDMFIIntercepted=1;}
    else if (FindSubString(GetStringLowerCase(sLCEmote), "fiddle")!= -1)
        {AssignCommand(oPC, ActionPlayAnimation(ANIMATION_LOOPING_GET_MID, 1.0, 5.0));emoteDMFIIntercepted=1;}
    else if (FindSubString(GetStringLowerCase(sLCEmote), "nod")!= -1 ||
             FindSubString(GetStringLowerCase(sLCEmote), "agree")!= -1)
        {AssignCommand(oPC, ActionPlayAnimation(ANIMATION_LOOPING_LISTEN, 1.0, 4.0));emoteDMFIIntercepted=1;}
    else if (FindSubString(GetStringLowerCase(sLCEmote), "peers")!= -1 ||
             FindSubString(GetStringLowerCase(sLCEmote), "scans")!= -1 ||
             FindSubString(GetStringLowerCase(sLCEmote), "search")!= -1)
        {AssignCommand(oPC,ActionPlayAnimation(ANIMATION_LOOPING_LOOK_FAR, 1.0, 99999.0));emoteDMFIIntercepted=1;}
    else if (FindSubString(GetStringLowerCase(sLCEmote), "*pray")!= -1 ||
             FindSubString(GetStringLowerCase(sLCEmote), " pray")!= -1 ||
             FindSubString(GetStringLowerCase(sLCEmote), "meditate")!= -1)
    {
        AssignCommand(oPC,ActionUnequipItem(oRightHand));
        AssignCommand(oPC,ActionUnequipItem(oLeftHand));
        AssignCommand(oPC,ActionPlayAnimation(ANIMATION_LOOPING_MEDITATE, 1.0, 99999.0));
        emoteDMFIIntercepted=1;
    }
    else if (FindSubString(GetStringLowerCase(sLCEmote), "drunk")!= -1 ||
             FindSubString(GetStringLowerCase(sLCEmote), "woozy")!= -1)
        {AssignCommand(oPC, ActionPlayAnimation(ANIMATION_LOOPING_PAUSE_DRUNK, 1.0, 99999.0));emoteDMFIIntercepted=1;}
    else if (FindSubString(GetStringLowerCase(sLCEmote), "tired")!= -1 ||
             FindSubString(GetStringLowerCase(sLCEmote), "fatigue")!= -1 ||
             FindSubString(GetStringLowerCase(sLCEmote), "exhausted")!= -1)
    {
        PlayVoiceChat(VOICE_CHAT_REST, oPC);
        AssignCommand(oPC, ActionPlayAnimation(ANIMATION_LOOPING_PAUSE_TIRED, 1.0, 3.0));
        emoteDMFIIntercepted=1;
    }
    else if (FindSubString(GetStringLowerCase(sLCEmote), "fidget")!= -1 ||
             FindSubString(GetStringLowerCase(sLCEmote), "shifts")!= -1)
        {AssignCommand(oPC, ActionPlayAnimation(ANIMATION_LOOPING_PAUSE2, 1.0, 99999.0));emoteDMFIIntercepted=1;}
    else if (FindSubString(GetStringLowerCase(sLCEmote), "sits")!= -1 &&
             (FindSubString(GetStringLowerCase(sLCEmote), "floor")!= -1 ||
              FindSubString(GetStringLowerCase(sLCEmote), "ground")!= -1))
        {AssignCommand(oPC, ActionPlayAnimation(ANIMATION_LOOPING_SIT_CROSS, 1.0, 99999.0));emoteDMFIIntercepted=1;}
    else if (FindSubString(GetStringLowerCase(sLCEmote), "demand")!= -1 ||
             FindSubString(GetStringLowerCase(sLCEmote), "threaten")!= -1)
        {AssignCommand(oPC, ActionPlayAnimation(ANIMATION_LOOPING_TALK_FORCEFUL, 1.0, 99999.0));emoteDMFIIntercepted=1;}
    else if (FindSubString(GetStringLowerCase(sLCEmote), "laugh")!= -1 ||
             FindSubString(GetStringLowerCase(sLCEmote), "chuckle")!= -1)
    {
        PlayVoiceChat(VOICE_CHAT_LAUGH, oPC);
        AssignCommand(oPC, ActionPlayAnimation(ANIMATION_LOOPING_TALK_LAUGHING, 1.0, 2.0));
        emoteDMFIIntercepted=1;
    }
    else if (FindSubString(GetStringLowerCase(sLCEmote), "begs")!= -1 ||
             FindSubString(GetStringLowerCase(sLCEmote), "plead")!= -1)
        {AssignCommand(oPC, ActionPlayAnimation(ANIMATION_LOOPING_TALK_PLEADING, 1.0, 99999.0));emoteDMFIIntercepted=1;}
    else if (FindSubString(GetStringLowerCase(sLCEmote), "worship")!= -1)
        {AssignCommand(oPC, ActionPlayAnimation(ANIMATION_LOOPING_WORSHIP, 1.0, 99999.0));emoteDMFIIntercepted=1;}
    else if (FindSubString(GetStringLowerCase(sLCEmote), "snore")!= -1 ||
             FindSubString(GetStringLowerCase(sLCEmote), "*naps")!= -1 ||
             FindSubString(GetStringLowerCase(sLCEmote), " naps")!= -1||
             FindSubString(GetStringLowerCase(sLCEmote), "nap")!= -1)
        {ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_IMP_SLEEP), oPC);emoteDMFIIntercepted=1;}
    else if (FindSubString(GetStringLowerCase(sLCEmote), "*sings")!= -1 ||
             FindSubString(GetStringLowerCase(sLCEmote), " sings")!= -1 ||
             FindSubString(GetStringLowerCase(sLCEmote), "hums")!= -1)
        {ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectVisualEffect(VFX_DUR_BARD_SONG), oPC, 6.0f);emoteDMFIIntercepted=1;}
    else if (FindSubString(GetStringLowerCase(sLCEmote), "whistles")!= -1)
        {AssignCommand(oPC, PlaySound("as_pl_whistle2"));emoteDMFIIntercepted=1;}
    else if (FindSubString(GetStringLowerCase(sLCEmote), "talks")!= -1 ||
             FindSubString(GetStringLowerCase(sLCEmote), "chats")!= -1)
        {AssignCommand(oPC, ActionPlayAnimation(ANIMATION_LOOPING_TALK_NORMAL, 1.0, 99999.0));emoteDMFIIntercepted=1;}
    else if (FindSubString(GetStringLowerCase(sLCEmote), "shakes head")!= -1)
    {
        AssignCommand(oPC, PlayAnimation(ANIMATION_FIREFORGET_HEAD_TURN_LEFT, 1.0, 0.25f));
        DelayCommand(0.15f, AssignCommand(oPC, PlayAnimation(ANIMATION_FIREFORGET_HEAD_TURN_RIGHT, 1.0, 0.25f)));
        DelayCommand(0.40f, AssignCommand(oPC, PlayAnimation(ANIMATION_FIREFORGET_HEAD_TURN_LEFT, 1.0, 0.25f)));
        DelayCommand(0.65f, AssignCommand(oPC, PlayAnimation(ANIMATION_FIREFORGET_HEAD_TURN_RIGHT, 1.0, 0.25f)));
        emoteDMFIIntercepted=1;
    }
    else if (FindSubString(GetStringLowerCase(sLCEmote), "ducks")!= -1)
        {AssignCommand(oPC, ActionPlayAnimation(ANIMATION_FIREFORGET_DODGE_DUCK, 1.0, 99999.0));emoteDMFIIntercepted=1;}
    else if (FindSubString(GetStringLowerCase(sLCEmote), "dodge")!= -1)
        {AssignCommand(oPC, ActionPlayAnimation(ANIMATION_FIREFORGET_DODGE_SIDE, 1.0, 99999.0));emoteDMFIIntercepted=1;}
    else if (FindSubString(GetStringLowerCase(sLCEmote), "cantrip")!= -1)
        {AssignCommand(oPC, ActionPlayAnimation(ANIMATION_LOOPING_CONJURE1, 1.0, 99999.0));emoteDMFIIntercepted=1;}
    else if (FindSubString(GetStringLowerCase(sLCEmote), "spellcast")!= -1)
        {AssignCommand(oPC, ActionPlayAnimation(ANIMATION_LOOPING_CONJURE2, 1.0, 99999.0));emoteDMFIIntercepted=1;}
    else if (FindSubString(GetStringLowerCase(sLCEmote), "fall")!= -1 &&
             FindSubString(GetStringLowerCase(sLCEmote), "back")!= -1)
        {AssignCommand(oPC, ActionPlayAnimation(ANIMATION_LOOPING_DEAD_BACK, 1.0, 99999.0));emoteDMFIIntercepted=1;}
    else if (FindSubString(GetStringLowerCase(sLCEmote), "spasm")!= -1)
        {AssignCommand(oPC, ActionPlayAnimation(ANIMATION_LOOPING_SPASM, 1.0, 99999.0));emoteDMFIIntercepted=1;}
    sendMessageAuPJ(oPC,1,"Emote DMFI:"+IntToString(emoteDMFIIntercepted));
    sendMessageAuPJ(oPC,1,"ROLL DMFI:"+IntToString(rollDMFIIntercepted));
    sendMessageAuPJ(oPC,1,"LONGUEUR:"+IntToString(GetStringLength(sLCEmote)));
    if ((rollDMFIIntercepted ==1 )|| (emoteDMFIIntercepted ==1))
        {
            sEmote = GetStringRight(sEmote,GetStringLength(sEmote)-GetStringLength(sLCEmote)-1);
            sendMessageAuPJ(oPC,1,"SEmote:["+sEmote+"]");
            sendMessageAuPJ(oPC,1,"GetStringRight:["+GetStringRight(sEmote,1)+"]");
            sendMessageAuPJ(oPC,1,"GetStringLeft:["+GetStringLeft(sEmote,1)+"]");
            if ((GetStringRight(sLCEmote,1)!="*"))
            {
                if (GetStringRight(sEmote,1)!="*")
                    sEmote=sEmote+"*";
                if (GetStringLeft(sEmote,1)!="*")
                    sEmote="*"+sEmote;
            }
        }
        
    return sEmote;
}
string enleverEspaceDebutTexte(string sSaid)
{
    while (GetStringLeft(sSaid, 1) == " ")
    {
        sSaid = GetStringRight(sSaid, GetStringLength(sSaid)-1);
    }
    return sSaid;
}
object getCibleDMFIVoice(object oSpeaker)
{
    object oTarget;
    if (GetIsDM(oSpeaker) || GetIsDMPossessed(oSpeaker))
                    {
                        oTarget = GetLocalObject(oSpeaker, "dmfi_VoiceTarget");
                    
    }
    return oTarget;
}
object getCibleFromMasterToSummon(object oSpeaker)
{
    object oTarget = GetMaster(oSpeaker);
    if (!GetIsObjectValid(oTarget))
    {
        oTarget = GetAssociate(ASSOCIATE_TYPE_ANIMALCOMPANION, oSpeaker);
        if (!GetIsObjectValid(oTarget))
        {
            oTarget = GetAssociate(ASSOCIATE_TYPE_FAMILIAR, oSpeaker);
            if (!GetIsObjectValid(oTarget))
            {
                oTarget = GetAssociate(ASSOCIATE_TYPE_HENCHMAN, oSpeaker);
                if (!GetIsObjectValid(oTarget))
                {
                    oTarget = GetAssociate(ASSOCIATE_TYPE_SUMMONED, oSpeaker);
                }
            }
        }
    }
    return oTarget;
}
object getCibleFromSummonToMaster(object oSpeaker)
{
    object oTarget = GetAssociate(ASSOCIATE_TYPE_SUMMONED, oSpeaker);
    if (!GetIsObjectValid(oTarget))
    {
        oTarget = GetAssociate(ASSOCIATE_TYPE_HENCHMAN, oSpeaker);
        if (!GetIsObjectValid(oTarget))
        {
            oTarget = GetAssociate(ASSOCIATE_TYPE_FAMILIAR, oSpeaker);
            if (!GetIsObjectValid(oTarget))
            {
                oTarget = GetAssociate(ASSOCIATE_TYPE_ANIMALCOMPANION, oSpeaker);
                if (!GetIsObjectValid(oTarget))
                {
                    oTarget = GetMaster(oSpeaker);
                }
            }
        }
    }
    return oTarget;
}
object selectionCible(object oShouter,string chatText)
{        
        //     : = throw voice to last designated target
        //     ; = throw voice to master / animal companion / familiar / henchman / summon
        //     , = throw voice summon / henchman / familiar / animal companion / master
        object oTarget = oShouter;
        string cmdChar = GetStringLeft(chatText, 1);
            if (cmdChar == ":")                
                    oTarget = getCibleDMFIVoice(oShouter);                    
            if (cmdChar == ";")
                    oTarget = getCibleFromMasterToSummon(oShouter);
            if (cmdChar == ",")
                oTarget = getCibleFromSummonToMaster(oShouter);
                
    return oTarget;
}
int selectionCommandChat(string chatText)
{
    string cmdChar = GetStringLeft(chatText, 1);
    if ((cmdChar == ":")||(cmdChar == ";")||(cmdChar == ","))
        cmdChar = GetStringLeft(GetStringRight(chatText, GetStringLength(chatText)-1),1);
    if (cmdChar == ".")
        return COMMAND_CHAT_DMFI_CMD;
    if (cmdChar == "*")
        return COMMAND_CHAT_EMOTE;
    if(cmdChar == "[")
        return COMMAND_CHAT_SPEAK_SELECT_LANG;
    if(cmdChar == "!")
        return COMMAND_CHAT_MODULE_CMD;    
    return COMMAND_CHAT_NOT_FOUND;
}
/*
const int COMMAND_CHAT_EMOTE = 10; //*
const int COMMAND_CHAT_DMFI_CMD = 11;//.
const int COMMAND_CHAT_SPEAK_SELECT_LANG = 12;//[
const int COMMAND_CHAT_MODULE_CMD = 13;//!
const int DEBUG_COMMAND_CHAT_CHAR_GRANT_LANGUE = 107;
const int DEBUG_COMMAND_CHAT_CHAR_REMOVE_LANGUE = 108;
*/
string executeDMFICommand(object oShouter,object oTarget,string sSaid)
{
    sendStatusTacheAuPJ(oShouter, 1, "executeDMFICommand");
        if (oTarget == OBJECT_INVALID)
            oTarget = GetLocalObject(oShouter, "dmfi_univ_target");
        if (GetIsObjectValid(oTarget))
            ParseCommand(oTarget, oShouter, sSaid);
        else
            DMFISendMessageToPC(oShouter, "Invalid command target - not processed.", FALSE, DMFI_MESSAGE_COLOR_ALERT);
    sendStatusTacheAuPJ(oShouter, 2, "executeDMFICommand");
    return "";
}
string executeDMFIEmote(object oShouter,object oTarget,string sSaid)
{
    sendStatusTacheAuPJ(oShouter, 1, "executeDMFIEmote");
    if (oTarget == OBJECT_INVALID) 
        oTarget = oShouter; // untargeted emotes apply to self
        sSaid=ParseEmote(sSaid, oTarget);
    sendStatusTacheAuPJ(oShouter, 2, "executeDMFIEmote");
        return sSaid;           
}
string executeDMFITranslation(object oShouter,object oTarget,string sSaid, int nVolume, int targetLangue)
{
        sendStatusTacheAuPJ(oShouter, 1, "executeDMFITranslation");
        sSaid = GetStringRight(sSaid, GetStringLength(sSaid)-1);
        sendMessageAuPJ(oShouter,1,"Texte: "+sSaid);
        sendMessageAuPJ(oShouter,1,"Langue: "+getIntituleLangue(targetLangue));
        if (targetLangue>0)
            sSaid= TranslateToLanguage( oTarget,sSaid, nVolume,targetLangue, oShouter);
        sendStatusTacheAuPJ(oShouter, 2, "executeDMFITranslation");
        return sSaid;
}
string executeModuleCommand(object oShouter,object oTarget,string sSaid)
{
    sendStatusTacheAuPJ(oShouter, 1, "executeModuleCommand");
    sendMessageAuPJ(oShouter,1,"Texte: "+sSaid);
    if (isCommandChatFound(sSaid))
    {                    
        if (getCommandChatFound(sSaid)>0)
            {        
                sendMessageAuPJ(oShouter,1,"Commande: "+IntToString(getCommandChatFound(sSaid)));
                sendMessageAuPJ(oShouter,1,"Parametre: "+getParameterCommandChatFound(sSaid));
                executeCommandChat( oShouter,getCommandChatFound(sSaid),getParameterCommandChatFound(sSaid));
            }
    }
    sendStatusTacheAuPJ(oShouter, 2, "executeModuleCommand");
    return "";
}