//////////////////////////////////////////////////////////////////////////////// // hos_chat - Replaces the invisible listeners that were needed before // By Deva B. Winblood. August 16th, 2008 //////////////////////////////////////////////////////////////////////////////// #include "x3_inc_string" #include "npcactivitiesh" #include "color_header" #include "header_sounds" #include "speech_j_h" #include "prc_inc_racial" ///////////////////////////////// // CONSTANTS ///////////////////////////////// string sHOLLY_BERRY_WORD = "MISTLETOE"; ///////////////////////////////// // PROTOTYPES ///////////////////////////////// void fnListHelp(object oPC); void fnListCmd(object oPC); void fnListTroops(object oPC); void fnListSettings(object oPC); void fnListTroop(object oPC); void fnSayDM(object oPC,string sSay); void fnSayLeader(object oPC,string sSay); void fnSayTeam(object oPC,string sSay); void fnSaySquad(object oPC,string sSay); void fnTroopsCommand(object oPC,string sCmd); void fnSpecificTroop(object oPC, string sCmd); void fnVoiceChat(object oPC,string sMaster); void fnAnimate(object oPC,string sMaster); void fnVampire(object oPC,string sMaster); void fnDetonateSeed(object oSeed); void fnFireSeedDetonate(object oPC); void fnSettings(object oPC,string sCmd); void fnListLeader(object oPC); void fnDebugThis(object oPC,string sMsg); void fnCountContainers(object oPC); ////////////////////////////////////////////////////////////////[ MAIN ]//////// void main() { string sMsg=GetPCChatMessage(); string sOriginal=sMsg; object oMod=GetModule(); object oPC=GetPCChatSpeaker(); int nVolume=GetPCChatVolume(); int bGameInProgress=GetLocalInt(oMod,"nInProgress"); int nShoutTokens=GetLocalInt(oPC,"nShoutTokens"); int bIsLeader=FALSE; int nShoutGameLevel=GetLocalInt(oMod,"nShoutGameLevel"); string sLetter=GetStringLeft(sMsg,1); string sWord=StringParse(sMsg); string sTeamID=GetLocalString(oPC,"sTeamID"); string sUpperWord=GetStringUpperCase(sWord); string sMsgUpper; string sOrigUpper=GetStringUpperCase(sOriginal); object oOb; if (GetLocalObject(oMod,"oTeamLead"+sTeamID)==oPC) bIsLeader=TRUE; int bWasCommand=FALSE; if (sLetter=="@") { // say to leader fnSayLeader(oPC,sOriginal); bWasCommand=TRUE; } // say to leader else if (sLetter=="[") { // debug oOb=GetItemPossessedBy(oPC,"rts_debug_wand"); if (GetIsObjectValid(oOb)) { // has debug wand SetLocalString(oPC,"sOriginal",sOriginal); SetLocalString(oPC,"sMsg",GetStringRight(sMsg,GetStringLength(sMsg)-1)); ExecuteScript("debug_routine",oPC); } // has debug wand else { // need wand SendMessageToPC(oPC,"You cannot use debug commands without a debug wand. :DEBUGWAND will create a wand. [WARNING: This wand can be used to cheat.] Other players will be notified when you use this."); } // need wand } // debug else if (sLetter=="!") { // say to squad fnSaySquad(oPC,sOriginal); bWasCommand=TRUE; } // say to squad else if (sLetter=="?") { // say to team fnSayTeam(oPC,sOriginal); bWasCommand=TRUE; } // say to team else if (sLetter=="]") { // say to DM and get their attention fnSayDM(oPC,sOriginal); bWasCommand=TRUE; } // say to DM and get their attention else if (sLetter=="'") { // say MUD style sMsg=GetStringRight(sMsg,GetStringLength(sMsg)-1); SetPCChatMessage(sMsg); } // say MUD style else if (sLetter==":") { // system command sMsg=GetStringRight(sMsg,GetStringLength(sMsg)-1); sWord=StringParse(sMsg," "); sUpperWord=GetStringUpperCase(sWord); if (sUpperWord=="DEBUG") { // debug fnDebugThis(oPC,sOriginal); } // debug else if (sUpperWord=="CSKIN") { // Change Skin Color sMsg=StringRemoveParsed(sMsg,sWord," "); SendMessageToPC(oPC,"Set Skin Color:"+sMsg); SetColor(oPC,COLOR_CHANNEL_SKIN,StringToInt(sMsg)); } // Change Skin Color else if (sUpperWord=="CHAIR") { // Change hair color sMsg=StringRemoveParsed(sMsg,sWord," "); SendMessageToPC(oPC,"Set Hair Color:"+sMsg); SetColor(oPC,COLOR_CHANNEL_HAIR,StringToInt(sMsg)); } // change hair color else if (sUpperWord=="CONTAINERS") { // count containers fnCountContainers(oPC); } // count containers else if (sUpperWord=="?"||sUpperWord=="HELP") { // list SendMessageToPC(oPC,":DEBUG "); SendMessageToPC(oPC,":CSKIN #"); SendMessageToPC(oPC,":CHAIR #"); SendMessageToPC(oPC,":CONTAINERS"); SendMessageToPC(oPC,":COLORS"); } // list else if (sUpperWord=="COLORS") { // list colors SendMessageToPC(oPC,"Skin:"+IntToString(GetColor(oPC,COLOR_CHANNEL_SKIN))); SendMessageToPC(oPC,"Hair:"+IntToString(GetColor(oPC,COLOR_CHANNEL_HAIR))); SendMessageToPC(oPC,"Tattoo1:"+IntToString(GetColor(oPC,COLOR_CHANNEL_TATTOO_1))); SendMessageToPC(oPC,"Tattoo2:"+IntToString(GetColor(oPC,COLOR_CHANNEL_TATTOO_2))); } // list colors else if (sUpperWord=="DEBUGWAND") { // create debug wand oOb=GetItemPossessedBy(oPC,"rts_debug_wand"); if (!GetIsObjectValid(oOb)) { // create oOb=CreateItemOnObject("rts_debug_wand",oPC); PrintString("[DEBUG WAND CREATED] by "+GetName(oOb)+" controlled by "+GetPCPlayerName(oOb)); } // create SendMessageToPC(oPC,"Chat [? or [help to get a list of debug commands."); sMsgUpper=GetName(oPC)+" created a debug wand... it is possible to use this to cheat."; sMsgUpper=StringToRGBString(sMsgUpper,"744"); oOb=GetFirstPC(); while(GetIsObjectValid(oOb)) { // notify players if (oOb!=oPC) { // don't tell the PC that created it SendMessageToPC(oOb,sMsgUpper); } // don't tell the PC that created it oOb=GetNextPC(); } // notify players } // create debug wand bWasCommand=TRUE; } // system command else { // other sMsg=StringRemoveParsed(sMsg,sWord," "); sMsgUpper=GetStringUpperCase(sMsg); if (sUpperWord=="LIST") { // list command if (sMsgUpper=="COMMANDS") { // list commands fnListCmd(oPC); } // list commands else if (sMsgUpper=="HELP") { // list help fnListHelp(oPC); } // list help else if (sMsgUpper=="TROOP") { // list troop fnListTroop(oPC); } // list troop else if (sMsgUpper=="TROOPS") { // list troops fnListTroops(oPC); } // list troops else if (sMsgUpper=="SETTINGS") { // list settings fnListSettings(oPC); } // list settings else if (sMsgUpper=="LEADER") { // list leaders fnListLeader(oPC); } // list leaders else { // error SendMessageToPC(oPC,"TRY: list help, list commands, or list leader"); } // error bWasCommand=TRUE; } // list command else if (sUpperWord=="TROOP,") { // single unit command fnSpecificTroop(oPC,GetStringLowerCase(sOriginal)); } // single unit command else if (sUpperWord=="TROOPS,") { // multiple unit command fnTroopsCommand(oPC,GetStringLowerCase(sOriginal)); } // multiple unit command else if (sUpperWord=="ANIM") { // Play animation fnAnimate(oPC,GetStringLowerCase(sOriginal)); bWasCommand=TRUE; } // Play animation else if (sUpperWord=="VOICECHAT") { // Play Voicechat fnVoiceChat(oPC,GetStringLowerCase(sOriginal)); bWasCommand=TRUE; } // Play Voicechat else if (sUpperWord=="VAMPIRE") { // vampire abilities if (GetLocalInt(oPC,"nIsVampire")) { // is vampire fnVampire(oPC,GetStringLowerCase(sOriginal)); } // is vampire bWasCommand=TRUE; } // vampire abilities else if (sUpperWord=="SETTINGS") { // chat and game settings adjustment fnSettings(oPC,GetStringLowerCase(sOriginal)); bWasCommand=TRUE; } // chat and game settings adjustment else if (sUpperWord==sHOLLY_BERRY_WORD) { // fireseed fnFireSeedDetonate(oPC); bWasCommand=TRUE; } // fireseed else if (sOrigUpper=="SUMMON MINOR"||sOrigUpper=="SUMMON MEDIUM"||sOrigUpper=="SUMMON MAJOR") { // leader summon emergency help if (bIsLeader) { // is leader oOb=GetWaypointByTag(sTeamID+"_START"); if (GetArea(oOb)==GetArea(oPC)) { // is in the lair int nN=1; if (sOrigUpper=="SUMMON MEDIUM") nN=2; else if (sOrigUpper=="SUMMON MAJOR") nN=3; SetLocalInt(oPC,"nParm",nN); ExecuteScript("leader_summon",oPC); } // is in the lair else { // not in the lair SendMessageToPC(oPC,"You can only use this ability when in your lair."); } // not in the lair } // is leader else { // not leader SendMessageToPC(oPC,"Only the team leader can use this command when in the lair."); } // not leader bWasCommand=TRUE; } // leader summon emergency help } // other if (bWasCommand) SetPCChatMessage(""); // display nothing else { // adjust volume? // 0 = only leaders and PCs with shout tokens can shout [ Default ] // 1 = Anyone can shout // 2 = only people with shout tokens can shout if (nVolume==TALKVOLUME_SHOUT&&!GetIsDM(oPC)) { // was a shout check rules if (nShoutGameLevel==2&&nShoutTokens<1) { // no shouting without tokens SendMessageToPC(oPC,"Shout Tokens via spell or other method are required to shout. Your volume has been lowered."); SetPCChatVolume(TALKVOLUME_TALK); } // no shouting without tokens else if (nShoutGameLevel==0&&!bIsLeader&&nShoutTokens<1) { // only leaders and people with tokens can shout SendMessageToPC(oPC,"Only Leaders or Players with unused Shout Tokens are permitted to shout. Your volume has been lowered."); SetPCChatVolume(TALKVOLUME_TALK); } // only leaders and people with tokens can shout else { // shouting okay nShoutTokens=nShoutTokens-1; if (nShoutTokens<1) nShoutTokens=0; SetLocalInt(oPC,"nShoutTokens",nShoutTokens); if (nShoutGameLevel==2) SendMessageToPC(oPC,"Shout Tokens Remaining:"+IntToString(nShoutTokens)); else if (nShoutGameLevel==0&&!bIsLeader) SendMessageToPC(oPC,"Shout Tokens Remaining:"+IntToString(nShoutTokens)); } // shouting okay } // was a shout check rules } // adjust volume? } ////////////////////////////////////////////////////////////////[ MAIN ]//////// /////////////////////////////////// // FUNCTIONS /////////////////////////////////// void fnCountContainers(object oPC) { // PURPOSE: containers int nN=0; int nC; object oWP=GetObjectByTag("AREA_DEBUG",nN); object oC; SendMessageToPC(oPC,"Begin Containers capable of being cleaned report==="); while(GetIsObjectValid(oWP)) { // look at containers nC=1; if (GetLocalInt(GetArea(oWP),"nCleanMode")!=5) { // no clean oC=GetNearestObject(OBJECT_TYPE_PLACEABLE,oWP,nC); while(GetIsObjectValid(oC)) { // check placeables if (!GetPlotFlag(oC)&&!GetLocalInt(oC,"bNoClean")&&GetHasInventory(oC)) { // report SendMessageToPC(oPC,"Container '"+GetName(oC)+"' in area '"+GetName(GetArea(oWP))+"'."); } // report nC++; oC=GetNearestObject(OBJECT_TYPE_PLACEABLE,oWP,nC); } // check placeables } // no clean nN++; oWP=GetObjectByTag("AREA_DEBUG",nN); } // look at containers SendMessageToPC(oPC,"End of Container Report==="); } // fnCountContainers void fnSettings(object oPC,string sCmd) { // PURPOSE: To adjust settings for these commands string sMaster=sCmd; string sParse=StringParse(sMaster," "); int nN; sMaster=StringRemoveParsed(sMaster,sParse," "); // strip settings sParse=StringParse(sMaster," "); sMaster=StringRemoveParsed(sMaster,sParse," "); nN=StringToInt(sMaster); if (sParse=="range") { // range if (nN<1||nN>30) nN=30; SetLocalInt(oPC,"nVoiceRange",nN); SendMessageToPC(oPC,"Voice range has been set to "+IntToString(nN)+" meters."); } // range else if (sParse=="number") { // number if (nN<1||nN>40) nN=20; SetLocalInt(oPC,"nVoiceNumber",nN); SendMessageToPC(oPC,"Number of units to respond to voice commands has been set to "+IntToString(nN)+"."); } // number else { // unknown SendMessageToPC(oPC,"That is an unknown settings command '"+sParse+"' try 'list settings' for more help. [You typed '"+sCmd+"']"); } // unknown } // fnSettings() void fnIssueCommand(object oPC,object oCreature,int nCMD,int nOpt=0) { // PURPOSE: Issue the command to the unit string sS; switch(nCMD) { // switch case 1: { // Follow SetLocalInt(oCreature,"nMState",5); SetLocalInt(oCreature,"nSState",0); SetLocalObject(oCreature,"oDestWP",oPC); SetLocalInt(oCreature,"nFollowDist",nOpt); if (GetAbilityScore(oCreature,ABILITY_INTELLIGENCE)>9) AssignCommand(oCreature,SpeakString("Following")); break; } // Follow case 2: { // Recon SetLocalInt(oCreature,"nMState",14); SetLocalInt(oCreature,"nSState",0); SetLocalObject(oCreature,"oDestWP",oPC); SetLocalInt(oCreature,"nFollowDist",nOpt); if (GetAbilityScore(oCreature,ABILITY_INTELLIGENCE)>9) AssignCommand(oCreature,SpeakString("Reconnoitering")); break; } // Recon case 3: { // Guard Lair SetLocalInt(oCreature,"nMState",11); SetLocalInt(oCreature,"nSState",0); if (GetAbilityScore(oCreature,ABILITY_INTELLIGENCE)>9) AssignCommand(oCreature,SpeakString("Guarding Lair")); break; } // Guard Lair case 4: { // Stop SetLocalInt(oCreature,"nMState",7); SetLocalInt(oCreature,"nSState",0); if (GetAbilityScore(oCreature,ABILITY_INTELLIGENCE)>9) AssignCommand(oCreature,SpeakString("Stopped")); break; } // Stop case 5: { // Guard Mana SetLocalInt(oCreature,"nMState",2); SetLocalInt(oCreature,"nSState",0); SetLocalInt(oCreature,"nParm",4); if (GetAbilityScore(oCreature,ABILITY_INTELLIGENCE)>9) AssignCommand(oCreature,SpeakString("Mana Guard")); break; } // Guard Mana case 6: { // Guard Throne SetLocalInt(oCreature,"nMState",2); SetLocalInt(oCreature,"nSState",0); SetLocalInt(oCreature,"nParm",5); if (GetAbilityScore(oCreature,ABILITY_INTELLIGENCE)>9) AssignCommand(oCreature,SpeakString("Throne Guard")); break; } // Guard Throne case 7: { // Guard Here SetLocalInt(oCreature,"nMState",2); SetLocalInt(oCreature,"nSState",0); SetLocalInt(oCreature,"nParm",0); if (GetAbilityScore(oCreature,ABILITY_INTELLIGENCE)>9) AssignCommand(oCreature,SpeakString("Guarding")); break; } // Guard Here case 8: { // Raid SetLocalInt(oCreature,"nMState",17); SetLocalInt(oCreature,"nSState",0); if (nOpt==1) SetLocalString(oCreature,"sTeamToRaid","DWF"); else if (nOpt==2) SetLocalString(oCreature,"sTeamToRaid","UNC"); else if (nOpt==3) SetLocalString(oCreature,"sTeamToRaid","UND"); else if (nOpt==4) SetLocalString(oCreature,"sTeamToRaid","SPID"); if (GetAbilityScore(oCreature,ABILITY_INTELLIGENCE)>9) AssignCommand(oCreature,SpeakString("Raiding")); SetLocalInt(oCreature,"nParm",1); break; } // Raid case 9: { // control point capture SetLocalInt(oCreature,"nMState",18); SetLocalInt(oCreature,"nSState",0); if (GetAbilityScore(oCreature,ABILITY_INTELLIGENCE)>9) AssignCommand(oCreature,SpeakString("Capturing Control Points")); break; } // control point capture case 10: { // Roam SetLocalInt(oCreature,"nMState",8); SetLocalInt(oCreature,"nSState",0); if (GetAbilityScore(oCreature,ABILITY_INTELLIGENCE)>9) AssignCommand(oCreature,SpeakString("Roaming")); break; } // Roam case 11: { // power reservoir SetLocalInt(oCreature,"nMState",23); SetLocalInt(oCreature,"nSState",0); if (GetAbilityScore(oCreature,ABILITY_INTELLIGENCE)>9) AssignCommand(oCreature,SpeakString("Power Reservoir Recovery Duty")); break; } // power reservoir case 12: { // tactics if (nOpt==9) { // disable DeleteLocalInt(oCreature,"bCOMBAT_AI_ON"); DeleteLocalString(oCreature,"sCOMBAT_AI_TYPE"); } // disable else { // enable sS="melee"; if (nOpt==2) sS="ranged"; else if (nOpt==3) sS="stealth"; else if (nOpt==4) sS="flee"; else if (nOpt==5) sS="hold"; else if (nOpt==6) sS="support"; else if (nOpt==7) sS="summon"; else if (nOpt==8) sS="caster"; SetLocalInt(oCreature,"bCOMBAT_AI_ON",TRUE); SetLocalString(oCreature,"sCOMBAT_AI_TYPE",sS); } // enable break; } // tactics default: break; } // switch } // fnIssueCommand() void fnTroopsCommand(object oPC,string sCmd) { // PURPOSE: Commands issued to all units within range int nRange=GetLocalInt(oPC,"nVoiceRange"); int nNumber=GetLocalInt(oPC,"nVoiceNumber"); float fRange; int nC=0; float fF; int nN; object oOb; string sID=GetLocalString(oPC,"sTeamID"); string sVocalized; string sDo; string sParse; string sHeader; int bNoSubLeader; object oLeader=GetLocalObject(GetModule(),"oTeamLead"+sID); fRange=IntToFloat(nRange); if (fRange<1.0||fRange>30.0) fRange=30.0; if (nNumber<1||nNumber>40) nNumber=20; if (sID=="DWF") sHeader="Friends, "; else if (sID=="SPID") sHeader="Minions, "; else if (sID=="UNC") sHeader="Grunts, "; else if (sID=="UND") sHeader="Slaves, "; sDo=GetStringRight(sCmd,GetStringLength(sCmd)-7); //SendMessageToPC(oPC,sDo); while(GetStringLeft(sDo,1)==" ") { sDo=GetStringRight(sDo,GetStringLength(sDo)-1); } //SendMessageToPC(oPC,sDo); sParse=fnParse(sDo," "); //SendMessageToPC(oPC,"PARSE:"+sParse); //SendMessageToPC(oPC,sDo); sDo=fnRemoveParsed(sDo,sParse," "); //SendMessageToPC(oPC,"FINAL sDo:"+sDo); //SendMessageToPC(oPC,"nNumber:"+IntToString(nNumber)+" fRange"+FloatToString(fRange)); nN=1; oOb=GetNearestCreature(CREATURE_TYPE_IS_ALIVE,TRUE,oPC,nN,CREATURE_TYPE_PLAYER_CHAR,PLAYER_CHAR_NOT_PC); fF=GetDistanceBetween(oPC,oOb); while(oOb!=OBJECT_INVALID&&nC2) SetPCChatMessage(sHeader+sVocalized); else { SetPCChatMessage(); SendMessageToPC(oPC,"Nothing to do."); } } // fnTroopsCommand() void fnSpecificTroop(object oPC, string sCmd) { // PURPOSE: Commands issued to specific unit type within range int nRange=GetLocalInt(oPC,"nVoiceRange"); int nNumber=GetLocalInt(oPC,"nVoiceNumber"); float fRange; int nC=0; float fF; int nN; object oOb; string sID=GetLocalString(oPC,"sTeamID"); string sVocalized; string sDo; string sParse; string sHeader; string sName; int bNoSubLeader; object oLeader=GetLocalObject(GetModule(),"oTeamLead"+sID); fRange=IntToFloat(nRange); if (fRange<1.0||fRange>30.0) fRange=30.0; if (nNumber<1||nNumber>40) nNumber=20; if (sID=="DWF") sHeader="Friends, "; else if (sID=="SPID") sHeader="Minions, "; else if (sID=="UNC") sHeader="Grunts, "; else if (sID=="UND") sHeader="Slaves, "; sDo=GetStringRight(sCmd,GetStringLength(sCmd)-6); //SendMessageToPC(oPC,sDo); while(GetStringLeft(sDo,1)==" ") { sDo=GetStringRight(sDo,GetStringLength(sDo)-1); } //SendMessageToPC(oPC,sDo); sParse=fnParse(sDo,":"); //SendMessageToPC(oPC,"PARSE:"+sParse); //SendMessageToPC(oPC,sDo); sDo=fnRemoveParsed(sDo,sParse,":"); sName=sParse; while(GetStringLeft(sDo,1)==" ") { sDo=GetStringRight(sDo,GetStringLength(sDo)-1); } sParse=fnParse(sDo," "); sDo=fnRemoveParsed(sDo,sParse," "); //SendMessageToPC(oPC,"FINAL sDo:"+sDo); //SendMessageToPC(oPC,"nNumber:"+IntToString(nNumber)+" fRange"+FloatToString(fRange)); nN=1; oOb=GetNearestCreature(CREATURE_TYPE_IS_ALIVE,TRUE,oPC,nN,CREATURE_TYPE_PLAYER_CHAR,PLAYER_CHAR_NOT_PC); fF=GetDistanceBetween(oPC,oOb); while(oOb!=OBJECT_INVALID&&nC2) SetPCChatMessage(sHeader+sVocalized); else { SetPCChatMessage(); SendMessageToPC(oPC,"Nothing to do.");} } // fnSpecificTroop() void fnSay(object oPC,string sSay) { // PURPOSE: say something outloud if you are using the DM channel string sWords=GetStringRight(sSay,GetStringLength(sSay)-1); AssignCommand(oPC,SpeakString(sWords)); } // fnSay() void fnSayDM(object oPC,string sSay) { // PURPOSE: Send message to DMs object oDM; string sWords=GetStringRight(sSay,GetStringLength(sSay)-1); sWords=ColorRGBString(sWords,4,4,6); sWords=ColorRGBString("["+GetName(oPC)+"]: ",4,4,4)+sWords; oDM=GetFirstPC(); while(oDM!=OBJECT_INVALID) { // DM if (GetIsDM(oDM)) { SendMessageToPC(oDM,sWords); AssignCommand(oDM,fnSoundAlert("as_an_catmeow1")); ChatJ_AddToJournal(oDM,sWords); } oDM=GetNextPC(); } // DM } // fnSayDM() void fnSayLeader(object oPC,string sSay) { // PURPOSE: send message to team leader object oMod=GetModule(); string sID=GetLocalString(oPC,"sTeamID"); object oLeader=GetLocalObject(oMod,"oTeamLead"+sID); string sWords=GetStringRight(sSay,GetStringLength(sSay)-1); sWords=ColorRGBString(sWords,6,4,4); sWords=ColorRGBString("["+GetName(oPC)+"]: ",4,4,4)+sWords; if (oLeader!=OBJECT_INVALID) { SendMessageToPC(oLeader,sWords); AssignCommand(oLeader,fnSoundAlert("as_an_gull1")); ChatJ_AddToJournal(oLeader,sWords); } } // fnSayLeader() void fnSayTeam(object oPC,string sSay) { // PURPOSE: send message to team members object oMod=GetModule(); string sID=GetLocalString(oPC,"sTeamID"); string sWords=GetStringRight(sSay,GetStringLength(sSay)-1); object oOb; sWords=ColorRGBString(sWords,6,6,6); sWords=ColorRGBString("["+GetName(oPC)+"]: ",4,4,4)+sWords; oOb=GetFirstPC(); while(oOb!=OBJECT_INVALID) { // look for team members if (GetLocalString(oOb,"sTeamID")==sID) { SendMessageToPC(oOb,sWords); ChatJ_AddToJournal(oOb,sWords); } oOb=GetNextPC(); } // look for team members } // fnSayTeam() void fnSaySquad(object oPC,string sSay) { // PURPOSE: Send a message to squad members object oMod=GetModule(); string sID=GetLocalString(oPC,"sTeamID"); string sWords=GetStringRight(sSay,GetStringLength(sSay)-1); object oOb; int nSQN=GetLocalInt(oPC,"nSquadNum"); sWords=ColorRGBString(sWords,2,6,2); sWords=ColorRGBString("["+GetName(oPC)+"]: ",4,4,4)+sWords; oOb=GetFirstPC(); while(oOb!=OBJECT_INVALID) { // look for team members if (GetLocalString(oOb,"sTeamID")==sID&&GetLocalInt(oOb,"nSquadNum")==nSQN) { AssignCommand(oOb,fnSoundAlert("as_an_woodpeckr1")); SendMessageToPC(oOb,sWords); ChatJ_AddToJournal(oOb,sWords); } oOb=GetNextPC(); } // look for team members } // fnSaySquad() void fnListHelp(object oPC) { // PURPOSE: display help SendMessageToPC(oPC,"+------------------------+"); SendMessageToPC(oPC,"| Spoken Commands Help |"); SendMessageToPC(oPC,"+------------------------+"); SendMessageToPC(oPC,"list help = this help"); SendMessageToPC(oPC,"' = will output text even if spoken into the DM channel."); SendMessageToPC(oPC,"] = will send message to DM."); SendMessageToPC(oPC,"@ = will send message to the team leader."); SendMessageToPC(oPC,"! = will send message to the squad you are assigned to."); SendMessageToPC(oPC,"? = will send message to all your team members."); SendMessageToPC(oPC,": = will write a debug message to log file."); SendMessageToPC(oPC," Types are: placeable, transition, creature, and other."); SendMessageToPC(oPC,"+------------------------+"); SendMessageToPC(oPC,"| Roleplaying Commands |"); SendMessageToPC(oPC,"+------------------------+"); SendMessageToPC(oPC,"VOICECHAT # = will play that voice chat # for your character."); SendMessageToPC(oPC,"ANIM #/# = will cause PC to play animation # for # seconds."); SendMessageToPC(oPC,"+------------------------+"); SendMessageToPC(oPC,"| Vampire Commands |"); SendMessageToPC(oPC,"+------------------------+"); SendMessageToPC(oPC,"VAMPIRE command = If the PC is a vampire they can access some of"); SendMessageToPC(oPC," COMMAND The vampire commands using spoken commands."); SendMessageToPC(oPC," level = How much blood and vampire XP do I have?"); SendMessageToPC(oPC," wolf = costs 40 blood to shape change into a wolf"); SendMessageToPC(oPC," dire = costs 60 blood to shape change into a dire wolf"); SendMessageToPC(oPC," bury = bury yourself in the ground to protect from sunlight"); SendMessageToPC(oPC," children = costs 20 blood and summons children of the night"); SendMessageToPC(oPC," heal5 = costs 1 blood and heals the PC 5 points"); SendMessageToPC(oPC," heal25 = costs 5 blood and heals the PC 25 points"); SendMessageToPC(oPC," coffin = places your coffin here. Can only be used once!"); SendMessageToPC(oPC," stun = attempts to stun nearest neutral or enemy target"); SendMessageToPC(oPC," feed = attempts to feed upon nearest neutral or enemy target"); SendMessageToPC(oPC,"============================="); SendMessageToPC(oPC,"list commands = list of troop commands"); SendMessageToPC(oPC,"list leader = list of team leader specific commands"); SendMessageToPC(oPC,"============================="); } // fnListHelp() void fnListCmd(object oPC) { // PURPOSE: To list troop related commands SendMessageToPC(oPC,"+------------------------+"); SendMessageToPC(oPC,"| Spoken Commands Help |"); SendMessageToPC(oPC,"+------------------------+"); SendMessageToPC(oPC,"list help = list other types of commands"); SendMessageToPC(oPC,"--------------------------"); SendMessageToPC(oPC,"Troops, = issue command to troops within range"); SendMessageToPC(oPC,"Troop, : = issue command to specific troop in range"); SendMessageToPC(oPC,"Settings = set the settings for spoken commands"); SendMessageToPC(oPC,"More info on the above can be had by typing. list troops, list troop, or list settings."); SendMessageToPC(oPC,"============================="); } // fnListCmd() void fnListTroops(object oPC) { // PURPOSE: Troops commands SendMessageToPC(oPC,"[==== Troops, ====]"); SendMessageToPC(oPC,"COMMANDS:"); SendMessageToPC(oPC," Follow = follow me distance 3 or 7"); SendMessageToPC(oPC," Recon = recon in front of me 3 or 7"); SendMessageToPC(oPC," Guard Lair = Go into guard lair mode"); SendMessageToPC(oPC," Stop = abort any existing commands"); SendMessageToPC(oPC," Guard Mana = Guard Mana Vault"); SendMessageToPC(oPC," Guard Throne = Guard Throne Room"); SendMessageToPC(oPC," Guard Here = Guard where you stand"); SendMessageToPC(oPC," Raid = Go on an attack raid against team"); SendMessageToPC(oPC," Capture Control = Capture control points"); SendMessageToPC(oPC," Roam = Roam mode"); SendMessageToPC(oPC," Power Reservoir = puts them on power reservoir recovery"); SendMessageToPC(oPC," Run = tell the unit to run"); SendMessageToPC(oPC," Walk = tell the unit to walk"); SendMessageToPC(oPC," Tactics = will set the troops to the specific combat"); SendMessageToPC(oPC," AI tactic. TACTICS ARE: Melee, Ranged, Stealth,"); SendMessageToPC(oPC," Flee, Hold, Support, Summon, Caster, and Bioware."); } // fnListTroops() void fnListSettings(object oPC) { // PURPOSE: To list settings SendMessageToPC(oPC,"[==== Settings ====]"); SendMessageToPC(oPC,"COMMANDS:"); SendMessageToPC(oPC," range <1-30> = how many meters people should listen to you"); SendMessageToPC(oPC," number <1-40>= how many units maximum should respond to you"); SendMessageToPC(oPC,"[==== Current Settings ====]"); SendMessageToPC(oPC,"Range: "+IntToString(GetLocalInt(oPC,"nVoiceRange"))); SendMessageToPC(oPC,"Number: "+IntToString(GetLocalInt(oPC,"nVoiceNumber"))); } // fnListSettings() void fnListTroop(object oPC) { // PURPOSE: To list individual troop commands SendMessageToPC(oPC,"[==== Troop, : ====]"); SendMessageToPC(oPC,"COMMANDS:"); SendMessageToPC(oPC," Follow = follow me distance 3 or 7"); SendMessageToPC(oPC," Recon = recon in front of me 3 or 7"); SendMessageToPC(oPC," Guard Lair = Go into guard lair mode"); SendMessageToPC(oPC," Stop = abort any existing commands"); SendMessageToPC(oPC," Guard Mana = Guard Mana Vault"); SendMessageToPC(oPC," Guard Throne = Guard Throne Room"); SendMessageToPC(oPC," Guard Here = Guard where you stand"); SendMessageToPC(oPC," Raid = Go on an attack raid against team"); SendMessageToPC(oPC," Capture Control = Capture control points"); SendMessageToPC(oPC," Roam = Roam mode"); SendMessageToPC(oPC," Power Reservoir = puts them on power reservoir recovery"); SendMessageToPC(oPC," Run = tell the unit to run"); SendMessageToPC(oPC," Walk = tell the unit to walk"); SendMessageToPC(oPC," Tactics = will set the troops to the specific combat"); SendMessageToPC(oPC," AI tactic. TACTICS ARE: Melee, Ranged, Stealth,"); SendMessageToPC(oPC," Flee, Hold, Support, Summon, Caster, and Bioware."); } // fnListTroop() void fnListLeader(object oPC) { // PURPOSE: To list leader specific commands SendMessageToPC(oPC,"[==== List of Commands only useable by Leader ====]"); SendMessageToPC(oPC,"MESSAGE = Dispatch a messenger with the message to specified team"); SendMessageToPC(oPC," Teams: dwarves, unclean, undead, and spiders"); SendMessageToPC(oPC,"CLEAN = Will clean clutter in lair instantly [costs 50 mana]"); SendMessageToPC(oPC,"SUMMON = summons units to the leader in the lair in an emergency. Can only be use in lair."); SendMessageToPC(oPC," Degree: Minor [costs 100 mana], Medium [costs 200 mana], Major [costs 300 mana]"); SendMessageToPC(oPC," This will summon 2 Units that follow the leader, and 8 Units on Guard Lair. All of these"); SendMessageToPC(oPC," Units will despawn in 4 minutes. These are emergency units. They are short lived but powerful."); } // fnListLeader() void fnVoiceChat(object oPC,string sMaster) { // PURPOSE: play voice chat # string sChat=GetStringRight(sMaster,GetStringLength(sMaster)-10); int nVC=StringToInt(sChat); PlayVoiceChat(nVC,oPC); } // fnVoiceChat() void fnAnimate(object oPC,string sMaster) { // PURPOSE: Give PCs access to all animations for role playing purposes string sFull=sMaster; string sParse; int nAnim; int nDur; sFull=GetStringRight(sFull,GetStringLength(sFull)-5); sParse=fnParse(sFull,"/"); sFull=fnRemoveParsed(sFull,sParse,"/"); nAnim=StringToInt(sParse); nDur=StringToInt(sFull); AssignCommand(oPC,ActionPlayAnimation(nAnim,1.0,IntToFloat(nDur))); } // fnAnimate() void fnVampire(object oPC,string sMaster) { // PURPOSE: to handle spoken vampire commands string sFull=sMaster; int nN; object oOb; object oNeutral; object oEnemy; int nRace; object oC; int nBlood=GetLocalInt(oPC,"nBloodPool"); string sS; int nXP=GetLocalInt(oPC,"nVampireXP"); sFull=GetStringRight(sFull,GetStringLength(sFull)-8); if (sFull=="level") { // provide level information SendMessageToPC(oPC," VAMPIRE XP:"+IntToString(nXP)+" BLOOD:"+IntToString(nBlood)); } // provide level information else if (sFull=="wolf") { // wolf shape if (nBlood>39) { // enough blood ExecuteScript("vamp_act_wolf",oPC); } // enough blood else { // not enough blood SendMessageToPC(oPC,"You do not have enough blood to use that power. You must feed!"); } // not enough blood } // wolf shape else if (sFull=="dire") { // dire wolf shape if (nBlood>59) { // enough blood ExecuteScript("vamp_act_dwolf",oPC); } // enough blood else { // not enough blood SendMessageToPC(oPC,"You do not have enough blood to use that power. You must feed!"); } // not enough blood } // dire wolf shape else if (sFull=="bury") { // bury in ground ExecuteScript("vamp_act_bury",oPC); } // bury in ground else if (sFull=="children") { // children of the night if (nBlood>19) { // enough blood ExecuteScript("vamp_act_summon",oPC); } // enough blood else { // not enough blood SendMessageToPC(oPC,"You do not have enough blood to use that power. You must feed!"); } // not enough blood } // children of the night else if (sFull=="heal5") { // heal 5 points if (nBlood>0) { // enough blood ExecuteScript("vamp_act_heal5",oPC); } // enough blood else { // not enough blood SendMessageToPC(oPC,"You do not have enough blood to use that power. You must feed!"); } // not enough blood } // heal 5 points else if (sFull=="heal25") { // heal 25 points if (nBlood>4) { // enough blood ExecuteScript("vamp_act_heal25",oPC); } // enough blood else { // not enough blood SendMessageToPC(oPC,"You do not have enough blood to use that power. You must feed!"); } // not enough blood } // heal 25 points else if (sFull=="coffin") { // place coffin if (GetLocalInt(oPC,"nCoffinPlaced")==FALSE) { // place coffin ExecuteScript("vamp_place_coffi",oPC); } // place coffin else { // already placed SendMessageToPC(oPC,"You already placed the coffin and are only permitted to do so once."); } // already placed } // place coffin else if (sFull=="stun") { // stun nearest neutral or enemy nN=1; oOb=OBJECT_INVALID; oNeutral=GetNearestCreature(CREATURE_TYPE_IS_ALIVE,TRUE,oPC,nN,CREATURE_TYPE_REPUTATION,REPUTATION_TYPE_NEUTRAL,CREATURE_TYPE_PERCEPTION,PERCEPTION_SEEN); while(oNeutral!=OBJECT_INVALID&&oOb==OBJECT_INVALID) { // check all nearby neutrals if (GetCreatureSize(oNeutral)<=GetCreatureSize(oPC)) oOb=oNeutral; nN++; oNeutral=GetNearestCreature(CREATURE_TYPE_IS_ALIVE,TRUE,oPC,nN,CREATURE_TYPE_REPUTATION,REPUTATION_TYPE_NEUTRAL,CREATURE_TYPE_PERCEPTION,PERCEPTION_SEEN); } // check all nearby neutrals nN++; oEnemy=GetNearestCreature(CREATURE_TYPE_IS_ALIVE,TRUE,oPC,nN,CREATURE_TYPE_REPUTATION,REPUTATION_TYPE_ENEMY,CREATURE_TYPE_PERCEPTION,PERCEPTION_SEEN); while(oEnemy!=OBJECT_INVALID) { // check all nearby neutrals oC=OBJECT_INVALID; if (GetCreatureSize(oEnemy)<=GetCreatureSize(oPC)) oC=oEnemy; if (oC!=OBJECT_INVALID) { // possible target if (oOb==OBJECT_INVALID||GetDistanceBetween(oOb,oPC)>GetDistanceBetween(oC,oPC)) oOb=oC; } // possible target nN++; oEnemy=GetNearestCreature(CREATURE_TYPE_IS_ALIVE,TRUE,oPC,nN,CREATURE_TYPE_REPUTATION,REPUTATION_TYPE_ENEMY,CREATURE_TYPE_PERCEPTION,PERCEPTION_SEEN); } // check all nearby neutrals if (oOb!=OBJECT_INVALID) { // target found SetLocalObject(oPC,"oTarget",oOb); ExecuteScript("vamp_act_stun",oPC); } // target found else { // no good targets SendMessageToPC(oPC,"No suitable neutral or enemy targets are nearby."); } // no good targets } // stun nearest neutral or enemy else if (sFull=="feed") { // feed upon nearby enemy or neutral nN=1; oOb=OBJECT_INVALID; oNeutral=GetNearestCreature(CREATURE_TYPE_IS_ALIVE,TRUE,oPC,nN,CREATURE_TYPE_REPUTATION,REPUTATION_TYPE_NEUTRAL,CREATURE_TYPE_PERCEPTION,PERCEPTION_SEEN); while(oNeutral!=OBJECT_INVALID&&oOb==OBJECT_INVALID) { // check all nearby neutrals nRace=MyPRCGetRacialType(oNeutral); if (GetIsPC(oNeutral)&&GetLocalInt(oNeutral,"nIsVampire")==FALSE) oOb=oNeutral; else if (nRace==RACIAL_TYPE_DWARF||nRace==RACIAL_TYPE_GNOME||nRace==RACIAL_TYPE_HALFLING) oOb=oNeutral; else if (nRace==RACIAL_TYPE_GIANT||nRace==RACIAL_TYPE_HALFELF||nRace==RACIAL_TYPE_HALFORC) oOb=oNeutral; else if (nRace==RACIAL_TYPE_HUMAN||nRace==RACIAL_TYPE_HUMANOID_GOBLINOID) oOb=oNeutral; else if (nRace==RACIAL_TYPE_HUMANOID_ORC||nRace==RACIAL_TYPE_FEY||nRace==RACIAL_TYPE_ELF) oOb=oNeutral; nN++; oNeutral=GetNearestCreature(CREATURE_TYPE_IS_ALIVE,TRUE,oPC,nN,CREATURE_TYPE_REPUTATION,REPUTATION_TYPE_NEUTRAL,CREATURE_TYPE_PERCEPTION,PERCEPTION_SEEN); } // check all nearby neutrals nN++; oEnemy=GetNearestCreature(CREATURE_TYPE_IS_ALIVE,TRUE,oPC,nN,CREATURE_TYPE_REPUTATION,REPUTATION_TYPE_ENEMY,CREATURE_TYPE_PERCEPTION,PERCEPTION_SEEN); while(oEnemy!=OBJECT_INVALID) { // check all nearby neutrals nRace=MyPRCGetRacialType(oEnemy); oC=OBJECT_INVALID; if (GetIsPC(oNeutral)&&GetLocalInt(oNeutral,"nIsVampire")==FALSE) oC=oEnemy; else if (nRace==RACIAL_TYPE_DWARF||nRace==RACIAL_TYPE_GNOME||nRace==RACIAL_TYPE_HALFLING) oC=oEnemy; else if (nRace==RACIAL_TYPE_GIANT||nRace==RACIAL_TYPE_HALFELF||nRace==RACIAL_TYPE_HALFORC) oC=oEnemy; else if (nRace==RACIAL_TYPE_HUMAN||nRace==RACIAL_TYPE_HUMANOID_GOBLINOID) oC=oEnemy; else if (nRace==RACIAL_TYPE_HUMANOID_ORC||nRace==RACIAL_TYPE_FEY||nRace==RACIAL_TYPE_ELF) oC=oEnemy; if (oC!=OBJECT_INVALID) { // possible target if (oOb==OBJECT_INVALID||GetDistanceBetween(oOb,oPC)>GetDistanceBetween(oC,oPC)) oOb=oC; } // possible target nN++; oEnemy=GetNearestCreature(CREATURE_TYPE_IS_ALIVE,TRUE,oPC,nN,CREATURE_TYPE_REPUTATION,REPUTATION_TYPE_ENEMY,CREATURE_TYPE_PERCEPTION,PERCEPTION_SEEN); } // check all nearby neutrals if (oOb!=OBJECT_INVALID) { // target found SetLocalObject(oPC,"oTarget",oOb); ExecuteScript("vamp_act_drink",oPC); } // target found else { // no good targets SendMessageToPC(oPC,"No suitable neutral or enemy targets are nearby."); } // no good targets } // feed upon nearby enemy or neutral } // fnVampire() void fnDetonateSeed(object oSeed) { // PURPOSE: This holly berry bomb must now explode object oPC=GetLocalObject(oSeed,"oOwner"); int nLevel=GetLocalInt(oSeed,"nLevel"); location lLoc=GetLocation(oSeed); int nN; int nDmg; effect eE; object oOb; int nEL=nLevel; int nRoll; int nDC; if (nEL>20) nEL=20; DestroyObject(oSeed); nDC=10+nLevel; eE=EffectVisualEffect(VFX_FNF_FIREBALL); ApplyEffectAtLocation(DURATION_TYPE_INSTANT,eE,lLoc); nN=1; oOb=GetNearestCreatureToLocation(CREATURE_TYPE_IS_ALIVE,TRUE,lLoc,nN); while(oOb!=OBJECT_INVALID&&GetDistanceBetweenLocations(lLoc,GetLocation(oOb))<=5.0) { // in range nRoll=d20()+GetReflexSavingThrow(oOb); if (nRoll>=nDC) { // saved nDmg=d8(nEL); nDmg=nDmg/2; eE=EffectDamage(nDmg,DAMAGE_TYPE_FIRE); AssignCommand(oPC,ApplyEffectToObject(DURATION_TYPE_INSTANT,eE,oOb)); nDmg=nEL/2; eE=EffectDamage(nDmg,DAMAGE_TYPE_BLUDGEONING); AssignCommand(oPC,ApplyEffectToObject(DURATION_TYPE_INSTANT,eE,oOb)); } // saved else { // no-save nDmg=d8(nEL); eE=EffectDamage(nDmg,DAMAGE_TYPE_FIRE); AssignCommand(oPC,ApplyEffectToObject(DURATION_TYPE_INSTANT,eE,oOb)); eE=EffectDamage(nEL,DAMAGE_TYPE_BLUDGEONING); AssignCommand(oPC,ApplyEffectToObject(DURATION_TYPE_INSTANT,eE,oOb)); } // no-save nN++; oOb=GetNearestCreatureToLocation(CREATURE_TYPE_IS_ALIVE,TRUE,lLoc,nN); } // in range } // fnDetonateSeed() void fnFireSeedDetonate(object oPC) { // PURPOSE: Detonate any placed holly berry bombs int nN; object oHB; nN=1; oHB=GetNearestObjectByTag("wazoo_pl_hbb",oPC,nN); while(oHB!=OBJECT_INVALID&&GetDistanceBetween(oPC,oHB)<=90.0) { // holly berries in range if (GetLocalObject(oHB,"oOwner")==oPC) DelayCommand(0.2,fnDetonateSeed(oHB)); nN++; oHB=GetNearestObjectByTag("wazoo_pl_hbb",oPC,nN); } // holly berries in range } // fnFireSeedDetonate() void fnHandleCommands(object oMe,object oPC,string sCmd) { // PURPOSE: Do the parsing and handle the commands string sMaster=GetStringLowerCase(sCmd); string sParse; if (sMaster=="list help") fnListHelp(oPC); else if (sMaster=="list") SendMessageToPC(oPC,"TRY: list help, or list commands"); else if (sMaster=="list commands") fnListCmd(oPC); else if (GetStringLeft(sMaster,1)=="'") fnSay(oPC,sCmd); else if (GetStringLeft(sMaster,7)=="troops,") fnTroopsCommand(oPC,sMaster); else if (GetStringLeft(sMaster,6)=="troop,") fnSpecificTroop(oPC,sMaster); else if (GetStringLeft(sMaster,8)=="settings") fnSettings(oPC,sMaster); else if (sMaster=="list troops") fnListTroops(oPC); else if (sMaster=="list troop") fnListTroop(oPC); else if (sMaster=="list settings") fnListSettings(oPC); else if (GetStringLeft(sMaster,1)=="]") fnSayDM(oPC,sCmd); else if (GetStringLeft(sMaster,1)=="@") fnSayLeader(oPC,sCmd); else if (GetStringLeft(sMaster,1)=="?") fnSayTeam(oPC,sCmd); else if (GetStringLeft(sMaster,1)=="!") fnSaySquad(oPC,sCmd); else if (GetStringLeft(sMaster,10)=="voicechat ") fnVoiceChat(oPC,sMaster); else if (GetStringLeft(sMaster,5)=="anim ") fnAnimate(oPC,sMaster); else if (GetStringLeft(sMaster,8)=="vampire "&&GetLocalInt(oPC,"nIsVampire")==TRUE) fnVampire(oPC,sMaster); else if (sMaster==sHOLLY_BERRY_WORD) fnFireSeedDetonate(oPC); } // fnHandleCommands() void fnDebugThis(object oPC,string sMsg) { // PURPOSE: Save a debug Message to the Log PrintString("[]-[]-[]-BEGIN-[]-[]"); PrintString(" "+sMsg); PrintString("--------------------"); string sS; object oOb; int nN; float fF; vector vVec; sS=" GAME TIME: "+IntToString(GetTimeHour())+" Hour, "+IntToString(GetCalendarDay())+" Day, "; sS=sS+IntToString(GetCalendarMonth())+" Month, "+IntToString(GetCalendarYear())+" Version:"+GetLocalString(GetModule(),"sVersion"); PrintString(sS); sS=" LOCATION: "+GetName(GetArea(oPC))+" Tag("+GetTag(GetArea(oPC))+") Coordinates: "; vVec=GetPosition(oPC); sS=sS+FloatToString(vVec.x)+" X, "+FloatToString(vVec.y)+" Y, "+FloatToString(vVec.z)+" Z FACING:"; sS=sS+FloatToString(GetFacing(oPC)); PrintString(sS); sS=" TeamID:"+GetLocalString(oPC,"sTeamID")+" PC Name:"+GetName(oPC)+" Level:"; sS=sS+IntToString(GetLevelByPosition(1,oPC)+GetLevelByPosition(2,oPC)+GetLevelByPosition(3,oPC)); PrintString(sS); PrintString("--------------------"); sS=" ASSOCIATES:"; oOb=GetAssociate(ASSOCIATE_TYPE_FAMILIAR,oPC,1); if (GetIsObjectValid(oOb)) sS=sS+" Familiar("+GetName(oOb)+" Tag:"+GetTag(oOb)+" RR:"+GetResRef(oOb)+", "; oOb=GetAssociate(ASSOCIATE_TYPE_ANIMALCOMPANION,oPC,1); if (GetIsObjectValid(oOb)) sS=sS+" Animal Companion("+GetName(oOb)+" Tag:"+GetTag(oOb)+" RR:"+GetResRef(oOb)+", "; nN=1; oOb=GetAssociate(ASSOCIATE_TYPE_DOMINATED,oPC,nN); while(GetIsObjectValid(oOb)) { // Dominated if (GetIsObjectValid(oOb)) sS=sS+" Dominated("+GetName(oOb)+" Tag:"+GetTag(oOb)+" RR:"+GetResRef(oOb)+", "; nN++; oOb=GetAssociate(ASSOCIATE_TYPE_DOMINATED,oPC,nN); } // Dominated nN=1; oOb=GetAssociate(ASSOCIATE_TYPE_HENCHMAN,oPC,nN); while(GetIsObjectValid(oOb)) { // Henchmen if (GetIsObjectValid(oOb)) sS=sS+" Henchman("+GetName(oOb)+" Tag:"+GetTag(oOb)+" RR:"+GetResRef(oOb)+", "; nN++; oOb=GetAssociate(ASSOCIATE_TYPE_HENCHMAN,oPC,nN); } // Henchmen nN=1; oOb=GetAssociate(ASSOCIATE_TYPE_SUMMONED,oPC,nN); while(GetIsObjectValid(oOb)) { // Summoned if (GetIsObjectValid(oOb)) sS=sS+" Summoned("+GetName(oOb)+" Tag:"+GetTag(oOb)+" RR:"+GetResRef(oOb)+", "; nN++; oOb=GetAssociate(ASSOCIATE_TYPE_SUMMONED,oPC,nN); } // Summoned sS=sS+" END."; PrintString(sS); sS=" NEAREST NON-ASSOCIATE:"; nN=1; oOb=GetNearestCreature(CREATURE_TYPE_IS_ALIVE,TRUE,oPC,nN); while(GetIsObjectValid(oOb)) { // find nearest non associate if (GetAssociateType(oOb)==ASSOCIATE_TYPE_NONE) { // found sS=sS+" Name:"+GetName(oOb)+" Tag:"+GetTag(oOb)+" RR:"+GetResRef(oOb)+" Distance:"+FloatToString(GetDistanceBetween(oPC,oOb)); oOb=OBJECT_INVALID; } // found else { // continue nN++; oOb=GetNearestCreature(CREATURE_TYPE_IS_ALIVE,TRUE,oPC,nN); } // continue } // find nearest non associate PrintString(sS); sS=" NEAREST ENEMY:"; oOb=GetNearestCreature(CREATURE_TYPE_IS_ALIVE,TRUE,oPC,1,CREATURE_TYPE_REPUTATION,REPUTATION_TYPE_ENEMY); if (GetIsObjectValid(oOb)) sS=sS+" Name:"+GetName(oOb)+" Tag:"+GetTag(oOb)+" RR:"+GetResRef(oOb)+" Distance:"+FloatToString(GetDistanceBetween(oPC,oOb)); PrintString(sS); sS=" NEAREST NEUTRAL:"; oOb=GetNearestCreature(CREATURE_TYPE_IS_ALIVE,TRUE,oPC,1,CREATURE_TYPE_REPUTATION,REPUTATION_TYPE_NEUTRAL); if (GetIsObjectValid(oOb)) sS=sS+" Name:"+GetName(oOb)+" Tag:"+GetTag(oOb)+" RR:"+GetResRef(oOb)+" Distance:"+FloatToString(GetDistanceBetween(oPC,oOb)); PrintString(sS); sS=" NEAREST WAYPOINT:"; oOb=GetNearestObject(OBJECT_TYPE_WAYPOINT,oPC,1); if (GetIsObjectValid(oOb)) sS=sS+" Name:"+GetName(oOb)+" Tag:"+GetTag(oOb)+" RR:"+GetResRef(oOb)+" Distance:"+FloatToString(GetDistanceBetween(oPC,oOb)); PrintString(sS); sS=" NEAREST PLACEABLE:"; oOb=GetNearestObject(OBJECT_TYPE_PLACEABLE,oPC,1); if (GetIsObjectValid(oOb)) sS=sS+" Name:"+GetName(oOb)+" Tag:"+GetTag(oOb)+" RR:"+GetResRef(oOb)+" Distance:"+FloatToString(GetDistanceBetween(oPC,oOb)); PrintString(sS); sS=" NEAREST DOOR:"; oOb=GetNearestObject(OBJECT_TYPE_DOOR,oPC,1); if (GetIsObjectValid(oOb)) sS=sS+" Name:"+GetName(oOb)+" Tag:"+GetTag(oOb)+" RR:"+GetResRef(oOb)+" Distance:"+FloatToString(GetDistanceBetween(oPC,oOb)); PrintString(sS); sS=" NEAREST ITEM:"; oOb=GetNearestObject(OBJECT_TYPE_ITEM,oPC,1); if (GetIsObjectValid(oOb)) sS=sS+" Name:"+GetName(oOb)+" Tag:"+GetTag(oOb)+" RR:"+GetResRef(oOb)+" Distance:"+FloatToString(GetDistanceBetween(oPC,oOb)); PrintString(sS); sS=" NEAREST TRIGGER:"; oOb=GetNearestObject(OBJECT_TYPE_TRIGGER,oPC,1); if (GetIsObjectValid(oOb)) sS=sS+" Name:"+GetName(oOb)+" Tag:"+GetTag(oOb)+" RR:"+GetResRef(oOb)+" Distance:"+FloatToString(GetDistanceBetween(oPC,oOb)); PrintString(sS); PrintString("[]-[]-[]-END---[]-[]"); SendMessageToPC(oPC,"A Bug message has been written to the Log file. Please read the log file and copy and paste the information in the bug report into any email, or mantis bug report."); } // fnDebug()