• You've discovered RedGuides, an EverQuest multi-boxing and scripting community 🧙‍♀️⚙️. We want you to play several EQ characters at once, come join us and say hello! 👋

  • A TLP without truebox has thawed (Very Vanilla ready)
    Frostreaver

Mq2AutoSkills.cpp EMU Titanium Edition Source and Compile

Joined
Feb 8, 2005
RedCents
8,901¢
Below is the source code and the compiled dll for mq2autoskills

Please Report any bugs
Rich (BB code):
// MQ2AutoSkills.cpp : Auto-activate various skills
//
//   version EMU
//   11/22/10 - Reverted code back to 20051116 MQ2Source Compatitble
//
//   Project started 8/30/2004 by Cr4zyb4rd
//   9/27/06 - GuildLeader added nils and Drumstix42's fixes for latest zip
//   12/15/05 - DigitalMocking;
//     Added a check to use /pet hold if you have the AA during enrage,
//     Fixed bash to work properly with the 2 Hand Bash AA
//     Fixed a crash bug with bash and equipping a 2handed weapon
//   10/5/05 - DigitalMocking;
//     Added /pet back to the enrage and infurate sections of the code
//     Added a shield check for the bash ability, ability will no longer fire
//     and spam the screen if you don't have a shield equipped.
//
// Commands:
//  /autoskills help - lists options
//
// INI file will be auto-created, MQ2AutoSkills_Charname_server.ini
// Syntax is simply Skill=on/off and MeleeRange=distance
//
// Currently suported skills:
//  Backstab, Bash, Begging, Disarm, Dragon Punch, Eagle Strike, Flying Kick,
//  Frenzy, Evade, Forage, Feign Death, Intimidation, Kick, Mend, Pick Pockets,
//  Round Kick, Sense Traps, Slam, Taunt, Tiger Claw
//
//  /attack off on mob ENRAGE/infuriate is also supported, treated as the "ENRAGE"
//  and "infuriate" skills in the INI.
//
// Known issues: Trade/Vendor windows and possibly some other events may cause some
// skills to fire when not appropriate and spam you
//
//////////////////////////////////////////////////////////////////////////////////////
#include "../MQ2Plugin.h"

#ifndef nSkillsNonInnate
#define nSkillsNonInnate            100
#endif
#ifndef nSkillsMax
#define nSkillsMax                  132
#endif

PSPAWNINFO psOldTarget = NULL;

bool MQ2ASenabled = false;

bool DoBackstab = false;
bool DoBash = false;
bool DoBegging = false;
bool DoDisarm = false;
bool DoDragonPunch = false;
bool DoEagleStrike = false;
bool DoENRAGE;
bool DoEvade = false;
bool DoForage = false;
bool DoFeignDeath = false;
bool DoFlyingKick = false;
bool DoFrenzy = false;
bool DoIntimidation = false;
bool DoInfuriate = false;
bool DoKick = false;
bool DoMend = false;
bool DoPickPockets = false;
bool DoRoundKick = false;
bool DoSenseTraps = false;
bool DoSlam = false;
bool DoTaunt = false;
bool DoTigerClaw = false;
bool DoingBegging = false;
bool DoingENRAGE = false;
bool DoingEvade = false;
bool DoingForage = false;
bool DoingInfuriate = false;
bool DoingPickPockets = false;
bool DoingFeignDeath = false;

float MeleeRange = 15;
int   BackOffHP  = 0;
int   DoMendHP  = 80;

PreSetup("MQ2AutoSkills");

//shamelessly stolen from MQ2MoveUtils
float angularDistance(float h1, float h2)
{
   if( h1 == h2 ) return 0.0;

   if( fabs(h1-h2) > 256.0 )
      *(h1<h2?&h1:&h2) += 512.0;

   return (fabs(h1-h2)>256.0)?(h2-h1):(h1-h2);
}

