Plugin: MQ2Feedme

htw

Developer
Joined
Aug 27, 2006
Messages
13,193
Reaction score
374
Points
83
Location
Albuquerque, NM
MQ2Feedme.cpp
Code:
//****************************************************************//
// MQ2FeedMe v1.09
// based on snippet FeedMe 2.3 from A_Druid_00
// by s0rCieR 2005.12.10
// updated 10/06 for TSS patch
//****************************************************************//
// I was real bored this morning and wake up, checking mq2 forums
// snippet by A_Druid_00 then i see a comment from hendrix04 that
// say that this would be an awsome plugin. Well here it is ...
//
// It will eat food and drink you specify in the ini (MQ2FeedMe.ini)
// if your hunger or thirst level fall below 5000. (GAGE_HUNGER and
// GAGE_THIRST to change those threshold). Threshold level is check
// every 15 seconds or so (SKIP_PULSES).
//
// Lots of code stolen, credits goes to the author of those.
//****************************************************************//
// Usage: /autodrink          -> Force manual drinking
//        /autodrink 0        -> Turn off autodrinking
//        /autodrink 3500     -> Set Level where plugin should drink
//
//        /autofeed           -> Force manual feeding
//        /autofeed 0         -> Turn off autofeeding
//        /autofeed 3500      -> Set Level where plugin should eat
//****************************************************************//

#include "../MQ2Plugin.h"
#include <list>
#include <string>

PreSetup("MQ2FeedMe");

#define      SKIP_PULSES  500
#define      SLOT_MAX      30
#define      NOID          -1

bool         Loaded=0;                           // List Loaded?
bool       Justate=0;
long         Pulses=0;                           // Pulses Skipped Counter
long         jPulses=0;                          //pulses skipped
short        cstep=0;

DWORD         FeedAt=0;                           // Feed Level
DWORD         DrnkAt=0;                           // Drnk Level

char         Buffer[16];

list<string> Hunger;                             // Hunger Fix List
list<string> Thirst;                             // Thirst Fix List

char         FindName[ITEM_NAME_LEN];            // Find Food/Drink Name
DWORD        FindPile;                           // Find Qty in Stack
DWORD        FindSlot;                           // Find Inventory Slot

BOOL WindowOpen(PCHAR WindowName) {
    PCSIDLWND pWnd=(PCSIDLWND)FindMQ2Window(WindowName);
    return (!pWnd)?false:(BOOL)pWnd->Show;
}

void SendModClick(PCHAR WindowName, PCHAR ScreenID, PCHAR ClickNotification, DWORD KeyState) {
    bool KeyboardFlags[4];
    *(DWORD*)&KeyboardFlags=*(DWORD*)&((PCXWNDMGR)pWndMgr)->KeyboardFlags;
    *(DWORD*)&((PCXWNDMGR)pWndMgr)->KeyboardFlags=KeyState;
    SendWndClick(WindowName,ScreenID,ClickNotification);
    *(DWORD*)&((PCXWNDMGR)pWndMgr)->KeyboardFlags=*(DWORD*)&KeyboardFlags;
}

void ReadList(list<string> *MyList, PCHAR fSec) {
    char Buffer[MAX_STRING*10];
    MyList->clear();
    if(GetPrivateProfileString(fSec,NULL,"",Buffer,MAX_STRING*10,INIFileName)) {
        char  szTemp[MAX_STRING];
        PCHAR pBuffer=Buffer;
        while (pBuffer[0]!=0) {
            GetPrivateProfileString(fSec,pBuffer,"",szTemp,MAX_STRING,INIFileName);
            if(szTemp[0]!=0) MyList->push_back(string(szTemp));
            pBuffer+=strlen(pBuffer)+1;
        }
    }
}

