rendered paste body//:://////////////////////////////////////////////
//:: Created By: cawila
//:: Created On: v643
//:://////////////////////////////////////////////
//:: Heavily modified by Arkov in v666, v685
//:://////////////////////////////////////////////
#include "inc_dmb_chat"
#include "chat_listener"
#include "chat_actions"
#include "chat_emotes"
///////////////////////////////////////////////////////////////////////////////
// DEFINES/PROTOTYPES
///////////////////////////////////////////////////////////////////////////////
void chat_ProcessVoice(object oPC, string sVoice);
void Eavesdrop(object oPC, string sText, object oTo, int nMode);
void HandleSimpleAction(string sAction, object oPC);
void ParseSimpleAction(string sInput, object oPC);
///////////////////////////////////////////////////////////////////////////////
// MAIN
///////////////////////////////////////////////////////////////////////////////
void main()
{
// speaking object
object oPC = OBJECT_SELF;
object oArea = GetArea(oPC);
// get text
SetLocalString(oPC, "NWNX!CHAT!TEXT", dmb_GetSpacer());
string sText = GetLocalString(oPC, "NWNX!CHAT!TEXT");
int nMode = StringToInt(GetStringLeft(sText,2));
int nTo = StringToInt(GetSubString(sText,2,10));
sText = dmb_GetStringFrom(sText, 12);
int iLength = GetStringLength(sText);
Eavesdrop(oPC, sText, dmb_getPC(nTo), nMode);
if(GetSubString(sText, 0, 3) == "/c "){
chat_ProcessAction(oPC, GetStringRight(sText, iLength - 3));
SetLocalString(oPC, "NWNX!CHAT!SUPRESS", "1");
} else if(GetSubString(sText, 0, 3) == "/e "){
chat_ProcessEmote(oPC, GetStringRight(sText, iLength - 3));
SetLocalString(oPC, "NWNX!CHAT!SUPRESS", "1");
} else if(GetSubString(sText, 0, 3) == "/r "){
chat_ProcessRoll(oPC, GetStringRight(sText, iLength - 3));
SetLocalString(oPC, "NWNX!CHAT!SUPRESS", "1");
} else if(GetSubString(sText, 0, 3) == "/v "){
chat_ProcessVoice(oPC, GetStringRight(sText, iLength - 3));
SetLocalString(oPC, "NWNX!CHAT!SUPRESS", "1");
}
else {
if(nMode == 3) {
SendMessageToAllDMs("Whisper being ignored");
return;
}
// Talk mode, Whisper mode, Shout mode
if(nMode == 1 || nMode == 2 || nMode == 3){
if(GetLocalInt(oArea, "bHasNoListeningRegion") == FALSE){
object oListeningRegion = GetNearestObjectByTag("ListeningRegion", oPC);
if(oListeningRegion == OBJECT_INVALID){
SetLocalInt(oArea, "bHasNoListeningRegion", TRUE);
}else{
if(GetIsInSubArea(oPC, oListeningRegion)){
doListening(oListeningRegion, oPC, sText, nMode);
}
}
}
// Talk mode
if (nMode == 1) {
ParseSimpleAction(sText, oPC);
SetLocalString(oPC, "sListener_LastSpoken", sText);
}
}
}
// remove garbage
DeleteLocalString(oPC, "NWNX!CHAT!TEXT");
DeleteLocalString(oPC, "NWNX!CHAT!SUPRESS");
}
///////////////////////////////////////////////////////////////////////////////
// UTILITY FUNCTIONS
///////////////////////////////////////////////////////////////////////////////
void chat_ProcessVoice(object oPC, string sVoice)
{
//Speaking through an Associate:
// /v a <message> = Animal Companion
// /v d <message> = Dominated Monster
// /v f <message> = Familiar
// /v h <message> = Henchman
// /v s <message> = Summoned Creature
int iLength = GetStringLength(sVoice);
if(GetSubString(sVoice, 0, 2) == "a ")
chat_RemoteSpeech(GetStringRight(sVoice, iLength-2), GetAssociate(ASSOCIATE_TYPE_ANIMALCOMPANION, oPC), oPC);
else if(GetSubString(sVoice, 0, 2) == "d ")
chat_RemoteSpeech(GetStringRight(sVoice, iLength-2), GetAssociate(ASSOCIATE_TYPE_DOMINATED, oPC), oPC);
else if(GetSubString(sVoice, 0, 2) == "f ")
chat_RemoteSpeech(GetStringRight(sVoice, iLength-2), GetAssociate(ASSOCIATE_TYPE_FAMILIAR, oPC), oPC);
else if(GetSubString(sVoice, 0, 2) == "h ")
chat_RemoteSpeech(GetStringRight(sVoice, iLength-2), GetAssociate(ASSOCIATE_TYPE_HENCHMAN, oPC), oPC);
else if(GetSubString(sVoice, 0, 2) == "s ")
chat_RemoteSpeech(GetStringRight(sVoice, iLength-2), GetAssociate(ASSOCIATE_TYPE_SUMMONED, oPC), oPC);
else if(GetIsDM(oPC)){
int nCritter = StringToInt(GetSubString(sVoice, 0, FindSubString(sVoice, " ")));
if(nCritter > 0){
object oTarget = GetLocalObject(oPC, "LDSCRITTER" + IntToString(nCritter));
if (!GetIsObjectValid(oTarget))
SendMessageToPC(oPC, "You must first use <setc #> to store a creature in slot " + IntToString(nCritter));
else
chat_RemoteSpeech(GetStringRight(sVoice, iLength - FindSubString(sVoice, " ") - 1), oTarget, oPC);
}else
SendMessageToPC(oPC, "Invalid slot " + IntToString(nCritter));
}else
SendMessageToPC(oPC, "Unrecognized command.");
}
// Eavesdrop:
// A debugging routine that sends all text passing
// through listening directly to interested DMs. There can
// be ten DMs eavesdropping at a time; as soon as they're
// all gone, the eavesdropping flag is set to zero and
// the routine does nothing, to minimize overhead.
void Eavesdrop(object oPC, string sText, object oTo, int nMode)
{
int nCount;
object oModule = GetModule();
// Compose the logging message
string sAreaName = GetName(GetArea(oPC));
if(GetStringLength(sAreaName) > 14)
sAreaName = GetStringLeft(sAreaName, 4) + "..." + GetStringRight(sAreaName, 7);
string sPrefix = GetName(oPC) + " (" + sAreaName + ") ["
+ GetSpeechModeString(nMode) + "]: ";
string sMessage = sPrefix + GetSpeechModeColor(nMode) + sText + "</c>";
string sLogfile = sPrefix + sText;
nMode %= 16;
if(nMode == 4 || nMode == 5 || nMode == 7){
sMessage += " >> " + GetName(oTo);
sLogfile += " >> " + GetName(oTo);
}
string sTimeStamp = GetLocalString(GetModule(), "sModule_TimeStamp");
SetLocalString(oPC, "NWNX!CHAT!LOG", sTimeStamp + " " + sLogfile + "\n");
object oEavesdropper;
for(; nCount < 10; nCount++){
oEavesdropper = GetLocalObject(oModule, "oEavesdropper_" + IntToString(nCount));
if(!GetIsObjectValid(oEavesdropper))
continue;
// And send to each listening DM.
if(GetIsDM(oEavesdropper))
SendMessageToPC(oEavesdropper, sMessage);
else
DeleteLocalObject(oModule, "oEavesdropper_" + IntToString(nCount));
}
}
// HandleSimpleAction:
// Major routine, called on every *emote* that
// goes through the Talk channel; also should be
// called by voice-throwing routines. The contents
// of the *emote* (e.g. "emote") are passed in as
// the string sAction.
void HandleSimpleAction(string sAction, object oPC)
{
if(GetStringUpperCase(GetStringLeft(sAction, 5)) == "ROLL ")
chat_ProcessRoll(oPC, GetStringRight(sAction, GetStringLength(sAction) - 5));
else if(GetIsPC(oPC) && !GetIsDM(oPC) && !GetIsDMPossessed(oPC) && GetTokenInt(oPC, "Talus_parse_emotes"))
chat_ProcessEmote_Strict(oPC, sAction);
}
// ParseSimpleAction:
// Text processing routine to prepare strings to
// be put through HandleSimpleAction.
// -- doesn't really need to return the string it pulled out.
void ParseSimpleAction(string sInput, object oPC)
{
string sAction="";
int iLength=GetStringLength(sInput);
int iStar1=FindSubString(sInput, "*");
if(iStar1 >= 0 && iStar1 < iLength+1)
{
string sRight=GetStringRight(sInput, iLength-iStar1-1);
int iStar2=FindSubString(sRight, "*");
if(iStar2 >= 0 && iStar2+iStar1 < iLength)
{
sAction=GetStringLeft(sRight, iStar2);
if(GetStringLength(sAction))
HandleSimpleAction(sAction, oPC);
string sNext = GetStringRight(sRight, GetStringLength(sRight)-iStar2-1);
//recursively parse for more actions.
ParseSimpleAction(sNext, oPC);
}
}
}