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

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

Search Bazaar for Tribute Items

DustinE

New member
Joined
May 24, 2006
RedCents
I posted this in the VIP::Macros section of the MQ2 boards, but nobody seems to appreciate it I guess. Anyway, here is the in-macro help I provided:

Rich (BB code):
Usage: /mac BazaarTribute [@Search String] [Type[Optional]] [Tribute Ratio[*Optional]] [@Price Range[Optional]] [Min Tribute[Optional]] [Min Profit[Optional]]
EX: /mac BazaarTribute "gem of" any 3 "0 100" 50 50
This will return items of any type that contain the words "gem of" that are less than 100pp and will give you a pp/tribute ratio of 3 that is at least 50 Tribute or a profit of at least 50pp to a vendor.
*This is only optional unless you wish to specify a later parameter!
@This parameter MUST be surrounded in quotes!

You can also search for ALL items of a certain type by formatting your search such as:
/mac BazaarTribute "" food 3
and you'll get all food with a ratio >= 3

Which brings me to my next point, all parameters after ratio will default themselves. You CAN also leave out ratio, but it's rather pointless because then it will just return ALL items searched for (0 ratio).

You can also use a syntax I call shorthand and only specify the search string and ratio, so for instance:
/mac BazaarTribute "gem of" 3
will work.

However, should you choose to do this you cannot specify any parameters following ratio or you WILL get errors and for christs sake, do not search for anything w/ less than two parameters unless you use /mac BazaarTribute help

So here's the macro itself:
Rich (BB code):
#turbo

Sub Main(string Param0, String Param1, int Param2, string Param3, int Param4, int Param5)

  |Eject if Search String = help
  /if (${Param0.Equal[help]}) {
    /declare help bool local TRUE
    /goto :end
  }
  |if Param1 is not given, assume any Type
  /if (${Param1.Equal[]}||${Param1.Length}<3) {
    /declare Param2 int local ${Param1}
    /varset Param1 any
  }
  |if Param3 is not given, assume max range
  /if (${Param3.Equal[NULL]}||${Param3}>0||!${Param3}) {
    /declare Param3 string local 0 9999999
  }
  |if Param4 and Param5 are not given, assume 0
  /if (!${Param4}) /declare Param4 int local 0
  /if (!${Param5}) /declare Param5 int local 0
  |Declarations
  /declare ratio int local ${Param2}
  /declare pFin int local 0
  /declare i int local 0
  /declare o int local 0
  /declare tVal int local 0
  /declare pVal float local 0
  /declare sVal float local 0
  /declare profit float local 0
  /declare repeat bool local FALSE
  
  
  |Make sure the bazaar window is open
  :BSWnd
  /bazaar
  /delay 1s ${Window[BazaarSearchWnd].Open}
  /if (!${Window[BazaarSearchWnd].Open}) /goto :BSWnd

  |Search the bazaar for the item
  /echo Searched for ${Param0} Type: ${Param1}, Ratio: ${Param2}, Price: ${Param3}, Min Tribute: ${Param4}, Min Value: ${Param5}  and now waiting for updates...
  /bzsrch race any class any slot any stat any type ${Param1} price ${Param3} ${Param0}
  :Search
  /delay 5s ${Bazaar.Done}
  /if (!${Bazaar.Done}) /goto :Search
  |Go through all items in the bazaar window
  /echo ${Bazaar.Count} items found!
  /if (${Bazaar.Count}==0) {
    /goto :end
  }
  |Declare array for deductive reasoning
  /declare iNames[${Bazaar.Count}] int local 0
  |Fill array with ID's
  /for i 1 to ${Bazaar.Count}
    /varset iNames[${i}] ${Bazaar.Item[${i}].ItemID}
  /next i
  /for i 1 to ${Bazaar.Count}
    /varset repeat FALSE
    |Select the Item that we want to investigate and open it
    /for o ${i} to ${Bazaar.Count}
      /if (${Bazaar.Item[${i}].ItemID}==${iNames[${o}]}) {
        /varset repeat FALSE
        /goto :quitloop
      } else {
        |A repeat item! Save some processing time and...
        /varset repeat TRUE
      }
    |Avoid this for loop if it's the last item, to solve some issues
    /if (${i}==${Bazaar.Count}) /goto :quitloop
    /next o
    :quitloop
    |...SKIP IT! Other wise continue to...
    /if (${repeat}) {
	/goto :skip
    } else {
        |...Open the item then...
	/pricecheck ${i}
        /delay 1s
    }
    |...Close the window and move on
    /keypress ESC
    |Because I'm lazy and stupid, we're creating a nested loop to cycle through all items greater than or equal to i.
    /for o ${i} to ${Bazaar.Count}
    |Checking the ID of the selected item vs those in the rest of the list
    /if (${ItemC.ID}==${Bazaar.Item[${o}].ItemID}) {
      |Cannot Derive Tribute or Value directly from Bazaar Search, so now, thanks to editing of ItemDisplay, we have ItemC
      |and we can now make Comparisons!
      /varset tVal ${ItemC.Tribute}
      /varset pVal ${Math.Calc[${Bazaar.Item[${o}].Price}/1000]}
      /varset sVal ${Math.Calc[${ItemC.Value}/1000]}
      /varset profit ${Math.Calc[${sVal}-${pVal}]}
      
      |Check for Tribute (and multiple Tributes!)
      /if (${tVal}>=${Param4} && ((${ratio}>0 && ${Math.Calc[${pVal}*${ratio}].Int}<=${tVal}) || (${ratio}==0 && ${tVal}>${ratio} && ${tVal}>${pVal.Int}) || (!${ratio}))) {
        /echo ${Bazaar.Item[${o}].Trader} - ${Bazaar.Item[${o}].Name}:  ${pVal}pp => ${tVal} Tribute (${Math.Calc[${tVal}/(${pVal}+.0000001)]} Ratio)
        /if (${Bazaar.Item[${o}].Quantity}>1) /echo Multiple ${Bazaar.Item[${o}].Name} on ${Bazaar.Item[${o}].Trader}:  ${Math.Calc[${pVal}*${Bazaar.Item[${o}].Quantity}]}pp => ${Math.Calc[${tVal}*${Bazaar.Item[${o}].Quantity}]} Tribute (${Math.Calc[${tVal}/(${pVal}+.0000001)]} Ratio) Total (${Bazaar.Item[${o}].Quantity}x Factor)
      }

      |Check for Value (and multiple Values!)
      /if (${profit}>0 && ${Profit}>=${Param5}) {
        /echo ${Bazaar.Item[${o}].Trader} - ${Bazaar.Item[${o}].Name}:  Profit: ${sVal} - ${pVal} = ${profit}
	/if (${Bazaar.Item[${o}].Quantity}>1) /echo Multiple ${Bazaar.Item[${o}].Name} on ${Bazaar.Item[${o}].Trader}:  ${Math.Calc[${sVal}*${Bazaar.Item[${o}].Quantity}]} - ${Math.Calc[${pVal}*${Bazaar.Item[${o}].Quantity}]} = ${Math.Calc[${profit}*${Bazaar.Item[${o}].Quantity}]} Total (${Bazaar.Item[${o}].Quantity}x Factor)
      }
    }
    |Avoid this for loop if it's the last item, to solve some issues
    /if (${i}==${Bazaar.Count}) /goto :skip
    /next o
    |Check to make sure that the next item in the ItemList has not already ran and 0 out any used ID's
    /for o 1 to ${Bazaar.Count}
      /if (${iNames[${o}]}==${ItemC.ID}) /varset iNames[${o}] 0
    /next o
    :skip
    /if (${i}>${Bazaar.Count}) /goto :end
    |If the item to be has already been used, save all this processing and skip it!
    /if (${iNames[${Math.Calc[${i}+1]}]}==0 && ${i}<${Bazaar.Count}) {
      /varset i ${Math.Calc[${i}+1]}
      /goto :skip
    }
    |Progress Indicator
    /if (${Math.Calc[${i}/${Bazaar.Count}]}>.9 && ${pFin} < 9) {
	/varset pFin 9
	/echo ${Math.Calc[${i}/${Bazaar.Count}*100]}% Completed.
	/goto :exitprogress
    } else /if (${Math.Calc[${i}/${Bazaar.Count}]}>.8 && ${pFin} < 8) {
	/varset pFin 8
	/echo ${Math.Calc[${i}/${Bazaar.Count}*100]}% Completed.
	/goto :exitprogress
    } else /if (${Math.Calc[${i}/${Bazaar.Count}]}>.7 && ${pFin} < 7) {
	/varset pFin 7
	/echo ${Math.Calc[${i}/${Bazaar.Count}*100]}% Completed.
	/goto :exitprogress
    } else /if (${Math.Calc[${i}/${Bazaar.Count}]}>.6 && ${pFin} < 6) {
	/varset pFin 6
	/echo ${Math.Calc[${i}/${Bazaar.Count}*100]}% Completed.
	/goto :exitprogress
    } else /if (${Math.Calc[${i}/${Bazaar.Count}]}>.5 && ${pFin} < 5) {
	/varset pFin 5
	/echo ${Math.Calc[${i}/${Bazaar.Count}*100]}% Completed.
	/goto :exitprogress
    } else /if (${Math.Calc[${i}/${Bazaar.Count}]}>.4 && ${pFin} < 4) {
	/varset pFin 4
	/echo ${Math.Calc[${i}/${Bazaar.Count}*100]}% Completed.
	/goto :exitprogress
    } else /if (${Math.Calc[${i}/${Bazaar.Count}]}>.3 && ${pFin} < 3) {
	/varset pFin 3
	/echo ${Math.Calc[${i}/${Bazaar.Count}*100]}% Completed.
	/goto :exitprogress
    } else /if (${Math.Calc[${i}/${Bazaar.Count}]}>.2 && ${pFin} < 2) {
	/varset pFin 2
	/echo ${Math.Calc[${i}/${Bazaar.Count}*100]}% Completed.
	/goto :exitprogress
    } else /if (${Math.Calc[${i}/${Bazaar.Count}]}>.1 && ${pFin} < 1) {
	/varset pFin 1
	/echo ${Math.Calc[${i}/${Bazaar.Count}*100]}% Completed.
	/goto :exitprogress
    }
    :exitprogress
  /next i

