• You've discovered RedGuides 📕 an EverQuest multi-boxing community 🛡️🧙🗡️. We want you to play several EQ characters at once, come join us and say hello! 👋
  • IS THIS SITE UGLY? Change the look. To dismiss this notice, click the X --->
Resource icon

Plugin - MQ2Cast (1 Viewer)

Jensen

New member
Joined
Mar 19, 2007
RedCents
926¢
Hi, I'm using mq2melee/ cast for buffs, but atm I can only make it use bagged items if I have the bag open the clickies are in. I have the new bagwindow too, anyone know whats up?
 
I have tried doing the same steps above but I still get the message Mq2 Bagwindow detected but not loaded please use /loadskin and reload your UI.

But no matter how many times I load the Ui I cant get the back window to load... :/
 
mqui_bagwnd.xml is in my default folder and I have been trying both the /skin thing and loading it thou the EQ then options butten. Sadly still no luck.
 
If you're talking about using the current MQ2Cast and putting it into a P99 compile, then the answer is no, it won't. The coding structure of P99 is nothing at all like the current live version. There have been an uncountable number of structure, op-code, and offset changes over the years. MQ2Cast would need to essentially be downgraded accordingly.
 
This should work on the Titanium build (P99)

Rich (BB code):
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=//
// Projet: MQ2Cast.cpp		| Set DEBUGGING 0 or 1 (false/true) for DEBUGGING msg
// Author: s0rCieR			  | 
//			   A_Enchanter_00 |
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=//
// Last edited by: Kroak on 12-8-07
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=//
 
#define       DEBUGGING         0
 
#ifndef PLUGIN_API
  #include "../MQ2Plugin.h"
  #include "../Blech/Blech.h"
  PreSetup("MQ2Cast");
#endif
 
#define       GEMS_MAX          10
 
#define       DELAY_CAST    12000
#define       DELAY_MEMO     6000
#define       DELAY_STOP     3000
#define       DELAY_PULSE     125
 
#define       CAST_SUCCESS      0
#define       CAST_INTERRUPTED  1
#define       CAST_RESIST       2
#define       CAST_COLLAPSE     3
#define       CAST_RECOVER      4
#define       CAST_FIZZLE       5
#define       CAST_STANDING     6
#define       CAST_STUNNED      7
#define       CAST_INVISIBLE    8
#define       CAST_NOTREADY     9
#define       CAST_OUTOFMANA   10
#define       CAST_OUTOFRANGE  11
#define       CAST_NOTARGET    12
#define       CAST_CANNOTSEE   13
#define       CAST_COMPONENTS  14
#define       CAST_OUTDOORS    15
#define       CAST_TAKEHOLD    16
#define       CAST_IMMUNE      17
#define       CAST_DISTRACTED  18
#define       CAST_ABORTED     19
#define       CAST_UNKNOWN     20
 
#define       FLAG_COMPLETE     0 
#define       FLAG_REQUEST     -1
#define       FLAG_PROGRESS1   -2 
#define       FLAG_PROGRESS2   -3 
#define       FLAG_PROGRESS3   -4 
#define       FLAG_PROGRESS4   -5 
 
#define       DONE_COMPLETE    -3
#define       DONE_ABORTED     -2 
#define       DONE_PROGRESS    -1 
#define       DONE_SUCCESS      0
 
#define       TYPE_SPELL        1
#define       TYPE_ALT          2
#define       TYPE_ITEM         3
 
#define       RECAST_DEAD       2
#define       RECAST_LAND       1
#define       RECAST_ZERO       0
 
#define       NOID             -1
#define       NUM_INV_SLOTS    30

//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=//
 
bool          Immobile = false;        // Immobile?
bool          Invisible= false;        // Invisibility Check?
bool          Twisting = false;        // Twisting?
bool          Casting  = false;        // Casting Window was opened?
long          Resultat = CAST_SUCCESS; // Resultat
long          ImmobileT= 0;            // Estimate when it be immobilized!
 
long          CastingD=NOID;           // Casting Spell Detected
long          CastingC=NOID;           // Casting Current ID
long          CastingE=CAST_SUCCESS;   // Casting Current Result
long          CastingL=NOID;           // Casting LastOne ID
long          CastingX=CAST_SUCCESS;   // Casting LastOne Result
long          CastingT=0;              // Casting Timeout
long          CastingO=NOID;           // Casting OnTarget
long          CastingP=0;              // Casting Pulse
 
long          TargI=0;                 // Target ID
long          TargC=0;                 // Target Current
 
long          StopF=FLAG_COMPLETE;     // Stop Event Flag Progress? 
long          StopE=DONE_SUCCESS;      // Stop Event Exit Value 
long          StopM=0;                 // Stop Event Mark 
 
long          MoveA=FLAG_COMPLETE;     // Move Event AdvPath? 
long          MoveS=FLAG_COMPLETE;     // Move Event Stick? 
long          MoveP=FLAG_COMPLETE;     // Move Event MQ2AdvPath?

long          MemoF=FLAG_COMPLETE;     // Memo Event Flag 
long          MemoE=DONE_SUCCESS;      // Memo Event Exit 
long          MemoM=0;                 // Memo Event Mark 
 
long          ItemF=FLAG_COMPLETE;     // Item Flag
long          ItemA[NUM_INV_SLOTS];         // Item Arrays
 
long          DuckF=FLAG_COMPLETE;     // Duck Flag
long          DuckM=0;                 // Duck Time Stamp
 
long          CastF=FLAG_COMPLETE;     // Cast Flag
long          CastE=CAST_SUCCESS;      // Cast Exit Return value
long          CastG=NOID;              // Cast Gem ID
void         *CastI=NULL;              // Cast ID   [spell/alt/item]
long          CastK=NOID;              // Cast Kind [spell/alt/item]
long          CastT=0;                 // Cast Time [spell/alt/item]
long          CastM=0;                 // Cast TimeMark Start Casting
long          CastR=0;                 // Cast Retry Counter
long          CastW=0;                 // Cast Retry Type
char          CastB[MAX_STRING];       // Cast Bandolier In
char          CastC[MAX_STRING];       // Cast SpellType
char          CastN[MAX_STRING];       // Cast SpellName
PSPELL        CastS=NULL;              // Cast Spell Pointer
 
bool          Parsed=false;            // BTree List Found Flags
Blech         LIST013('#');            // BTree List for OnChat Message on Color  13
Blech         LIST264('#');            // BTree List for OnChat Message on Color 264
Blech         LIST289('#');            // BTree List for OnChat Message on Color 289
Blech         UNKNOWN('#');            // BTree List for OnChat Message on UNKNOWN Yet Color
Blech         SUCCESS('#');            // BTree List for OnChat Message on SUCCESS Detection
 
PCONTENTS     fPACK=0;                 // ItemFound/ItemSearch - Find Pack Contents
PCONTENTS     fITEM=0;                 // ItemFound/ItemSearch - Find Item Contents
long          fSLOT=0;                 // ItemFound/ItemSearch - Find Item SlotID
// long		  SwapSlot=0;				// Item Swapped to slot#
long		  PulseCount=0;

PSPELL        fFIND;                   // SpellFind - Casting Spell Effect
void         *fINFO;                   // SpellFind - Casting Type Structure
int           fTYPE;                   // SpellFind - Casting Type
int           fTIME;                   // SpellFind - Casting Time
PCHAR         fNAME;                   // SpellFind - Casting Name
 
SPELLFAVORITE SpellToMemorize;         // Favorite Spells Array
long          SpellTotal;              // Favorite Spells Total
void WinClick(CXWnd *Wnd, PCHAR ScreenID, PCHAR ClickNotification, DWORD KeyState) ;
void ClickBack();
PCHAR         ListGems[]={"1","2","3","4","5","6","7","8","9","A","B","C","D","E","F"};
 
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=//
 
#define aCastEvent(List,Value,Filter) List.AddEvent(Filter,CastEvent,(void*)Value);
 
void __stdcall CastEvent(unsigned int ID, void *pData, PBLECHVALUE pValues) {
  Parsed=true;
  if(CastingE<(long)pData) CastingE=(long)pData;
  #if DEBUGGING
    WriteChatf("[%d] MQ2Cast:[OnChat]: Result=[%d] Called=[%d].",(long)clock(),CastingE,(long)pData);
  #endif
}
 
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=//
 
PALTABILITY AltAbility(PCHAR ID) {
  if(ID[0]) {
    int Number=IsNumber(ID);
    int Values=atoi(ID);
    for(DWORD nAbility=0; nAbility < AA_CHAR_MAX_REAL; nAbility++) {
      if(GetCharInfo2()->AAList[nAbility].AAIndex) if(PALTABILITY pAbility=pAltAdvManager->GetAltAbility(GetCharInfo2()->AAList[nAbility].AAIndex)) {
        if(Number) {
          if(pAbility->ID == Values) return pAbility;
        } else if(PCHAR pName=pCDBStr->GetString(pAbility->nName,1,NULL)) {
          if(!stricmp(ID,pName)) return pAbility;
        }
      }
    }
  }
  return NULL;
}
 
void Bandolier(PCHAR zFormat, ...) {
  typedef VOID (__cdecl *BandolierCALL) (PCHAR);
  char zOutput[MAX_STRING]; va_list vaList; va_start(vaList,zFormat);
  vsprintf(zOutput,zFormat,vaList);
  PMQPLUGIN pLook=pPlugins;
  while(pLook && strnicmp(pLook->szFilename,"MQ2Bandolier",12)) pLook=pLook->pNext;
  if(pLook)
    if(BandolierCALL Request=(BandolierCALL)GetProcAddress(pLook->hModule,"doBandolier"))
      Request(zOutput);
}
 
bool BardClass() {
  return (strncmp(pEverQuest->GetClassDesc(GetCharInfo2()->Class & 0xFF),"Bard",5))?false:true;
}
 
void Cast(PCHAR zFormat, ...) {
  char zOutput[MAX_STRING]={0}; va_list vaList; va_start(vaList,zFormat);
  vsprintf(zOutput,zFormat,vaList); if(!zOutput[0]) return;
//  WriteChatf("Cast = %s : zOutput %s  Line 193 - Cast()",GetCharInfo()->pSpawn,zOutput);
  Cast(GetCharInfo()->pSpawn,zOutput);
}
 
long CastingLeft() {
  long CL=0;
  if(pCastingWnd && (PCSIDLWND)pCastingWnd->Show) {
    CL=GetCharInfo()->pSpawn->SpellETA - GetCharInfo()->pSpawn->TimeStamp;
    if(CL<1) CL=1;
  }
  return CL;
}
long Evaluate(PCHAR zFormat, ...) {
  char zOutput[MAX_STRING]={0}; va_list vaList; va_start(vaList,zFormat);
  vsprintf(zOutput,zFormat,vaList); if(!zOutput[0]) return 1;
  ParseMacroData(zOutput); return atoi(zOutput);
}
 
void CastTimer(int TargetID,int SpellID,long TickE) {
  typedef VOID (__cdecl *CastTimerCALL) (int,int,long);
  PMQPLUGIN pLook=pPlugins;
  while(pLook && strnicmp(pLook->szFilename,"MQ2Casttimer",11)) pLook=pLook->pNext;
  if(pLook && pLook->fpVersion>1.1100)
    if(CastTimerCALL Request=(CastTimerCALL)GetProcAddress(pLook->hModule,"TimerCastHandle"))
      Request(TargetID, SpellID, TickE);
}
 
void Exchange(PCHAR zFormat, ...) {
  typedef VOID (__cdecl *ExchangeCALL) (PCHAR);
  char zOutput[MAX_STRING]; va_list vaList; va_start(vaList,zFormat);
  vsprintf(zOutput,zFormat,vaList);
  PMQPLUGIN pLook=pPlugins;
  while(pLook && strnicmp(pLook->szFilename,"MQ2Exchange",11)) pLook=pLook->pNext;
  if(pLook && pLook->fpVersion>1.1500)
    if(ExchangeCALL Request=(ExchangeCALL)GetProcAddress(pLook->hModule,"doExchange"))
      Request(zOutput);
}

void Execute(PCHAR zFormat, ...) {
  char zOutput[MAX_STRING]={0}; va_list vaList; va_start(vaList,zFormat);
  vsprintf(zOutput,zFormat,vaList); if(!zOutput[0]) return;
  DoCommand(GetCharInfo()->pSpawn,zOutput);
}
 
bool Flags() {
  if(!BardClass() && pCastingWnd && (PCSIDLWND)pCastingWnd->Show) return true;
  if(CastF!=FLAG_COMPLETE) return true;
  if(DuckF!=FLAG_COMPLETE) return true;
  if(ItemF!=FLAG_COMPLETE) return true;
  if(MemoF!=FLAG_COMPLETE) return true;
  if(StopF!=FLAG_COMPLETE) return true;
  if(MoveS!=FLAG_COMPLETE) return true;
  if(MoveP!=FLAG_COMPLETE) return true;
  if(MoveA!=FLAG_COMPLETE) return true;
  return false;
} 
 
long GEMID(DWORD ID) {
  for(int GEM=0; GEM < GEMS_MAX; GEM++) if(GetCharInfo2()->MemorizedSpells[GEM] == ID) return GEM;
  return NOID;
}
 
bool GEMReady(DWORD ID) {
  if(pCastSpellWnd && ID < GEMS_MAX)
    if((long)((PEQCASTSPELLWINDOW)pCastSpellWnd)->SpellSlots[ID]->spellicon!=NOID)
      if(BardClass() || (long)((PEQCASTSPELLWINDOW)pCastSpellWnd)->SpellSlots[ID]->spellstate!=1)
        return true;
  return false;
}

bool GiftOfMana() {
	for (unsigned long nBuff=0 ; nBuff < 35 ; nBuff++) {
		if (PSPELL pSpell=GetSpellByID(GetCharInfo2()->ShortBuff[nBuff].SpellID)) {
			if (!stricmp("Gift of Mana",pSpell->Name)) {
				return true;
			}
		}
	}
	return false;
}

long ItemFound(long ID, long B, long E) {
  for(int iSlot=B; iSlot < E; iSlot++)
    if(PCONTENTS cSlot=GetCharInfo2()->InventoryArray[iSlot]) {
      if(ID == cSlot->Item->ItemNumber) {
        fSLOT=iSlot;
        fITEM=cSlot;
        fPACK=(iSlot>=BAG_SLOT_START)?cSlot:NULL;
        return true;
      } else if (cSlot->Item->Type == ITEMTYPE_PACK) {
        for(int iPack=0; iPack < cSlot->Item->Slots; iPack++) {
          if(PCONTENTS cPack=cSlot->Contents[iPack]) {
            if(ID == cPack->Item->ItemNumber) {
              fSLOT=(iSlot-BAG_SLOT_START)*10+262+iPack;
              fITEM=cPack; 
              fPACK=cSlot;
              return true;
            }
          }
        }
      }
    }
  fSLOT=0;
  fITEM=0;
  fPACK=0;
  return false;
}