bool GoodToFeed() {
    if(MQ2Globals::gGameState==GAMESTATE_INGAME)   // currently ingame
        if(GetCharInfo2())                                       // get charinfo
            if(!GetCharInfo2()->Cursor)                    // nothing on cursor
                if(GetCharInfo()->pSpawn->CastingSpellID==NOID)// not casting
                    if(GetCharInfo()->pSpawn->SpellETA==0)         // not using abilities
                        if(!WindowOpen("SpellBookWnd"))                // not medding a spell
                            if(!WindowOpen("MerchantWnd"))                 // not interacting with vendor
                                if(!WindowOpen("TradeWnd"))                    // not trading with someone
                                    if(!WindowOpen("BigBankWnd"))                  // not banking
                                        if(!WindowOpen("BankWnd"))                     // not banking
                                            if(!WindowOpen("LootWnd"))                     // not looting
                                                return true;                                   // then return true
    return false;                                  // otherwise false
}

void FindFood(DWORD fTYPE, list<string> fLIST, DWORD fSLOT, PCONTENTS fITEM) {
    if(fITEM) if(fITEM->Item->ItemType==fTYPE) {
        if(fITEM->Item->NoRent) {
            list<string>::iterator pLIST;
            pLIST=(fITEM->StackCount<FindPile)?fLIST.begin():fLIST.end();
            while(pLIST!=fLIST.end()) if(!stricmp(fITEM->Item->Name,pLIST->c_str())) break; else pLIST++;
            if(pLIST==fLIST.end()) return;
        }
        strcpy(FindName,fITEM->Item->Name);
        FindSlot=fSLOT;
        FindPile=(fITEM->Item->NoRent)?fITEM->StackCount:0;
    }
}

void Consume(DWORD fTYPE, list<string> fLIST) {
    if (Justate) return;
    FindPile=99999;
    for(int iSlot=22; iSlot<SLOT_MAX; iSlot++) if(PCONTENTS pSlot=GetCharInfo2()->InventoryArray[iSlot]) {
        if(pSlot->Item->Type!=ITEMTYPE_PACK) FindFood(fTYPE,fLIST,iSlot,pSlot);
        else for(int bSlot=0; bSlot<pSlot->Item->Slots; bSlot++) FindFood(fTYPE,fLIST,251+(iSlot-22)*10+bSlot,pSlot->Contents[bSlot]);
    }
    if(FindPile<99999) {
        WriteChatf("MQ2FeedMe::Consuming -> %s.",FindName);
        if(FindSlot<0) {//not sure why it doesnt work when food is in main inv slot
            //just moving it
            sprintf(FindName,"InvSlot%d",FindSlot);
            SendModClick("InventoryWindow",FindName,"rightmouseup",0);
        } else {
            pInvSlotMgr->MoveItem(FindSlot,0x1E,1,1);
            SendModClick("InventoryWindow","InvSlot29","leftmouseup",0);
            SendModClick("InventoryWindow","InvSlot29","rightmouseup",0);
            Justate = true;
            cstep = 1;
            jPulses = 0;
        }
    }
}

void AutoFeedCmd(PSPAWNINFO pChar, PCHAR zLine) {
    if(zLine[0]!=0) {
        FeedAt=atoi(zLine); if(FeedAt<0) FeedAt=0; else if(FeedAt>5000) FeedAt=5000;
        sprintf(Buffer,"%d",FeedAt);
        WritePrivateProfileString(GetCharInfo()->Name,"AutoFeed",Buffer,INIFileName);
        WriteChatf("MQ2FeedMe::AutoFeed (\ag%s\ax).",(FeedAt)?Buffer:"\aroff");
    } else if(GoodToFeed()) Consume(ITEMITEMTYPE_FOOD,Hunger);
}

void AutoDrinkCmd(PSPAWNINFO pCHAR, PCHAR zLine) {
    if(zLine[0]!=0) {
        DrnkAt=atoi(zLine); if(DrnkAt<0) DrnkAt=0; else if(DrnkAt>5000) DrnkAt=5000;
        sprintf(Buffer,"%d",DrnkAt);
        WritePrivateProfileString(GetCharInfo()->Name,"AutoDrink",Buffer,INIFileName);
        WriteChatf("MQ2FeedMe::AutoDrink (\ag%s\ax).",(DrnkAt)?Buffer:"\aroff");
    } else if(GoodToFeed()) Consume(ITEMITEMTYPE_WATER,Thirst);
}

