• 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

EMU MQ2Melee

HardOne

Member
Joined
Jan 15, 2006
RedCents
61¢
Rich (BB code):
//==================================================================================// 
// MQ2Melee Plugin v0.703 [under developpment] 
// based on Cr4zyb4rd MQ2AutoSkills 
// by s0rCieR (05/10/06) 
// 
// Modified by Ebs2002: Added support for Slam.  Needs some testing 
//----------------------------------------------------------------------------------// 
// The goal of this plugin is to use common combat abilities 
// at logical times determined by the user 
// 
// Before an ability fires, a few requirements must be met. The combat ability 
// needs to be mapped to a doability button (Ctrl A), you must have at least have 1 point 
// in that skill, and any other requirements the ability relies on must be met, ie: bash, you can't bash at 
// a target without wearing a shield or disarm a mob if he 
// is not holding something... 
// 
// Right now the engage / validating target part is a litle awkward, i might removes 
// some sanity checks to make it smoother if people ask for it. It will engage 
// a target if that target is: a NPC, Standing, in Line of Sight, in decent range for 
// archery or melee, and in a Line of Sight (ie, it will not engage a target 
// that is behind ya) and finally you must have melee or range attack on to confirm 
// your intention! (it's designed to be used with some kind of assist macro, as soon 
// as you acquire a target, its below percentage you want etc, you will need to turn 
// attack on to trigger the engage). 
// 
// Attack will be turned off if current target does not meet the engage requirements. Any 
// newly acquired target will be saved and monitored for enrage/infuriate even if you 
// switch targets (ie to a NPC or PET to heal or buff).  As soon as you switch back to 
// the saved target, it will auto-resume. 
// 
// You can toggle between melee/range mode as needed 
// 
// The plugin monitors engaged target for enrage/infuriate conditions and will react to them. 
// It will also watch for a failed feign death message and automatically issue /stand. 
// 
// If you are a pet class, have a pet up, and use the pet 
// assist setting, it will auto-send pet to attack on engage and back him off 
// on enrage/infuriate. If you have /pet hold or /pet focus those commands will be 
// used on attack / backoff. 
// 
// There is a parameter called "aggro" that could be toggled on/off and will react to 
// skills and how the plugin operates. When in aggro mode: taunt & provoke will 
// will be used if they are "on", you will never backoff a fight because of 
// low health. When aggro is off, taunt/provoke will never 
// be used, but now you will backoff if the ini includes this setting. 
// 
// Currently supported abilities: 
//   BackStab, Bash, Begging, Disarm, Dragon Punch, Eagle Strike, Feign Death, Flying 
//   Kick, Forage, Frenzy, Hide, Intimidation, Kick, Mend, Pick Pockets, Round Kick, 
//   Sense Traps, Sneak, Taunt and Tiger Claw. 
// 
// Currently supported alt abilities: 
//   FeralSwipe, Pet Discipline, and Advanced Pet Discipline. 
// 
// Currently supported combat abilities: 
//   Throw Stone, Bazu Bellow, Ancient Chaos Cry, Bellow of the Mastruq, Incite, 
//   Berate, Below, Provoke, Destroyer's Volley, Rage Volley, Dragon Fang and Leopard 
//   Claw. 
// 
//----------------------------------------------------------------------------------// 
// COMMAND: /melee 
//          /melee on aggro=on taunt=on kick=1 bash=0 intimidation=false disarm=true 
// 
//         In other words, you may use on/off, 1/0, or true/false 
// 
// /melee will only list and report abilities and setting that are available to you. 
// 
// Note: /melee just changes the values in the INI.  If you begin with /melee 
// aggro=on kick=on, but want to stop taunting, you must use /melee aggro=off, not 
// /melee kick=on (in other words, your settings are NOT reset with each use of /melee 
//----------------------------------------------------------------------------------// 
// on/off       : Turn On/Off features. 
// aggro        : [On/Off] Means that you want to keep aggro on target, it will use 
//                aggro abilities/disciplines(enabled) and will keep on going until 
//                either you or the target dies. 
// melee        : [0+] This is the maximum melee distance for abilities that require 
//                a target to be used. (0=off) 
// range        : [0+] This is the minimum distance to be considered in archery/throwing 
//                range (0=off). You must have bow/arrow or throwing item equipped 
//                for /ranged to activate. 
//----------------------------------------------------------------------------------// 
// enrage       : [On/Off] Watch for enrage messages and turn off/on 
//                attack if needed. Attack will be turned back on if you are standing behind 
//                the target during enrage. 
// infuriate    : [On/Off] Watch for infuriate messages and turns off/on attack. 
// petassist    : [On/Off] Will send pet attack on engage and backoff on enrage/infuriate 
//                if those skills are on. The plugin will also use /pet focus or /pet hold 
//                if you have those AAs. 
//----------------------------------------------------------------------------------// 
// mend         : [0-100] Mend your wound if your life percentage goes below the designated value. 
// backoff      : [0-100] Turns attack off if your life percentage goes below the designated value. 
//                (0=off) If you are in aggro mode, you will never back off due to low health. 
// evade        : [0-100] Turn off Attack and Hide if your life percentage goes below 
//                the designated value. Will never happen if you are in aggro mode. (Needs more testing) 
// feigndeath   : [0-100] Feigns death if your life percentage goes below this value. Will 
//                never happen if you are in aggro mode. (Needs more testing) 
// resume       : [0-100] Stand Up and turn back attack on if your life percentage 
//                goes above this value.  Used with /melee feigndeath 
//----------------------------------------------------------------------------------// 
// backstab     : [0-180] Will try to backstab if you wielding a piercing weapon in main 
//                hand and you are within X degrees +/- of the targets back (ie 45 is a good 
//                angle for just backstabbing, 180 will backstab from all directions. 
// bash         : [On/Off] Will try to bash target if you have a shield equipped. 
// begging      : [On/Off] Will turn attack off and beg target if not in aggro mode. 
// disarm       : [On/Off] Will try to disarm target if target is wielding something. 
// dragonpunch  : [On/Off] Will use dragon punch if available. 
// eaglestrike  : [On/Off] Will use eagle strike if available. 
// flyingkick   : [On/Off] Will use flying kick if available. 
// forage       : [On/Off] Will try to forage up food/water if not in combat. 
// frenzy       : [On/Off] Will try to use frenzy if available. 
// hide         : [On/Off] Will try to hide if you're not in a combat and not moving. 
// intimidation : [On/Off] Will use intimidation if available. 
// kick         : [On/Off] Will use kick as often as possible. 
// pickpockets  : [On/Off] Turn off attack & try to pickpocket if not in aggro mode. 
// roundkick    : [On/Off] Will use round kick if available. 
// sensetraps   : [On/Off] Will try to sense traps if not in combat. 
// slam         : [On/Off] Will use kick as often as possible. 
// sneak        : [On/Off] Will try to sneak if not in combat. 
// taunt        : [On/Off] Will push taunt button if aggro is on and you're not hott. 
// tigerclaw    : [On/Off] Will try to use tiger claw if available. 
//----------------------------------------------------------------------------------// 
// feralswipe   : [On/Off] Will trigger feral swipe AA as it refreshes. 
// provoke      : [0-100]  Will use best provoke discipline once per target if you are 
//                         in aggro mode and your endurance percentage above this. 
//                         0=off. 
// throwstone   : [0-100]  Will use throw stone disc when ready and target in range. 
//                         (Will not use in aggro/provoke mode if provoke has not been 
//                         used yet). 
// ragevolley   : [0-100]  Will use best ragevolley discipline available and ready. 
// leopardclaw  : [0-100]  Will use "leopard claw" or "dragon fang" discipline when 
//                         your endurace is above X%. If not operating in aggro mode it 
//                         will wait till target hp get below 70% before firing up 
//                         this. 
//==================================================================================// 