long ItemSearch(PCHAR ID, long B, long E) {
  if(IsNumber(ID)) return ItemFound(atoi(ID),B,E);
  for(int iSlot=B; iSlot < E; iSlot++)
    if(PCONTENTS cSlot=GetCharInfo2()->InventoryArray[iSlot]) {
      if(!stricmp(ID,cSlot->Item->Name)) {
        fSLOT=iSlot;
        fITEM=cSlot;
        fPACK=(iSlot>=BAG_SLOT_START)?cSlot:NULL;
        return true;
      } else if (cSlot->Item->Type == ITEMTYPE_PACK) {
        for(int iPack=0; iPack < cSlot->Item->Slots; iPack++) {
          if(PCONTENTS cPack=cSlot->Contents[iPack]) {
WriteChatf("Checking contents of pack %d",iSlot);
            if(!stricmp(ID,cPack->Item->Name)) {
              fSLOT=(iSlot-BAG_SLOT_START)*10+262+iPack;
  WriteChatf("iSlot == %d : fSlot == %d",iSlot,fSLOT);
  WriteChatf("Compute fSlot? : %d",(BAG_SLOT_START+iSlot)/10+262+iPack);
//  PCONTENTS fPACK=GetCharInfo2()->InventoryArray[(InvSlot-262)/10+BAG_SLOT_START];
              fITEM=cPack; 
              fPACK=cSlot;
              return true;
            }
          }
        }
      }
    }
  fSLOT=0;
  fITEM=0;
  fPACK=0;
  return false;
} 
 
void MemoLoad(long Gem, PSPELL Spell) {
  if(!Spell || Spell->Level[GetCharInfo2()->Class-1]>GetCharInfo2()->Level) return;
  for(int sp=0;sp<GEMS_MAX;sp++)
    if(SpellToMemorize.SpellId[sp]==Spell->ID) SpellToMemorize.SpellId[sp]=0xFFFFFFFF;
  SpellToMemorize.SpellId[((DWORD)Gem<GEMS_MAX)?Gem:4]=Spell->ID;
}
 
float Speed() {
  float MySpeed=0.0f;
  if(PSPAWNINFO Self=GetCharInfo()->pSpawn) {
    MySpeed=Self->SpeedRun;
    if(PSPAWNINFO Mount=FindMount(Self))
      MySpeed=Mount->SpeedRun;
  }
  return MySpeed;
}
 
void Success(PSPELL Cast) {
  SUCCESS.Reset();
  if(Cast) {
    char Temps[MAX_STRING];
    bool Added=false;
    if(Cast->CastOnYou[0]) {
      sprintf(Temps,"%s#*#",Cast->CastOnYou);
      aCastEvent(SUCCESS,CAST_SUCCESS,Temps);
      Added=true;
    }
    if(Cast->CastOnAnother[0]) {
      sprintf(Temps,"#*#%s#*#",Cast->CastOnAnother);
      aCastEvent(SUCCESS,CAST_SUCCESS,Temps);
      Added=true;
    }
    if(!Added)
      aCastEvent(SUCCESS,CAST_SUCCESS,"You begin casting#*#");
  }
}
 
bool Moving() {
  long  MyTimer=(long)clock();
  if(Speed()!=0.0f) ImmobileT=MyTimer+500;
  return (!MQ2Globals::gbMoving && (!ImmobileT || MyTimer>ImmobileT));
}
 
BOOL Open(PCHAR WindowName) {
  PCSIDLWND pWnd=(PCSIDLWND)FindMQ2Window(WindowName);
  return (!pWnd)?false:(BOOL)pWnd->Show;
}
 
BOOL Paused() {
  if(BardClass()) return false;
  if(pLootWnd && (PCSIDLWND)pLootWnd->Show)         return true;
  if(pBankWnd && (PCSIDLWND)pBankWnd->Show)         return true;
  if(pMerchantWnd && (PCSIDLWND)pMerchantWnd->Show) return true;
  if(pTradeWnd && (PCSIDLWND)pTradeWnd->Show)       return true;
  if(pGiveWnd && (PCSIDLWND)pGiveWnd->Show)         return true;
  if(Open("TributeMasterWnd"))      return true;
  if(Open("GuildTributeMasterWnd")) return true;
  if(Open("GuildBankWnd"))          return true;
  return false;
}
 
void Reset() {
  TargI=0;                 // Target ID
  TargC=0;                 // Target Check ID
  StopF=FLAG_COMPLETE;     // Stop Event Flag Progress? 
  StopE=DONE_SUCCESS;      // Stop Event Exit Value 
  MoveA=FLAG_COMPLETE;     // Stop Event AdvPath? 
  MoveS=FLAG_COMPLETE;     // Stop Event Stick? 
  MoveP=FLAG_COMPLETE;     // Stop Event MQ2AdvPath?
  MemoF=FLAG_COMPLETE;     // Memo Event Flag 
  MemoE=DONE_SUCCESS;      // Memo Event Exit 
  ItemF=FLAG_COMPLETE;     // Item Flag
  DuckF=FLAG_COMPLETE;     // Duck Flag
  CastF=FLAG_COMPLETE;     // Cast Flag
  CastE=CAST_SUCCESS;      // Cast Exit Return value
  CastG=NOID;              // Cast Gem ID
  CastI=NULL;              // Cast ID   [spell/alt/item/disc]
  CastK=NOID;              // Cast Kind [spell/alt/item/disc] [-1=unknown]
  CastT=0;                 // Cast Time [spell/alt/item/disc]
  CastB[0]=0;              // Cast Bandolier In
  CastB[0]=0;              // Cast Bandolier Out
  CastC[0]=0;              // Cast SpellType
  CastN[0]=0;              // Cast SpellName
  CastR=1;                 // Cast Retry Counter
  CastW=0;                 // Cast Retry Type
  Invisible=false;         // Invisibility Check?
  ZeroMemory(&SpellToMemorize,sizeof(SPELLFAVORITE));
  strcpy(SpellToMemorize.Name,"Mem a Spell");
  SpellToMemorize.inuse=1;
  for(int sp=0;sp<GEMS_MAX;sp++) SpellToMemorize.SpellId[sp]=0xFFFFFFFF;
  SpellTotal=0;
}
 
long SlotEquip(PITEMINFO Item, long CurrSlotID, long WantSlotID) {
  BYTE Effects=((long)Item->Clicky.SpellID==NOID)?0:Item->Clicky.EffectType;
  long MaxSlot=(Effects==1 || Effects==3 || Effects==5)?NUM_INV_SLOTS-1:BAG_SLOT_START-1;
  if(CurrSlotID<=MaxSlot) return CurrSlotID;
  if(WantSlotID>NOID && WantSlotID<=MaxSlot) {
    if(WantSlotID>BAG_SLOT_START-1) {
      PCONTENTS pSlot=GetCharInfo2()->InventoryArray[WantSlotID];
      if(!pSlot || pSlot->Item->Type!=ITEMTYPE_PACK) return WantSlotID;
    } else if(Item->EquipSlots&(1<<WantSlotID)) return WantSlotID;
  }
  for(long Desired=MaxSlot; Desired>=0; Desired--) {
    if(Desired>BAG_SLOT_START-1) {
      PCONTENTS pSlot=GetCharInfo2()->InventoryArray[Desired];
      if (!pSlot || pSlot->Item->Type!=ITEMTYPE_PACK) return Desired;
    } else if(Item->EquipSlots&(1<<Desired)) return Desired;
  }
  return BAG_SLOT_START+7;
//  return NOID;
}
 
long SlotID(PCHAR ID) {
  long Search=IsNumber(ID); DWORD Number=atoi(ID);
  if(Search) return (Number<NUM_INV_SLOTS)?Number:NOID;
  for(Number=0; szItemSlot[Number]; Number++) if(!stricmp(ID,szItemSlot[Number])) return Number;
  return NOID;
}
 
PSPELL SpellBook(PCHAR ID) {
  if(ID[0]) {
    if(IsNumber(ID)) {
      int Number=atoi(ID);
      for(DWORD nSpell=0; nSpell < NUM_BOOK_SLOTS; nSpell++)
        if(GetCharInfo2()->SpellBook[nSpell]==Number)
          return GetSpellByID(Number);
    } else {
      for(DWORD nSpell=0; nSpell < NUM_BOOK_SLOTS; nSpell++)
        if(PSPELL pSpell=GetSpellByID(GetCharInfo2()->SpellBook[nSpell]))
			if (!stricmp(ID,pSpell->Name) || (strstr(pSpell->Name,"Rk. II") && !strnicmp(ID,pSpell->Name,strlen(pSpell->Name)-8))) return pSpell;
//          if(!stricmp(ID,pSpell->Name)) return pSpell;
    }
  }
  return NULL;
}
 
bool SpellFind(PCHAR ID, PCHAR TYPE) {
  if(ID[0]) {
    // assume it's an alt ability
    if(!TYPE[0] || !strnicmp(TYPE,"alt",3)) {
      if(PALTABILITY Search=AltAbility(ID)) {
        if(PSPELL spell=GetSpellByID(Search->SpellID)) {
          fFIND=spell; 
          fINFO=Search; 
          fTIME=fFIND->CastTime; 
          fNAME=(PCHAR)fFIND->Name; 
          fTYPE=TYPE_ALT; 
          return true; 
        } 
      }
    }
    // assume it's a spell
    if(!TYPE[0] || !strnicmp(TYPE,"gem",3) || IsNumber(TYPE)) {
      if(PSPELL Search=SpellBook(ID)) {
        fFIND=Search;
        fINFO=Search;
        fTIME=pCharData1->GetAACastingTimeModifier((EQ_Spell*)fFIND)+
              pCharData1->GetFocusCastingTimeModifier((EQ_Spell*)fFIND,0)+
              fFIND->CastTime;
        fNAME=(PCHAR)fFIND->Name;
        fTYPE=TYPE_SPELL;
        return true;
      }
    }
    // assume it's an item clicky
    if(ItemSearch(ID,0,NUM_INV_SLOTS)) if(fITEM->Item->Clicky.SpellID) {
      fFIND=GetSpellByID(fITEM->Item->Clicky.SpellID);
      fINFO=fITEM;
      fTIME=fITEM->Item->CastTime;
      fNAME=(PCHAR)fITEM->Item->Name;
      fTYPE=TYPE_ITEM;
      return true;
    }
  }
  fFIND=NULL;
  fINFO=NULL;
  fTYPE=0;
  return false;
}
 
long SpellTimer(long Type, void *Data) {
  int Ready;
  switch(Type) {
    case TYPE_SPELL:
      if(GEMReady(GEMID(((PSPELL)Data)->ID))) return 0;
      return (long)((PSPELL)Data)->FizzleTime;
    case TYPE_ALT:
      if(pAltAdvManager->GetCalculatedTimer(pPCData,(PALTABILITY)Data)>0) {
        pAltAdvManager->IsAbilityReady(pPCData,(PALTABILITY)Data,&Ready);
        return (Ready<1)?0:Ready*1000;
      }
      return 999999;
    case TYPE_ITEM:
      return GetItemTimer((PCONTENTS)Data)*1000;
  }
  return 999999;
}
 
bool SpellReady(PCHAR ID) { 
  if(ID[0]==0) return true;
  if(IsNumber(ID)) {
    long number=atoi(ID)-1;
    if((DWORD)number<GEMS_MAX) return GEMReady(number);
  }
  if(ID[0]=='M' && strlen(ID)==1)
    return !(Twisting=Evaluate("${If[${Twist.Twisting},1,0]}")?true:false);
  char zName[MAX_STRING]; GetArg(zName,ID,1,FALSE,FALSE,FALSE,'|');
  char zType[MAX_STRING]; GetArg(zType,ID,2,FALSE,FALSE,FALSE,'|');
  if(SpellFind(zName,zType)) if(!SpellTimer(fTYPE,fINFO)) return true;
  return false;
}
 
void Stick(PCHAR zFormat, ...) {
  typedef VOID (__cdecl *StickCALL) (PSPAWNINFO,PCHAR);
  char zOutput[MAX_STRING]; va_list vaList; va_start(vaList,zFormat);
  vsprintf(zOutput,zFormat,vaList);
  PMQPLUGIN pLook=pPlugins;
  while(pLook && strnicmp(pLook->szFilename,"MQ2MoveUtils",12)) pLook=pLook->pNext;
  if(pLook && pLook->RemoveSpawn)
    if(StickCALL Request=(StickCALL)GetProcAddress(pLook->hModule,"StickCommand"))
      Request(GetCharInfo()->pSpawn,zOutput);
}
 
void Path(PCHAR zFormat, ...) {
  typedef VOID (__cdecl *FollowCALL) (PSPAWNINFO,PCHAR);
  char zOutput[MAX_STRING]; va_list vaList; va_start(vaList,zFormat);
  vsprintf(zOutput,zFormat,vaList);
  PMQPLUGIN pLook=pPlugins;
  while(pLook && strnicmp(pLook->szFilename,"MQ2AdvPath",10)) pLook=pLook->pNext;
  if(pLook && pLook->RemoveSpawn)
    if(FollowCALL Request=(FollowCALL)GetProcAddress(pLook->hModule,"MQFollowCommand"))
      Request(GetCharInfo()->pSpawn,zOutput);
}
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=//
 