void ASDoAbility(PCHAR Ability)
{
   if (!strncmp(szSkills[112],"Slam",4)) {
      DWORD Index, DoIndex, ListIndex = 0xFFFFFFFF;
      for (Index=0;Index<10;Index++) {
         ListIndex = EQADDR_DOABILITYLIST[Index];
         if (ListIndex!= 0xFFFFFFFF) {
            if (ListIndex>nSkillsNonInnate) ListIndex++;
            if (!strnicmp(Ability,szSkills[ListIndex],strlen(szSkills[ListIndex]))) {
               if (Index<4) {
                  DoIndex = Index+7; // 0-3 = Combat abilities (7-10)
               } else {
                  DoIndex = Index-3; // 4-9 = Abilities (1-6)
               }
            }
         }
      }
      if (DoIndex!=0xFFFFFFFF) {
         CHAR szBuffer[MAX_STRING];
         cmdDoAbility(GetCharInfo()->pSpawn,itoa(DoIndex,szBuffer,10));
      } else {
         WriteChatColor("You do not seem to have that ability on a /doability button",USERCOLOR_DEFAULT);
      }

   } else DoAbility(GetCharInfo()->pSpawn,Ability);
}

bool BoolFromINI(PCHAR Section, PCHAR Key)
{
   char szTemp[MAX_STRING];
   GetPrivateProfileString(Section,Key,"off",szTemp,MAX_STRING,INIFileName);
   if (!strnicmp(szTemp,"off",3)) {
      WritePrivateProfileString(Section,Key,"off",INIFileName);
      return false;
   }
   WritePrivateProfileString(Section,Key,"on",INIFileName);
   return true;
}

bool CheckAbilityReady(PCHAR szSkillName)
{
  for (DWORD nSkill=0;nSkill<=nSkillsMax;nSkill++) {
    if (!stricmp(szSkillName,szSkills[nSkill])) {
      if (nSkill>nSkillsNonInnate && !strncmp(szSkills[112],"Slam",4)) nSkill++;
        if (nSkill>nSkillsNonInnate)
          return gbAltTimerReady?true:false;
        else
          return EQADDR_DOABILITYAVAILABLE[nSkill]?true:false;
    }
  }
    return false;
}

VOID LoadINI()
{
   char szTemp[MAX_STRING];
   char MeleeRangeTemp[MAX_STRING];

   DoBackstab = BoolFromINI("Skills","Backstab");
   DoBash = BoolFromINI("Skills","Bash");
   DoBegging = BoolFromINI("Skills","Begging");
   DoDisarm = BoolFromINI("Skills","Disarm");
   DoDragonPunch = BoolFromINI("Skills","DragonPunch");
   DoEagleStrike = BoolFromINI("Skills","EagleStrike");
   DoENRAGE = BoolFromINI("Skills","ENRAGE");
   DoEvade = BoolFromINI("Skills","Evade");
   DoFeignDeath = BoolFromINI("Skills","FeignDeath");
   DoForage = BoolFromINI("Skills","Forage");
   DoFlyingKick = BoolFromINI("Skills","FlyingKick");
   DoFrenzy = BoolFromINI("Skills","Frenzy");
   DoIntimidation = BoolFromINI("Skills","Intimidation");
   DoInfuriate = BoolFromINI("Skills","Infuriate");
   DoKick = BoolFromINI("Skills","Kick");
   DoMend = BoolFromINI("Skills","Mend");
   DoRoundKick = BoolFromINI("Skills","RoundKick");
   DoPickPockets = BoolFromINI("Skills","PickPockets");
   DoSenseTraps = BoolFromINI("Skills","SenseTraps");
   DoSlam = BoolFromINI("Skills","Slam");
   DoTaunt = BoolFromINI("Skills","Taunt");
   DoTigerClaw = BoolFromINI("Skills","TigerClaw");
   sprintf(MeleeRangeTemp,"%3.3f",MeleeRange);
   GetPrivateProfileString("Settings","MeleeRange",MeleeRangeTemp,szTemp,MAX_STRING,INIFileName);
   MeleeRange = (float)atof(szTemp);
   WritePrivateProfileString("Settings","MeleeRange",szTemp,INIFileName);
   BackOffHP = GetPrivateProfileInt("Settings","BackOffHP",0,INIFileName);
   sprintf(szTemp,"%d",BackOffHP);
   WritePrivateProfileString("Settings","BackOffHP",szTemp,INIFileName);
   DoMendHP = GetPrivateProfileInt("Settings","DoMendHP",80,INIFileName);
   sprintf(szTemp,"%d",DoMendHP);
   WritePrivateProfileString("Settings","DoMendHP",szTemp,INIFileName);
}   