#include "../MQ2Plugin.h" 
PreSetup("MQ2Melee"); 

// debug 1 1=output action taken, should always be on during beta test 
// aabug 0 0=altabilities functions still not broken so dont need to disbale them 
// cabug 0 0=combat abilities function still not broken so dont need to disable 

#define      debug 1 
#define      aabug 0 
#define      cabug 0 

//================================================================// 

int          doSKILL         =0;       // Plugin Support? 

int          doAGGRO         =0;       // Aggro? (enable/disable taunt/evades)? 
int          doMELEE         =15;      // Melee? Consider Melee if Target dist < this? 
int          doRANGE         =40;      // Range? Consider Range if Target dist > this? 
int          doBACKSTAB      =0;       // BackStab? 
int          doBASH          =0;       // Bash? 
int          doBEGGING       =0;       // Begging? 
int          doDISARM        =0;       // Disarm? 
int          doDRAGONPUNCH   =0;       // Dragon Punch? 
int          doEAGLESTRIKE   =0;       // Eagle Strike? 
int          doFLYINGKICK    =0;       // Flying Kick? 
int          doFORAGE        =0;       // Forage? 
int          doFRENZY        =0;       // Fenzy? 
int          doHIDE          =0;       // Hide? 
int          doINTIMIDATION  =0;       // Intimidation? 
int          doKICK          =0;       // Kick? 
int          doPICKPOCKETS   =0;       // Pick Pockets? 
int          doROUNDKICK     =0;       // Round Kick? 
int          doSENSETRAPS    =0;       // Sense Traps? 
int          doSLAM          =0;       // Slam? 
int          doSNEAK         =0;       // Sneak? 
int          doTAUNT         =0;       // Taunt? 
int          doTIGERCLAW     =0;       // Tiger Claw? 

int          doENRAGE        =1;       // watch for enrage? 
int          doINFURIATE     =1;       // watch for infuriate? 
int          doPETASSIST     =1;       // pet in assist? 

int          doMENDS         =40;      // Mend? if My Life Below This? 
int          doBKOFF         =40;      // BackOff? if My Life Below This? 
int          doEVADE         =40;      // Evade? if My Life Below This? 
int          doFEIGN         =30;      // Feign? if My Life Below This? 
int          doSTAND         =70;      // Stand? Resume Meleeing if My Life Above This? 

int          doFERAL         =1;       // Feral Swipe AA? if My Endu > This? 
int          doPROVOKE       =25;      // Provoke? if Endu above This? 
int          doTHROWSTONE    =50;      // ThrowStone if Endu above This? 
int          doRAGEVOLLEY    =25;      // RageVolley if Endu above This? 
int          doLEOPARDCLAW   =50;      // Leopard Claw if Endu above This? 

eSpawnType   TarType         =NONE;    // Target SpawnType 
PSPAWNINFO   TarKill         =0;       // Target Kill Struct 
float        TarBack         =0.0f;    // Target Behind 
float        TarDist         =0.0f;    // Target Distance 
long         TarLife         =100;     // Target Life 

int          CurEndu         =0;       // MySelf Endurance 
int          PctEndu         =0;       // MySelf % Endu 
int          PctLife         =0;       // MySelf % Life 

DWORD        onCLOCK         =0;       // Clock Timers 
DWORD        onTIMER         =0;       // Timed Delays 

int          onENRAGE        =0;       // Enrage Event? 
int          onINFURIATE     =0;       // Infuriate Event? 
int          onEVADE         =0;       // Evading Event? 
int          onSTEAL         =0;       // Begging/PickPockets Event? 
int          onPROVOKE       =0;       // Incite Flag? 
int          onHOLD          =0;       // Pet On Hold? 

char         Fallen[MAX_STRING]="+|HACKED|+"; 

//================================================================// 

// return pointer to abilities search only for aa that i own! 
PALTABILITY AltByName(PCHAR ID) { 
  for(DWORD nAbility=0; nAbility<AA_CHAR_MAX_REAL; nAbility++) { 
    if(!GetCharInfo2()->AAList[nAbility].AAIndex) break; 
    if(PALTABILITY pAbility=pAltAdvManager->GetAltAbility(GetCharInfo2()->AAList[nAbility].AAIndex)) 
      if(PCHAR pName=pCDBStr->GetString(pAbility->nName,1,NULL)) 
      if(!stricmp(ID,pName)) return pAbility; 
  } 
  return NULL; 
} 

// return true if we own that aa. 
int AltAvail(PCHAR ID) { 
 if(aabug || !ID[0]) return 0; 
 PALTABILITY pAbility=AltByName(ID); 
 return (pAbility)?1:0; 
} 

// return timer left or -1 if not found/available. 
int AltTimer(PCHAR ID) { 
  int Result=-1; 
  if(!cabug && ID[0]) if(PALTABILITY pAbility=AltByName(ID)) 
  if(pAltAdvManager->GetCalculatedTimer(pPCData,pAbility)>0) { 
    pAltAdvManager->IsAbilityReady(pPCData,pAbility,&Result); 
    if(Result<0) Result=0; 
  } 
  return (Result); 
} 

// trigger that aa. 
void AltPress(PCHAR ID) { 
  if(aabug && !ID[0]) return; 
  char Buffer[MAX_STRING]; 
  if(PALTABILITY pAbility=AltByName(ID)) { 
    if(debug) WriteChatf("MQ2Melee:: <\ay%s\ax>.",ID); 
    sprintf(Buffer,"/alt act %d",pAbility->ID); 
    HideDoCommand(GetCharInfo()->pSpawn,Buffer,FromPlugin); 
  } 
} 

//================================================================// 

// return pointer to spells corresponding to that abilities. 
PSPELL CABByName(PCHAR ID) { 
  for(DWORD nCombat=0; nCombat<NUM_COMBAT_ABILITIES; nCombat++) 
    if(PSPELL pSpell=GetSpellByID(GetCharInfo2()->CombatAbilities[nCombat])) 
    if(!stricmp(ID,pSpell->Name)) return pSpell; 
  return NULL; 
} 

// return true if combat abilities available. 
int CABAvail(PCHAR ID) { 
  if(!cabug && ID[0]) if(PSPELL pSpell=CABByName(ID)) return 1; 
  return 0; 
} 