:end

|Help stuff and whatnots
/if (${help}) {
  /echo HELP! (/mac BazaarTribute help)
  /echo Usage: /mac BazaarTribute [@Search String] [Type[Optional]] [Tribute Ratio[*Optional]] [@Price Range[Optional]] [Min Tribute[Optional]] [Min Profit[Optional]]
  /echo EX: /mac BazaarTribute "gem of" any 3 "0 100" 50 50
  /echo This will return items of any type that contain the words "gem of" that are less than 100pp and will give you a pp/tribute ratio of 3 that is at least 50 Tribute or a profit of at least 50pp to a vendor.
  /echo *This is only optional unless you wish to specify a later parameter!
  /echo @This parameter MUST be surrounded in quotes!
}

/echo BazaarTribute Finished.

/return

To use this you have to use a slightly modified version of MQ2ItemDisplay. The changes are highlighted in red. (If you know of some way to do this w/o modifying MQ2ItemDisplay, that'd be great.)
Rich (BB code):
// MQ2ItemDisplay.cpp : Defines the entry point for the DLL application.
//

// PLUGIN_API is only to be used for callbacks.  All existing callbacks at this time
// are shown below. Remove the ones your plugin does not use.  Always use Initialize
// and Shutdown for setup and cleanup, do NOT do it in DllMain.


#ifndef ISXEQ
#include "../MQ2Plugin.h"
PreSetup("MQ2ItemDisplay");
#else
#include "../ISXEQClient.h"
#include "ISXEQItemDisplay.h"
#endif

void Comment(PSPAWNINFO pChar, PCHAR szLine); 

//ItemC Declares
BOOL dataItemC(PCHAR szName, MQ2TYPEVAR &Ret);
int dID;
int dTrib;
int dGTrib;
int dValue;

extern "C" {
__declspec(dllexport) ITEMINFO g_Item;
}

// *************************************************************************** 
// Function:    ItemDisplayHook
// Description: Our Item display hook 
// *************************************************************************** 
class ItemDisplayHook
{
   typedef enum {None = 0, Clicky, Proc, Worn, Focus, Scroll} SEffectType;

   static bool bNoSpellTramp;
   static SEffectType eEffectType;
public:
	   bool CXStrReplace (PCXSTR * Str, const char * cFind, const char * cReplace)
   {
      char cTemp[2048];
      DWORD dwSize = GetCXStr (*Str, cTemp, sizeof (cTemp));
      if (dwSize > 0 && dwSize < sizeof (cTemp) - 20) {
         char * cPtr = strstr (cTemp, cFind);
         if (cPtr != NULL) {
            char * cDup = strdup (cPtr);

            strcpy (cPtr, cReplace);
            strcpy (cPtr + strlen (cReplace), cDup + strlen (cFind));

            free (cDup);

            SetCXStr (Str, cTemp);
            return true;
         }
      }

      return false;
   }

   const char * GetRaceThreeLetterCode (int iRace)
   {
      switch (iRace) {
         case 1: return ("HUM");
         case 2: return ("BAR");
         case 3: return ("ERU");
         case 4: return ("ELF");
         case 5: return ("HIE");
         case 6: return ("DEF");
         case 7: return ("HEF");
         case 8: return ("DWF");
         case 9: return ("TRL");
         case 10:return ("OGR");
         case 11:return ("HLF");
         case 12:return ("GNM");
         case 13:return ("IKS");
         case 14:return ("VAH");
         case 15:return ("FRG");
      }

      return ("UNKNOWN RACE");
   }
    int GetDmgBonus (PCXSTR * Str)
   {
      char cTemp[2048];
      INT dmgbonuspos;
      INT dmgbonus = 0;
      INT badcharpos;

      GetCXStr(*Str, cTemp, sizeof (cTemp));
      
      string ItemDisplay;
      ItemDisplay = cTemp;

      char ActualDmgBonus[3];

      dmgbonuspos = ItemDisplay.find("Dmg Bonus:");
      
      if (dmgbonuspos != string::npos) {
         dmgbonuspos = dmgbonuspos + 11;
         ItemDisplay = ItemDisplay.substr(dmgbonuspos,3);

         badcharpos = ItemDisplay.find(" ");

         if (badcharpos != string::npos) { //found blank
            ItemDisplay = ItemDisplay.substr(0,2);
         }else{
            //badcharpos = tmpActualDmgBonus.find("<");
            badcharpos = ItemDisplay.find("<");
            if (badcharpos != string::npos) { //found <
               ItemDisplay = ItemDisplay.substr(0,2);
            }
         }

         strcpy (ActualDmgBonus,ItemDisplay.c_str());
         dmgbonus = atoi(ActualDmgBonus);
      }

      return dmgbonus;
   }
   VOID SetItem_Trampoline(class EQ_Item *pitem,bool unknown);
   VOID SetItem_Detour(class EQ_Item *pitem,bool unknown)
   {
      PEQITEMWINDOW This=(PEQITEMWINDOW)this;
      //PITEMINFO Item=*(PITEMINFO*)pitem;
      PCONTENTS item=(PCONTENTS)pitem;
      volatile PITEMINFO Item=(PITEMINFO)item->Item;
      CHAR out[MAX_STRING] = {0};
      CHAR temp[MAX_STRING] = {0};
      CHAR temp2[MAX_STRING] = {0};
      PCHAR lore = NULL;
      SetItem_Trampoline(pitem,unknown);

      // keep a global copy of the last item displayed...
      memcpy(&g_Item, Item, sizeof(ITEMINFO));

      strcpy(out,"<BR><c \"#00FFFF\">");
	 if ( Item->ItemNumber > 0 ) { 
        sprintf(temp,"Item ID: %d<br>", Item->ItemNumber); 
        strcat(out, temp); 
 		//Global ID for ItemC
		dID = Item->ItemNumber;
	 } else {
 		//Global ID for ItemC to 0
		dID = 0;
	 }
	 if (Item->Cost>0) {
		  DWORD cp = Item->Cost;
		  DWORD sp = cp/10; cp=cp%10;
		  DWORD gp = sp/10; sp=sp%10;
		  DWORD pp = gp/10; gp=gp%10;
		  strcat(out,"Value:");
		  if (pp>0) {
			  sprintf(temp," %dpp",pp);
			  strcat(out,temp);
		  }
		  if (gp>0) {
			  sprintf(temp," %dgp",gp);
			  strcat(out,temp);
		  }
		  if (sp>0) {
			  sprintf(temp," %dsp",sp);
			  strcat(out,temp);
		  }
		  if (cp>0) {
			  sprintf(temp," %dcp",cp);
			  strcat(out,temp);
		  }
		  strcat(out,"<BR>");
		  //Global Value for ItemC
		  dValue = Item->Cost;
	 } else {
		  //Global Value for ItemC to 0
		  dValue = 0;
	 }

	 if ( Item->Favor > 0 ) {
		 sprintf(temp,"Tribute Value: %d<br>", Item->Favor);
		 strcat(out, temp);
		 //Global Tribute for ItemC
		 dTrib = Item->Favor;
	 } else {
 		 //Global Tribute for ItemC to 0
		 dTrib = 0;
	 }
     if (Item->GuildFavor > 0 )  { 
        sprintf(temp,"Guild Tribute Value: %d<br>", Item->GuildFavor); 
        strcat(out, temp); 
		//Global Guild Tribute for ItemC
		dGTrib = Item->GuildFavor;
	 } else {
 		//Global Guild Tribute for ItemC
		dGTrib = 0;
	 }

	 if (Item->TimerID) {
		 int Secs = GetItemTimer(item);
		 if (!Secs) {
			 sprintf(temp,"Item Timer: <c \"#20FF20\">Ready</c><br>");
		 } else {
             int Mins=(Secs/60)%60;
             int Hrs=(Secs/3600);
             Secs=Secs%60;
             if (Hrs)
                 sprintf(temp,"Item Timer: %d:%02d:%02d<br>",Hrs,Mins,Secs);
             else
                 sprintf(temp,"Item Timer: %d:%02d<br>",Mins,Secs);
		 }
		 strcat(out, temp);
	 }

	 //Outlaw (AKA CheckinThingsOut) (02/24/2005)
   if (Item->ItemType != 27) { //Arrows..they have dmg/dly but we don't want them
      if ( Item->Delay > 0) {
         if ( Item->Damage > 0) {
            sprintf(temp,"Ratio: %5.3f<br>", (float)Item->Delay / (float)Item->Damage);
            strcat(out, temp);
            //Calculate Efficiency
            INT dmgbonus = 0;

            if (GetCharInfo2()->Level > 27) { //bonus is 0 for anything below 28
               dmgbonus = GetDmgBonus(&This->ItemInfo);
            }

            sprintf(temp,"Efficiency: %3.0f<br>",((((float)Item->Damage * 2) + dmgbonus) / (float)Item->Delay) * 50);
            strcat(out, temp);
            if (Item->EquipSlots & 16384) { // Equipable In Secondary Slot
               sprintf(temp,"Offhand Efficiency: %3.0f<br>",((((float)Item->Damage * 2) / (float)Item->Delay) * 50) * 0.62);
               strcat(out, temp);
            }
            sprintf(temp,"<br>");
            strcat(out,temp);    
         }
      }
   }
     lore=Item->LoreName;
     if (lore[0]=='*') lore++;
     if (strcmp(lore,Item->Name)) {
      sprintf(temp,"Item Lore: %s<BR>",Item->LoreName);
      strcat(out,temp);
     }
	PCHARINFO pChar = GetCharInfo();     // Ziggy - for item level highlights 
    // Will be 0 for no effect or -1 if other effects present 
    if (Item->Proc.SpellID && Item->Proc.SpellID!=-1) { 
       if (Item->Proc.RequiredLevel == 0 ) 
          sprintf(temp, "Procs at level 1 (Proc rate modifier: %d)<BR>", Item->ProcRate); 
      else 
         sprintf(temp,"%sProcs at level %d%s (Proc rate modifier: %d)<BR>", (Item->Proc.RequiredLevel > GetCharInfo2()->Level ? "<c \"#FF4040\">" : ""), Item->Proc.RequiredLevel, (Item->Proc.RequiredLevel > GetCharInfo2()->Level ? "</C>" : ""), Item->ProcRate); 
       strcat(out,temp); 
     } 
   /* No longer needed? 
    else if (Item->SpellId==998) { // 998 = haste 
      sprintf(temp,"%d%% Haste<BR>",Item->Level+1); 
      strcat(out,temp); 
     } 
   */ 
	
	 // Just in case...
	 if ( (!strstr(This->ItemInfo->Text,"(Combat)")) && Item->ProcRate > 0 )
	 {
		 sprintf(temp, "Proc rate Modifier: %d<BR>", Item->ProcRate );
		 strcat(out,temp);
	 }

	 // Teh_Ish (02/08/2004) 
     if ( Item->Clicky.EffectType==4 || Item->Clicky.EffectType==1 || Item->Clicky.EffectType==5) {
		 if ( Item->Clicky.RequiredLevel == 0 )
			 sprintf(temp, "Clickable at level 1<br>");
		else
			sprintf(temp,"%sClickable at level %d%s<BR>", (Item->Clicky.RequiredLevel > GetCharInfo2()->Level ? "<c \"#FF4040\">" : ""), Item->Clicky.RequiredLevel, (Item->Clicky.RequiredLevel > GetCharInfo2()->Level ? "</C>" : ""));  
        strcat(out,temp); 
     }

	 // TheColonel (12/24/2003)
	if (Item->LDType == 1) {
        if(Item->LDCost == 0)
           sprintf(temp,"This drops in %s dungeons<BR>", GetLDoNTheme(Item->LDTheme));
        else
           sprintf(temp,"LDoN Cost: %d from %s<BR>", Item->LDCost, GetLDoNTheme(Item->LDTheme));
        strcat(out,temp);
     }
     if (Item->LDType == 2 && Item->LDCost > 0) {
        sprintf(temp,"Discord Cost: %d points<BR>", Item->LDCost);
        strcat(out,temp);
     }
     if (Item->LDType == 4 && Item->LDCost > 0) {
        sprintf(temp,"DoN Cost: %d Radiant Crystals<BR>", Item->LDCost);
        strcat(out,temp);
     }
     if (Item->LDType == 5 && Item->LDCost > 0) {
        sprintf(temp,"DoN Cost: %d Ebon Crystals<BR>", Item->LDCost);
        strcat(out,temp); 
     } 
     // TheColonel (1/18/2004)
 /*
     if (Item->InstrumentType != 0){ 
       float instrumentmod = ((float)Item->InstrumentMod)/10.0f; 
       sprintf(temp,"Instrument mod: %3.1f to %s.<BR>", instrumentmod, szItemTypes[Item->InstrumentType]); 
       strcat(out,temp);       
     } 
 /**/

     if (Item->Type == ITEMTYPE_PACK) {
        sprintf(temp,"Container Type: %s<BR>",szCombineTypes[Item->Combine]);
        strcat(out,temp);
     }


	 sprintf(temp,"%07d",Item->ItemNumber); 
#ifndef ISXEQ
     GetPrivateProfileString("Notes",temp,"",temp2,MAX_STRING,INIFileName); 
     if (strlen(temp2)>0) 
     { 
        sprintf(temp,"Note: %s<br>",temp2); 
        strcat(out, temp); 
     }  
#endif

     if (out[0]!=17) {
      strcat(out,"</c>");
	  //((CXStr)This->ItemInfo)+=
      AppendCXStr(&This->ItemInfo,&out[0]);
     }
      // Ziggy - Highlight existing item display parts.
      // eg. Required level insufficient
      //     Wrong class, race, deity etc.
      if (GetCharInfo() != NULL) {
         char cFind[256];
         char cReplace[256];

         if (Item->RequiredLevel > GetCharInfo2()->Level) {
            sprintf (cFind, "Required level of %d.", Item->RequiredLevel);
            sprintf (cReplace, "<c \"#FF4040\">%s</C>", cFind);
            CXStrReplace (&This->ItemInfo, cFind, cReplace);
         }

         if (Item->RecommendedLevel > GetCharInfo2()->Level) {
            int iEffectiveness = (100 * GetCharInfo2()->Level / Item->RecommendedLevel);
            sprintf (cFind, "Recommended level of %d.", Item->RecommendedLevel);
            sprintf (cReplace, "<c \"#FF8020\">Recommended level of %d (%d%% effective).</C>", Item->RecommendedLevel, iEffectiveness);
            CXStrReplace (&This->ItemInfo, cFind, cReplace);
         }

         if (Item->Proc.RequiredLevel > GetCharInfo2()->Level) {
            sprintf (cFind, "<BR>Required Level: %d<BR>", Item->Proc.RequiredLevel);
            sprintf (cReplace, "<BR><c \"#FF4040\">Required Level: %d</C><BR>", Item->Proc.RequiredLevel);
            CXStrReplace (&This->ItemInfo, cFind, cReplace);
         }

         if (Item->Clicky.RequiredLevel > GetCharInfo2()->Level) {
            sprintf (cFind, "<BR>Required Level: %d<BR>", Item->Clicky.RequiredLevel);
            sprintf (cReplace, "<BR><c \"#FF4040\">Required Level: %d</C><BR>", Item->Clicky.RequiredLevel);
            CXStrReplace (&This->ItemInfo, cFind, cReplace);
         }

         // Highlight good/bad class match
         int iClassBit = 1 << (GetCharInfo2()->Class - 1);
         if (!(Item->Classes & iClassBit)) {
            char cClasses[64] = {0};
            int iClass = 1;
            for (WORD i = 1; i < 20; i++) {        // Only needs 15, but it's future proof.. oh yeah
               if (Item->Classes & iClass) {
                  char * cCode = pEverQuest->GetClassThreeLetterCode(i);
                  if (cCode == NULL) {
                     break;
                  }

                  strcat (cClasses, cCode);
                  strcat (cClasses, " ");
               }
               iClass *= 2;
            }

            sprintf (cFind, "Class:%s", cClasses);
            sprintf (cReplace, "Class:<c \"#FF4040\">%s</C>", cClasses);
            CXStrReplace (&This->ItemInfo, cFind, cReplace);

         } else {
            char * cCode = pEverQuest->GetClassThreeLetterCode(GetCharInfo2()->Class);
            sprintf (cFind, "%s ", cCode);
            sprintf (cReplace, "<c \"#20FF20\">%s</C>", cFind);

            if (!CXStrReplace (&This->ItemInfo, cFind, cReplace)) {
               sprintf (cReplace, "Class:  <c \"#20FF20\">ALL</C>", cFind);
               CXStrReplace (&This->ItemInfo, "Class:  ALL", cReplace);
            }
         }

         // Highlight good/bad race match
         DWORD raceNum;
         switch(GetCharInfo2()->Race) {
            case 0x80:  raceNum = 0xc; break;
            case 0x82:  raceNum = 0xd; break;
            case 0x4a:  raceNum = 0xe; break;
            default:    raceNum = GetCharInfo2()->Race - 1;
         }
         int iRaceBit = 1 << raceNum;
         if (!(Item->Races & iRaceBit)) {
            char cRaces[64] = {0};
            int iRace = 1;
            for (WORD i = 0; i < 20; i++) {
               if (Item->Races & iRace) {
                  const char * cCode = GetRaceThreeLetterCode(i + 1);
                  if (cCode == NULL) {
                     break;
                  }

                  strcat (cRaces, cCode);
                  strcat (cRaces, " ");
               }
               iRace *= 2;
            }

            sprintf (cFind, "Race:%s", cRaces);
            sprintf (cReplace, "Race:<c \"#FF4040\">%s</C>", cRaces);
            CXStrReplace (&This->ItemInfo, cFind, cReplace);

         } else {
            const char * cCode = GetRaceThreeLetterCode (raceNum + 1);
            sprintf (cFind, "%s ", cCode);
            sprintf (cReplace, "<c \"#20FF20\">%s</C>", cFind);

            if (!CXStrReplace (&This->ItemInfo, cFind, cReplace)) {
               sprintf (cReplace, "Race:  <c \"#20FF20\">ALL</C>", cFind);
               CXStrReplace (&This->ItemInfo, "Race:  ALL", cReplace);
            }
         }

         // Highlight deity mismatch
         if (Item->Diety != 0) {
            int iDeityBit = 1 << (GetCharInfo2()->Deity - 200);
            if (GetCharInfo2()->Deity < DEITY_Bertoxxulous || GetCharInfo2()->Deity > DEITY_Veeshan) {
               iDeityBit = 0;                         // Agnostic shows as 396
            }

            char * cPlayerD = pEverQuest->GetDeityDesc (GetCharInfo2()->Deity);

            strcpy (cFind, "Deity:");
            strcpy (cReplace, "Deity:");

			//Mahull Changes			
			//bool bMatch = (Item->Diety & iDeityBit);  // Do we have required deity?
			bool bMatch;
			
			if (Item->Diety & iDeityBit) {
				bMatch = true;
			}
			else {
				bMatch = false;
			}

            if (!bMatch) {
               strcat (cReplace, "<c \"#FF4040\">");
            }
			

            int iDeity = 1;
            int iAdded = 0;
            for (int i = 0; i < 16; i++) {
               if (Item->Diety & iDeity) {
                  const char * cDeity = pEverQuest->GetDeityDesc (i + 200);
                  if (cDeity == NULL) {
                     break;
                  }

                  if (strlen (cFind) > 6) {
                     strcat (cReplace, ",");    // We comma seperate, for clarity
                  }

                  if (iAdded > 0 && iAdded % 5 == 0) {
                     strcat (cFind, "<BR>");    // They force a new-line per 5
                  }
                  iAdded++;

                  strcat (cFind, "  ");         // 2 spaces before each deity
                  strcat (cReplace, " ");       // 1 space after our comma though

                  if (strcmp (cDeity, cPlayerD) == 0) {     // Ours?
                     strcat (cReplace, "<c \"#20FF20\">");  // Green it
                  }

                  strcat (cFind, cDeity);
                  strcat (cReplace, cDeity);

                  if (strcmp (cDeity, cPlayerD) == 0) {
                     strcat (cReplace, "</C>");
                  }
               }
               iDeity *= 2;
            }

            if (!bMatch) {
               strcat (cReplace, "</C>");
            }

            CXStrReplace (&This->ItemInfo, cFind, cReplace);
         }
      }
 
      // Ziggy - Items showing their spell details:
      bNoSpellTramp=true;
      if (Item->Clicky.SpellID > 0 && Item->Clicky.SpellID != -1) {
         eEffectType = Clicky;
         SetSpell_Detour(Item->Clicky.SpellID, false, 0);
      }

      if (Item->Proc.SpellID > 0 && Item->Proc.SpellID != -1) {
         eEffectType = Proc;
         SetSpell_Detour(Item->Proc.SpellID, false, 0);
      }

      if (Item->Worn.SpellID > 0 && Item->Worn.SpellID != -1) {
         eEffectType = Worn;
         SetSpell_Detour(Item->Worn.SpellID, false, 0);
      }

      if (Item->Focus.SpellID > 0 && Item->Focus.SpellID != -1) {
         eEffectType = Focus;
         SetSpell_Detour(Item->Focus.SpellID, false, 0);
      }

      if (Item->Scroll.SpellID > 0 && Item->Scroll.SpellID != -1) {
         eEffectType = Scroll;
         SetSpell_Detour(Item->Scroll.SpellID, false, 0);
      }
      bNoSpellTramp=false;
      eEffectType = None;
   }

   VOID SetSpell_Trampoline(int SpellID,bool HasSpellDescr,int unknown_int);
   VOID SetSpell_Detour(int SpellID,bool HasSpellDescr,int unknown_int)
   {
     PEQITEMWINDOW This=(PEQITEMWINDOW)this;
     PCHARINFO pCharInfo = NULL;
     if (NULL == (pCharInfo = GetCharInfo())) return;
     PSPELL pSpell = GetSpellByID(SpellID);
     if (pSpell == NULL) {
        return;
     }

     CHAR out[MAX_STRING] = {0};
     CHAR temp[MAX_STRING] = {0};
     if (!bNoSpellTramp) {
        SetSpell_Trampoline(SpellID,HasSpellDescr,unknown_int);
        strcpy(out,"<BR><c \"#00FFFF\">");
     } else {
        char * cColour = "FF0000", * cName = "Blub";

        switch (eEffectType) {
           case Clicky:
              cColour = "00FF00";
              cName = "Clicky";
              break;
           case Proc:
              cColour = "FF00FF";
              cName = "Proc";
              break;
           case Worn:
              cColour = "FFFF00";
              cName = "Worn";
              break;
           case Focus:
              cColour = "9F9F00";
              cName = "Focus";
              break;
           case Scroll:
              cColour = "9F9F9F";
              cName = "Scroll";
              break;
        }

        sprintf (out, "<BR><c \"#%s\">Spell Info for %s effect: %s<br>", cColour, cName, pSpell->Name);
     }

	 sprintf(temp, "ID: %04d&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;", pSpell->ID );
	 strcat(out,temp);

	 DWORD Tics=GetSpellDuration(pSpell,pCharInfo->pSpawn);
     if (Tics==0xFFFFFFFF)
	    strcat(out, "Duration: Permanent<br>" );
     else if (Tics==0xFFFFFFFE) 
	    strcat(out, "Duration: Unknown<br>" );
	 else if (Tics==0) {
	    // It's "instant", who cares?
		 strcat(out,"<br>");
	 }
     else {
		sprintf(temp, "Duration: %1.1f minutes<br>",(float)((Tics*6.0f)/60.0f));
		strcat(out, temp);
     }

	 sprintf(temp, "RecoveryTime: %1.2f&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;RecastTime: %1.2f <br>", (float)(pSpell->FizzleTime/1000.0f), (float)(pSpell->RecastTime/1000.0f) );
	 strcat(out,temp);

	 if (pSpell->Range > 0.0f ) {
		 sprintf(temp, "Range: %1.0f", pSpell->Range );
		 strcat(out,temp);
		 if ( pSpell->PushBack == 0.0f && pSpell->AERange == 0.0f)
			 strcat(out, "<br>");
	 }

	 if (pSpell->PushBack != 0.0f ) {
		 if (pSpell->Range > 0.0f ) 
			 strcat(out, "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;" );
		 sprintf(temp, "PushBack: %1.1f", pSpell->PushBack );
		 strcat(out, temp);
		 if (pSpell->AERange == 0.0f || pSpell->Range > 0.0f )
			 strcat(out, "<br>" );
	 }

	 if (pSpell->AERange > 0.0f ) {
		 if (pSpell->Range > 0.0f)
			 strcat(out, "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;" );
		 else if (pSpell->PushBack > 0.0f )
			 strcat(out, "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;" );
		 sprintf(temp, "AERange: %1.0f<br>", pSpell->AERange );
		 strcat(out, temp);
	 }

	 if (pSpell->TargetType != 0x06 && pSpell->TargetType != 0x0e && pSpell->TargetType != 0x03 && pSpell->TargetType != 0x28 && pSpell->TargetType != 0x29 ) {
		   if (pSpell->SpellType == 0) {   // Ziggy: Only show resist type for detrimental spells
          switch(pSpell->Resist) {
             case 7: strcat(out, "Resist: Prismatic[Avg]" ); break; // Ziggy - Added Reminder which..
             case 6: strcat(out, "Resist: Chromatic[Low]" ); break; // ..is what type of resist
             case 5: strcat(out, "Resist: Disease" ); break;
             case 4: strcat(out, "Resist: Poison" ); break;
             case 3: strcat(out, "Resist: Cold/Ice" ); break;
             case 2: strcat(out, "Resist: Fire" ); break;
             case 1: strcat(out, "Resist: Magic" ); break;
             case 0: strcat(out, "Resist: Unresistable"); break;
          }

          if (pSpell->ResistAdj != 0 ) {
             sprintf(temp, "&nbsp;&nbsp;&nbsp;(Resist Adj.: %d)<br>", pSpell->ResistAdj );
             strcat(out,temp);
          } else {
             strcat(out,"<br>");
          }
       } 
	 }

	 strcat(out, "<br>" );
	 ShowSpellSlotInfo(pSpell,&out[strlen(out)]);

	 //show usable classes routine by Koad//
     bool bUseableClasses = false; 
	 strcat(out, "<br>" ); 
    for (int j=0; j<16; j++) {  // Ziggy - output will word wrap properly now
       if (pSpell->Level[j]>0 && pSpell->Level[j]<=70) {
          if (bUseableClasses) strcat (out, ", ");

          sprintf(temp,"%s(%d)", GetClassDesc(j+1), pSpell->Level[j]);
          strcat(out, temp);
          bUseableClasses = true;
       }
    } 
	 if (bUseableClasses) strcat(out, "<br><br>" ); 

     if (pSpell->CastOnYou[0]) { 
       sprintf(temp, "Cast on you: %s<br>", pSpell->CastOnYou); 
       strcat(out,temp); 
     } 

   if (pSpell->CastOnAnother[0]) { 
    sprintf(temp, "Cast on another: %s<br>", pSpell->CastOnAnother); 
    strcat(out,temp); 
   } 

   if (pSpell->WearOff[0]) { 
    sprintf(temp, "Wears off: %s<br>", pSpell->WearOff); 
    strcat(out,temp); 
   } 


	 if (out[0]!=17) {
     strcat(out,"</c>");
	 //((CXStr)This->ItemInfo)+=
	 AppendCXStr(&This->ItemInfo,&out[0]);   
     }
   }
};

class InvSlotWndHook
{
public:
   VOID DrawTooltip_Trampoline(class CXWnd const *);
   VOID DrawTooltip_Detour(class CXWnd const * pWnd)
   {
       CHAR Temp[MAX_STRING]={0};
       CHAR Temp2[MAX_STRING]={0};

       PCONTENTS pitem = GetItemContentsBySlotID(((CSidlScreenWnd *)pWnd)->SlotID);
	   if (pitem)
	   {
           PITEMINFO pItem = pitem->Item;

           if (pItem && pItem->TimerID)
           {
               int Secs=GetItemTimer(pitem);
               if (Secs)
               {
                   int Mins=(Secs/60)%60;
                   int Hrs=(Secs/3600);
                   Secs=Secs%60;
                   if (Hrs)
                       sprintf(Temp2,"%d:%02d:%02d",Hrs,Mins,Secs);
                   else
                       sprintf(Temp2,"%d:%02d",Mins,Secs);
               } else
                   strcpy(Temp2,"Ready");
               sprintf(Temp,"%s (%s)",pItem->Name,Temp2);
               SetCXStr((PCXSTR *)&pWnd->Tooltip,Temp);
           }
	   }
       DrawTooltip_Trampoline(pWnd);
       return;
   }
};

class XWndHook
{
public:
   VOID DrawTooltip_Trampoline(class CXWnd const *);
   VOID DrawTooltip_Detour(class CXWnd const * pWnd)
   {
       if (GetParentWnd(pWnd)==(CXWnd *)pPotionBeltWnd)
	   {
           CHAR Temp[MAX_STRING]={0};
           CHAR Temp2[MAX_STRING]={0};

           STMLToPlainText(&pWnd->Tooltip->Text[0],Temp);
           PCONTENTS pitem = GetItemContentsByName(Temp);
           if (pitem)
           {
               PITEMINFO pItem = pitem->Item;

               if (pItem && pItem->TimerID)
               {
                   int Secs=GetItemTimer(pitem);
                   if (Secs)
                   {
                       int Mins=(Secs/60)%60;
                       int Hrs=(Secs/3600);
                       Secs=Secs%60;
                       if (Hrs)
                           sprintf(Temp2,"%d:%02d:%02d",Hrs,Mins,Secs);
                       else
                           sprintf(Temp2,"%d:%02d",Mins,Secs);
                   } else
                       strcpy(Temp2,"Ready");
                   sprintf(Temp,"%s (%s)",pItem->Name,Temp2);
                   SetCXStr((PCXSTR *)&pWnd->Tooltip,Temp);
               }
           }
	   }
       DrawTooltip_Trampoline(pWnd);
       return;
   }
};

ItemDisplayHook::SEffectType ItemDisplayHook::eEffectType = None;
bool ItemDisplayHook::bNoSpellTramp = false;

DETOUR_TRAMPOLINE_EMPTY(VOID ItemDisplayHook::SetItem_Trampoline(class EQ_Item *,bool)); 
DETOUR_TRAMPOLINE_EMPTY(VOID ItemDisplayHook::SetSpell_Trampoline(int SpellID,bool HasSpellDescr,int));
DETOUR_TRAMPOLINE_EMPTY(VOID InvSlotWndHook::DrawTooltip_Trampoline(class CXWnd const *));
DETOUR_TRAMPOLINE_EMPTY(VOID XWndHook::DrawTooltip_Trampoline(class CXWnd const *));

#ifndef ISXEQ
void Comment(PSPAWNINFO pChar, PCHAR szLine) 
{ 
   CHAR Arg[MAX_STRING] = {0}; 
   CHAR ItemNo[MAX_STRING] = {0}; 
   CHAR Comment[MAX_STRING] = {0}; 
   CHAR szTemp[MAX_STRING] = {0}; 
   GetArg(Arg,szLine,1); 
   GetArg(ItemNo,szLine,2); 
   GetArg(szTemp,szLine,3); 
   for(int i=4;strlen(szTemp);i++){ 
      strcat(Comment,szTemp); 
      strcat(Comment," "); 
      GetArg(szTemp,szLine,i); 
   } 
   int itemno = atoi(ItemNo); 
 
   if (stricmp(Arg,"add") && stricmp(Arg,"del")) 
   { 
      WriteChatColor("Use: /inote <add|del> <itemno> \"Comment\"",CONCOLOR_YELLOW); 
      return; 
   } 
   if (itemno <= 0) 
   { 
      WriteChatColor("Invalid item number"); 
      WriteChatColor("Use: /inote <add|del> <itemno> \"Comment\"",CONCOLOR_YELLOW); 
      return; 
   } 
   if (strlen(Comment)==0 || !stricmp(Arg,"del")) 
   { 
      sprintf(szTemp,"%07d",itemno); 
      WritePrivateProfileString("Notes",szTemp,"",INIFileName); 
      return; 
   } 
 
   if (!stricmp(Arg,"add")) 
   { 
      sprintf(szTemp,"%07d",itemno); 
      WritePrivateProfileString("Notes",szTemp,Comment,INIFileName); 
      return; 
   } 
} 
 

//This is the ItemC DataType
class MQ2ItemCType *pItemCType=0;
class MQ2ItemCType : public MQ2Type
{
public:
	enum ItemCMembers
	{
		ID=1,
		Tribute=2,
		GuildTribute=3,
        Value=4,
	};

	MQ2ItemCType():MQ2Type("itemc")
	{
		TypeMember(ID);
		TypeMember(Tribute);
		TypeMember(GuildTribute);
		TypeMember(Value);
	}
	~MQ2ItemCType()
	{
	}

	bool GetMember(MQ2VARPTR VarPtr, PCHAR Member, PCHAR Index, MQ2TYPEVAR &Dest)
	{
		PMQ2TYPEMEMBER pMember=MQ2ItemCType::FindMember(Member);
		if (!pMember)
			return false;
		switch((ItemCMembers)pMember->ID)
		{
		case ID:
			Dest.Int=dID;
			Dest.Type=pIntType;
			return true;
		case Tribute:
			Dest.Int=dTrib;
			Dest.Type=pIntType;
			return true;
		case GuildTribute:
			Dest.Int=dGTrib;
			Dest.Type=pIntType;
			return true;
		case Value:
			Dest.Int=dValue;
			Dest.Type=pIntType;
			return true;
		}
		return false;
	}

	bool FromData(MQ2VARPTR &VarPtr, MQ2TYPEVAR &Source)
	{
		return false;
	}

	bool FromString(MQ2VARPTR &VarPtr, PCHAR Source)
	{
		return false;
	}
};

BOOL dataItemC(PCHAR szName, MQ2TYPEVAR &Ret)
{
	Ret.DWord=1;
	Ret.Type=pItemCType;
	return true;
}

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

	// Add commands, macro parameters, hooks, etc.

	EzDetour(CItemDisplayWnd__SetItem,&ItemDisplayHook::SetItem_Detour,&ItemDisplayHook::SetItem_Trampoline);
	EzDetour(CItemDisplayWnd__SetSpell,&ItemDisplayHook::SetSpell_Detour,&ItemDisplayHook::SetSpell_Trampoline);
	EzDetour(CInvSlotWnd__DrawTooltip,&InvSlotWndHook::DrawTooltip_Detour,&InvSlotWndHook::DrawTooltip_Trampoline);
	EzDetour(CXWnd__DrawTooltip,&XWndHook::DrawTooltip_Detour,&XWndHook::DrawTooltip_Trampoline);

	AddCommand("/inote",Comment); 

	//ItemC Junk
	AddMQ2Data("ItemC",dataItemC); // cc - added, but not using TLO yet
    pItemCType = new MQ2ItemCType;
}

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

	// Remove commands, macro parameters, hooks, etc.
	RemoveDetour(CItemDisplayWnd__SetItem);
	RemoveDetour(CItemDisplayWnd__SetSpell);
	RemoveDetour(CInvSlotWnd__DrawTooltip);
	RemoveDetour(CXWnd__DrawTooltip);

	RemoveCommand("/inote");

	//ItemC Junk
	delete pItemCType;
}
#endif