class MQ2CastType *pCastType=0; 
class MQ2CastType : public MQ2Type {
private:
  char Temps[MAX_STRING];
public:
  enum CastMembers {
    Active=1,
    Effect=2,
    Stored=3,
    Result=4,
    Return=5,    
    Status=6,
    Timing=7,
    Taken=8,
    Ready=9,
  };
  MQ2CastType():MQ2Type("Cast") {
    TypeMember(Active);
    TypeMember(Effect);
    TypeMember(Stored);
    TypeMember(Result);
    TypeMember(Return);
    TypeMember(Status);
    TypeMember(Timing);
    TypeMember(Taken);
    TypeMember(Ready);
  }
  bool GetMember(MQ2VARPTR VarPtr, PCHAR Member, PCHAR Index, MQ2TYPEVAR &Dest) {
    PMQ2TYPEMEMBER pMember=MQ2CastType::FindMember(Member); 
    if(pMember) switch((CastMembers)pMember->ID) {
      case Active:
        Dest.DWord=(gbInZone);
        Dest.Type=pBoolType;
        return true;
      case Effect:
        Dest.DWord=GetCharInfo()->pSpawn->CastingSpellID;
        if((long)Dest.DWord==NOID && CastF!=FLAG_COMPLETE) Dest.DWord=CastS->ID;
        if((long)Dest.DWord!=NOID) {
          Dest.Ptr=GetSpellByID(Dest.DWord); 
          Dest.Type=pSpellType; 
        }
        return true; 
      case Stored:
        if(CastingL!=NOID) {
          Dest.Ptr=GetSpellByID(CastingL);
          Dest.Type=pSpellType;
        } 
        return true;
      case Timing:
        Dest.DWord=(DWORD)CastingLeft(); 
        Dest.Type=pIntType;
        return true;
      case Status: 
        strcpy(Temps,"");
        if(CastF!=FLAG_COMPLETE || 
          (pCastingWnd && (PCSIDLWND)pCastingWnd->Show)) strcat(Temps,"C");
        if(StopF!=FLAG_COMPLETE) strcat(Temps,"S");
        if(MoveA!=FLAG_COMPLETE) strcat(Temps,"A");
        if(MoveS!=FLAG_COMPLETE) strcat(Temps,"F");
		if(MoveP!=FLAG_COMPLETE) strcat(Temps,"S");
        if(MemoF!=FLAG_COMPLETE) strcat(Temps,"M");
        if(DuckF!=FLAG_COMPLETE) strcat(Temps,"D");
        if(ItemF!=FLAG_COMPLETE) strcat(Temps,"E");
        if(!Temps[0]) strcat(Temps,"I");
        Dest.Ptr=Temps; 
        Dest.Type=pStringType; 
        return true;
      case Result:
      case Return:
        switch((pMember->ID==Result)?CastingX:Resultat) {
          case DONE_PROGRESS:
          case CAST_SUCCESS:      strcpy(Temps,"CAST_SUCCESS");     break;
          case CAST_INTERRUPTED:  strcpy(Temps,"CAST_INTERRUPTED"); break;
          case CAST_RESIST:       strcpy(Temps,"CAST_RESIST");      break;
          case CAST_COLLAPSE:     strcpy(Temps,"CAST_COLLAPSE");    break;
          case CAST_RECOVER:      strcpy(Temps,"CAST_RECOVER");     break;
          case CAST_FIZZLE:       strcpy(Temps,"CAST_FIZZLE");      break; 
          case CAST_STANDING:     strcpy(Temps,"CAST_STANDING");    break; 
          case CAST_STUNNED:      strcpy(Temps,"CAST_STUNNED");     break;
          case CAST_INVISIBLE:    strcpy(Temps,"CAST_INVISIBLE");   break;
          case CAST_NOTREADY:     strcpy(Temps,"CAST_NOTREADY");    break;
          case CAST_OUTOFMANA:    strcpy(Temps,"CAST_OUTOFMANA");   break;
          case CAST_OUTOFRANGE:   strcpy(Temps,"CAST_OUTOFRANGE");  break;
          case CAST_NOTARGET:     strcpy(Temps,"CAST_NOTARGET");    break; 
          case CAST_CANNOTSEE:    strcpy(Temps,"CAST_CANNOTSEE");   break;
          case CAST_COMPONENTS:   strcpy(Temps,"CAST_COMPONENTS");  break;
          case CAST_OUTDOORS:     strcpy(Temps,"CAST_OUTDOORS");    break;
          case CAST_TAKEHOLD:     strcpy(Temps,"CAST_TAKEHOLD");    break; 
          case CAST_IMMUNE:       strcpy(Temps,"CAST_IMMUNE");      break; 
          case CAST_DISTRACTED:   strcpy(Temps,"CAST_DISTRACTED");  break;
          case CAST_ABORTED:      strcpy(Temps,"CAST_CANCELLED");   break;
          case CAST_UNKNOWN:      strcpy(Temps,"CAST_UNKNOWN");     break; 
          default:                strcpy(Temps,"CAST_NEEDFIXTYPE"); break; 
        }
        Dest.Ptr=Temps; 
        Dest.Type=pStringType; 
        return true; 
      case Ready:
        Dest.DWord=(gbInZone && !Flags() && !Paused() && !Open("SpellBookWnd") && 
                    !(GetCharInfo()->Stunned) && SpellReady(Index));
        Dest.Type=pBoolType;
        return true;
      case Taken:
        Dest.DWord=(CastingX==CAST_TAKEHOLD);
        Dest.Type=pBoolType;
        return true;
    }
    strcpy(Temps,"NULL");
    Dest.Type=pStringType;
    Dest.Ptr=Temps;
    return true;
  }
  bool ToString(MQ2VARPTR VarPtr, PCHAR Destination) {
    strcpy(Destination,"TRUE"); 
    return true; 
  } 
  bool FromData(MQ2VARPTR &VarPtr, MQ2TYPEVAR &Source) {
    return false; 
  } 
  bool FromString(MQ2VARPTR &VarPtr, PCHAR Source) {
    return false; 
  } 
  ~MQ2CastType() { } 
}; 
 
BOOL dataCast(PCHAR szName, MQ2TYPEVAR &Dest) {
  Dest.DWord=1;
  Dest.Type=pCastType;
  return true;
}
 
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=//
 
void StopEnding() {
  if(MoveS!=FLAG_COMPLETE) {
    #if DEBUGGING
      WriteChatf("[%d] MQ2Cast:[Immobilize]: Stick UnPause Request.",(long)clock());
    #endif
    Stick("unpause");
    MoveS=FLAG_COMPLETE;
  }
  if(MoveA!=FLAG_COMPLETE) {
    #if DEBUGGING
      WriteChatf("[%d] MQ2Cast:[Immobilize]: AdvPath UnPause Request.",(long)clock());
    #endif
    Execute("/varcalc PauseFlag 0");
    MoveA=FLAG_COMPLETE;
  }
  if(MoveP!=FLAG_COMPLETE) {
    #if DEBUGGING
      WriteChatf("[%d] MQ2Cast:[Immobilize]: MQ2AdvPath UnPause Request.",(long)clock());
    #endif
    Path("unpause");
    MoveP=FLAG_COMPLETE;
  }
}
 
void StopHandle() {
  if(StopF==FLAG_REQUEST) {
    #if DEBUGGING
      WriteChatf("[%d] MQ2Cast:[Immobilize]: Request.",(long)clock());
    #endif
    StopM=(long)clock()+DELAY_STOP;
    StopF=FLAG_PROGRESS1;
    StopE=DONE_PROGRESS;
  }
  if(Evaluate("${If[${Stick.Status.Equal[ON]},1,0]}")) {
    #if DEBUGGING
      WriteChatf("[%d] MQ2Cast:[Immobilize]: Stick Pause Request.",(long)clock());
    #endif
    Stick("pause");
    MoveS=FLAG_PROGRESS1;
  }
  if(Evaluate("${If[${Bool[${FollowFlag}]},1,0]}")) {
    #if DEBUGGING
      WriteChatf("[%d] MQ2Cast:[Immobilize]: AdvPath Pause Request.",(long)clock());
    #endif
    Execute("/varcalc PauseFlag 1");
    MoveA=FLAG_PROGRESS1;
  }
  if(Evaluate("${If[${AdvPath.Following},1,0]}")) {
    #if DEBUGGING
      WriteChatf("[%d] MQ2Cast:[Immobilize]: MQ2AdvPath Pause Request.",(long)clock());
    #endif
    Path("pause");
    MoveP=FLAG_PROGRESS1;
  }
  if(Immobile=Moving()) {
    #if DEBUGGING
      WriteChatf("[%d] MQ2Cast:[Immobilize]: Complete.",(long)clock());
    #endif
    StopF=FLAG_COMPLETE;
    StopE=DONE_SUCCESS;
  }
  if((long)clock() > StopM) {
    WriteChatf("[%d] MQ2Cast:[Immobilize]: Aborting!",(long)clock());
    StopF=FLAG_COMPLETE;
    StopE=DONE_ABORTED;
    return;
  }
  if(StopF==FLAG_PROGRESS1) {
    StopF=FLAG_PROGRESS2;
    if(Speed()!=0.0f) {
      MQ2Globals::ExecuteCmd(FindMappableCommand("back"),1,0);
      MQ2Globals::ExecuteCmd(FindMappableCommand("back"),0,0);
    }
  }
}
 
void MemoHandle() {
  if(!pSpellBookWnd) MemoE=DONE_ABORTED;
  else {
    bool Complete=true;
    for(int sp=0; sp<GEMS_MAX; sp++)
      if(SpellToMemorize.SpellId[sp]!=0xFFFFFFFF &&
         SpellToMemorize.SpellId[sp]!=
         GetCharInfo2()->MemorizedSpells[sp]) {
        Complete=false;
        break;
      }
    if(!Complete) {
      if(MemoF==FLAG_REQUEST) {
        #if DEBUGGING 
          WriteChatf("[%d] MQ2Cast:[Memorize]: Immobilize.",(long)clock());
        #endif
        MemoF=FLAG_PROGRESS1; 
        MemoE=DONE_PROGRESS;
        MemoM=(long)clock()+DELAY_STOP+DELAY_MEMO*SpellTotal;
        if(StopF==FLAG_COMPLETE) StopE=DONE_SUCCESS;
        if(StopF==FLAG_COMPLETE) StopF=FLAG_REQUEST;
        if(StopF!=FLAG_COMPLETE) StopHandle();
      }
      if(MemoF==FLAG_PROGRESS1 && StopE==DONE_SUCCESS) {
        #if DEBUGGING
          WriteChatf("[%d] MQ2Cast:[Memorize]: Spell(s).",(long)clock());
        #endif
        MemoF=FLAG_PROGRESS2;
        DWORD Favorite=(DWORD)&SpellToMemorize;
        pSpellBookWnd->MemorizeSet((int*)Favorite,GEMS_MAX);
      }
      if(StopE==DONE_ABORTED || (long)clock()>MemoM) MemoE=DONE_ABORTED;
    } else {
      #if DEBUGGING
        WriteChatf("[%d] MQ2Cast:[Memorize]: Complete.",(long)clock());
      #endif
      MemoF=FLAG_COMPLETE;
      MemoE=DONE_SUCCESS;
    }
  }
  if(MemoE==DONE_ABORTED || !pSpellBookWnd) {
    WriteChatf("[%d] MQ2Cast:[Memorize]: Aborting!",(long)clock());
    MemoF=FLAG_COMPLETE;
  }
  if(MemoF==FLAG_COMPLETE && (pSpellBookWnd && (PCSIDLWND)pSpellBookWnd->Show)) {
    #if DEBUGGING
      WriteChatf("[%d] MQ2Cast:[Memorize]: Closebook.",(long)clock());
    #endif
    Execute("/book");
  }
}
 
void ItemHandle(bool SwapIn) {
  if(GetCharInfo2()->Cursor || (pCastingWnd && (PCSIDLWND)pCastingWnd->Show) || 
    (pSpellBookWnd && (PCSIDLWND)pSpellBookWnd->Show)
    ) return;
  if(GetCharInfo2()->Cursor && !SwapIn) WinClick((CXWnd*)pInventoryWnd,"InvSlot30","leftmouseup",1);
  if(!SwapIn && ItemF!=FLAG_COMPLETE && !GetCharInfo()->pSpawn->SpellETA) {
    #if DEBUGGING
      WriteChatf("[%d] MQ2Cast:[Swapping]: Out.",(long)clock());
    #endif
    for(int X=0;X<NUM_INV_SLOTS;X++) 
      if(ItemA[X]) Exchange("%d %d",ItemA[X],X);
    for(int Y=0;Y<NUM_INV_SLOTS;Y++) 
      if(PCONTENTS Cont=GetCharInfo2()->InventoryArray[Y])
        if(ItemA[Y] && Cont->Item->ItemNumber==ItemA[Y]) ItemA[Y]=0;
    ItemF=FLAG_COMPLETE;
    for(int Z=0;Z<NUM_INV_SLOTS && ItemF==FLAG_COMPLETE;Z++) if(ItemA[Z]) ItemF=FLAG_PROGRESS1;
  }
  if(SwapIn && ItemF==FLAG_COMPLETE && (CastB[0] || CastK==TYPE_ITEM)) {
    memset(&ItemA,0,sizeof(ItemA));
    for(int X=0;X<NUM_INV_SLOTS;X++)
      if(PCONTENTS Cont=GetCharInfo2()->InventoryArray[X])
        if(Cont->Item->Type!=ITEMTYPE_PACK)
          ItemA[X]=Cont->Item->ItemNumber;
    if(CastB[0]) Bandolier(CastB);
    if(CastK==TYPE_ITEM) {
      if(ItemFound(((PCONTENTS)CastI)->Item->ItemNumber,0,NUM_INV_SLOTS)) {
        long wSLOT=SlotID(CastC);
        long eSLOT=SlotEquip(fITEM->Item,fSLOT,wSLOT);
        if(fSLOT!=eSLOT) Exchange("%d %d",((PCONTENTS)CastI)->Item->ItemNumber,eSLOT);
		if(!wSLOT && !PulseCount) PulseCount=1;
      }
    }
    for(int Y=0;Y<NUM_INV_SLOTS;Y++)
      if(PCONTENTS Cont=GetCharInfo2()->InventoryArray[Y])
        if(Cont->Item->Type==ITEMTYPE_PACK || Cont->Item->ItemNumber==ItemA[Y]) ItemA[Y]=0;
    for(int Z=0;Z<NUM_INV_SLOTS && ItemF==FLAG_COMPLETE;Z++) if(ItemA[Z]) ItemF=FLAG_PROGRESS1;
    if(ItemF!=FLAG_COMPLETE) {
      #if DEBUGGING
        WriteChatf("[%d] MQ2Cast:[Swapping]: In.",(long)clock());
      #endif
    }
  }         
}
 
void DuckHandle() {
  if(DuckF==FLAG_REQUEST) {
    #if DEBUGGING
      WriteChatf("[%d] MQ2Cast:[Duck]: Request.",(long)clock());
    #endif
    DuckF=FLAG_PROGRESS1;
    DuckM=0;
  }
  if(DuckF==FLAG_PROGRESS1) {
    if(GetCharInfo()->pSpawn->Mount) {
      if(!DuckM) {
        #if DEBUGGING
          WriteChatf("[%d] MQ2Cast:[Duck]: Dismount.",(long)clock());
        #endif
        DuckM=(long)clock();
        Execute("/dismount");
      }
    } else DuckF=FLAG_PROGRESS2;
 }
 if(DuckF==FLAG_PROGRESS2) {
    #if DEBUGGING
      WriteChatf("[%d] MQ2Cast:[Duck]: StopCast.",(long)clock());
    #endif
	Execute("/stopcast");
    CastingE=CAST_ABORTED;
    DuckF=FLAG_COMPLETE;
  }
}
 