// return 0 if ready, -1 if not found, 1+ timeleft 
int CABTimer(PCHAR ID) { 
  long Result=-1; 
  if(!cabug && ID[0]) 
    if(PSPELL pSpell=CABByName(ID)) 
    if(pSpell->CARecastTimerID) { 
      Result=(GetCharInfo2()->CombatAbilityTimes[pSpell->CARecastTimerID]-(DWORD)time(NULL)); 
      if(Result<0) Result=0; 
    } 
  return Result; 
} 

// fire that discipline. 
void CABPress(PSPELL DiscName) { 
  if(cabug || !DiscName) return; 
  pCharData->DoCombatAbility(DiscName->ID); 
  if(debug) WriteChatf("MQ2Melee:: <\ay%s\ax>.",DiscName->Name); 
} 

//================================================================// 

// return true if windowname is open. 
BOOL WindowOpen(PCHAR WindowName) { 
  PCSIDLWND pWnd=(PCSIDLWND)FindMQ2Window(WindowName); 
  return (!pWnd)?false:(BOOL)pWnd->Show; 
} 

// return true if i get a window that interfere with actions. 
bool Windows() { 
  if(!WindowOpen("SpellBookWnd"))                // not medding spells 
  if(!WindowOpen("LootWnd"))                     // not looting stuffs 
  if(!WindowOpen("TradeWnd"))                    // not trading stuffs 
  if(!WindowOpen("MerchantWnd"))                 // not selling stuffs 
  if(!WindowOpen("BigBankWnd"))                  // not banking stuffs 
  if(!WindowOpen("BankWnd"))                     // not banking stuffs 
  return true;                                   // all good so return true 
  return false;                                  // else return false 
} 

// return true if im stunned or dead. 
bool Stunned() { 
  return (GetCharInfo()->Stunned || GetCharInfo()->standstate==STANDSTATE_DEAD); 
} 

// return the spawntype (if pet and owner not a pc respond its a npc) 
eSpawnType SpawnType (PSPAWNINFO pSpawn) { 
  eSpawnType eST=(pSpawn)?GetSpawnType(pSpawn):NONE; 
  return (eST!=PET)?eST:(GetSpawnType((PSPAWNINFO)GetSpawnByID(pSpawn->MasterID))!=PC)?NPC:PET; 
} 

// return true if skill is trained 
bool SkillTrain(PCHAR szSkillName) { 
  if(szSkillName=="Slam") { 
    if(GetCharInfo2()->Race==9 || GetCharInfo2()->Race==2 || GetCharInfo2()->Race==10) { 
      return true; 
    } 
  } 
  for(DWORD idx=0;idx<100;idx++) 
    if(GetCharInfo2()->Skill[idx] && !stricmp(szSkillName,szSkills[idx])) 
    return true; 
  return false; 
} 

// return true if skill found trained and ready to use. 
BOOL SkillReady(PCHAR szSkillName) { 
  DWORD btn, idx; 
  for(btn=0;btn<10;btn++) { 
    idx=EQADDR_DOABILITYLIST[btn]; 
    if(idx<100 && GetCharInfo2()->Skill[idx] && !stricmp(szSkillName,szSkills[idx])) 
    return(SkillDict[idx]->AltTimer==2)?gbAltTimerReady:EQADDR_DOABILITYAVAILABLE[idx]; 
  } 
   return false; 
} 

// press the doability button corresponging to skillname 
void SkillPress(PCHAR szSkillName) { 

  DWORD btn, idx, skl = 0xFFFFFFFF; 
  for(btn=0;btn<10;btn++) 
    if((idx=EQADDR_DOABILITYLIST[btn])!=0xFFFFFFFF) 
    if(!stricmp(szSkillName,szSkills[idx])) 
    skl=(btn<4)?btn+7:btn-3; 
  if(skl!=0xFFFFFFFF) { 
    if(debug) WriteChatf("MQ2Melee:: <\ay%s\ax>.",(szSkillName=="111")?"Slam":szSkillName); 
    char Buffers[MAX_STRING]; 
    cmdDoAbility(GetCharInfo()->pSpawn,itoa(skl,Buffers,10)); 
  } 
} 

// return true if skill available on a doability 
bool SkillAvail(PCHAR szSkillName) { 
  if(szSkillName=="Slam") { 
    if(GetCharInfo2()->Race==9 || GetCharInfo2()->Race==2 || GetCharInfo2()->Race==10) { 
      return true; 
    } 
  } 
  DWORD btn, idx; 
  for(btn=0;btn<10;btn++) { 
    idx=EQADDR_DOABILITYLIST[btn]; 
    if(idx<100 && !stricmp(szSkillName,szSkills[idx])) 
    return true; 
  } 
  return false; 
} 

// send pet this command if i have one! 
void PetCommand(PCHAR Cmd) { 
  if(!doPETASSIST || !pPetInfoWnd || !GetCharInfo()->pSpawn->pActorInfo->PetID || 
     !ClassInfo[GetCharInfo2()->Class & 0xff].PetClass) return; 
  if(!strnicmp(Cmd,"focus",5) && !AltAvail("Advanced Pet Discipline")) return; 
  if(!strnicmp(Cmd,"hold",4)) { 
     onHOLD=true; 
     if(!AltAvail("Pet Discipline")) return; 
  } else onHOLD=false; 
  char Pet[MAX_STRING]; sprintf(Pet,"/pet %s",Cmd); 
  if(debug) WriteChatf("MQ2Melee:: <\ay%s\ax>.",Pet); 
  HideDoCommand(GetCharInfo()->pSpawn,Pet,FromPlugin); 
} 

// return value 1/0 (on/off/toggle or default) 
int OnOff(PCHAR Set, int Def, int Cur) { 
  char Val[MAX_STRING]; GetArg(Val,Set,1); 
  if(!strlen(Val)) return (Cur)?0:1; 
  if(!strnicmp(Val,"true" ,4)) return 1; 
  if(!strnicmp(Val,"on"   ,2)) return 1; 
  if(!strnicmp(Val,"1"    ,1)) return 1; 
  if(!strnicmp(Val,"false",5)) return 0; 
  if(!strnicmp(Val,"off"  ,3)) return 0; 
  if(!strnicmp(Val,"0"    ,1)) return 0; 
  return Def; 
} 