PLUGIN_API void InitializePlugin(void) {
    DebugSpewAlways("Initializing MQ2FeedMe");
    AddCommand("/autofeed",AutoFeedCmd);
    AddCommand("/autodrink",AutoDrinkCmd);
}

PLUGIN_API void OnPulse(void) {
    if(Justate && ++jPulses >= 18)
    {
        jPulses = 0;
        Justate = false;
        SendModClick("InventoryWindow","InvSlot29","leftmouseup",1);
        if(GetCharInfo2()->Cursor) pInvSlotMgr->MoveItem(0x1E,FindSlot,1,1);
    }

    if(++Pulses<SKIP_PULSES) return; Pulses=0;
    if(!GoodToFeed())        return;
    if(DrnkAt && GetCharInfo2()->thirstlevel<DrnkAt) Consume(ITEMITEMTYPE_WATER,Thirst);
    if(FeedAt && GetCharInfo2()->hungerlevel<FeedAt) Consume(ITEMITEMTYPE_FOOD,Hunger);
}   

PLUGIN_API void SetGameState(DWORD GameState) {
    if(MQ2Globals::gGameState==GAMESTATE_INGAME)
        if(GetCharInfo2()) {
            DrnkAt=GetPrivateProfileInt(GetCharInfo()->Name,"AutoDrink",0,INIFileName);
            FeedAt=GetPrivateProfileInt(GetCharInfo()->Name,"AutoFeed" ,0,INIFileName);
            if(!Loaded) {
                ReadList(&Hunger,"FOOD");
                ReadList(&Thirst,"DRINK");
                Loaded=true;
            }
        }
}

PLUGIN_API void ShutdownPlugin(void) {
    DebugSpewAlways("Shutting down MQ2FeedMe");
    RemoveCommand("/autofeed");
    RemoveCommand("/autodrink");
}

htw
 

Attachments

  • MQ2FeedMe.dll
    168 KB · Views: 17
Last edited by a moderator:
dont think its autofeeding.

it works for sure when you force it with /autofeed or /autodrink but havent yet seen it autofeed. Will watch my food a bit closer to see if it does or not.
 
I have mine set to 4000, and it works (at least for using the foraged food listed in the .ini), and not using my stat food.

I'll try to move some crap around in inv, change out various stuff in bank/bags, etc. and try some different values for the limits, and see how it goes.

htw
 
im currently using 5000. Ill set it at 4k and see if it helps

I dont use the forage stuff. I make it eat halas pies and Kaladim constitutional's but that shouldnt mater. Should work as long as you can /autofeed and you get a message saying it tried to.
 
Thx for the info, it helps that I can use the same stuff you do, if I'm gonna help you track it down.

htw
 
That's a repost of my ghetto fix of someone else's ghetto fix on the MQ2 forums. It should work fine except for times when you're lagging very badly... in those cases it'll leave the bag on your cursor and you'll have to place it back into your inventory slot manually. I've been running it since I posted it a bit over a month ago and that's my experience anyways... haven't lost any stat food while running it. Really wasn't intended to be a permanent fix, just something to use until someone with more know-how gets around to fixing it.

Edit: Also, if you do happen to be playing with a lot of lag, you might try increasing the number 18 in the line below to something higher to see if it helps.

if(Justate && ++jPulses >= 18)
 
Nafets said:
That's a repost of my ghetto fix of someone else's ghetto fix on the MQ2 forums. It should work fine except for times when you're lagging very badly... in those cases it'll leave the bag on your cursor and you'll have to place it back into your inventory slot manually. I've been running it since I posted it a bit over a month ago and that's my experience anyways... haven't lost any stat food while running it. Really wasn't intended to be a permanent fix, just something to use until someone with more know-how gets around to fixing it.