VOID DisplayAutoSkillsHelp()
{
   WriteChatColor("MQ2AutoSkills - Auto-Use Abilities",USERCOLOR_DEFAULT);
   WriteChatColor("Usage:",USERCOLOR_DEFAULT);
   WriteChatColor("/autoskills list        - List available skills and whether they are enabled",USERCOLOR_DEFAULT);
   WriteChatColor("/autoskills settings    - List settings/thresholds",USERCOLOR_DEFAULT);
   WriteChatColor("/autoskills backoff [#] - %HP at which to not re-engage after FD/Evade",USERCOLOR_DEFAULT);
   WriteChatColor("/autoskills melee   [#] - Range to be considered 'in melee'",USERCOLOR_DEFAULT);
   WriteChatColor("/autoskills mendhp  [#] - %HP at which to use the mend ability",USERCOLOR_DEFAULT);
   WriteChatColor("/autoskills [skill]     - Toggle a skill on/off and update the INI",USERCOLOR_DEFAULT);
   WriteChatColor("/autoskills [skill] on  - Enable a skill",USERCOLOR_DEFAULT);
   WriteChatColor("/autoskills [skill] off - Disable a skill",USERCOLOR_DEFAULT);
}

VOID MQ2AutoSkillsCommand(PSPAWNINFO pChar, PCHAR szLine)
{
   char szTemp[MAX_STRING];
   char szTemp2[MAX_STRING];
   char szArg2[MAX_STRING];
   GetArg(szTemp,szLine,1);

   if (strlen(szTemp)==0 || !strnicmp(szTemp,"help",4)) {
      DisplayAutoSkillsHelp();
      return;
   }

   if (!strnicmp(szTemp,"backoff",7)) {
      GetArg(szTemp,szLine,2);
      if (strlen(szTemp)) {
         BackOffHP=atoi(szTemp);
         sprintf(szTemp, "%d",BackOffHP);
         WritePrivateProfileString("Settings","BackOffHP",szTemp,INIFileName);
      }
      WriteChatf("MQ2AutoSkills:: Backing off at %d%%",BackOffHP);
      return;
   }

   if (!strnicmp(szTemp,"mendhp",7)) {
      GetArg(szTemp,szLine,2);
      if (strlen(szTemp)) {
         DoMendHP=atoi(szTemp);
         sprintf(szTemp, "%d",DoMendHP);
         WritePrivateProfileString("Settings","DoMendHP",szTemp,INIFileName);
      }
      WriteChatf("MQ2AutoSkills:: Mending at %d%%",DoMendHP);
      return;
   }

   if (!strnicmp(szTemp,"melee",7)) {
      GetArg(szTemp,szLine,2);
      if (strlen(szTemp)) {
         MeleeRange=(float)atof(szTemp);
         sprintf(szTemp, "%3.3f",MeleeRange);
         WritePrivateProfileString("Settings","MeleeRange",szTemp,INIFileName);
      }
      WriteChatf("MQ2AutoSkills:: Melee range set to  %3.3f%%",MeleeRange);
      return;
   }

   if (!strnicmp(szTemp,"settings",8)) {
      WriteChatf("MQ2AutoSkills:: Melee range set to  %3.3f%%",MeleeRange);
      WriteChatf("MQ2AutoSkills:: Backing off at %d%%",BackOffHP);
      WriteChatf("MQ2AutoSkills:: Mending at %d%%",DoMendHP);
      return;
   }

   if (!strnicmp(szTemp,"list", 4)) {
      WriteChatColor("MQ2AutoSkills:: Supported abilites and current status",CONCOLOR_RED);
      sprintf(szTemp," Backstab (%s)",DoBackstab?"\agon\ax":"\aroff\ax");
      WriteChatColor(szTemp,USERCOLOR_WHO);
      sprintf(szTemp," Bash (%s)",DoBash?"\agon\ax":"\aroff\ax");
      WriteChatColor(szTemp,USERCOLOR_WHO);
      sprintf(szTemp," Begging (%s)",DoBegging?"\agon\ax":"\aroff\ax");
      WriteChatColor(szTemp,USERCOLOR_WHO);
      sprintf(szTemp," Disarm (%s)",DoDisarm?"\agon\ax":"\aroff\ax");
      WriteChatColor(szTemp,USERCOLOR_WHO);
      sprintf(szTemp," DragonPunch (%s)",DoDragonPunch?"\agon\ax":"\aroff\ax");
      WriteChatColor(szTemp,USERCOLOR_WHO);
      sprintf(szTemp," EagleStrike (%s)",DoEagleStrike?"\agon\ax":"\aroff\ax");
      WriteChatColor(szTemp,USERCOLOR_WHO);
      sprintf(szTemp," ENRAGE (%s)",DoENRAGE?"\agon\ax":"\aroff\ax");
      WriteChatColor(szTemp,USERCOLOR_WHO);
      sprintf(szTemp," Evade (%s)",DoEvade?"\agon\ax":"\aroff\ax");
      WriteChatColor(szTemp,USERCOLOR_WHO);
      sprintf(szTemp," FeignDeath (%s)",DoFeignDeath?"\agon\ax":"\aroff\ax");
      WriteChatColor(szTemp,USERCOLOR_WHO);
      sprintf(szTemp," Forage (%s)",DoForage?"\agon\ax":"\aroff\ax");
      WriteChatColor(szTemp,USERCOLOR_WHO);
      sprintf(szTemp," FlyingKick (%s)",DoFlyingKick?"\agon\ax":"\aroff\ax");
      WriteChatColor(szTemp,USERCOLOR_WHO);
      sprintf(szTemp," Frenzy (%s)",DoFrenzy?"\agon\ax":"\aroff\ax");
      WriteChatColor(szTemp,USERCOLOR_WHO);
      sprintf(szTemp," Intimidation (%s)",DoIntimidation?"\agon\ax":"\aroff\ax");
      WriteChatColor(szTemp,USERCOLOR_WHO);
      sprintf(szTemp," Infuriate (%s)",DoInfuriate?"\agon\ax":"\aroff\ax");
      WriteChatColor(szTemp,USERCOLOR_WHO);
      sprintf(szTemp," Kick (%s)",DoKick?"\agon\ax":"\aroff\ax");
      WriteChatColor(szTemp,USERCOLOR_WHO);
      sprintf(szTemp," Mend (%s)",DoMend?"\agon\ax":"\aroff\ax");
      WriteChatColor(szTemp,USERCOLOR_WHO);
      sprintf(szTemp," PickPockets (%s)",DoPickPockets?"\agon\ax":"\aroff\ax");
      WriteChatColor(szTemp,USERCOLOR_WHO);
      sprintf(szTemp," RoundKick (%s)",DoRoundKick?"\agon\ax":"\aroff\ax");
      WriteChatColor(szTemp,USERCOLOR_WHO);
      sprintf(szTemp," SenseTraps (%s)",DoSenseTraps?"\agon\ax":"\aroff\ax");
      WriteChatColor(szTemp,USERCOLOR_WHO);
      sprintf(szTemp," Slam (%s)",DoSlam?"\agon\ax":"\aroff\ax");
      WriteChatColor(szTemp,USERCOLOR_WHO);
      sprintf(szTemp," Taunt (%s)",DoTaunt?"\agon\ax":"\aroff\ax");
      WriteChatColor(szTemp,USERCOLOR_WHO);
      sprintf(szTemp," TigerClaw (%s)",DoTigerClaw?"\agon\ax":"\aroff\ax");
      WriteChatColor(szTemp,USERCOLOR_WHO);
      return;
   }

   // Check if entry exists in INI
   GetPrivateProfileString("Skills",szTemp,"NULL",szTemp2,MAX_STRING,INIFileName);

   if (!strnicmp(szTemp2,"NULL", 4)) { // unsupported skill
      WriteChatColor("MQ2AutoSkills::Unsupported argument",CONCOLOR_RED);
      WriteChatColor("Use '/autoskills list' for a list",CONCOLOR_RED);
      return;
   }

   GetArg(szArg2,szLine,2);
   if ((!strlen(szArg2) && !strnicmp(szTemp2,"off",3)) || !strnicmp(szArg2,"on",2)) {
      WritePrivateProfileString("Skills",szTemp,"on",INIFileName);
      sprintf(szTemp2,"MQ2AutoSkills::auto %s is now ON",szTemp);
      WriteChatColor(szTemp2,CONCOLOR_YELLOW);
   } else if ((!strlen(szArg2) && !strnicmp(szTemp2,"on",2)) || !strnicmp(szArg2,"off",3)) {
      WritePrivateProfileString("Skills",szTemp,"off",INIFileName);
      sprintf(szTemp2,"MQ2AutoSkills::auto %s is now OFF",szTemp);
      WriteChatColor(szTemp2,CONCOLOR_YELLOW);
   } else {
      DisplayAutoSkillsHelp();
      return;
   }
   LoadINI();
}