void CastHandle() {
 
  // we got the casting request cookies, request immobilize/memorize if needed.
  if(CastF==FLAG_REQUEST) {
    #if DEBUGGING
      WriteChatf("[%d] MQ2Cast:[Casting]: Request.",(long)clock());
    #endif
    CastF=FLAG_PROGRESS1;
    if(StopF==FLAG_COMPLETE) StopF=DONE_SUCCESS;
    if(StopF==FLAG_COMPLETE && CastT>100 && !BardClass()) StopF=FLAG_REQUEST;
    if(MemoF!=FLAG_COMPLETE) MemoHandle();
    else if(StopF!=FLAG_COMPLETE) StopHandle();
  }
 
  // waiting on the casting results to take actions.
  if(CastF==FLAG_PROGRESS3 && CastingE!=DONE_PROGRESS) {
    CastF=FLAG_PROGRESS4;
    if(CastR) CastR--;
    if(CastR) {
      if((CastingE==CAST_SUCCESS && CastW!=RECAST_LAND) || 
         (CastingE==CAST_COLLAPSE) || 
         (CastingE==CAST_FIZZLE) || 
         (CastingE==CAST_INTERRUPTED) || 
         (CastingE==CAST_RECOVER) || 
         (CastingE==CAST_RESIST)) {
        #if DEBUGGING 
          WriteChatf("[%d] MQ2Cast:[Casting]: AutoRecast [%d].",(long)clock(),CastingE);
        #endif 
        if(CastW!=RECAST_ZERO && !TargC) TargC=(pTarget)?((PSPAWNINFO)pTarget)->SpawnID:0;
        CastM=(long)clock()+DELAY_CAST;
        CastF=FLAG_REQUEST;
      }
    }
  }
 
  // casting is over, grab latest casting results and exit.
  if(CastF==FLAG_PROGRESS4) {
    if(CastE>CastingE) CastingE=CastE;
    CastF=FLAG_COMPLETE;
  } 
 
  // evaluate if we are taking too long, or immobilize/memorize event failed.
  if(CastF!=FLAG_COMPLETE) {
    if(StopE==DONE_ABORTED || MemoE==DONE_ABORTED || (long)clock()>CastM) {
      WriteChatf("[%d] MQ2Cast:[Casting]: Aborting!",(long)clock()); 
      CastF=FLAG_PROGRESS4; 
      CastE=CAST_NOTREADY; 
    } 
  }
 
  // waiting for opportunity to start casting, end if conditions not favorables.
  if(CastF==FLAG_PROGRESS1) {
    if(pCastingWnd && (PCSIDLWND)pCastingWnd->Show) return; // casting going on
    CastF=FLAG_PROGRESS4;
    if(TargC && (!pTarget || (pTarget && ((PSPAWNINFO)pTarget)->SpawnID!=TargC))) {
      if(CastW==RECAST_DEAD)      CastE=CAST_NOTARGET;
      else if(CastW==RECAST_LAND) CastE=CAST_ABORTED;
    } else if(Invisible && GetCharInfo()->pSpawn->HideMode) { CastE=CAST_INVISIBLE;
    } else if(GetCharInfo()->Stunned)                       { CastE=CAST_STUNNED;
    } else if(StopF!=FLAG_COMPLETE || MemoF!=FLAG_COMPLETE) { CastF=FLAG_PROGRESS1;
    } else {
      long TimeReady=SpellTimer(CastK,CastI);    // get estimate time before it's ready.
      if(TimeReady>3000)  CastE=CAST_NOTREADY;   // if estimate higher then 3 seconds aborts.
      else if(!TimeReady) CastF=FLAG_PROGRESS2;  // estimate says it's ready so cast it
      else CastF=FLAG_PROGRESS1;                 // otherwise give it some time to be ready.
    }
  }
 
  // we got the final approbation to cast, so lets do it.
  if(CastF==FLAG_PROGRESS2) {
    #if DEBUGGING 
      WriteChatf("[%d] MQ2Cast:[Casting]: Cast.",(long)clock());
    #endif
    Success(CastS);
    ItemHandle(true);
    CastF=FLAG_PROGRESS3;
    CastE=DONE_PROGRESS;
    CastingT=(long)clock()+CastT+250+(pConnection->Last)*4;
    CastingE=DONE_PROGRESS;
    CastingC=CastS->ID;
    if((long)GetCharInfo()->pSpawn->CastingSpellID>0) {
      CastingX=(CastingE<CAST_SUCCESS)?CAST_SUCCESS:CastingE;
      CastingL=CastingC;
      if(CastK==TYPE_SPELL)     Execute("/multiline ; /stopsong ; /cast \"%s\"",CastN);
      else if(CastK==TYPE_ITEM) Execute("/multiline ; /stopsong ; /cast item \"%s\"",CastN);
      else if(CastK==TYPE_ALT)  Execute("/multiline ; /stopsong ; /alt activate %d",((PALTABILITY)CastI)->ID);
    } else {
      if(CastK==TYPE_SPELL)     Cast("\"%s\"",CastN);
      else if(CastK==TYPE_ITEM) Cast("item \"%s\"",CastN);
      else if(CastK==TYPE_ALT)  Execute("/alt activate %d",((PALTABILITY)CastI)->ID);
    }
  }
} 
 
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=//
 
PLUGIN_API VOID CastCommand(PSPAWNINFO pChar, PCHAR Cmd) {
  Resultat=CAST_DISTRACTED;
  if(!gbInZone || Flags() || Paused() || 
     (pSpellBookWnd && (PCSIDLWND)pSpellBookWnd->Show)
    ) return;
  Reset();
  char zParm[MAX_STRING]; 
  long iParm=0;
  do {
    GetArg(zParm,Cmd,++iParm);
    if(zParm[0]==0) { break;
    } else if(!strnicmp(zParm,"-targetid|",10))  { TargI=atoi(&zParm[10]);
    } else if(!strnicmp(zParm,"-kill",5))        { CastW=RECAST_DEAD; CastR=9999;
    } else if(!strnicmp(zParm,"-maxtries|",10))  { CastW=RECAST_LAND; CastR=atoi(&zParm[10]);
    } else if(!strnicmp(zParm,"-recast|",8))     { CastW=RECAST_ZERO; CastR=atoi(&zParm[8]);
    } else if(!strnicmp(zParm,"-setin|",6))      { GetArg(CastB,zParm,2,FALSE,FALSE,FALSE,'|');
    } else if(!strnicmp(zParm,"-bandolier|",11)) { GetArg(CastB,zParm,2,FALSE,FALSE,FALSE,'|');
    } else if(!strnicmp(zParm,"-invis",6))       { Invisible=true;
    } else if(zParm[0]!='-' && CastN[0]==0) {
      GetArg(CastN,zParm,1,FALSE,FALSE,FALSE,'|');
      GetArg(CastC,zParm,2,FALSE,FALSE,FALSE,'|');
    } else if(zParm[0]!='-' && CastC[0]==0) {
      GetArg(CastC,zParm,1,FALSE,FALSE,FALSE,'|');
    }
  } while(true);
  Resultat=CAST_SUCCESS;
  if(GetCharInfo()->Stunned)                            Resultat=CAST_STUNNED;
  else if(Invisible && GetCharInfo()->pSpawn->HideMode) Resultat=CAST_INVISIBLE;
  else if(!SpellFind(CastN,CastC))                      Resultat=CAST_UNKNOWN;
  else if(fTYPE!=TYPE_SPELL && SpellTimer(fTYPE,fINFO)) Resultat=CAST_NOTREADY;
  else if(TargI) {
    if(PSPAWNINFO Target=(PSPAWNINFO)GetSpawnByID(TargI)) *(PSPAWNINFO*)ppTarget=Target;
    else Resultat=CAST_NOTARGET;
  }
  if(Resultat==CAST_SUCCESS && fTYPE==TYPE_SPELL) {
    if(!BardClass()) {
      CastG=GEMID(fFIND->ID);
      if(CastG==NOID) {
        CastG=atoi(&CastC[(strnicmp(CastC,"gem",3))?0:3])-1;
        MemoLoad(CastG,fFIND);
        SpellTotal=1;
        MemoF=FLAG_REQUEST;
        MemoE=DONE_SUCCESS;
      }
    } else Resultat=CAST_DISTRACTED;
  }
  if(Resultat!=CAST_SUCCESS) {
    #if DEBUGGING 
      WriteChatf("[%d] MQ2Cast:[Casting]: Complete. [%d]",(long)clock(),Resultat);
    #endif
    return;
  }
  CastF=FLAG_REQUEST;
  CastI=fINFO;
  CastK=fTYPE;
  CastT=fTIME;
  CastS=fFIND;
  CastM=(long)clock()+DELAY_CAST;
  strcpy(CastN,fNAME);
  #if DEBUGGING
    WriteChatf("[%d] MQ2Cast:[Casting]: Name<%s> Type<%d>.",(long)clock(),CastN,CastK);
  #endif
  CastHandle();
}
 
PLUGIN_API VOID DuckCommand(PSPAWNINFO pChar, PCHAR Cmd) {
  if(gbInZone) {
    if(CastF!=FLAG_COMPLETE) CastR=0;
    if((pCastingWnd && (PCSIDLWND)pCastingWnd->Show) && CastingLeft()>500) {
      DuckF=FLAG_REQUEST;
      DuckHandle();
    }
  }
  Resultat=CAST_SUCCESS;
} 
 
PLUGIN_API VOID MemoCommand(PSPAWNINFO pChar, PCHAR zLine) {
  Resultat=CAST_DISTRACTED;
  if(!gbInZone || Flags() || Paused() || !pSpellBookWnd) return;
  if(GetCharInfo()->Stunned) {
    Resultat=CAST_STUNNED;
    return;
  }
  Reset();
  long iParm=0;
  char zParm[MAX_STRING];
  char zTemp[MAX_STRING];
  Resultat=CAST_SUCCESS;
  do {
    GetArg(zParm,zLine,++iParm);
    if(!zParm[0]) break;
    GetArg(zTemp,zParm,1,FALSE,FALSE,FALSE,'|');
    if(PSPELL Search=SpellBook(zTemp)) {
      GetArg(zTemp,zParm,2,FALSE,FALSE,FALSE,'|');
      long Gem=atoi(&zTemp[(strnicmp(zTemp,"gem",3))?0:3])-1;
      if(!((DWORD)Gem<GEMS_MAX)) {
        GetArg(zTemp,zLine,1+iParm);
        Gem=atoi(&zTemp[(strnicmp(zTemp,"gem",3))?0:3])-1;
        if((DWORD)Gem<GEMS_MAX) iParm++;
      }
      MemoLoad(Gem,Search);
    }
  } while(true);
  for(int sp=0;sp<GEMS_MAX;sp++)
    if(SpellToMemorize.SpellId[sp] != 0xFFFFFFFF &&
       SpellToMemorize.SpellId[sp] !=
       GetCharInfo2()->MemorizedSpells[sp]) SpellTotal++;
  if(SpellTotal) {
    MemoF=FLAG_REQUEST;
    MemoE=DONE_SUCCESS;
    MemoHandle();
  }
}
 
PLUGIN_API VOID SpellSetDelete(PSPAWNINFO pChar,PCHAR Cmd) {
  Resultat=CAST_ABORTED;
  if(!gbInZone) return;
  else if(!Cmd[0]) MacroError("Usage: /ssd setname");
  else {
    Resultat=CAST_SUCCESS;
    sprintf(INIFileName,"%s\\%s_%s.ini",gszINIPath,EQADDR_SERVERNAME,GetCharInfo()->Name);
    WritePrivateProfileString("MQ2Cast(SpellSet)",Cmd,NULL,INIFileName);
  }
}
 
PLUGIN_API VOID SpellSetList(PSPAWNINFO pChar, PCHAR Cmd) {
  Resultat=CAST_SUCCESS;
  if(!gbInZone) return;
  char Keys[MAX_STRING*10]={0}; 
  char Temp[MAX_STRING];
  PCHAR pKeys=Keys; 
  long Disp=0;
	Resultat=CAST_SUCCESS;
	sprintf(INIFileName,"%s\\%s_%s.ini",gszINIPath,EQADDR_SERVERNAME,GetCharInfo()->Name);
	WriteChatf("MQ2Cast:: SpellSet [\ay Listing... \ax].",Disp);
  GetPrivateProfileString("MQ2Cast(SpellSet)",NULL,"",Keys,MAX_STRING*10,INIFileName);
  while(pKeys[0]) {
  	GetPrivateProfileString("MQ2Cast(SpellSet)",pKeys,"",Temp,MAX_STRING,INIFileName);
    if(Temp[0]) {
      if(!Disp) WriteChatf("-=-=-=-=-=-=-=-=-=-=-=-=-=-=-");
      WriteChatf("\ay%s\ax",pKeys);
      Disp++;
    }
    pKeys+=strlen(pKeys)+1;
  }
  if(Disp) WriteChatf("-=-=-=-=-=-=-=-=-=-=-=-=-=-=-");
  WriteChatf("MQ2Cast:: SpellSet [\ay %d Displayed\ax ].",Disp);
}
 
PLUGIN_API VOID SpellSetMemorize(PSPAWNINFO pChar, PCHAR Cmd) {
  Resultat=CAST_UNKNOWN;
  if(!gbInZone)   return;
  else if(!Cmd[0]) MacroError("Usage: /ssm setname");
  else {
    char List[MAX_STRING];
    Resultat=CAST_SUCCESS;
    sprintf(INIFileName,"%s\\%s_%s.ini",gszINIPath,EQADDR_SERVERNAME,GetCharInfo()->Name);
		GetPrivateProfileString("MQ2Cast(SpellSet)",Cmd,"",List,MAX_STRING,INIFileName);
    if(List[0]) MemoCommand(GetCharInfo()->pSpawn,List);
  }
}
 
PLUGIN_API VOID SpellSetSave(PSPAWNINFO pChar, PCHAR Cmd) {
  if(!gbInZone) return;
  char zSet[MAX_STRING]; GetArg(zSet,Cmd,1);
  char zGem[MAX_STRING]; GetArg(zGem,Cmd,2);
  Resultat=CAST_ABORTED;
  if(!zSet[0]) {
    MacroError("Usage: /sss setname <gemlist>");
    return;
  }
  if(!zGem[0]) sprintf(zGem,"123456789");
  char zLst[MAX_STRING]={0};
  char zTmp[MAX_STRING];
  long find=0;
  for(int g=0;g<GEMS_MAX;g++)
    if((long)GetCharInfo2()->MemorizedSpells[g]>0)
      if(strstr(zGem,ListGems[g])) {
        sprintf(zTmp,"%d|%d",GetCharInfo2()->MemorizedSpells[g],g+1);
        if(find) strcat(zLst," ");
        strcat(zLst,zTmp);
        find++;
      }
  Resultat=CAST_UNKNOWN;
  if(find) {
    Resultat=CAST_SUCCESS;
    sprintf(INIFileName,"%s\\%s_%s.ini",gszINIPath,EQADDR_SERVERNAME,GetCharInfo()->Name);
		WritePrivateProfileString("MQ2Cast(SpellSet)",Cmd,zLst,INIFileName);
  } 
}
 
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=//
 