It would probably be best to simply modify the code from the latest MQ2 release as opposed to just copying and pasting the entire code and I'll try to keep this attachment updated.


Using this macro I was able to stretch 3kpp into about 28k tribute in about 15 minutes.

Hope you enjoy this.

Here's the latest modified, compiled MQ2ItemDisplay:
 
Anyone had any luck with this? I tried it for some time last night, and wasn't able to get it to work as I thought it should.

The statement:

Rich (BB code):
/mac BazaarTribute "" any 3 "0 1000" 50 50

should search the entire Baz database and return only those items that have a multiple of 3 beteween the cost of the item and the tribute value (such as cost is 100 plat, trib value is 300) between a cost of 0 plat and 1000 plat. Also, it should only list items that have a minumium tribute value of 50 or a profit of 50 plat to a vendor.

Typing this line and letting the macro work returns ALL items that are between 0 and 1000 plat, with no reguard to the specified 3x factor or the 50 minumium tribute or the 50 plat profit.

Am I doing something wrong? Or did I misinterpt what the macro is supposed to do?
 
This idea sounds AMAZING, I have been dreaming of this. It may be my ignorance but how do you make the changes to the plugin mq2itemdisplay? When I open it as a notepad document to make the changes it just a bunch of screwing characters as all plugins look. I can make and change macros but how do I change a plugin?