// Called once, when the plugin is to initialize
PLUGIN_API VOID InitializePlugin(VOID)
{
   DebugSpewAlways("Initializing MQ2AutoSkills");

   AddCommand("/autoskills",MQ2AutoSkillsCommand);
   if (MQ2Globals::gGameState==GAMESTATE_INGAME) {
      if (GetCharInfo2()) {
         sprintf(INIFileName,"%s\\MQ2AutoSkills_%s_%s.ini",gszINIPath,GetCharInfo()->Name,EQADDR_SERVERNAME);
         LoadINI();
         MQ2ASenabled=true;
         return;
      }
   } else MQ2ASenabled = false;

}

// Called once, when the plugin is to shutdown
PLUGIN_API VOID ShutdownPlugin(VOID)
{
   DebugSpewAlways("Shutting down MQ2AutoSkills");

   RemoveCommand("/autoskills");
}

// Called every frame that the "HUD" is drawn -- e.g. net status / packet loss bar
PLUGIN_API VOID OnDrawHUD(VOID)
{
   // DONT leave in this debugspew, even if you leave in all the others
   //   DebugSpewAlways("MQ2AutoSkills::OnDrawHUD()");
}

PLUGIN_API VOID SetGameState(DWORD GameState)
{
   DebugSpewAlways("MQ2AutoSkills::SetGameState()");
   if (GameState==GAMESTATE_INGAME) {
      if (GetCharInfo2()) {
         sprintf(INIFileName,"%s\\MQ2AutoSkills_%s_%s.ini",gszINIPath,GetCharInfo()->Name,EQADDR_SERVERNAME);
         LoadINI();
         MQ2ASenabled=true;
         return;
      }
   } else MQ2ASenabled = false;
}