PLUGIN_API VOID InitializePlugin(VOID) {
  aCastEvent(LIST289, CAST_COLLAPSE    ,"Your gate is too unstable, and collapses#*#");
  aCastEvent(LIST289, CAST_CANNOTSEE   ,"You cannot see your target#*#");
  aCastEvent(LIST289, CAST_COMPONENTS  ,"You are missing some required components#*#");
  aCastEvent(LIST289, CAST_COMPONENTS  ,"You need to play a#*#instrument for this song#*#");
  aCastEvent(LIST289, CAST_DISTRACTED  ,"You are too distracted to cast a spell now#*#");
  aCastEvent(LIST289, CAST_DISTRACTED  ,"You can't cast spells while invulnerable#*#");
  aCastEvent(LIST289, CAST_DISTRACTED  ,"You *CANNOT* cast spells, you have been silenced#*#");
  aCastEvent(LIST289, CAST_IMMUNE      ,"Your target has no mana to affect#*#");
  aCastEvent(LIST013, CAST_IMMUNE      ,"Your target is immune to changes in its attack speed#*#");
  aCastEvent(LIST013, CAST_IMMUNE      ,"Your target is immune to changes in its run speed#*#");
  aCastEvent(LIST289, CAST_IMMUNE      ,"Your target cannot be mesmerized#*#");
  aCastEvent(UNKNOWN, CAST_IMMUNE      ,"Your target looks unaffected#*#");
  aCastEvent(LIST264, CAST_INTERRUPTED ,"Your spell is interrupted#*#");
  aCastEvent(UNKNOWN, CAST_INTERRUPTED ,"Your casting has been interrupted#*#");
  aCastEvent(LIST289, CAST_FIZZLE      ,"Your spell fizzles#*#");
  aCastEvent(LIST289, CAST_FIZZLE      ,"You miss a note, bringing your song to a close#*#");
  aCastEvent(LIST289, CAST_NOTARGET    ,"You must first select a target for this spell#*#");
  aCastEvent(LIST289, CAST_NOTARGET    ,"This spell only works on#*#");
  aCastEvent(LIST289, CAST_NOTARGET    ,"You must first target a group member#*#");
  aCastEvent(LIST289, CAST_NOTREADY    ,"Spell recast time not yet met#*#");
  aCastEvent(LIST289, CAST_OUTOFMANA   ,"Insufficient Mana to cast this spell#*#");
  aCastEvent(LIST289, CAST_OUTOFRANGE  ,"Your target is out of range, get closer#*#");
  aCastEvent(LIST289, CAST_OUTDOORS    ,"This spell does not work here#*#");
  aCastEvent(LIST289, CAST_OUTDOORS    ,"You can only cast this spell in the outdoors#*#");
  aCastEvent(LIST289, CAST_OUTDOORS    ,"You can not summon a mount here#*#");
  aCastEvent(LIST289, CAST_OUTDOORS    ,"You must have both the Horse Models and your current Luclin Character Model enabled to summon a mount#*#");
  aCastEvent(LIST264, CAST_RECOVER     ,"You haven't recovered yet#*#");
  aCastEvent(LIST289, CAST_RECOVER     ,"Spell recovery time not yet met#*#");
  aCastEvent(LIST289, CAST_RESIST      ,"Your target resisted the#*#spell#*#");
  aCastEvent(LIST289, CAST_STANDING    ,"You must be standing to cast a spell#*#");
  aCastEvent(LIST289, CAST_STUNNED     ,"You can't cast spells while stunned#*#");
  aCastEvent(LIST289, CAST_SUCCESS     ,"You are already on a mount#*#");
  aCastEvent(LIST289, CAST_TAKEHOLD    ,"Your spell did not take hold#*#");
  aCastEvent(LIST289, CAST_TAKEHOLD    ,"Your spell would not have taken hold#*#");
  aCastEvent(LIST289, CAST_TAKEHOLD    ,"Your spell is too powerfull for your intended target#*#");
  aCastEvent(LIST289, CAST_TAKEHOLD    ,"You need to be in a more open area to summon a mount#*#");
  aCastEvent(LIST289, CAST_TAKEHOLD    ,"You can only summon a mount on dry land#*#");
  aCastEvent(LIST289, CAST_TAKEHOLD    ,"This pet may not be made invisible#*#");
  pCastType= new MQ2CastType;
  AddMQ2Data("Cast",dataCast);
  AddCommand("/casting"  ,CastCommand);
  AddCommand("/interrupt",DuckCommand);
  AddCommand("/memorize" ,MemoCommand);
  AddCommand("/ssd",SpellSetDelete);
  AddCommand("/ssl",SpellSetList);
  AddCommand("/ssm",SpellSetMemorize);
  AddCommand("/sss",SpellSetSave);
}
 
PLUGIN_API VOID ShutdownPlugin(VOID) { 
  RemoveMQ2Data("Cast");
  delete pCastType;
  RemoveCommand("/casting");
  RemoveCommand("/interrupt");
  RemoveCommand("/memorize");
  RemoveCommand("/ssd");
  RemoveCommand("/ssl");
  RemoveCommand("/ssm");
  RemoveCommand("/sss");
}
 
PLUGIN_API VOID OnEndZone(VOID) {
  Reset();
  CastingO=NOID;
  CastingC=NOID;
  CastingE=CAST_SUCCESS;
  CastingT=0;
  ImmobileT=0;
}

PLUGIN_API DWORD OnIncomingChat(PCHAR Line, DWORD Color) {
  if(gbInZone) {
    if(CastingC!=NOID && !Twisting) {
      Parsed=false;
      if(Color==264)      { LIST264.Feed(Line); SUCCESS.Feed(Line); }
      else if(Color==289) { LIST289.Feed(Line);                     }
      else if(Color==13)  { LIST013.Feed(Line);                     }
      if(!Parsed) {
        UNKNOWN.Feed(Line);
        if(Parsed) WriteChatf("\arMQ2Cast::Note for Author[\ay%s\ar]=(\ag%d\ar)\ax",Line,Color);
      }
    }
  }
  return 0;
}
 
PLUGIN_API VOID OnPulse(VOID) {
  if(gbInZone && (long)clock()>CastingP && GetCharInfo() && GetCharInfo()->pSpawn) { 
  	CastingP=(long)clock()+DELAY_PULSE;
  	
    // evaluate immobile flag and handle immobilize request
    Immobile=Moving();
    if(StopF!=FLAG_COMPLETE) StopHandle();
    CastingD=GetCharInfo()->pSpawn->CastingSpellID;
 
    // casting window currently openened?
    if(pCastingWnd && (PCSIDLWND)pCastingWnd->Show) {
      Casting=true;
      if(CastingO==NOID) CastingO=(pTarget)?((long)((PSPAWNINFO)pTarget)->SpawnID):0;
 
      // was this an unecpected cast?
      if(CastingD!=CastingC && CastingD!=NOID) {
        CastingE=DONE_PROGRESS;
        CastingC=CastingD;
        CastingT=GetCharInfo()->pSpawn->SpellETA  - 
                 GetCharInfo()->pSpawn->TimeStamp +
                 clock()+450+(pConnection->Last)*4;
        Success(GetSpellByID(CastingD));
      }
 
      // are we attempting to interrupt this?
      if(DuckF!=FLAG_COMPLETE) DuckHandle();
      return;
    }
 
    // wait for incoming chat, timers, and windows to be closed.
    DuckF=FLAG_COMPLETE;
    Twisting=Evaluate("${If[${Twist.Twisting},1,0]}")?true:false;
    if(Casting) {
      if(CastingC==CastingD)
        if(PSPELL Spell=GetSpellByID(CastingC)) 
          switch(Spell->TargetType) {
            case 18: // Uber Dragons
            case 17: // Uber Giants
            case 16: // Plant
            case 15: // Corpse
            case 14: // Pet
            case 11: // Summoned
            case 10: // Undead
            case  9: // Animal
            case  5: // Single
              if(!pTarget) CastingE=CAST_NOTARGET;
              break;
          }
 
      // re-evaluate casting timer after cast window close
      CastingT=clock()+450+(pConnection->Last)*2;
      Casting=false;
    }
    if(CastingE==DONE_PROGRESS) {
      if((long)clock()>CastingT) CastingE=CAST_SUCCESS;
      else if(!Twisting) return;
    }
    if(Paused()) {
      if((long)GetCharInfo()->pSpawn->CastingSpellID>0) Execute("/stopsong");
      return;
    }
 
    // give time to proceed other casting events
    if(MemoF!=FLAG_COMPLETE) MemoHandle();
    if(MemoF!=FLAG_COMPLETE) return;
    if(CastF!=FLAG_COMPLETE) CastHandle();
 
    // make sure we get final casting results
    if((CastF==FLAG_COMPLETE && CastingC!=NOID && CastingD==NOID) ||
       (BardClass() && CastingC!=NOID && (CastingD!=NOID))) {
      CastingX=(CastingE<CAST_SUCCESS)?CAST_SUCCESS:CastingE;
      CastingL=CastingC;
      CastingE=DONE_COMPLETE;
      if(!Twisting) {
        #if DEBUGGING
          WriteChatf("[%d] MQ2Cast:: Casting Complete ID[%d] Result=[%d]",(long)clock(),CastingL,CastingX);
        #endif
		    CastTimer(CastingO,CastingC,CastingX); // patches for ae but sound illogicials
      }
      CastingC=NOID;
      CastingO=NOID;
    }
 
    // make sure we finish other casting events
    if(CastF==FLAG_COMPLETE) {
		if(ItemF!=FLAG_COMPLETE) {
			ItemHandle(false);
//			if(!PulseCount) PulseCount=1;
		}
    StopEnding();
	if(PulseCount) {
		if(GetCharInfo2()->Cursor) ClickBack();
//		WriteChatf("PulseCount : %d",PulseCount);
		if(PulseCount<=3) {
//			WriteChatf("PulseCount ++ : %d",PulseCount);
			PulseCount++;
			return;
		}
		if(PulseCount>3 && !GetCharInfo2()->Cursor) {
			PulseCount=0;
			return;
		}
	}
    }
  }
}

void WinClick(CXWnd *Wnd, PCHAR ScreenID, PCHAR ClickNotification, DWORD KeyState) {
  if(Wnd) if(CXWnd *Child=Wnd->GetChildItem(ScreenID)) {
    BOOL KeyboardFlags[4];
    *(DWORD*)&KeyboardFlags=*(DWORD*)&((PCXWNDMGR)pWndMgr)->KeyboardFlags;
    *(DWORD*)&((PCXWNDMGR)pWndMgr)->KeyboardFlags=KeyState;
    SendWndClick2(Child,ClickNotification);
    *(DWORD*)&((PCXWNDMGR)pWndMgr)->KeyboardFlags=*(DWORD*)&KeyboardFlags;
  }
}
void ClickBack() {
  if(GetCharInfo2()->Cursor && PulseCount) {
		if(GetCharInfo2()->Cursor->Item->Type==ITEMTYPE_PACK) {
//			WriteChatf("Pack Type");
			WinClick((CXWnd*)pInventoryWnd,"InvSlot30","leftmouseup",1);
			PulseCount=1;
			return;
		}
		else {		
//		WriteChatf("Not a pack");
		WinClick((CXWnd*)pInventoryWnd,"IW_CharacterView","leftmouseup",1);
		PulseCount=1;
		return;
		}
  }
}
 
What date of MQ2 source are you using noob? I'm using 20051101, and the source you are posting is from 2007. I wasn't aware that the 2007 MQ2 would work with Titanium.

As such, I get a lot of missing stuff that is referenced in your MQ2Cast and MQ2Melee posts.
 
Honestly, these are just old versions I had, I haven't even compiled a EQEmu build yet lol. I'm just leveling legit on P99 atm. Once I get board, I'm sure i'll break out the MQ2 compiles and fix many of these reference errors.
 
MQ2Cast - This is a plugin form of Spell_Routines.inc, and far, far superior. It can, among other things, memorize and cast spells, recast them, and, with the use of MQ2CastTimer, monitor the estimated duration on long term spells like DoTs, Buffs, etc. The plugin can also deal with events, similar to MQ2Events.

SYNTAX FOR MQ2CAST MacroQuest2 WIKI

Rich (BB code):
/casting "Arm Cannon" mainhand -forceswap

A nice little HUD snippet to go with the plugin:
Rich (BB code):
[CASTING]
CS1=3,425,150,255,255,255,~~ CASTING ~~~~~~~~~~~~~~~~~~~~~
CS2=3,425,162,255,255,255,Cast Effect: ${If[${Cast.Effect.ID},${Cast.Effect.Name},NONE]}
CS3=3,425,174,255,255,255,Cast Timing: ${Cast.Timing}
CS4=3,425,186,255,255,255,Cast Ready : ${Cast.Ready}
CS5=3,425,198,255,255,255,Cast Status: ${Cast.Status}
CS6=3,425,210,255,255,255,Cast Result: ${Cast.Result}
CS7=3,425,222,255,255,255,Cast Stored: ${If[${Cast.Stored.ID},${Cast.Stored.Name},NONE]}
 
Last edited:
i have not messed with MQ2 in a long time but i started using it on emu and am working on making a macro but one of the new features of MQ2Cast is that after it starts a command it returns control of the character back over to the macro before finishing the command i'm trying to get my macro to memorize more than one spell in a row MQ2Cast used to wait till done memorizing one spell before starting the next one now by the time the first spell is memorized the macro has passed the rest of the spells i wanted to memorize and they don't get memorized im hoping there is a bit of code i can add to a command like " /memorize "Root" 1 " that will make it wait until that command is done before going on to the next command any help would be great. i used to just use /delays but im trying to make the macro memorize different spells depending on the characters level and depending on the characters meditate skill the time to memorize the spell will vary so i don't want the macro waist extra time just sitting there doing nothing if i don't have to
 
The follow is the wiki for it here on RG.

https://www.redguides.com/community/threads/24743-MQ2Cast

Likely not what you need though.

Macroquest2.com's WIKI is a pretty valuable source. I wish more people used it.
https://redguides.com/wiki/MQ2Cast

Rich (BB code):
/memorize  "1234|1" "gate|2" "cannibalize|gem4"As with /casting, the plugin will attempt to immobilize you before memorizing the spell.
/sss

Spell Set Save - This will save your any number of your currently memmed spells into a spell set.
Syntax:
/sss "name" [gems]
Name is what you want your spell set to be called. If no gems are specified, all your gems are saved (ie. 123456789ABC). You can specify a smaller subset if needed.
/sss dps 1238 
/sss dps 12ABC
/sss wunshi 5
/ssm

Spell Set Memorize - This will memorize a previously saved spell set.
/ssm dps
/ssl

Spell Set List - This will list all spell sets that have been saved.
/ssl
/ssd

Spell Set Delete - This will delete a spell set from the ini file.
/ssd wunshi
 
yea i seen that stuff on the wiki and on here also but the spell set will change ans the character levels up and i don't want to have to keep changing the spell set every time the character levels up i'm trying to make the macro scribe and memorize new spells as the character levels up or after the character dies while they wait on a rezz i'm sure its some simple little piece of code i just cant seem to find it anywhere i would post the whole macro i have so far it's not close to being complete yet but im testing it on a private server as i add more stuff to it to make sure what i have added is working but i cant remember how to do that its been so long since i used MQ2 and been on this site
 
You sir are in for a lot of coding then.

It doesn't just know what you want. Scripts are input/output based systems. You tell it what you want and it does it.

Unfortunately I'm unaware of a program that currently exists which already knows all the spells you need.

Granted it wouldn't take very long to program. Maybe a week or 3, but then there would be guesswork involved on the developers end and assumptions made as to what you should have memorized. Also, we're talking about coding statements that check your level, scan your book for known spells, reverting back a spell level if you haven't scribed the spell into your book. Assuming you want Spirit of Bah`li Instead of spirit of scale on your group etc.

To many factors, and likely the reason nobody has bothered to code such a thing. It's generally easy for a player to just make a spell set and save it then it is for a developer to spend weeks coding the thought process and having it shot down because a group of people don't care for the selection of spells.

While I'm not saying it hasn't happened, or that it won't happen. I'm just saying that it's unlikely that it has/will.

I've considered doing pretty much exactly what we're discussing here. But have opted not to do so for the very reasons I've mentioned.

I do hope you can find something like this. If you do, please let me know. I'd love to take a gander at it.
 
yea its gonna be a lot of work for me but what i'm looking for rite now is a line of code to make MQ2Cast wait for one spell to finish memorizing before it lets the macro continue on to memorizing the next spell.
the old MQ2Cast that i used to use back in the day would hold up the macro while it was memorizing spells before it would let the macro continue on to the next line of it.
i do not want to just add in long delays because as the character levels up it's meditate skill will go up making memorizing spells faster and id have to change the macro as the character levels up or the character would be sitting there doing nothing for a while after memorizing each spell
the checking level and all that ain't that hard its just a lot of coding