// load settings from ini files. 
void LoadINI() { 
  if(debug) WriteChatf("MQ2Melee:: Loading INI."); 
  sprintf(Fallen,"%s has fallen to the ground.",GetCharInfo()->Name); 
  doSKILL       =GetPrivateProfileInt(GetCharInfo()->Name,"Plugin"      ,0,INIFileName); 
  doAGGRO       =GetPrivateProfileInt(GetCharInfo()->Name,"Aggro"       ,0,INIFileName); 
  doMELEE       =GetPrivateProfileInt(GetCharInfo()->Name,"Melee"       ,0,INIFileName); 
  doRANGE       =GetPrivateProfileInt(GetCharInfo()->Name,"Range"       ,0,INIFileName); 
  doBACKSTAB    =GetPrivateProfileInt(GetCharInfo()->Name,"BackStab"    ,0,INIFileName); 
  doBASH        =GetPrivateProfileInt(GetCharInfo()->Name,"Bash"        ,0,INIFileName); 
  doBEGGING     =GetPrivateProfileInt(GetCharInfo()->Name,"Begging"     ,0,INIFileName); 
  doDISARM      =GetPrivateProfileInt(GetCharInfo()->Name,"Disarm"      ,0,INIFileName); 
  doDRAGONPUNCH =GetPrivateProfileInt(GetCharInfo()->Name,"DragonPunch" ,0,INIFileName); 
  doEAGLESTRIKE =GetPrivateProfileInt(GetCharInfo()->Name,"EagleStrike" ,0,INIFileName); 
  doFLYINGKICK  =GetPrivateProfileInt(GetCharInfo()->Name,"FlyingKick"  ,0,INIFileName); 
  doFORAGE      =GetPrivateProfileInt(GetCharInfo()->Name,"Forage"      ,0,INIFileName); 
  doFRENZY      =GetPrivateProfileInt(GetCharInfo()->Name,"Frenzy"      ,0,INIFileName); 
  doHIDE        =GetPrivateProfileInt(GetCharInfo()->Name,"Hide"        ,0,INIFileName); 
  doINTIMIDATION=GetPrivateProfileInt(GetCharInfo()->Name,"Intimidation",0,INIFileName); 
  doKICK        =GetPrivateProfileInt(GetCharInfo()->Name,"Kick"        ,0,INIFileName); 
  doPICKPOCKETS =GetPrivateProfileInt(GetCharInfo()->Name,"PickPockets" ,0,INIFileName); 
  doROUNDKICK   =GetPrivateProfileInt(GetCharInfo()->Name,"RoundKick"   ,0,INIFileName); 
  doSENSETRAPS  =GetPrivateProfileInt(GetCharInfo()->Name,"SenseTraps"  ,0,INIFileName); 
  doSLAM        =GetPrivateProfileInt(GetCharInfo()->Name,"Slam"        ,0,INIFileName); 
  doSNEAK       =GetPrivateProfileInt(GetCharInfo()->Name,"Sneak"       ,0,INIFileName); 
  doTAUNT       =GetPrivateProfileInt(GetCharInfo()->Name,"Taunt"       ,0,INIFileName); 
  doTIGERCLAW   =GetPrivateProfileInt(GetCharInfo()->Name,"TigerClaw"   ,0,INIFileName); 
  doFERAL       =GetPrivateProfileInt(GetCharInfo()->Name,"FeralSwipe"  ,0,INIFileName); 
  doENRAGE      =GetPrivateProfileInt(GetCharInfo()->Name,"Enrage"      ,1,INIFileName); 
  doINFURIATE   =GetPrivateProfileInt(GetCharInfo()->Name,"Infuriate"   ,1,INIFileName); 
  doPETASSIST   =GetPrivateProfileInt(GetCharInfo()->Name,"PetAssist"   ,1,INIFileName); 
  doMENDS       =GetPrivateProfileInt(GetCharInfo()->Name,"Mend"        ,0,INIFileName); 
  doBKOFF       =GetPrivateProfileInt(GetCharInfo()->Name,"BackOff"     ,0,INIFileName); 
  doEVADE       =GetPrivateProfileInt(GetCharInfo()->Name,"Evade"       ,0,INIFileName); 
  doFEIGN       =GetPrivateProfileInt(GetCharInfo()->Name,"FeignDeath"  ,0,INIFileName); 
  doSTAND       =GetPrivateProfileInt(GetCharInfo()->Name,"Resume"      ,0,INIFileName); 
  doFERAL       =GetPrivateProfileInt(GetCharInfo()->Name,"FeralSwipe"  ,0,INIFileName); 
  doPROVOKE     =GetPrivateProfileInt(GetCharInfo()->Name,"Provoke"     ,0,INIFileName); 
  doTHROWSTONE  =GetPrivateProfileInt(GetCharInfo()->Name,"ThrowStone"  ,0,INIFileName); 
  doRAGEVOLLEY  =GetPrivateProfileInt(GetCharInfo()->Name,"RageVolley"  ,0,INIFileName); 
  doLEOPARDCLAW =GetPrivateProfileInt(GetCharInfo()->Name,"LeopardClaw" ,0,INIFileName); 
} 

// return true if im ingame and have access to all characters informations. 
bool InGames() { 
  if(MQ2Globals::gGameState==GAMESTATE_INGAME)   // currently ingame 
  if(GetCharInfo())                              // get charinfo1 structure 
  if(GetCharInfo()->pSpawn)                      // get spawninfo structure 
  if(GetCharInfo()->pSpawn->pActorInfo)          // get actorinfo structure 
  if(GetCharInfo2())                             // get charinfo2 structure 
  return true;                                   // got all return true 
  return false;                                  // else return false 
} 

// return angle dif heading in radiants from source facing destination 
float HeadingAngle(PSPAWNINFO s, PSPAWNINFO d) { 
  double Head=atan2(d->X-s->X,d->Y-s->Y)*256.0/PI; 
  if(Head<0.0f)Head += 512.0f; else if(Head>= 512.0f) Head -= 512.0f; 
  return fabs(s->Heading-Head); 
} 

// return true if i am grouped 
BOOL Grouped() { 
  return GetCharInfo()->GroupLeader[0]; 
} 

// experimental gotaggro test 
bool GotAggro() { 
  PSPAWNINFO MySelf=GetCharInfo()->pSpawn; 
  PSPAWNINFO CurTar=(ppTarget && pTarget)?(PSPAWNINFO)pTarget:NULL; 
  if(CurTar && SpawnType(CurTar)==NPC) { 
    if(MySelf==MySelf->pActorInfo->pTargetOfTarget) return true; 
    if(HeadingAngle(CurTar,MySelf)<8.0f)            return true; 
  } 
  return false; 
} 

// return true if iam casting and not a bard class. 
bool Casting() { 
  return (GetCharInfo()->pSpawn->pActorInfo->CastingSpellID!=-1 && strncmp(pEverQuest->GetClassDesc 

(GetCharInfo2()->Class  & 0xff),"Bard",5)); 
} 

// return true if i get equipped throwing ammo or archery items. 
bool CanRange() { 
  PCONTENTS aSlot=GetCharInfo2()->Inventory.Ammo; 
  if(PCONTENTS rSlot=GetCharInfo2()->Inventory.Range) { 
    if((rSlot->Item->ItemType==7 || rSlot->Item->ItemType==19) && 
       (!aSlot || aSlot->Item->ItemNumber==rSlot->Item->ItemNumber))   return true; 
    if(rSlot->Item->ItemType==5 && aSlot && aSlot->Item->ItemType==27) return true; 
  } 
  return false; 
} 

// return true if i have a poker equipped in primary hand. 
bool CanStab() { 
  PCONTENTS pItem=GetCharInfo2()->Inventory.Primary; 
  return (!pItem)?false:(pItem->Item->ItemType==2); 
} 

// return true if you could bash (have a shield in secondary or a 2h weapon in primary with 2 hand 

bool CanBash() { 
  PCONTENTS pItem=GetCharInfo2()->Inventory.Secondary; 
  if(pItem) return (pItem->Item->ItemType==8); 
  pItem=GetCharInfo2()->Inventory.Primary; 
  return (pItem && (pItem->Item->ItemType==1 || pItem->Item->ItemType==4 || pItem->Item->ItemType==35) && AltAvail("2 Hand Bash")); 
} 

// turn off attack 
void AttackOFF(PCHAR DisplayWhy, bool PassToPet) { 
  if(*EQADDR_ATTACK) HideDoCommand(GetCharInfo()->pSpawn,"/attack off",FromPlugin); 
  if(PassToPet) { 
    PetCommand("hold"); 
    PetCommand("back off"); 
  } 
  if(strlen(DisplayWhy)) WriteChatColor(DisplayWhy,CONCOLOR_YELLOW); 
} 

// turn on attack 
void AttackON(PCHAR DisplayWhy, bool PassToPet) { 
  if(strlen(DisplayWhy)) WriteChatColor(DisplayWhy,CONCOLOR_YELLOW); 
  PSPAWNINFO CurrTar=(ppTarget && pTarget)?(PSPAWNINFO)pTarget:NULL; 
  if(CurrTar!=TarKill) return; 
  if(!*EQADDR_ATTACK) HideDoCommand(GetCharInfo()->pSpawn,"/attack on",FromPlugin); 
  if(PassToPet) { 
    PetCommand("attack"); 
    PetCommand("focus"); 
  } 
} 

// 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); 
} 

//================================================================// 

int SetSkillOnOff(PCHAR SkillName, PCHAR SkillCheck, PCHAR Setting, int Cur) { 
  char Buffer[MAX_STRING]; 
  int  Result=OnOff(Setting,strlen(SkillCheck)?SkillTrain(SkillCheck):0,Cur); 
  WriteChatf("MQ2Melee:: %s (%s)%s",SkillName,Result?"\agon\ax":"\aroff\ax",!strlen 

(SkillCheck)?".":SkillAvail(SkillCheck)?" \agMAPPED\ax.":" \arNOTMAPPED\ax."); 
  WritePrivateProfileString(GetCharInfo()->Name,SkillName,itoa(Result,Buffer,10),INIFileName); 

  return Result; 
} 

int SetSkillValue(PCHAR SkillName, PCHAR SkillCheck, PCHAR Setting, int Cur) { 
  char Buffer[MAX_STRING]; 
  int Result=atoi(Setting); 
  if(Result) sprintf(Buffer,"\ag%d\ax",Result); else sprintf(Buffer,"\aroff\ax"); 
  WriteChatf("MQ2Melee:: %s (%s)%s",SkillName,Buffer,!strlen(SkillCheck)?".":SkillAvail 

(SkillCheck)?" \agMAPPED\ax.":" \arNOTMAPPED\ax."); 
  WritePrivateProfileString(GetCharInfo()->Name,SkillName,itoa(Result,Buffer,10),INIFileName); 
  return Result; 
} 

void PutSkillOnOff(PCHAR SkillName, PCHAR SkillCheck, int Cur, PCHAR ShowHelp) { 
  if(strlen(SkillCheck) && !SkillTrain(SkillCheck)) return; 
  WriteChatf("MQ2Melee:: %s (%s) <%s>%s",SkillName,Cur?"\agon\ax":"\aroff\ax",ShowHelp,!strlen 

(SkillCheck)?".":SkillAvail(SkillCheck)?" \agMAPPED\ax.":" \arNOTMAPPED\ax."); 
} 

void PutSkillValue(PCHAR SkillName, PCHAR SkillCheck, int Cur, PCHAR ShowHelp) { 
  if(strlen(SkillCheck) && !SkillTrain(SkillCheck)) return; 
  char Buffer[MAX_STRING]; sprintf(Buffer,"\ag%d\ax",Cur); 
  WriteChatf("MQ2Melee:: %s (%s) <%s>%s",SkillName,Cur?Buffer:"\aroff\ax",ShowHelp,!strlen 

(SkillCheck)?".":SkillAvail(SkillCheck)?" \agMAPPED\ax.":" \arNOTMAPPED\ax."); 
} 