Edit: Also, if you do happen to be playing with a lot of lag, you might try increasing the number 18 in the line below to something higher to see if it helps.

*nods*

Posted here, as it's sorc's plugin, and he's a dev here. It works decent (thx for the "ghetto fix", heh). I'm mostly done rewriting it, but also working on several other things at the same time, so will post it when completed. Already fixed the bag-lag issue, and rewrote the code to actually verify server ack of eating/drinking. Also trying to patch up a couple of other plugins, plus finish the loader auto-update code though, so don't hold your breath right away... I change which one I'm working on depending on how bored I get. :p Sorc might be working on it too (since it's his), but I know he has put a lot of time into mq2melee to this point, so he might not be working on feedme.

htw
 
Replacing the below chunk of code should "ghetto fix" the plugin again for today's compile.

Code:
void FindFood(DWORD fTYPE, list<string> fLIST, DWORD fSLOT, PCONTENTS fITEM) {
   if(fITEM) if(fITEM->Item->ItemType==fTYPE) {
      if(fITEM->Item) {
         list<string>::iterator pLIST;
         pLIST=(fITEM->StackCount<FindPile)?fLIST.begin():fLIST.end();
         while(pLIST!=fLIST.end()) if(!stricmp(fITEM->Item->Name,pLIST->c_str())) break; else pLIST++;
         if(pLIST==fLIST.end()) return;
      }
      strcpy(FindName,fITEM->Item->Name);
      FindSlot=fSLOT;
      FindPile=(fITEM->Item)?fITEM->StackCount:0;
   }
}
 
Could someone post a fixed compiled version when time allows? Thanks!
 
Looks like it was an offset problem in the MQ source causing this to break, the 12/07 source has it fixed, so you won't need to use this change I posted once you compile that.
 
OK, forgive the noob once again please.

I have the plugin mq2feedme active, i edited the ini file to have Misty Thicket Picnic as the number 1 item and it still eats my Bristlebane. Can someone give me a blow by blow on setting this? I am tired of buying food. Would really like to get the haloween stuff in number 1 position if i could do it without it getting eaten.
 
/autofeed 3500
/autodrink 3500

This in game will set the ini at what hunger or thirst level you will actually eat or drink.
 
Read it, makes no sense to me. Not sure what autofeed would be, since you automatically eat anyway. Not sure how that would aim feed at specific food lower in the bags.
 
Read it, makes no sense to me. Not sure what autofeed would be, since you automatically eat anyway. Not sure how that would aim feed at specific food lower in the bags.

There is a number that represents your hunger and thirst level, that plugin makes sure to keep your numerical representation of your hunger and thirst levels high enough that you won't eat from your stat food if you configure it correctly. Hence, it eats the food you specify when your hunger/thirst dips to a level specified.
 
That doesn't make sense to me. The game'll still eat from top food if hungry, if you force game to eat, it'll still suck from top food...
 
That doesn't make sense to me. The game'll still eat from top food if hungry, if you force game to eat, it'll still suck from top food...

the plugin detours that function and takes care of it accordingly. force food/drink only ever helped me max alchohol tolerance. but yes mq2feedme or whatever will do what your asking for.....stop fightin it n try it lol.
 
We have tried it. We couldn't get it to work.

Taken directly from the FAQ posted here.

MQ2FeedMe
- Will eat food and drink you specify in the ini
Commands:
/autofeed (will force manual feeding)
/autofeed 0 (will turn off autofeeding)
/autofeed 3500 (will set up autofeed point and turn on autofeeding.
/autodrink (will force manual drinking)
/autodrink 0 (will turn off autodrinking)
/autodrink 3500 (will set up autodrink point and turn on autodrinking.

I'll check this out tonight to be sure its not broken, but it has definitely worked for me in the past.
 
I see part of the problem. How would I specify foods in the ini ?