- - - Updated - - -

lets see if i can figure out how to post the little bit of my macro for memorizing spells
if i add in long delays it works fine so far but i don't like that fact that after my character got higher level he would mem a spell and just sit there for a few seconds afterwards so i'm trying to replace the delays i removed with some script that will wait until one spell is done then allow the macro to go to the next one


HOPE IT SHOWS UP BELOW


Sub MemSpells

/if (${Me.Class.Name.Equal[Bard]}) {
/if (${Me.Level}<23) {
/gsay no Single Slow/Snare song to mem yet :-(
/goto :BardGem2
}
/if (${Me.Level}<51) {
/memorize "Selo`s Consonant Chain" 1
/goto :BardGem2
}
/if (${Me.Level}>50) {
/memorize "Largo`s Absonant Binding" 1
/goto :BardGem2
}
:BardGem2

:BardGem3

:BardGem4

:BardGem5

:BardGem6

/if (${Me.Level}<10) {
/memorize "Chant of Battle" 6
/goto :BardGem7
}
/if (${Me.Level}<36) {
/memorize "Anthem de Arms" 6
/goto :BardGem7
}
/if (${Me.Level}<42) {
/memorize "Vilia`s Verses of Celerity" 6
/goto :BardGem7
}
/if (${Me.Level}<50) {
/memorize "McVaxius` Berserker Crescendo" 6
/goto :BardGem7
}
:BardGem7
/if (${Me.Level}<5) {
/gsay no Run Speed song to mem yet :-(
/goto :BardGem8
}
/if (${Me.Level}<25) {
/memorize "Selo`s Accelerando" 7
/goto :BardGem8
}
/if (${Me.Level}<49) {
/memorize "Selo's Rhythm of Speed" 7
/goto :BardGem8
}
/if (${Me.Level}>50) {
/memorize "Selo`s Accelerating Chorus" 7
/goto :BardGem8
}
:BardGem8
/if (${Me.Level}<6) {
/gsay no Regen song to mem yet :-(
/Return
}
/if (${Me.Level}<34) {
/memorize "Hymn of Restoration" 8
/Return
}
/if (${Me.Level}<55) {
/memorize "Cantata of Soothing" 8
/Return
}
/if (${Me.Level}<58) {
/memorize "Cantata of Replenishment" 8
/Return
}
/if (${Me.Level}<60) {
/memorize "Chorus of Replenishment" 8
/Return
}
/if (${Me.Level}<62) {
/memorize "Ancient: Lcea's Lament" 8
/Return
}
/if (${Me.Level}<64) {
/memorize "Wind of Marr" 8
/Return
}
/if (${Me.Level}<67) {
/memorize "Chorus of Marr" 8
/Return
}
/if (${Me.Level}<69) {
/memorize "Cantata of Life" 8
/Return
}
/if (${Me.Level}>68) {
/memorize "Chorus of Life" 8
/Return
}
}

/if (${Me.Class.Name.Equal[Cleric]}) {
/if (${Me.Level}<7) {
/gsay no root spell to mem so you better hope we dont need it
/goto :ClericGem2
}
/if (${Me.Level}<27) {
/memorize "Root" 1
/goto :ClericGem2
}
/if (${Me.Level}<46) {
/memorize "Instill" 1
/goto :ClericGem2
}
/if (${Me.Level}<56) {
/memorize "Immobilize" 1
/goto :ClericGem2
}
/if (${Me.Level}<62) {
/memorize "Paralyzing Earth" 1
/goto :ClericGem2
}
/if (${Me.Level}<64) {
/memorize "Greater Immobilize" 1
/goto :ClericGem2
}
/if (${Me.Level}>63) {
/memorize "Petrifying Earth" 1
/goto :ClericGem2
}

:ClericGem2

/if (${Me.Level}<5) {
/memorize "Strike" 2
/goto :ClericGem3
}
/if (${Me.Level}<14) {
/memorize "Furor" 2
/goto :ClericGem3
}
/if (${Me.Level}<29) {
/memorize "Smite" 2
/goto :ClericGem3
}
/if (${Me.Level}<44) {
/memorize "Wrath" 2
/goto :ClericGem3
}
/if (${Me.Level}<54) {
/memorize "Retribution" 2
/goto :ClericGem3
}
/if (${Me.Level}<56) {
/memorize "Reckoning" 2
/goto :ClericGem3
}
/if (${Me.Level}<62) {
/memorize "Judgment" 2
/goto :ClericGem3
}
/if (${Me.Level}<65) {
/memorize "Condemnation" 2
/goto :ClericGem3
}
/if (${Me.Level}<67) {
/memorize "Order" 2
/goto :ClericGem3
}
/if (${Me.Level}>66) {
/memorize "Reproach" 2
/goto :ClericGem3
}

:ClericGem3
/delay 1

:ClericGem4
/delay 1

:ClericGem5
/if (${Me.Level}<7) {
/memorize "Courage" 5
/goto :ClericGem6
}
/if (${Me.Level}<17) {
/memorize "Center" 5
/goto :ClericGem6
}
/if (${Me.Level}<22) {
/memorize "Daring" 5
/goto :ClericGem6
}
/if (${Me.Level}<32) {
/memorize "Bravery" 5
/goto :ClericGem6
}
/if (${Me.Level}<42) {
/memorize "Valor" 5
/goto :ClericGem6
}
/if (${Me.Level}<52) {
/memorize "Resolution" 5
/goto :ClericGem6
}
/if (${Me.Level}<55) {
/memorize "Heroism" 5
/goto :ClericGem6
}
/if (${Me.Level}<61) {
/memorize "Fortitude" 5
/goto :ClericGem6
}
/if (${Me.Level}<66) {
/memorize "Faith" 5
/goto :ClericGem6
}
/if (${Me.Level}>65) {
/memorize "Confidence" 5
/goto :ClericGem6
}

:ClericGem6
/if (${Me.Level}<30) {
/gsay i dont have a group heal to mem yet
/goto :ClericGem7
}
/if (${Me.Level}<45) {
/memorize "Word of Health" 6
/goto :ClericGem7
}
/if (${Me.Level}<52) {
/memorize "Word of Healing" 6
/goto :ClericGem7
}
/if (${Me.Level}<57) {
/memorize "Word of Vigor" 6
/goto :ClericGem7
}
/if (${Me.Level}<60) {
/memorize "Word of Restoration" 6
/goto :ClericGem7
}
/if (${Me.Level}<64) {
/memorize "Word of Redemption" 6
/goto :ClericGem7
}
/if (${Me.Level}<69) {
/memorize "Word of replenishment" 6
/goto :ClericGem7
}
/if (${Me.Level}>68) {
/memorize "Word of Vivification" 6
/goto :ClericGem7
}

:ClericGem7
/if (${Me.Level}<4) {
/memorize "Minor Healing" 7
/goto :ClericGem8
}
/if (${Me.Level}<10) {
/memorize "Light Healing" 7
/goto :ClericGem8
}
/if (${Me.Level}<20) {
/memorize "Healing" 7
/goto :ClericGem8
}
/if (${Me.Level}<30) {
/memorize "Greater Healing" 7
/goto :ClericGem8
}
/if (${Me.Level}<39) {
/memorize "Superior Healing" 7
/goto :ClericGem8
}
/if (${Me.Level}<49) {
/memorize "Healing Light" 7
/goto :ClericGem8
}
/if (${Me.Level}<51) {
/memorize "Greater Healing Light" 7
/goto :ClericGem8
}
/if (${Me.Level}<53) {
/memorize "Remedy" 7
/goto :ClericGem8
}
/if (${Me.Level}<58) {
/memorize "Divine Light" 7
/goto :ClericGem8
}
/if (${Me.Level}<63) {
/memorize "Ethereal Light" 7
/goto :ClericGem8
}
/if (${Me.Level}<65) {
/memorize "Supernal Light" 7
/goto :ClericGem8
}
/if (${Me.Level}<68) {
/memorize "Holy Light" 7
/goto :ClericGem8
}
/if (${Me.Level}<70) {
/memorize "Pious Light" 7
/goto :ClericGem8
}
/if (${Me.Level}>69) {
/memorize "Desperate Renewal" 7
/goto :ClericGem8
}

:ClericGem8
/if (${Me.Level}<5) {
/gsay i dont have gate yet so lets hope i dont need it
/return
}
/memorize "Gate" 8

/return
}

/return
}
 
Scribing or memorizing a spell?

Scribing a spell would be easier to just use scribe.mac

If you're waiting to finish memorizing a spell then You want to wait until that gem has an ID.

/delay 5m ${Me.Gem[${i}].ID}

says wait 5 minutes -or- until my gem at index i has an ID.

So if you're trying to memorize a spell into gem 5, /delay 8s ${Me.Gem[5].ID}

The /delay command stops the macro from processing more code moving forward, but it also accepts a condition to stop waiting early.

You could say
/delay 5000m ${Target.ID}

That would wait until 5000 minutes has past or until you have a target. Whichever is shorter. I don't use really long delays, I'm just using them as an example. Figure about how long it should take Maximum before you figure the memorization has failed in some way and use that. Then add the condition to the end of it to exit the delay early.

Common practice for coders that want to open a window, and then wait until MQ2 sees that window as "Open"

Rich (BB code):
/if (!${Window[InventoryWindow].Open}) {
        /windowstate InventoryWindow open
        /delay 2s ${Window[InventoryWindow].Open}
    }
would be an example snippet I use to open the inventory without using a /keypress, because sometimes people change their keybinds.

Two seconds is a long time, but generally this happens over milliseconds. Only in the event of lag would their be an issue that prevents the window from opening. But if there does happen to be lag I've accounted for it somewhat.

You can also use conditions that are true and wait for them to be false.

/delay 5s !${Window[SpellBookWnd].Open}

Which is what I believe you should use in this case.
 
thank you that is exactly what i needed

- - - Updated - - -

and how do you post the macro in a box like that ??i couldn't figure it out
 
When you go to type a post there is a # at the top next to <> and a page with php written on it. You can highlight all the code and then click the hashtag.

Alternately, you can type out the tag, which is an [ bracket, followed by the word CODE, then a closing Bracet (which will mess this information up if I use the closing bracket.

Then to end the section of code use the /CODE inside the Square brackets. the slash to mean ending.

Rich (BB code):
I don't know if I can put the tags inside of a code block, but I'm going to try to type  tags.
 
I would also like to recommend that you approach this code a little bit different.
The method you are using makes sense. But it has a flaw. What if you are the level in question to memorize the spell, but you don't yet have the spell in question?

Regardless of your level you shouldn't have a spell/song in your book which you can't memorize.

Rich (BB code):
/if (${Me.Class.Name.Equal[Bard]}) {
		/if (${Me.Level} < 23) {
			/Echo \ayno Single Slow/Snare song to mem yet :-(
		} else /if (${Me.Book[Largo's Absonant Binding]} && !${Me.Gem[Largo's Absonant Binding]}) {
			/memorize "Largo`s Absonant Binding" 1
			/delay 5s ${Window[SpellBookWnd].Open}
			/delay 5s !${Window[SpellBookWnd].Open}
		} else /if (${Me.Book[Selo's Consonant Chain]} && !${Me.Gem[Selo's Consonant Chain]}) {
			/memorize "Selo's Consonant Chain" 1
			/delay 5s ${Window[SpellBookWnd].Open}
			/delay 5s !${Window[SpellBookWnd].Open}
		}

I start by checking the highest level song in this case, to see if it's in my book. If it is I also want to know that I don't already have it memorized. Then I say to Memorize it and put in a delay to wait until the book is open (So that I know I've started memorizing the spell) followed by a delay to wait for the book to close.
In conjunction with using an if else then style of statements. I also go from the highest level down to the lowest level. This way I will always memorize the highest known song/spell preference.

When you use a

/if (this) {
/dothis
} else /if (this) {

style chain, it will check from the top to the bottom and once it evaluates true it will execute the code and skip all the other checks. Which in this case would automatically move you to your :BardGem2 goto key. Thus removing the need for the goto statement.

I see that you've already done quite a bit. But hopefully this won't deter you from improving!
 
i tried that bit of /delay code you put up there for me and its waiting the full delay i put in it instead of stoping after the spell is memorized so using that i mite as well just go back to the plain old /delay commands must be a missing bracket or something in the /delay 5m ${Me.Gem[${i}].ID}

ill copy that bit of code there and play with it when i'm done with this macro i plan on having it do exactly what you have there but also if the spell not in the book i'm gonna try to make it check my bags to see if i have the spell in there to scribe so i can call my memspell section of the macro after character get a new level
 
The ${i} would be a variable if you were in a loop to check all of your gems. But you can just use the name instead. ${Me.Gem[NameOfSpellHere]}
 
okay that makes sense i put the spell gem number in there instead of the i i knew that the i had to be changed for my use just though it was the gem number it had to be changed to not spell name

- - - Updated - - -

looking at it i bet is i remove the ${} and just leave the number it mite work the way i though it would have to start with

- - - Updated - - -

with the spell gem number in there like this /delay 1m ${Me.Gem[8].ID} it seams to work it skips the spell if its already memorized but if not it memorizes it but it waits the full 1 min if it has to mem the spell and i get errors spamming my MQ2 window if i put in the spell names in quotation marks or not

- - - Updated - - -

i figured out how to make it work for now with a /for loop


Rich (BB code):
	:BardGem7
		/for w 1 to 120
			/if (${Me.Gem[6].ID}) /goto :BardGem7b
			/delay 5
		/next w
	:BardGem7b
 
Don't use goto's to jump out of /for /next loops. Please.

Rich (BB code):
	:BardGem7
		/for w 1 to 120
			/if (${Me.Gem[6].ID}) /break
			/delay 5
		/next w
	:BardGem7b

also

/delay 60s ${Me.Gem[6].ID}

would work, and

Rich (BB code):
    /varset w 1
    /while (${Me.Gem[6].ID}==0 && ${w}<120) {
         /delay 5
         /varcalc w ${w}+1
    }
 
I would like to point out that I don't understand the purpose of the loop that we are using.
A loop is used to iterate through something. IE:



Rich (BB code):
/declare i int local 0
/for i 1 to ${Me.NumGems}
    /if (!${Me.Gem[${i}]}) {
        /varset MissingGem ${i}
        /break
    }
/next i
The above statement says from the first gem to the maximum number of gems I have, if the gem doesn't have a value then set MissingGem to the value of ${i}. Then break out of the loop and /goto :Class#
so if I'm a bard and I'm missing gem3, /goto :Bard3 would be the result.


/if (${MissingGem}) {
/goto :${Me.Class}${MissingGem}
}


If you aren't iterating through something I see no need to check the same thing 120 times. In the case above where w is the loop index location, you don't use ${w} in anything but the check to make sure it's under 120.

You could honestly break all the :gotokeywords down into Sub Routines.
Rich (BB code):
Sub Bard1
	/if (${Me.Level} < 10) {
		/echo some text
	} else /if (${Me.Book[HighestLevelSpell]}) {
		/memorize HighestLevelSpell 1
	} else /if (.......) {
		/memorize ....... 1
	}
/return

then instead of /goto :keyword, you could /call ${Me.Class}${MissingGem}

Then after the call have that be the end of the loop

Rich (BB code):
    /while (${EverQuest.GameState.Equal[INGAME]}) {


        /declare i int local 0
        
        /for i 1 to ${Me.NumGems}
            /if (!${Me.Gem[${i}]}) {
                /varset MissingGem ${i}
                /break
            }
        /next i
        
        /if (${MissingGem}) {
            /call ${Me.Class}${MissingGem}
        }
        /varset ${MissingGem} 0
    }
 
i have the issue of making the macro wait for the spell to be done memorizing before continuing now but today i been playing around with a bit of code that ChatWithThisName posted last night for me. I had to find a few missing things to get it to run, and after that it still did not do what i had hoped it did not start the next spell as soon as the one before it was done it would still wait a while so i had to remove a few lines to get it to move on faster and i added in level checks to it also just in case my character dies after getting new spells and cant use ones in his book. I have redone 3 gems worth of my code for the bard part, 2 of the 3 is working great but i'm having a problem with it hanging up on gem number 6 now for some reason
can anyone see where i messed it up at ??



Rich (BB code):
Sub MemSpells

|	/call CheckforSpells

		/declare w int local

		/if (${Me.Class.Name.Equal[Bard]}) {
			/gsay memorizing my songs will be done shortly
			/if (${Me.Level}>22) {
				/if (${Me.Book[Largo`s Absonant Binding]} && (!${Me.Gem[1].[Largo's Absonant Binding]}) && (${Me.Level}>50)) {
					/memorize "Largo`s Absonant Binding" 1
				} else 	/if (${Me.Book[Selo`s Consonant Chain]} && (!${Me.Gem[1].[Selo`s Consonant Chain]}) && (${Me.Level}>22)) {
							/memorize "Selo`s Consonant Chain" 1
						} else /gsay im suposed to have a single target snare/slow song but someone (Points finger at ${Master}) was to fucking lazy to go buy it so we are going to have chase the mob's now
			}
		/goto :BardGem2b
	:BardGem2
		/for w 1 to 120
			/if (${Me.Gem[6].ID}) /goto :BardGem2b
			/delay 5
		/next w
	:BardGem2b

	:BardGem3
	
	:BardGem4

	:BardGem5
			/if (${Me.Level}>6) {
				/if (${Me.Book[Warsong of the Vah Shir]} && (!${Me.Gem[5].[Warsong of the Vah Shir]}) && (${Me.Level}>59)) {
					/memorize "Warsong of the Vah Shir" 5
				} else 	/if (${Me.Book[Composition of Ervaj]} && (!${Me.Gem[5].[Composition of Ervaj]}) && (${Me.Level}>59)) {
					/memorize "Composition of Ervaj" 5
						} else 	/if (${Me.Book[Battlecry of the Vah Shir]} && (!${Me.Gem[5].[Battlecry of the Vah Shir]}) && (${Me.Level}>51)) {
							/memorize "Battlecry of the Vah Shir" 5
								} else 	/if (${Me.Book[Melody of Ervaj]} && (!${Me.Gem[5].[Melody of Ervaj]}) && (${Me.Level}>49))) {
									/memorize "Melody of Ervaj" 5
										} else 	/if (${Me.Book[Katta's Song of Sword Dancing]} && (!${Me.Gem[5].[Katta's Song of Sword Dancing]}) && (${Me.Level}>38)) {
											/memorize "Katta's Song of Sword Dancing" 5
											/gsay I do not have a OverHaste Song yet so i am going to use a Weapon Prock for now
												} else 	/if (${Me.Book[Psalm of Purity]} && (!${Me.Gem[5].[Psalm of Purity]}) && (${Me.Level}>36)) {
													/memorize "Psalm of Purity" 5
													/gsay I do not have a OverHaste Song or a Weapon Prock yet so i guess DS it is
														} else 	/if (${Me.Book[Psalm of Cooling]} && (!${Me.Gem[5].[Psalm of Cooling]}) && (${Me.Level}>24)) {
															/memorize "Psalm of Cooling" 5
															/gsay I do not have a OverHaste Song or a Weapon Prock yet so i guess DS it is
																} else 	/if (${Me.Book[Psalm of Vitality]} && (!${Me.Gem[5].[Psalm of Vitality]}) && (${Me.Level}>28)) {
																	/memorize "Psalm of Vitality" 5
																	/gsay I do not have a OverHaste Song yet so i am going to use a Weapon Prock for now
																		} else 	/if (${Me.Book[Psalm of Warmth]} && (!${Me.Gem[5].[Psalm of Warmth]}) && (${Me.Level}>24)) {
																			/memorize "Psalm of Warmth" 5
																			/gsay I do not have a OverHaste Song or a Weapon Prock yet so i guess DS it is
																				} else 	/if (${Me.Book[Jonthan's Whistling Warsong]} && (!${Me.Gem[5].[Jonthan's Whistling Warsong]}) && (${Me.Level}>6)) {
																					/memorize "Jonthan's Whistling Warsong" 5
																					/gsay I do not have a OverHaste Song or Weapon Prock or DS  yet so i guess i will do self haste for now
																						}
			}	
			/goto :BardGem6b
	:BardGem6
		/for w 1 to 120
			/if (${Me.Gem[6].ID}) /goto :BardGem6b
			/delay 5
		/next w
	:BardGem6b
		/if (${Me.Book[War March of Brekt RK.III]} && (!${Me.Gem[6].[War March of Brekt RK.III]}) && (${Me.Level}>83)) {
			/memorize "War March of Brekt RK.III" 6
		} else 	/if (${Me.Book[War March of Brekt RK.II]} && (!${Me.Gem[6].[War March of Brekt RK.II]}) && (${Me.Level}>83)) {
			/memorize "War March of Brekt RK.II" 6
				} else 	/if (${Me.Book[War March of Brekt]} && (!${Me.Gem[6].[War March of Brekt]}) && (${Me.Level}>83)) {
					/memorize "War March of Brekt" 6
						} else 	/if (${Me.Book[War March of Meldrath RK.III]} && (!${Me.Gem[6].[War March of Meldrath RK.III]}) && (${Me.Level}>78)) {
							/memorize "War March of Meldrath RK.III" 6
								} else 	/if (${Me.Book[War March of Meldrath RK.II]} && (!${Me.Gem[6].[War March of Meldrath RK.II]}) && (${Me.Level}>78)) {
									/memorize "War March of Meldrath RK.II" 6
										} else 	/if (${Me.Book[War March of Meldrath]} && (!${Me.Gem[6].[War March of Meldrath]}) && (${Me.Level}>78)) {
											/memorize "War March of Meldrath" 6
												} else 	/if (${Me.Book[War March of Muram]} && (!${Me.Gem[6].[War March of Muram]}) && (${Me.Level}>67)) {
													/memorize "War March of Muram" 6
														} else 	/if (${Me.Book[War March of the Mastruq]} && (!${Me.Gem[6].[War March of the Mastruq]}) && (${Me.Level}>64)) {
															/memorize "War March of the Mastruq" 6
																} else 	/if (${Me.Book[Warsong of Zek]} && (!${Me.Gem[6].[Warsong of Zek]}) && (${Me.Level}>61)) {
																	/memorize "Warsong of Zek" 6
																		} else 	/if (${Me.Book[Vilia's Chorus of Celerity]} && (!${Me.Gem[6].[Vilia's Chorus of Celerity]}) && (${Me.Level}>53)) {
																			/memorize "Vilia's Chorus of Celerity" 6
																				} else 	/if (${Me.Book[Verses of Victory]} && (!${Me.Gem[6].[Verses of Victory]}) && (${Me.Level}>49)) {
																					/memorize "Verses of Victory" 6
																						} else 	/if (${Me.Book[Vilia's Verses of Celerity]} && (!${Me.Gem[6].[Vilia's Verses of Celerity]}) && (${Me.Level}>35)) {
																							/memorize "Vilia's Verses of Celerity" 6
																								} else 	/if (${Me.Book[Anthem de Arms]} && (!${Me.Gem[6].[Anthem de Arms]}) && (${Me.Level}>9)) {
																									/memorize "Anthem de Arms" 6
																										} else 	/if (${Me.Book[Chant of Battle]} && (!${Me.Gem[6].[Chant of Battle]}) && (${Me.Level}>0)) {
																											/memorize "Chant of Battle" 6
																												} else /gsay Damn ${Master} either we just started the game and are broke as Fuck or you are retarded because you did not buy my level 1 Haste song yet
	:BardGem7
		/for w 1 to 120
			/if (${Me.Gem[6].ID}) /goto :BardGem7b
			/delay 5
		/next w
	:BardGem7b
		/if (${Me.Level}<5) {
			/gsay no Run Speed song to mem yet :-(
			/goto :BardGem8b
		}
		/if (${Me.Level}<25) {
			/memorize  "Selo`s Accelerando" 7
			/delay 5
			/goto :BardGem8
		}
		/if (${Me.Level}<49) {
			/memorize  "Selo's Rhythm of Speed" 7
			/delay 5
			/goto :BardGem8
		}
		/if (${Me.Level}>50) {
			/memorize  "Selo`s Accelerating Chorus" 7
			/delay 5
			/goto :BardGem8
		}
	:BardGem8
		/for w 1 to 120
			/if (${Me.Gem[7].ID}) /goto :BardGem8b
			/delay 5
		/next w
	:BardGem8b
		/if (${Me.Level}<6) {
			/gsay no Regen song to mem yet :-(
			/Return
		}
		/if (${Me.Level}<34) {
			/memorize  "Hymn of Restoration" 8
			/delay 5
			/for w 1 to 120
			/if (${Me.Gem[8].ID}) /return
			/delay 5
		/next w
		}
		/if (${Me.Level}<55) {
			/memorize  "Cantata of Soothing" 8
			/delay 5
			/for w 1 to 120
			/if (${Me.Gem[8].ID}) /return
			/delay 5
		/next w
		}
			/if (${Me.Level}<58) {
			/memorize  "Cantata of Replenishment" 8
			/delay 5
			/for w 1 to 120
			/if (${Me.Gem[8].ID}) /return
			/delay 5
		/next w
		}
			/if (${Me.Level}<60) {
			/memorize  "Chorus of Replenishment" 8
			/delay 5
			/for w 1 to 120
			/if (${Me.Gem[8].ID}) /return
			/delay 5
		/next w
		}
			/if (${Me.Level}<62) {
			/memorize  "Ancient: Lcea's Lament" 8
			/delay 5
			/for w 1 to 120
			/if (${Me.Gem[8].ID}) /return
			/delay 5
		/next w
		}
			/if (${Me.Level}<64) {
			/memorize  "Wind of Marr" 8
			/delay 5
			/for w 1 to 120
			/if (${Me.Gem[8].ID}) /return
			/delay 5
		/next w
		}
			/if (${Me.Level}<67) {
			/memorize  "Chorus of Marr" 8
			/delay 5
			/for w 1 to 120
			/if (${Me.Gem[8].ID}) /return
			/delay 5
		/next w
		}
			/if (${Me.Level}<69) {
			/memorize  "Cantata of Life" 8
			/delay 5
			/for w 1 to 120
			/if (${Me.Gem[8].ID}) /return
			/delay 5
		/next w
		}
			/if (${Me.Level}>68) {
			/memorize  "Chorus of Life" 8
			/delay 5
			/for w 1 to 120
			/if (${Me.Gem[8].ID}) /return
			/delay 5
		/next w
		}
	}
 
@[email protected] I've caved and decided to just rewrite it all for you. This also gives you a template to use for future additions.

${Me.Class.ShortName} for Bard is BRD, For Cleric it is CLR

In game you can /echo ${Me.Class.ShortName} to see what it is. Then create a Sub based on that information. This is in working order. I tested it.

I have it coded as a stand alone macro. If you want it to be called as a Sub Routine of another macro. Change "Sub Main" to something else. Like "Sub MemSpells"
Then call it using /call MemSpells



Rich (BB code):
Sub Main
	/declare i int local 0
	
	/for i 1 to ${Me.NumGems}
	/echo Checking ${i}
	/delay 1s
	/call ${Me.Class.ShortName}${i}
	/delay 1s
	/echo Finished checking ${i}.
	/next i
/return


|** Checks the SpelltoCheck to be in GemToUse and returns true if it gets memorized or it's already in the gem slot specified. **|
Sub CheckSpell(string SpelltoCheck, int GemToUse)
	/if (${Me.Book[${SpelltoCheck}]} && ${Me.Gem[${GemToUse}].Name.NotEqual[${SpelltoCheck}]} || !${Me.Gem[${GemToUse}].ID}) {
		/memorize "${SpelltoCheck}" ${GemToUse}
		/delay 10s ${Me.Gem[${GemToUse}].Name.Equal[${SpelltoCheck}]}
		/return Complete
	} else /if (${Me.Gem[${SpelltoCheck}]}) {
		/return Complete
	}
/return Incomplete


|** Checks song to put into gem1 **|
Sub Brd1
	/if (${Me.Level} > 22) {
		/call CheckSpell "Largo's Absonant Binding" 1
		/if (${Macro.Return.Equal[Complete]}) /return
		
		/call CheckSpell "Selo's Consonant Chain" 1
		/if (${Macro.Return.Equal[Complete]}) /return
	}
/return


|** Checks song to put into gem2 **|
Sub Brd2
	|** Add code for gem**|
/return


|** Checks song to put into gem3 **|
Sub Brd3
	|** Add code for gem**|
/return


|** Checks song to put into gem4 **|
Sub Brd4
	|** Add code for gem**|
/return


|** Checks song to put into gem5 **|
Sub Brd5
	/if (${Me.Level}>6) {
		/call CheckSpell "Warsong of the Vah Shir" 5
		/if (${Macro.Return.Equal[Complete]}) /return
		
		/call CheckSpell "Composition of Ervaj" 5
		/if (${Macro.Return.Equal[Complete]}) /return
		
		/call CheckSpell "Battlecry of the Vah Shir" 5
		/if (${Macro.Return.Equal[Complete]}) /return
		
		/call CheckSpell "Melody of Ervaj" 5
		/if (${Macro.Return.Equal[Complete]}) /return
		
		/call CheckSpell "Katt's Song of Sword Dancing" 5
		/if (${Macro.Return.Equal[Complete]}) /return
		
		/call CheckSpell "Psalm of Purity" 5
		/if (${Macro.Return.Equal[Complete]}) /return
		
		/call CheckSpell "Psalm of Cooling" 5
		/if (${Macro.Return.Equal[Complete]}) /return
		
		/call CheckSpell "Psalm of Vitality" 5
		/if (${Macro.Return.Equal[Complete]}) /return
		
		/call CheckSpell "Psalm of Warmth" 5
		/if (${Macro.Return.Equal[Complete]}) /return
		
		/call CheckSpell "Jonthan's Whistling Warsong" 5
		/if (${Macro.Return.Equal[Complete]}) /return
	}
/return


|** Checks song to put into gem6 **|
Sub Brd6
	/call CheckSpell "Jonthan's Whistling Warsong" 6
	/if (${Macro.Return.Equal[Complete]}) /return
	
	/call CheckSpell "War March of Brekt Rk. III" 6
	/if (${Macro.Return.Equal[Complete]}) /return
	
	/call CheckSpell "War March of Brekt Rk. II" 6
	/if (${Macro.Return.Equal[Complete]}) /return
	
	/call CheckSpell "War March of Brekt" 6
	/if (${Macro.Return.Equal[Complete]}) /return
	
	/call CheckSpell "War March of Meldrath RK. III" 6
	/if (${Macro.Return.Equal[Complete]}) /return
	
	/call CheckSpell "War March of Meldrath RK.II" 6
	/if (${Macro.Return.Equal[Complete]}) /return
	
	/call CheckSpell "War March of Meldrath" 6
	/if (${Macro.Return.Equal[Complete]}) /return
	
	/call CheckSpell "War March of Muram" 6
	/if (${Macro.Return.Equal[Complete]}) /return
	
	/call CheckSpell "War March of the Mastruq" 6
	/if (${Macro.Return.Equal[Complete]}) /return
	
	/call CheckSpell "Warsong of Zek" 6
	/if (${Macro.Return.Equal[Complete]}) /return
	
	/call CheckSpell "Vilia's Chorus of Celerity" 6
	/if (${Macro.Return.Equal[Complete]}) /return
	
	/call CheckSpell "Verses of Victory" 6
	/if (${Macro.Return.Equal[Complete]}) /return
	
	/call CheckSpell "Vilia's Verses of Celerity" 6
	/if (${Macro.Return.Equal[Complete]}) /return
	
	/call CheckSpell "Anthem de Arms" 6
	/if (${Macro.Return.Equal[Complete]}) /return
	
	/call CheckSpell "Chant of Battle" 6
	/if (${Macro.Return.Equal[Complete]}) /return
/return


|** Checks song to put into gem7 **|
Sub Brd7
	/if (${Me.Level} > 5) {
		/call CheckSpell "Selo's Accelerating Chorus" 7
		/if (${Macro.Return.Equal[Complete]}) /return
		
		/call CheckSpell "Selo's Rhythm of Speed" 7
		/if (${Macro.Return.Equal[Complete]}) /return
		
		/call CheckSpell "Selo's Accelerando" 7
		/if (${Macro.Return.Equal[Complete]}) /return
	}
/return


|** Checks song to put into gem8 **|
Sub Brd8
	/if (${Me.Level} > 6) {
		/call CheckSpell "Chorus of Life" 8
		/if (${Macro.Return.Equal[Complete]}) /return
	
		/call CheckSpell "Cantata of Life" 8
		/if (${Macro.Return.Equal[Complete]}) /return
	
		/call CheckSpell "Chorus of Marr" 8
		/if (${Macro.Return.Equal[Complete]}) /return
	
		/call CheckSpell "Wind of Marr" 8
		/if (${Macro.Return.Equal[Complete]}) /return
	
		/call CheckSpell "Ancient: Lcea's Lament" 8
		/if (${Macro.Return.Equal[Complete]}) /return
	
		/call CheckSpell "Chorus of Replenishment" 8
		/if (${Macro.Return.Equal[Complete]}) /return
	
		/call CheckSpell "Cantata of Replenishment" 8
		/if (${Macro.Return.Equal[Complete]}) /return
	
		/call CheckSpell "Cantata of Soothing" 8
		/if (${Macro.Return.Equal[Complete]}) /return
	
		/call CheckSpell "Hymn of Restoration" 8
		/if (${Macro.Return.Equal[Complete]}) /return
	}
/return


|** Checks song to put into gem9 **|
Sub Brd9
	|** Add code for gem**|
/return


|** Checks song to put into gem10 **|
Sub Brd10
	|** Add code for gem**|
/return


|** Checks song to put into gem11 **|
Sub Brd11
	|** Add code for gem**|
/return


|** Checks song to put into gem12 **|
Sub Brd12
	|** Add code for gem**|
/return


|** Checks song to put into gem13 **|
Sub Brd13
	|** Add code for gem**|
/return
 
I can help explain it.

below is the Sub I keep calling. It's doing exactly the same thing as all those /if (This) { /do this } else /if (thisother) { /do this } Statements.

Rich (BB code):
|** Checks the SpelltoCheck to be in GemToUse and returns true if it gets memorized or it's already in the gem slot specified. **|
Sub CheckSpell(string SpelltoCheck, int GemToUse)
	/if (${Me.Book[${SpelltoCheck}]} && ${Me.Gem[${GemToUse}].Name.NotEqual[${SpelltoCheck}]} || !${Me.Gem[${GemToUse}].ID}) {
		/memorize "${SpelltoCheck}" ${GemToUse}
		/delay 10s ${Me.Gem[${GemToUse}].Name.Equal[${SpelltoCheck}]}
		/return Complete
	} else /if (${Me.Gem[${SpelltoCheck}]}) {
		/return Complete
	}
/return Incomplete

/return will return to the line immediately following a call. Additionally, it can return information. In this case I have it returning a string.

So when I go through that Sub Routine I can see that it checks

for the spell to be in my book AND for me to not already have that spell in the gem slot I'm checking OR for the gem to not have anything in it.
If it memorizes a spell it will /return Complete
I access the information returned by using ${Macro.Return} which is a string in this case. So I can use .Equal[Complete] to compare the return to what I want for the condition following the call.

Think of it like Drinking Coffee.

If I have Coffee, I want to drink the coffee

Rich (BB code):
/call drinkCoffee

The process of drinking coffee.
Rich (BB code):
/if (!${CupIsEmpty}) {
    /TakeASip
    /return Complete
} else {
    /echo The cup was empty
    /return CupWasEmpty
}
So now that I've tried to take a sip. I've returned information about that action. Which I can now access using ${Macro.Return}
I can /echo ${Macro.Return} and it will tell me the result. Alternately, I can use it to decide what to do next.

Rich (BB code):
/if (${Macro.Return.Equal[Complete]}) {
    /echo Ahh, that was tasty!
} else /if (${Macro.Return.Equal[CupWasEmpty]}) {
    /call GetARefill
}

So I've done much the same thing in this case. Except I never actually use the Return "Incomplete" in a check.

The call for the sub routine I made uses the name of the spell you want to check and the gem you want it to go in.

So If you have the spell, and the spell isn't already memorized to the gem you want or the gem is not empty then you want to memorize it.

Look at how familiar these two statements are.

Rich (BB code):
/memorize "${SpelltoMemorize}" ${GemToUse}
/call CheckSpell "${SpelltoCheck}" "${GemToCheck}

While they aren't really using those Variables per-say, they both have the same concept.

/memorize is the command.

/call CheckSpell is the command.

For both you pass it the spell and the gem

When you create a sub routine you can offer it variables that you can then pass to the sub routine.

Sub ThatThing(variable1, variable2)

You don't have to define the type, but I did.

Sub ThatThing(string variable1, int variable2)

So in this case I made a string called variable1 and an integer called variable2

they are automatically declared when they are passed to the sub routine.

/call ThatThing "I Love Redguides" 10

Now if I use that call to the subroutine ThatThing with the parameters above, then variable1 is "I Love Redguides" and variable2 is 10.

Now, while you are inside that subroutine, you can use those variables.

Rich (BB code):
Sub ThatThing(string variable1, int variable2)
    /declare i int local 0
    /for i 1 to ${variable2}
        /echo ${variable1}
    /next i
/return

Now if I defined that subroutine to the thing above, it would echo variable1 the quantity of variable2. In this case it would echo "I Love Redguides" 10 times.

So back to the code at hand.

Rich (BB code):
/call CheckSpell "Warsong of the Vah Shir" 5
		/if (${Macro.Return.Equal[Complete]}) /return

If I Check the spell "Warsong of the Vah Shir" using gem 5. as the above call. If I don't have a spell memorized in that slot, or the gem in that slot isn't Warsong of the Vah Shir, then it should memorize it if I have it in the book. Then it waits until that song is done memorizing. Then it returns "Complete"

I then check to see if the return is complete.

Rich (BB code):
/if (${Macro.Return.Equal[Complete]}) /return

If it returned anything other than complete it won't return, it will check the next spell.

In this case, it would be returning back to Sub Main, inside the /for i loop at the same i value it left, but immediately following the /call ${Me.Class.ShortName}${i}

So if the macro returns complete, it stops checking spells. Otherwise, it will check every spell in the list. If it gets to the end of the list of spells without finding anything to memorize, it /returns by default, which also returns it back to the /for i loop immediately following the call.
 
think my MQ2 is either out of date or maybe just not the same as one your using i got it from a different site a few weeks ago but i tried to run the macro you wrote to replace my memspell sub and it fails at line 10.
it give me a No such 'character' member 'NumGems' Error

- - - Updated - - -

i started doing it in a completely different way now it seem so work prefectly so far
I made a seperate sub for each spell gem and turned the /for loop into its own sub also


Rich (BB code):
Sub MemGem1
		/varset GemNum 1
		/if (${Me.Class.Name.Equal[Bard]}) {
			/if (${Me.Level}>50 && ${Me.Book[Largo`s Absonant Binding]}) {
				/memorize "Largo`s Absonant Binding" 1
				/call WaitForSpell
				/return
			}
			/if (${Me.Level}>22 && ${Me.Book[Selo`s Consonant Chain]}) {
				/memorize "Selo`s Consonant Chain" 1
				/call WaitForSpell
				/return
			} else {
				/gsay im suposed to have a single target snare/slow song but someone (Points finger at ${Master}) was to fucking lazy to go buy it so we are going to have chase the mob's now
				/return
			}
			/gsay no Single Target Slow/Snare song to memorize yet
		}
		
		/if (${Me.Class.Name.Equal[Cleric]}) {
			/if (${Me.Level}>63 && ${Me.Book[Petrifying Earth]}) {
				/memorize  "Petrifying Earth" 1
				/call WaitForSpell
				/return
			}
			/if (${Me.Level}>61 && ${Me.Book[Greater Immobilize]}) {
				/memorize  "Greater Immobilize" 1
				/call WaitForSpell
				/return
			}
			/if (${Me.Level}>55 && ${Me.Book[Paralyzing Earth]}) {
				/memorize  "Paralyzing Earth" 1
				/call WaitForSpell
				/return
			}
			/if (${Me.Level}>45 && ${Me.Book[Immobilize]}) {
				/memorize  "Immobilize" 1
				/call WaitForSpell
				/return
			}
			/if (${Me.Level}>26 && ${Me.Book[Instill]}) {
				/memorize  "Instill" 1
				/call WaitForSpell
				/return
			}
			/if (${Me.Level}>6 && ${Me.Book[Root]}) {
				/memorize  "Root" 1
				/call WaitForSpell
				/return
			} else {
				/gsay im suposed to have a Root Spell but someone (Points finger at ${Master}) was to fucking lazy to go buy it so we are going to have to do with out it
				/return
			}
			/gsay no root spells to memorize yet
			
		}
		
		
		/return
		
Sub MemGem2
		/varset GemNum 2
		/if (${Me.Class.Name.Equal[Cleric]}) {
			/if (${Me.Level}>66 && ${Me.Book[Reproach]}) {
				/memorize  "Reproach" 2
				/call WaitForSpell
				/return
			}
			/if (${Me.Level}>64 && ${Me.Book[Ancient: Chaos Censure]}) {
				/memorize  "Ancient: Chaos Censure" 2
				/call WaitForSpell
				/return
			}
			/if (${Me.Level}>64 && ${Me.Book[Order]}) {
				/memorize  "Order" 2
				/call WaitForSpell
				/return
			}
			/if (${Me.Level}>61 && ${Me.Book[Condemnation]}) {
				/memorize  "Condemnation" 2
				/call WaitForSpell
				/return
			}
			/if (${Me.Level}>55 && ${Me.Book[Judgment]}) {
				/memorize  "Judgment" 2
				/call WaitForSpell
				/return
			}
			/if (${Me.Level}>53 && ${Me.Book[Reckoning]}) {
				/memorize  "Reckoning" 2
				/call WaitForSpell
				/return
			}
			/if (${Me.Level}>43 && ${Me.Book[Retribution]}) {
				/memorize  "Retribution" 2
				/call WaitForSpell
				/return
			}
			/if (${Me.Level}>28 && ${Me.Book[Wrath]}) {
				/memorize  "Wrath" 2
				/call WaitForSpell
				/return
			}
			/if (${Me.Level}>13 && ${Me.Book[Smite]}) {
				/memorize  "Smite" 2
				/call WaitForSpell
				/return
			}
			/if (${Me.Level}>4 && ${Me.Book[Furor]}) {
				/memorize  "Furor" 2
				/call WaitForSpell
				/return
			}
			/if (${Me.Level}>0 && ${Me.Book[Strike]}) {
				/memorize  "Strike" 2
				/call WaitForSpell
				/return
			} else {
				/gsay We must be Broke as Fuck sinse you have not got my level 1 nuke for me yet
				/return
			}
		}
		/return


Sub WaitForSpell
		/declare w int local
		/for w 1 to 120
			/if (${Me.Gem[${GemNum}].ID}) /return
			/delay 5
		/next w
		/return

- - - Updated - - -

i guess it mite also be that i don't have the rite plugins loaded also only ones i have running on my MQ2 rite now is MQ2Chatwnd, MQ2Twist and MQ2Cast
 
Would probably be in your best interest to get help from the website you got your MQ2 from. Can't help you if you're using out of date MQ2/Plugins.
 
but you have helped me a lot already even though your code don't seem to run on my MQ2 it has given me ideas on how to rework my macro to make it work my goal with this macro i'm writing is to make it so anyone can run it on just about any MQ2 with as few plugins as possible needed but i will be getting the redguides compile here in a little while once i get some money to donate for a higher level membership again but it will probably be another month before i can afford to do that
 
Well hopefully you get a RG compile. But based on a member of a TLO not being accessible in your build that could only mean a few things. One being that your copy of MQ2 is a copy prior to the true box server block and the people maintaining it are working outside of the True Box agreement, which is potentially hazardous for the community. The alternative is that it is a build for EMU servers and the NumGems member of the datatype Character was not yet implemented yet.

Below is a screenshot that shows that the Member for the DataType character is available in the Test source of base MQ2 as released by Macroquest2.com
So any build for live should have access to the ${Me.NumGems}. Thus, regardless of the purpose for your build my support for it ceases as it is not designed to run on a build I have access to. If this is in fact a build for True Box servers I encourage you to cease use of the product immediately.

As a side note: NumGems was added to the MQ2 Wiki in this update. However, that doesn't mean that is when it was added to the live build, Just when it was added to the wiki.

NumGems for DataType character.png
 
my Compile is for emu servers i got it off from MQEmulator.net its the free RoF2 Compile they have it was the only one i could find for free that worked with RoF2 Client i don't play on live anymore i have not for years since they started selling ingame items and stuff for cash instead of making you work for it like you used to have to

- - - Updated - - -

This is a great thread, not only for some coding lessons.. but also because of [email protected] user name

back when i actualy joined this forum it wasn't even called RedGuides and people didn't worry about about privacy as much, i just never bothered to change it, its a free email account i don't really care about and don't use for anything important
 
Plugin - MQ2Cast

Users who are viewing this thread

Back
Top