void MeleeCmd(PSPAWNINFO pCHAR, PCHAR Cmd) { 
  char Tmp[MAX_STRING]; BYTE Parm=1; 
  char Var[MAX_STRING]; bool Help=0; 
  char Set[MAX_STRING]; 
  char Err[MAX_STRING]; sprintf(Err," \arNOT MAPPED\ax"); 
  char Dot[MAX_STRING]; sprintf(Dot,"."); 
  do { 
    GetArg(Tmp,Cmd,Parm++); 
    GetArg(Var,Tmp,1,FALSE,FALSE,FALSE,'='); 
    GetArg(Set,Tmp,2,FALSE,FALSE,FALSE,'='); 
    if(!strlen(Tmp)) { 
      if(Parm==2) Help=1; 
    } else if(!strnicmp(Tmp,"on",2) || !strnicmp(Tmp,"off",3)) { doSKILL=SetSkillOnOff 

("Plugin","",Tmp,doSKILL); 
    } else if(!strnicmp(Var,"aggro",5)) { 
       doAGGRO=SetSkillOnOff("Aggro","",Set,doAGGRO); 
       if(doAGGRO) onPROVOKE=(doPROVOKE && doAGGRO && Grouped())?true:false; 
    } else if(!strnicmp(Var,"Provoke",7)) { 
       doPROVOKE=SetSkillValue("Provoke","",Set,doPROVOKE); 
       if(doPROVOKE) onPROVOKE=(doPROVOKE && doAGGRO && Grouped())?true:false; 
    } else if(!strnicmp(Var,"Melee",5)) { doMELEE=SetSkillValue("Melee","",Set,doMELEE); 
    } else if(!strnicmp(Var,"Range",5)) { doRANGE=SetSkillValue("Range","",Set,doRANGE); 
    } else if(!strnicmp(Var,"BackStab",8)) { doBACKSTAB=SetSkillValue 

("BackStab","BackStab",Set,doBACKSTAB); 
    } else if(!strnicmp(Var,"Bash",4)) { doBASH=SetSkillOnOff("Bash","Bash",Set,doBASH); 
    } else if(!strnicmp(Var,"Begging",7)) { doBEGGING=SetSkillOnOff 

("Begging","Begging",Set,doBEGGING); 
    } else if(!strnicmp(Var,"Disarm",6)) { doDISARM=SetSkillOnOff("Disarm","Disarm",Set,doDISARM); 
    } else if(!strnicmp(Var,"DragonPunch",11)) { doDRAGONPUNCH=SetSkillOnOff("DragonPunch","DragonPunch",Set,doDRAGONPUNCH); 
    } else if(!strnicmp(Var,"EagleStrike",11)) { doEAGLESTRIKE=SetSkillOnOff("EagleStrike","EagleStrike",Set,doEAGLESTRIKE); 
    } else if(!strnicmp(Var,"FlyingKick",10)) { doFLYINGKICK=SetSkillOnOff("FlyingKick","FlyingKick",Set,doFLYINGKICK); 
    } else if(!strnicmp(Var,"Forage",6)) { doFORAGE=SetSkillOnOff("Forage","Forage",Set,doFORAGE); 
    } else if(!strnicmp(Var,"Frenzy",6)) { doFRENZY=SetSkillOnOff("Frenzy","Frenzy",Set,doFRENZY); 
    } else if(!strnicmp(Var,"Hide",4)) { doHIDE=SetSkillOnOff("Hide","Hide",Set,doHIDE); 
    } else if(!strnicmp(Var,"Intimidation",12)) { doINTIMIDATION=SetSkillOnOff("Intimidation","Intimidation",Set,doINTIMIDATION); 
    } else if(!strnicmp(Var,"Kick",4)) { doKICK=SetSkillOnOff("Kick","Kick",Set,doKICK); 
    } else if(!strnicmp(Var,"Slam",4)) { doSLAM=SetSkillOnOff("Slam","111",Set,doSLAM); 
    } else if(!strnicmp(Var,"PickPockets",11)) { doPICKPOCKETS=SetSkillOnOff("PickPockets","PickPockets",Set,doPICKPOCKETS); 
    } else if(!strnicmp(Var,"RoundKick",9)) { doROUNDKICK=SetSkillOnOff("RoundKick","RoundKick",Set,doROUNDKICK); 
    } else if(!strnicmp(Var,"SenseTraps",10)) { doSENSETRAPS=SetSkillOnOff("SenseTraps","SenseTraps",Set,doSENSETRAPS); 
    } else if(!strnicmp(Var,"Sneak",5)) { doSNEAK=SetSkillOnOff("Sneak","Sneak",Set,doSNEAK); 
    } else if(!strnicmp(Var,"Taunt",5)) { doTAUNT=SetSkillOnOff("Taunt","Taunt",Set,doTAUNT); 
    } else if(!strnicmp(Var,"TigerClaw",9)) { doTIGERCLAW=SetSkillOnOff("TigerClaw","TigerClaw",Set,doTIGERCLAW); 
    } else if(!strnicmp(Var,"Enrage",6)) { doENRAGE=SetSkillOnOff("Enrage","",Set,doENRAGE); 
    } else if(!strnicmp(Var,"Infuriate",9)) { doINFURIATE=SetSkillOnOff("Infuriate","",Set,doINFURIATE); 
    } else if(!strnicmp(Var,"Mend",4)) { doMENDS=SetSkillValue("Mend","Mend",Set,doMENDS); 
    } else if(!strnicmp(Var,"BackOff",7)) { doBKOFF=SetSkillValue("BackOff","",Set,doBKOFF); 
    } else if(!strnicmp(Var,"Evade",5)) { doEVADE=SetSkillValue("Evade","Hide",Set,doEVADE); 
    } else if(!strnicmp(Var,"FeignDeath",10)) { doFEIGN=SetSkillValue("FeignDeath","FeignDeath",Set,doFEIGN); 
    } else if(!strnicmp(Var,"Resume",6)) { doSTAND=SetSkillValue("Resume","",Set,doSTAND); 
    } else if(!strnicmp(Var,"PetAssist",9)) { doPETASSIST=SetSkillOnOff("PetAssist","",Set,doPETASSIST); 
    } else if(!strnicmp(Var,"FeralSwipe",10)) { doFERAL=SetSkillOnOff("FeralSwipe","",Set,doFERAL); 
    } else if(!strnicmp(Var,"ThrowStone",10)) { doTHROWSTONE=SetSkillValue("ThrowStone","",Set,doTHROWSTONE); 
    } else if(!strnicmp(Var,"RageVolley",10)) { doRAGEVOLLEY=SetSkillValue("RageVolley","",Set,doRAGEVOLLEY); 
    } else if(!strnicmp(Var,"LeopardClaw",11)) { doLEOPARDCLAW=SetSkillValue("LeopardClaw","",Set,doLEOPARDCLAW); 
    } else { 
      WriteChatf("MQ2Melee:: Unsupported Argument <\ar%s\ax>",Tmp); 
      Help++; 
    } 
  } while(strlen(Tmp)); 
  if(Help) { 
    WriteChatf("MQ2Melee:: ABILITIES LIST & SETTING"); 
    WriteChatf("-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-"); 
    PutSkillOnOff("Plugin","",doSKILL,"Turn On/Off Entire Plugin"); 
    PutSkillValue("Melee","",doMELEE,"Max Range to be in 'MELEE'"); 
    PutSkillValue("Range","",doRANGE,"Min Range to be in 'ARCHERY'"); 
    PutSkillOnOff("Aggro","",doAGGRO,"Aggro=ON BackOff/Evade/Feign=OFF"); 
    WriteChatf("-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-"); 
    PutSkillValue("BackStab","BackStab",doBACKSTAB,"+-Angle Back or Off|Need Poker"); 
    PutSkillOnOff("Bash","Bash",doBASH,"On/Off|Need Shield"); 
    PutSkillOnOff("Begging","Begging",doBEGGING,"On/Off"); 
    PutSkillOnOff("Disarm","Disarm",doDISARM,"On/Off"); 
    PutSkillOnOff("DragonPunch","Dragon Punch",doDRAGONPUNCH,"On/Off"); 
    PutSkillOnOff("EagleStrike","Eagle Strike",doEAGLESTRIKE,"On/Off"); 
    PutSkillOnOff("FlyingKick","Flying Kick",doFLYINGKICK,"On/Off"); 
    PutSkillOnOff("Forage","Forage",doFORAGE,"On/Off"); 
    PutSkillOnOff("Frenzy","Frenzy",doFRENZY,"On/Off"); 
    PutSkillOnOff("Hide","Hide",doHIDE,"On/Off"); 
    PutSkillOnOff("Intimidation","Intimidation",doINTIMIDATION,"On/Off"); 
    PutSkillOnOff("Kick","Kick",doKICK,"On/Off"); 
    PutSkillOnOff("Slam","Slam",doSLAM,"On/Off"); 
    PutSkillOnOff("PickPockets","Pick Pockets",doPICKPOCKETS,"On/Off"); 
    PutSkillOnOff("RoundKick","Round Kick",doROUNDKICK,"On/Off"); 
    PutSkillOnOff("SenseTraps","Sense Traps",doSENSETRAPS,"On/Off"); 
    PutSkillOnOff("Sneak","Sneak",doSNEAK,"On/Off"); 
    PutSkillOnOff("Taunt","Taunt",doTAUNT,"On/Off"); 
    PutSkillOnOff("TigarClaw","Tiger Claw",doTIGERCLAW,"On/Off"); 
    WriteChatf("-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-");    
    PutSkillOnOff("Enrage","",doENRAGE,"On/Off"); 
    PutSkillOnOff("Infuriate","",doINFURIATE,"On/Off"); 
    if(ClassInfo[GetCharInfo2()->Class & 0xff].PetClass) 
      PutSkillOnOff("PetAssist","",doPETASSIST,"Assist on Engage/Enrage"); 
    PutSkillValue("Mend","Mend",doMENDS,"Mend Wound if Life% Below/Off"); 
    PutSkillValue("BackOff","",doBKOFF,"Attack Off if Life% Below/Off"); 
    PutSkillValue("Evade","Hide",doEVADE,"Attack Off && Hide if Life% Below/Off"); 
    PutSkillValue("Feign Death","Feign Death",doFEIGN,"Feign if Life% Below/Off"); 
    PutSkillValue("Resume","",doSTAND,"Stand & Attack if Life% Above/Off"); 
    WriteChatf("-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-");    
    if(AltAvail("Feral Swipe")) PutSkillOnOff("FeralSwipe","",doFERAL,"On/Off"); 
    if(CABAvail("Throw Stone")) PutSkillValue("ThrowStone","",doTHROWSTONE,"Throw Stone if Endu%Above/Off"); 
    if(CABAvail("Bazu Bellow") || CABAvail("Ancient Chaos Cry") || CABAvail("Bellow of the Mastruq")|| 
       CABAvail("Incite") || CABAvail("Berate") || CABAvail("Bellow") || CABAvail("Provoke")) 
       PutSkillValue("Provoke","",doPROVOKE,"Provoke (once) if Endu% Above/Off"); 
    if(CABAvail("Rage Volley") || 
       CABAvail("Destroyer's Volley")) 
       PutSkillValue("RageVolley","",doRAGEVOLLEY,"Rage Volley if Endu% Above/Off"); 
    if(CABAvail("Leopard Claw") || 
       CABAvail("Dragon Fang")) 
       PutSkillValue("LeopardCalw","",doLEOPARDCLAW,"Leopard Claw Disc if Endu% Above/Off"); 
  } 
} 
//================================================================// 

