MQ2Feedme.cpp
htw
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
Last edited by a moderator: