1. Ищет еду в бекпаке (~60 разных типов)
2. Ест до тех пор пока не получит "you can't eat any more"
3. Если еда в рюкзаке кончилась, покупает у вендора и снова ест
4. Если не наелся см. пункт 3 пока у вендора не кончится еда.
(ЗЫ мне пришлось вставить переносы строк в FoodTypes чтобы пост отображался корректно)
Code: Select all
// Buy_and_Eat_v0_1 by sith_apprentice
// move your char close to the vendor and call
// Buy_And_Eat(VendorName:string);
// VendorName is the vendor's name __followed by a space__
// VendorName can be an empty string, then the shar just says "buy"
// the function knows ~60 different types of food
// the char will look for food in the backpack and if he is still able to
// eat after consuming it all will shop for more and eat whatever he bought
const
FoodBuyAtATime = 3; // buy 3 pieces of food of each type
FoodPrice = 3; // maximum food price you are willing to pay
StopEatingAtString = 'any more'; // if this text appears in the journal we are done eating
NotEdibleString = 'think of'; // if this text appears in the journal the object is not edible. Fix the FoodTypes arrays.
DelayEating = 4000; // 4 seconds between eating pieces of food
DelayShopping = 3000;
function Buy_And_Eat(VendorName:string):boolean;
var // buys food at 3 gp and eats it
ctime :TDateTime;
FoodTypes :array of word; // store all the known food types here
FoodTypesText :array of string; // same but store them as strings for shoplist parsing functions
i,k :integer;
FoodID :cardinal;
ShopList: TStringList;
SearchSubStr :string;
BuyString:string;
// SilentModeSave :boolean;
begin
AddToSystemJournal('Looking for some food...');
Result := false;
// set edible food types here
FoodTypes := [$976,$977,$978,$979,$97B,$97C,$97D,$97E,$98E,$993,$994,$9B7,$9B8,$9BB,$9BC,$9C0,
$9C1,$9C9,$9D0,$9D1,$9D2,$9D3,$9E9,$9EA,$9EB,$9EC,$9F2,$9FA,$103B,$103C,$1040,$1041,
$15F9,$15FA,$15FB,$15FC,$15FE,$15FF,$1600,$1601,$1602,$1604,$1606,$1608,$160A,$160B,
$160C,$171D,$171E,$171F,$1720,$1721,$1722,$1723,$1724,$1725,$1726,$1727,$1728,$1729,
$172A,$172B,$172C,$172D]; // add more food types here.
FoodTypesText := ['$976','$977','$978','$979','$97B','$97C','$97D','$97E','$98E','$993','$994','$9B7','$9B8','$9BB','$9BC',
'$9C0','$9C1','$9C9','$9D0','$9D1','$9D2','$9D3','$9E9','$9EA','$9EB','$9EC','$9F2','$9FA','$103B',
'$103C','$1040','$1041','$15F9','$15FA','$15FB','$15FC','$15FE','$15FF','$1600','$1601','$1602',
'$1604','$1606','$1608','$160A','$160B','$160C','$171D','$171E','$171F','$1720','$1721','$1722',
'$1723','$1724','$1725','$1726','$1727','$1728','$1729','$172A','$172B','$172C','$172D'];
// a nice example of ->(_!_)-> programming, especially when there is no sprintf;
if (High(FoodTypes) <> High(FoodTypesText)) then begin
// basic sanity check -- the lists should have the same length
AddToSystemJournal('FoodTypes and FoodTypesText lists have different number of elements. Food shopping is not working.');
Exit;
end;
// let's see if we already have food in our backpack:
for i:=Low(FoodTypes) to High(FoodTypes) do
begin
FoodID := FindTypeEx(FoodTypes[i],$0000,Backpack,true);
while (FoodID > 0) do
begin
ctime := Now;
AddToSystemJournal('Eating food, ID='+IntToStr(FoodID));
UseObject(FoodID);
Wait(DelayEating);
if (InJournalBetweenTimes(StopEatingAtString,ctime,Now)>=0) then Exit; // we are stuffed, no more food needed
if (InJournalBetweenTimes(NotEdibleString,ctime,Now)>=0) then
begin
AddToSystemJournal('FIXME: Type '+FoodTypesText[i]+' is not edible!');
break; // server does not believe it is edible
end;
FoodID := FindTypeEx(FoodTypes[i],$0000,Backpack,true); // search for a next piece of food
end;
end;
// well it seems we are going to have to buy the food
// moveOpenDoor := true; // come to the guy who sells food
// NewMoveXY(FoodX,FoodY,True,1,True);
//SilentModeSave := GetSilentMode(); //does not work
SetSilentMode(false);
BuyString := VendorName+'buy';
UOSay(BuyString); // talk to the guy selling the food
Wait(DelayShopping);
// see what the NPC is selling:
ShopList:= TStringList.Create; // save the previous silent mode status
GetShopList(ShopList);
//ShopList.AddStrings(GetShopList()); //does not work
//AddToSystemJournal('Shop list length: '+IntToStr(ShopList.Count));
for i:= 0 to ShopList.Count-1 do
begin
for k:=Low(FoodTypesText) to High(FoodTypesText) do
begin
SearchSubStr := '|type|'+FoodTypesText[k]+'|';
//AddToSystemJournal('Substring is '+SearchSubStr+', k='+IntToStr(k)+' i='+IntToStr(i));
if (BMSearch(1,ShopList.Strings[i],SearchSubStr) > 0) then
begin
// found some known food for sale
AddToSystemJournal('Food found in store, type is '+FoodTypesText[k]+', buying...');
AutoBuyEx(FoodTypes[k],$0000,FoodBuyAtATime,FoodPrice,'');
// buy the picked food:
UOSay(BuyString);
Wait(2*DelayShopping);
//eat whatever we just bought
FoodID := FindTypeEx(FoodTypes[k],$0000,Backpack,true);
//AddToSystemJournal('Food ID is '+IntToStr(FoodID));
while (FoodID > 0) do
begin
ctime := Now;
AddToSystemJournal('Eating food, ID='+IntToStr(FoodID));
UseObject(FoodID);
Wait(DelayEating);
if (InJournalBetweenTimes(StopEatingAtString,ctime,Now)>=0) then Exit; // we are stuffed, no more food needed
if (InJournalBetweenTimes(NotEdibleString,ctime,Now)>=0) then
begin
AddToSystemJournal('FIXME: Type '+FoodTypesText[k]+' is not edible!');
break; // server does not believe it is edible
end;
FoodID := FindTypeEx(FoodTypes[k],$0000,Backpack,true); // search for a next piece of food
//AddToSystemJournal('Food ID is '+IntToStr(FoodID));
end;
end;
end;
end;
ShopList.free;
ClearShopList(); // I really don't know what it does but I want to call it anyway
//SetSilentMode(SilentModeSave); // does not work // return the silent mode to whatever it was
SetSilentMode(true);
end;