Also, added examples for the syntax would be great. I don't think anyone cares what type of item they find, just the ratio is the key. Sorry if my ignorance creates a pain in your behind, This just seems like an extremely usefull macro and I really want to use it to it's full extent.
 
To edit MQ2ItemDisplay you have to edit and recompile the source code, which is provided with the latest release of macroquest.

If you don't know how to do that, then I would suggest you just download the attached copy.

The bazaar search window displays every item that it found via the search material, the macro then goes through each individual item for comparison and the results are returned in the MQ2 window. If it seems like the macro is doing nothing, just wait for the percentages to display in the MQ2 window, it shows progress every ~10%.

As for syntax it goes the following:

Usage: /mac BazaarTribute [@Search String] [Type[Optional]] [Tribute Ratio[*Optional]] [@Price Range[Optional]] [Min Tribute[Optional]] [Min Profit[Optional]]

So, /mac BazaarTribute "Jaundice" any 10 "0 1000" would return anything at all with the word jaundice in it that is less than a thousand plat that returns a tribute:pp ratio of 10:1 or higher.

Suppose though, that there are over 200 items with the name Jaundice in it and you're only concerned with armor that has the name Jaundice in it, then you could use the search string /mac BazaarTribute "Jaundice" armor 10 "0 1000" and help to filter down some of those results.