PLUGIN_API VOID InitializePlugin(VOID) { 
  AddCommand("/Melee",MeleeCmd); 
} 

PLUGIN_API VOID ShutdownPlugin(VOID) { 
  RemoveCommand("/Melee"); 
} 

PLUGIN_API VOID SetGameState(DWORD GameState) { 
  if(InGames()) LoadINI(); 
} 

PLUGIN_API VOID OnPulse(VOID) { 
  if(!doSKILL || !InGames() || Stunned() || Casting() || !Windows()) return; 

  PctLife=GetCurHPS()*100/GetMaxHPS(); 
  if(GetCharInfo()->standstate!=STANDSTATE_FEIGN) { 
    if(onEVADE && PctLife>=doSTAND) onEVADE=false; 
  } else if(doAGGRO || (!onEVADE && PctLife>=doSTAND)) HideDoCommand(GetCharInfo()->pSpawn,"/stand",FromPlugin); 
  if(GetCharInfo()->standstate!=STANDSTATE_STAND) return; 
  if(doMENDS && PctLife<doMENDS && SkillReady("Mend")) SkillPress("Mend"); 

  // NPC on Target? 
  PSPAWNINFO CurrTar=(ppTarget && pTarget)?(PSPAWNINFO)pTarget:NULL; 
  if((TarType=SpawnType(CurrTar))==NPC) { 
    TarDist=DistanceToSpawn(GetCharInfo()->pSpawn,CurrTar); 

    // target is a NPC, in Range, Standing, in Line of Sight? in good Angle? 
    if(TarDist<175.0f && CurrTar->StandState && 
       LineOfSight(GetCharInfo()->pSpawn,CurrTar) && 
       HeadingAngle(GetCharInfo()->pSpawn,CurrTar)<42.5f ) { 

      // check we engage a brand new target? 
      if(!gbRangedAttackReady && CurrTar!=TarKill) { 
        WriteChatf("MQ2Melee:: <\ay%s\ax>",CurrTar->DisplayedName); 
        TarKill=CurrTar; 
        onENRAGE=false; 
        onINFURIATE=false; 
        onEVADE=false; 
        onSTEAL=false; 
        onPROVOKE=(doPROVOKE && doAGGRO && Grouped())?true:false; 
        PetCommand("attack"); 
        PetCommand("focus"); 
      } 
  
      // Kill this target if we not evading/backoff/feigning? 
      if(CurrTar==TarKill && !onEVADE) { 

        // target in archery range 
        if(doRANGE && TarDist>=doRANGE && gbRangedAttackReady && CanRange()) 
          HideDoCommand(GetCharInfo()->pSpawn,"/ranged",FromPlugin); 

        // target in melee range 
        if(doMELEE && TarDist<=doMELEE) { 
          TarBack=fabs(AngularDistance(CurrTar->Heading,GetCharInfo()->pSpawn->Heading)); 

          // pickpockets/begging required a target and attack off 
          if(doPICKPOCKETS && SkillReady("Pick Pockets") && !doAGGRO) { 
            onSTEAL=false; 
            if(*EQADDR_ATTACK) onSTEAL=true; 
            else SkillPress("Pick Pockets"); 
          } else if(doBEGGING && SkillReady("Begging") && !doAGGRO) { 
            onSTEAL=false; 
            if(*EQADDR_ATTACK) onSTEAL=true; 
            else SkillPress("Begging"); 
          } 

          // attack is off should we turn it on? 
          if(!*EQADDR_ATTACK && !onSTEAL) { 
            if((!onENRAGE && !onINFURIATE) || (TarBack<60.0f && !onINFURIATE)) AttackON("",false); 
          } 
    
          // those skills need attack on 
          if(*EQADDR_ATTACK) { 
            if(doTAUNT && doAGGRO && !GotAggro() && SkillReady("Taunt")) SkillPress("Taunt"); 
            if(doBASH && SkillReady("Bash") && CanBash()) SkillPress("Bash"); 
            if(doBACKSTAB && SkillReady("BackStab") && CanStab() && TarBack<doBACKSTAB) SkillPress 

("BackStab"); 
            if(doDISARM && SkillReady("Disarm") && CurrTar->Holding) SkillPress("Disarm"); 
            if(doFRENZY && SkillReady("Frenzy")) SkillPress("Frenzy"); 
            if(doFLYINGKICK && SkillReady("Flying Kick")) SkillPress("Flying Kick"); 
            if(doDRAGONPUNCH && SkillReady("Dragon Punch")) SkillPress("Dragon Punch"); 
            if(doEAGLESTRIKE && SkillReady("Eagle Strike")) SkillPress("Eagle Strike"); 
            if(doTIGERCLAW && SkillReady("Tiger Claw")) SkillPress("Tiger Claw"); 
            if(doROUNDKICK && SkillReady("Round Kick")) SkillPress("Round Kick"); 
            if(doKICK && SkillReady("Kick")) SkillPress("Kick"); 
            if(doSLAM && (SkillReady("Kick") || SkillReady("Bash"))) SkillPress("111"); 
            if(doINTIMIDATION && SkillReady("Intimidation")) SkillPress("Intimidation"); 
          } 
        } 

        // time to use some alt/combat abilities? 
        if((onCLOCK=GetCharInfo()->pSpawn->pActorInfo->TimeStamp)>onTIMER) { 

          // Beast Feral Swipe 
          if(!aabug && doFERAL && TarDist<50.0f && !AltTimer("Feral Swipe")) { 
            AltPress("Feral Swipe"); 
            onTIMER=onCLOCK+3000; 
            return; 
          } 
        
          // combat abilities 
          if(!cabug) { 
            TarLife=((PSPAWNINFO)pTarget)->HPCurrent; 
            CurEndu=GetCharInfo2()->Endurance; 
            PctEndu=CurEndu*100/GetMaxEndurance(); 
            PSPELL pSpell=NULL; 

            // Monk Leopard Claw / Dragon Fang Discipline 
            if(!pSpell && doLEOPARDCLAW && PctEndu>doLEOPARDCLAW && CurEndu>240 && TarDist<50.0f && 

(doAGGRO || (!doAGGRO && TarLife<70)) && !CABTimer("Leopard Claw")) { 
              pSpell=CABByName("Dragon Fang"); 
              if(!pSpell) pSpell=CABByName("Leopard Claw"); 
            } 
          
            // Warrior Provoke Discipline 
            if(!pSpell && onPROVOKE && PctEndu>doPROVOKE && CurEndu>=350 && TarDist<100.0f && ! 

CABTimer("Provoke")) { 
              pSpell=CABByName("Bazu Bellow"); 
              if(!pSpell) pSpell=CABByName("Ancient Chaos Cry"); 
              if(!pSpell) pSpell=CABByName("Bellow of the Mastruq"); 
              if(!pSpell) pSpell=CABByName("Incite"); 
              if(!pSpell) pSpell=CABByName("Berate"); 
              if(!pSpell) pSpell=CABByName("Bellow"); 
              if(!pSpell) pSpell=CABByName("Provoke"); 
            } 
          
          
            // Berserker Rage Volley / Destroyer's Volley Discipline 
            if(!pSpell && doRAGEVOLLEY && PctEndu>doRAGEVOLLEY && CurEndu>=95 && TarDist<175.0f && 

!CABTimer("Rage Volley")) { 
              pSpell=CABByName("Destroyer's Volley"); 
              if(!pSpell) pSpell=CABByName("Rage Volley"); 
            } 
          
            // Monk/Warrior/Rogue/Berserker Throw Stone Discipline 
            if(!pSpell && !onPROVOKE && doTHROWSTONE && PctEndu>doTHROWSTONE && CurEndu>=10 && 

TarDist<50.0f && !CABTimer("Throw Stone")) 
              pSpell=CABByName("Throw Stone"); 

            // Did we find a Combat Abilities to Use? 
            if(pSpell) { 
              CABPress(pSpell); 
              onTIMER=onCLOCK+3000; 
              return; 
            } 
          } 
        } 
      } 
    } 
  } 

  // time to feign/evade or backoff if we bleeding too much and not tanking? 
  if(!doAGGRO && (doBKOFF || doEVADE || doFEIGN)) { 
    if(GetCharInfo()->standstate!=STANDSTATE_FEIGN) { 
      if(doFEIGN && PctLife<doFEIGN && SkillReady("Feign Death")) { 
        SkillPress("Feign Death"); 
        onEVADE=true; 
        return; 
      } 
    } else if(!GetCharInfo()->pSpawn->HideMode) { 
      if(doEVADE && PctLife<doEVADE && SkillReady("Hide") && FindSpeed(GetCharInfo()->pSpawn)==0 && 

!gbMoving) { 
        if(!*EQADDR_ATTACK) SkillPress("Hide"); 
        onEVADE=true; 
      } 
    } else if(doBKOFF && PctLife<doBKOFF) { 
      onEVADE=true; 
    } 
  } 

  // check time to fire non combat skills? 
  if(!*EQADDR_ATTACK) { 
    if(SpawnType(TarKill)!=NPC && gbRangedAttackReady && !gbMoving && FindSpeed(GetCharInfo()->pSpawn)==0) { 
      if(doSENSETRAPS && SkillReady("Sense Traps")) SkillPress("Sense Traps"); 
      if(doHIDE && SkillReady("Hide") && GetCharInfo()->pSpawn->HideMode) SkillPress("Hide"); 
      if(doSNEAK && SkillReady("Sneak") && !GetCharInfo()->pSpawn->Sneak) SkillPress("Sneak"); 
      if(doFORAGE && SkillReady("Forage") && !GetCharInfo()->pSpawn->pActorInfo->Mount) SkillPress("Forage"); 
      if(!onHOLD && doPETASSIST) PetCommand("hold"); 
    } 

  // should we turn off attack so i could fire some skills? 
  } else if (onEVADE || onSTEAL || TarType!=NPC || CurrTar!=TarKill || (CurrTar && TarDist>30.0f && 

doRANGE && CanRange())) AttackOFF("",false); 
} 