BOOL IsWindowOpen(PCHAR WindowName)
{
   PCSIDLWND pWnd=(PCSIDLWND)FindMQ2Window(WindowName);
   if (!pWnd) return false;
   return (BOOL)pWnd->Show;
}

PLUGIN_API VOID OnPulse(VOID)
{
   if (!MQ2ASenabled) return;

   bool mounted;

   PSPAWNINFO psTarget = NULL;
   PSPAWNINFO pChSpawn = GetCharInfo()->pSpawn;
   DWORD MyStandstate = GetCharInfo()->standstate;
   int pctHP = pChSpawn->HPCurrent*100/pChSpawn->HPMax;

   if (psOldTarget!=(PSPAWNINFO)pTarget && (DoingENRAGE || DoingInfuriate)) {
      WriteChatColor("MQ2AutoSkills::Target changed, ENRAGE/Infuriate monitors reset.",CONCOLOR_YELLOW);
      DoingENRAGE = false;
      DoingInfuriate = false;
   }

   if (GetCharInfo()->Stunned || MyStandstate==STANDSTATE_DEAD || IsWindowOpen("BigBankWnd") || IsWindowOpen("MerchantWnd") || IsWindowOpen("TradeWnd")) return;

   if (DoMend && pctHP < DoMendHP && CheckAbilityReady("Mend")) ASDoAbility("Mend");

   //check if stunned, feigned, ducking, dead, binding, sitting
   if (MyStandstate==STANDSTATE_FEIGN && DoingFeignDeath) {
      if (pctHP > BackOffHP) {
         HideDoCommand(pChSpawn,"/stand",FromPlugin);
         if (psOldTarget==(PSPAWNINFO)pTarget) HideDoCommand(pChSpawn,"/attack on",FromPlugin);
      } else WriteChatf("MQ2AutoSkills::HP lower than %d%%, staying down",BackOffHP);
      DoingFeignDeath = 0;
      return;
   }

   // check if not standing
   if (MyStandstate!=STANDSTATE_STAND) return;

   // check if mounted
   mounted = pChSpawn && pChSpawn->pActorInfo->Mount ? true : false;

   //check if casting (and not a bard)
   if ((pChSpawn->pActorInfo->CastingSpellID!=-1) && strncmp(pEverQuest->GetClassDesc(GetCharInfo2()->Class),"Bard",5)) return;

   if (DoSenseTraps && CheckAbilityReady("Sense Traps")) ASDoAbility("\"Sense Traps\"");
   if (!mounted && !DoingForage && DoForage && !*EQADDR_ATTACK && CheckAbilityReady("Forage")) {
      Sleep(50);
      DoAbility(pChSpawn,"Forage");
   }

   //check for a target
   if (ppTarget && pTarget) {
      psTarget = (PSPAWNINFO)pTarget;
   } else return;
   

   //make sure target isn't me
   if (psTarget!=pChSpawn) {
   } else return;

   //check melee distance
   if (GetDistance(pChSpawn,psTarget) < MeleeRange) {
   } else return;

   //check if in combat
   if (*EQADDR_ATTACK) {
   } else if (DoingBegging || DoingEvade || DoingPickPockets || DoingFeignDeath || DoingForage) {
      if (DoingBegging){
         DoAbility(pChSpawn,"Begging");
         DoingBegging = 0;
      }
      if (DoingEvade){
         DoAbility(pChSpawn,"Hide");
      }
      if (DoingPickPockets){
         DoAbility(pChSpawn,"\"Pick Pockets\"");
         DoingPickPockets =0;
      }
      if (DoingFeignDeath){
         DoAbility(pChSpawn,"\"Feign Death\"");
         return; //no attack on here
      }
      if (DoingForage){
         DoAbility(pChSpawn,"Forage");
         DoingForage=0;
      }
      if (psOldTarget==(PSPAWNINFO)pTarget) {
         if (DoingEvade && pctHP < BackOffHP) {
            WriteChatf("MQ2AutoSkills::HP lower than %d%%, staying hidden",BackOffHP);
         } else HideDoCommand(pChSpawn,"/attack on",FromPlugin);
      }
      DoingEvade =0;
      psOldTarget = psTarget;
   } else return;

   if (DoBash && CheckAbilityReady("Bash") && GetCharInfo2()->InventoryArray[0xe]) {
       if (GetCharInfo2()->InventoryArray[0xe]->Item->ItemType==0x8) ASDoAbility("Bash");
   } else if (DoBash && CheckAbilityReady("Bash")) {
        ASDoAbility("Bash");
   }
   if (DoDisarm && CheckAbilityReady("Disarm")) ASDoAbility("Disarm");
   if (DoDragonPunch && CheckAbilityReady("Dragon Punch")) ASDoAbility("\"Dragon Punch\"");
   if (DoEagleStrike && CheckAbilityReady("Eagle Strike")) ASDoAbility("\"Eagle Strike\"");
   if (DoFlyingKick && CheckAbilityReady("Flying Kick")) ASDoAbility("\"Flying Kick\"");
   if (DoFrenzy && CheckAbilityReady("Frenzy")) ASDoAbility("\"Frenzy\"");
   if (DoTaunt && CheckAbilityReady("Taunt")) ASDoAbility("Taunt");
   if (DoIntimidation && CheckAbilityReady("Intimidation")) ASDoAbility("Intimidation");
   if (DoKick && CheckAbilityReady("Kick")) ASDoAbility("Kick");
   if (DoRoundKick && CheckAbilityReady("Round Kick")) ASDoAbility("\"Round Kick\"");
   if (DoSlam && CheckAbilityReady("Slam")) ASDoAbility("Slam");
   if (DoTigerClaw && CheckAbilityReady("Tiger Claw")) ASDoAbility("\"Tiger Claw\"");

   // These skills need attack to be turned off
   if (DoBegging && CheckAbilityReady("Begging")) {
      HideDoCommand(pChSpawn, "/attack off",FromPlugin);
      DoingBegging = 1;
   }
   if (DoEvade && CheckAbilityReady("Hide") && FindSpeed(pChSpawn)==0) {
      HideDoCommand(pChSpawn, "/attack off",FromPlugin);
      DoingEvade = 1;
   }
   if (DoPickPockets && CheckAbilityReady("Pick Pockets")) {
      HideDoCommand(pChSpawn, "/attack off",FromPlugin);
      DoingPickPockets = 1;
   }
   if (DoFeignDeath && CheckAbilityReady("Feign Death")) {
      HideDoCommand(pChSpawn, "/attack off",FromPlugin);
      DoingFeignDeath = 1;
   }
   if (DoForage && CheckAbilityReady("Forage")) {
      HideDoCommand(pChSpawn, "/attack off",FromPlugin);
      DoingForage = 1;
   }
   psOldTarget = psTarget;

   //check if behind target
   if (fabs(angularDistance(psTarget->Heading,pChSpawn->Heading)) < 45.0) {
   } else return;

   if (DoBackstab && CheckAbilityReady("Backstab")) ASDoAbility("Backstab");
}