Also, there should be a lot of item windows popping up and closing, if there ISN'T then you need to download this attached MQ2Bzsrch. It's the latest version that the MQ2 team has released, but I don't think some of the compilations provided on the site are using it and it's causing this bug.

Sorry for this lengthy explanation. Hopefully this clears some things up.
 
Thanks DustinE...the new MQ2Bzsrch.dll file did the trick. Macro working like a charm now. Red Cent inc!
 
Good to hear, I've really no idea why that bugs out, and it sucks that just getting my macro up and running is such a hastle. Hopefully someone who's smarter than I am can figure out an easier way :)
 
I have found some nice tribute items in bazaar but not using this macro. I don't get anything when I run it. I run it as above

/mac bazaartribute "" any 3 "0 1000" 50 50 and it says 0 items found. I have also tried

/mac bazaartribute "" any 3 "0 1000" 5 5 and still nothing.

Am I doing something wrong?
 
Did you download the replacement to MQ2Bzsrch.dll ? If no item windows are popping up, then you need to download that. If item windows are popping up and you've downloaded the modified MQ2ItemDisplay.dll then it's just simply not finding anything out of the 200 returns. Refine your search down to items that you think would tribute well.

The reason for being able to specify type is that if, for instance, you want to search for armor vs gems or pots or something, cuz just searching for a generic name will cap the results list every time.
 