PLUGIN_API DWORD OnIncomingChat(PCHAR Line, DWORD Color) { 
  if(!doSKILL || MQ2Globals::gGameState!=GAMESTATE_INGAME) return 0; 
  
  // check has fallen to the ground message 
  if(Color==USERCOLOR_DEFAULT && !strncmp(Line,Fallen,strlen(Fallen))) { 
    HideDoCommand(GetCharInfo()->pSpawn,"/stand",FromPlugin); 
    return 0; 
  } 
  
  // check for enrage/infuriate message 
  if(Color==USERCOLOR_NPC_ENRAGE && (doENRAGE || doINFURIATE) && TarKill) { 
  
    // make sure it's our target! 
    if(strncmp(Line,TarKill->DisplayedName,strlen(TarKill->DisplayedName)) || 
      (strstr(Line,"pet") && !strstr(TarKill->DisplayedName,"pet"))) return 0; 

    // turn off attack on enrage 
    if(doENRAGE && strstr(Line,"has become ENRAGED")) { 
      AttackOFF("MQ2Melee::\arENRAGE\ax detected, turning attack off.",true); 
      onENRAGE=true; 
      return 0; 
    } 

    // turn off attack on infuriate 
    if(doINFURIATE && strstr(Line,"is infuriated")) { 
      AttackOFF("MQ2Melee::\arINFURIATE\ax detected, turning attack off.",true); 
      onINFURIATE=true; 
      return 0; 
    } 

    // turn back on attack if no longer enrage and not infuriated 
    if(strstr(Line,"is no longer enraged")) { 
      if(!onINFURIATE) AttackON("MQ2Melee::ENRAGE/INFURIATE ended resuming attack.",true); 
      onENRAGE=false; 
      return 0; 
    } 

    // turn back on attack if no longer infuriated and not enrage 
    if(strstr(Line,"no longer infuriated")) { 
      if(!onENRAGE) AttackON("MQ2Melee::ENRAGE/INFURIATE ended resuming attack.",true); 
      onINFURIATE=false; 
      return 0; 
    } 
  } 
  return 0; 
}
 
EMU MQ2Melee

Users who are viewing this thread

Back
Top
Cart