PLUGIN_API DWORD OnIncomingChat(PCHAR Line, DWORD Color)
{
   if (MQ2Globals::gGameState != GAMESTATE_INGAME || !MQ2ASenabled) return 0;
   // DebugSpewAlways("MQ2AutoSkills::OnIncomingChat(%s)",Line);
   if(Color == USERCOLOR_NPC_ENRAGE && (DoENRAGE || DoInfuriate) && ppTarget && pTarget) {
        WriteChatColor(Line,CONCOLOR_YELLOW);
      PSPAWNINFO psTarget = (PSPAWNINFO)pTarget;   
      if (strncmp(Line,psTarget->DisplayedName,strlen(psTarget->DisplayedName))||(strstr(Line,"pet")&&!strstr(psTarget->DisplayedName,"pet"))) return 0; // not our target
      if (DoENRAGE && strstr(Line,"has become ENRAGED")) {
         WriteChatColor("MQ2AutoSkills::\arENRAGE\ax detected, turning attack off.",CONCOLOR_YELLOW);
         HideDoCommand(GetCharInfo()->pSpawn, "/attack off",FromPlugin);
       if (GetCharInfo()->pSpawn->pActorInfo->PetID) {
             HideDoCommand(GetCharInfo()->pSpawn, "/pet back",FromPlugin);
       }
         DoingENRAGE = true;
         psOldTarget = psTarget;
         return 0;
      }
      if (DoInfuriate && strstr(Line,"is infuriated"))  {
         WriteChatColor("MQ2AutoSkills::\arInfuriate\ax detected, turning attack off.",CONCOLOR_YELLOW);
         HideDoCommand(GetCharInfo()->pSpawn, "/attack off",FromPlugin);
       if (GetCharInfo()->pSpawn->pActorInfo->PetID) {
             HideDoCommand(GetCharInfo()->pSpawn, "/pet back",FromPlugin);
       }
         DoingInfuriate = true;
         psOldTarget = psTarget;
         return 0;
      }
      if (strstr(Line,"is no longer enraged")) {
         if (psOldTarget==(PSPAWNINFO)pTarget && DoingENRAGE) {
            if (!DoingInfuriate) {
               WriteChatColor("MQ2AutoSkills::ENRAGE/infuriate ended, resuming attack.",CONCOLOR_YELLOW);
               HideDoCommand(GetCharInfo()->pSpawn, "/attack on",FromPlugin);
                if (GetCharInfo()->pSpawn->pActorInfo->PetID) {
                 HideDoCommand(GetCharInfo()->pSpawn, "/pet kill",FromPlugin);
             }
            } else {
               WriteChatColor("MQ2AutoSkills::\arENRAGE\ax ended, but mob still seems infuriated.",CONCOLOR_YELLOW);
            }
            DoingENRAGE = false;
         }
         return 0;
      }
      if (strstr(Line,"no longer infuriated")) {
         if (psOldTarget==(PSPAWNINFO)pTarget && DoingInfuriate) {
            if (!DoingENRAGE) {
               WriteChatColor("MQ2AutoSkills::ENRAGE/infuriate ended, resuming attack.",CONCOLOR_YELLOW);
               HideDoCommand(GetCharInfo()->pSpawn, "/attack on",FromPlugin);
                if (GetCharInfo()->pSpawn->pActorInfo->PetID) {
                 HideDoCommand(GetCharInfo()->pSpawn, "/pet kill",FromPlugin);
             }
            } else {
               WriteChatColor("MQ2AutoSkills::\arInfuriate\ax ended, but mob still seems ENRAGED.",CONCOLOR_YELLOW);
            }
            DoingInfuriate = false;
         }
         return 0;
      }
   }           
   return 0;
}

Please Red Cent me if you find this useful
 
Mq2AutoSkills.cpp EMU Titanium Edition Source and Compile

Users who are viewing this thread

Back
Top
Cart