Updated MQ2ItemDisplay.cpp as of 6/16/2006 with the changes that were listed above.

/MAC BAZAARTRIBUTE "" FOOD 3 "20 9999999" 1500 100

"" would be item name to search for
Ratio of 3
type is food
20 to 999999 pp is range

1500 is min tribute to display
100pp is vendor value

/MAC BAZAARTRIBUTE "bow" any 3 "20 9999999" 1500 100

Search for any thing with bow in the name that is 3 times the tribute value as the cost is.
 
Last edited:
The reason your not getting any thing is same reason if you do that search in the regular bazaar search window; nothing comes up.

Try

/mac bazaartribute "gem" any 3 "0 1000" 50 50

This will search for any thing with name of Gem with any type of value 0 to 1000pp min tribute value of 50 and vendor value of 50pp



Jinx said:
I have found some nice tribute items in bazaar but not using this macro. I don't get anything when I run it. I run it as above

/mac bazaartribute "" any 3 "0 1000" 50 50 and it says 0 items found. I have also tried

/mac bazaartribute "" any 3 "0 1000" 5 5 and still nothing.

Am I doing something wrong?
 
Anyone still use this? If so, can you tell me how it lists matches. I set parameters, it runs through "X" number of items found, gives me percent of completetion percentages, then says "BazaarTribute Finished" The current macro has ended. I test it by finding an item and setting the parameters to that item so I know there is a target item. It does the search, windows open and close but no "results" show anywhere that I can see.
 
Search Bazaar for Tribute Items

Users who are viewing this thread

Back
Top
Cart