{ ================================================================ Script name: neo's Inscription trainer Author: neo Version: 1.1 Client tested with: Stealth Interface 7.0.29.2 Stealth version tested with: 4.3.6 Shard: OSI Revision Date: March 26, 2013 Public Release: March 23, 2013 Purpose: Trains Inscription from 32.5 to GM Special thanks: Crome who has helped me A LOT, teaching me the ropes on Stealth and giving inumerous pointers. Cheers! :) ================================================================ Version 1.1 - Modified the setup part - Will put books inside secure when skillcap is reached - Removed the need for a full spellbook. Now you just need a book with recall and mark. - A few minor improvements ---------------------------------------------------------------- Version 1.0 - Public release ================================================================ Instructions: - Have 2 secures close to you: one with reagents, blank scrolls and ingots. The other is where your crafted scrolls and super slayer books will be stored (you can add more properties to check for. Check 'GoodPropertiesArray' and add more if needed. - Have a trash barrel nearby. You will need to trash crappy books. - Have at least 1 tinker tools inside your backpack before you start. - When you hit play, the script will ask you to open the containers one by one(material, books and trash) - You NEED A FULL SPELLBOOK in your bag for this!! ------------------------------------------------------------------------ 32.5 to 60.0 -> Crafts Recall scrolls 60 to 65 -> Crafts Mark scrolls 65+ -> Crafts Spellbook, keeps Super Slayers and trashes the rest ======================================================================== Only use this script if downloaded from the following places: http://www.scriptuo.com/index.php?topic=11033.0 http://stealth.od.ua/forum/viewtopic.php?f=15&t=2495 ======================================================================== } //===== Variables ===== Program Inscription; var LastUnload : Boolean; var LastCont : Cardinal; var GoodPropertiesArray : Array of String; var SelfID : Cardinal; var CurrentSkill : Double; var IsMeditating : Boolean; var Secure : Cardinal; var SafeContainer : Cardinal; var Trash : Cardinal; var gi : TGumpInfo; var StartTime : TDateTime; var StartingSkill : Double; var Status : String; var LoadLimit : Integer; var ScrollAmount : Integer; var ReagentAmount : Integer; //===== Constants ===== //----- Craft Buttons and Info ----- const CraftRecallButton = 32; const RecallArgs = '#1044412'; const RecallElemNum = 87; const cat2button = 9002; //third/fourth circle const CraftMarkButton = 45; const MarkArgs = '#1044425'; const MarkElemNum = 78; const CraftSpellBookButton = 202; const SpellBookArgs = '#1023834'; const SpellBookElemNum = 49; const cat6button = 9006; //Other - Spellbook const cat3button = 9003; //fifth/sixth circle - Tinker tools const PenButton = 30; const TinkerButton = 11; const TinkerArgs = '#1044164'; const TinkerElemNum = 58; //----- Item Types ----- const PenType = $0FBF; const BloodMoss = $0F7B; const BlackPearl = $0F7A; const MandrakeRoot = $0F86; const BlankScroll = $0EF3; const Ingots = $1BF2; const TinkerToolsType = $1EB9; const RecallScrollType = $1F4C; const MarkScrollType = $1F59; const SpellBookType = $0EFA; //----- Buff/Debuff Info ----- const ActiveMeditationID = 1013; //----- General Gump Info ----- const CraftingGumpID = $01CC; const InscriptionCliloc = 1044009; const TinkeringCliloc = 1044007; //----- other ----- const MinimumMana = 12; const MarkMana = 18; const ShortWait = 1; const MedWait = 10; const LongWait = 20; const WeightOffset = 5; const FullBook = '~1_NUMBERS_OF_SPELLS~ Spells'; //===== menu stuff ===== var Menu : TSTForm; var GeneralInfoBox : TSTGroupBox; var StatusBox : TSTGroupBox; var StartingSkillLabel : TSTLabel; var SkillGainsLabel : TSTLabel; var CurrentSkillLabel : TSTLabel; var TimeRunningLabel : TSTLabel; var StatusLabel : TSTLabel; var StartingSkillLbl : TSTLabel; var SkillGainsLbl : TSTLabel; var CurrentSkillLbl : TSTLabel; Procedure GUI_OnClose(Sender: TObject; var Action : TCloseAction); begin Menu.Free(); raiseException(erCustomError,'Menu was closed. Halting!'); Exit; end; Procedure MenuInit(); begin Menu := TSTForm.Create(); Menu.BorderStyle := bsSingle; Menu.Color := clBtnFace; Menu.Height := 151; Menu.Left := 0; Menu.Top := 0; Menu.Width := 319; Menu.Caption := 'neo''s Inscription Trainer' Menu.OnClose := @GUI_OnClose; GeneralInfoBox := TSTGroupBox.Create(Menu); GeneralInfoBox.Parent := Menu; GeneralInfoBox.Height := 65; GeneralInfoBox.Left := 8; GeneralInfoBox.Top := 8; GeneralInfoBox.Width := 297; GeneralInfoBox.Caption := 'General Info'; StatusBox := TSTGroupBox.Create(Menu); StatusBox.Parent := Menu; StatusBox.Height := 34; StatusBox.Left := 8; StatusBox.Top := 79; StatusBox.Width := 297; StatusBox.Caption := 'Status'; StartingSkillLabel := TSTLabel.Create(GeneralInfoBox); StartingSkillLabel.Parent := (GeneralInfoBox); StartingSkillLabel.Height := 13; StartingSkillLabel.Left := 11; StartingSkillLabel.Top := 16; StartingSkillLabel.Width := 62; StartingSkillLabel.Caption := 'Starting Skill:'; SkillGainsLabel := TSTLabel.Create(GeneralInfoBox); SkillGainsLabel.Parent := (GeneralInfoBox); SkillGainsLabel.Height := 13; SkillGainsLabel.Left := 11; SkillGainsLabel.Top := 35; SkillGainsLabel.Width := 50; SkillGainsLabel.Caption := 'Skill Gains:'; CurrentSkillLabel := TSTLabel.Create(GeneralInfoBox); CurrentSkillLabel.Parent := (GeneralInfoBox); CurrentSkillLabel.Height := 13; CurrentSkillLabel.Left := 152; CurrentSkillLabel.Top := 16; CurrentSkillLabel.Width := 61; CurrentSkillLabel.Caption := 'Current Skill:'; TimeRunningLabel := TSTLabel.Create(GeneralInfoBox); TimeRunningLabel.Parent := (GeneralInfoBox); TimeRunningLabel.Height := 13; TimeRunningLabel.Left := 152; TimeRunningLabel.Top := 35; TimeRunningLabel.Width := 115; TimeRunningLabel.Caption := 'Time Running: 00:00:00'; StatusLabel := TSTLabel.Create(StatusBox); StatusLabel.Parent := (StatusBox); StatusLabel.Height := 13; StatusLabel.Left := 11; StatusLabel.Top := 16; StatusLabel.Width := 100; StatusLabel.Caption := ''; StartingSkillLbl := TSTLabel.Create(GeneralInfoBox); StartingSkillLbl.Parent := (GeneralInfoBox); StartingSkillLbl.Height := 13; StartingSkillLbl.Left := 80; StartingSkillLbl.Top := 16; StartingSkillLbl.Width := 31; StartingSkillLbl.Caption := FloatToStrF(StartingSkill,ffFixed,12,1); SkillGainsLbl := TSTLabel.Create(GeneralInfoBox); SkillGainsLbl.Parent := (GeneralInfoBox); SkillGainsLbl.Height := 13; SkillGainsLbl.Left := 80; SkillGainsLbl.Top := 35; SkillGainsLbl.Width := 31; SkillGainsLbl.Caption := ''; CurrentSkillLbl := TSTLabel.Create(GeneralInfoBox); CurrentSkillLbl.Parent := (GeneralInfoBox); CurrentSkillLbl.Height := 13; CurrentSkillLbl.Left := 226; CurrentSkillLbl.Top := 16; CurrentSkillLbl.Width := 31; CurrentSkillLbl.Caption := ''; Menu.Show(); end; Procedure UpdateMenu; begin StatusLabel.Caption := Status; SkillGainsLbl.Caption := '+' + FloatToStrF((CurrentSkill - StartingSkill),ffFixed,12,1); CurrentSkillLbl.Caption := FloatToStrF (CurrentSkill,ffFixed,12,1); TimeRunningLabel.Caption := 'Time Running: ' + TimeToStr(Now - StartTime); end; //======================================= //===== WeightCheck ===== Procedure WeightCheck(ItemType:Cardinal); var b : Integer; var c : Integer; var IsGood : Boolean; var GoodTrigger : String; var BookRec : TClilocRec; var BookItemRec : TClilocItemRec; var MyBook : Boolean; var BackPackRec : TClilocRec; var BackPackItemRec : TClilocItemRec; var BackPackItems : Integer; begin Status := 'Checking weight and backpack load' UpdateMenu; BackPackRec := GetToolTipRec(BackPack); BackPackItemRec := BackPackRec.Items[2]; BackPackItems := StrToInt(BackPackItemRec.Params[0]); if ( Weight >= (MaxWeight - WeightOffset)) or ( BackPackItems >= 123 ) or ( LastUnload )then begin if LastUnload = False then Status := 'Unloading items'; if LastUnload = True then Status := 'Putting books away'; UpdateMenu; repeat MyBook := False; IsGood := False; FindType(ItemType,BackPack); if (FindCount > 0) then begin if ItemType = SpellBookType then begin BookRec := GetToolTipRec(FindItem); for b := 0 to (Length(BookRec.Items)-1) do begin BookItemRec := BookRec.Items[b]; for c := 0 to (Length(GoodPropertiesArray)-1) do begin if LowerCase(GoodPropertiesArray[c]) = LowerCase(GetClilocByID(BookItemRec.ClilocID)) then begin IsGood := True; GoodTrigger := GoodPropertiesArray[c]; end; if LowerCase(FullBook) = LowerCase(GetClilocByID(BookItemRec.ClilocID)) then begin if ( (StrToInt(BookItemRec.Params[0])) > 0 ) then begin MyBook := True; Ignore(FindItem); end; end; end; end; if (IsGood = True) AND ( MyBook = False ) then begin Status := GoodTrigger + ' found in property. Keeping book'; UpdateMenu; MoveItem(FindItem,1,SafeContainer,0,0,0); wait(1050); end; if ( IsGood = False ) AND ( MyBook <> True ) then begin Status := 'Trashing books'; UpdateMenu; MoveItem(FindItem,1,Trash,0,0,0); wait(1050); end; end else begin Status := 'Moving scrolls to secure container'; UpdateMenu; MoveItem(FindItem,Count(ItemType),SafeContainer,0,0,0); wait(1050); end; end; until FindCount = 0; end; end; //===== ButtonExistsNot (returns False if button exists in gump) ===== Function ButtonExistsNot(ButtonNumber:Integer;Arguments:String):Boolean; var TokLength : Integer; var i : Integer; begin Result := True; GetGumpInfo((GetGumpsCount-1),gi); TokLength := Length(gi.XmfHTMLTok); for i := 0 to (TokLength-1) do begin if (gi.XmfHTMLTok[i].ElemNum = ButtonNumber) AND (gi.XmfHTMLTok[i].Arguments = Arguments) then begin Result := False; end; end; end; //===== Init ===== Procedure Init; begin UseObject(BackPack); wait(2000); LastUnload := False; LoadLimit := (( MaxWeight - Weight ) - WeightOffset); ScrollAmount := Round( LoadLimit / 2 ); ReagentAmount := LoadLimit; DropDelay := 10; SelfID := Self; LastCont := LastContainer; ClientPrint('Open your resource container'); while LastCont = LastContainer do wait(1); Secure := LastContainer; LastCont := LastContainer; ClientPrint('Open your container to keep scrolls and super slayers'); While LastCont = LastContainer do wait(1); SafeContainer := LastContainer; LastCont := LastContainer; ClientPrint('Open your trash barrel'); while LastContainer = LastCont do wait(1); Trash := LastContainer; end; //===== GumpCheck (will return false if gump IS OPEN ===== Function GumpCheck(GumpID:Cardinal;GumpCliloc:Integer):Boolean; begin if ((GetGumpID(GetGumpsCount-1)) = GumpID) then begin GetGumpInfo((GetGumpsCount-1),gi); if (((gi.XmfHTMLGumpColor[0].Cliloc_id)) <> GumpCliloc) then begin CloseSimpleGump(GetGumpsCount-1); Result := True; end else begin Result := False; end; end else begin Result := True; end; end; //===== GumpWait ===== Function GumpWait(GumpID:Cardinal;GumpCliloc:Integer):Boolean; var Timeout : Cardinal; begin Timeout := Timer; While ((GetGumpID(GetGumpsCount-1)) <> GumpID) and (Timer < (Timeout + 3000)) do wait(1); if ( (GetGumpID(GetGumpsCount-1)) = GumpID) then begin If GumpCliloc <> 0 then begin GetGumpInfo((GetGumpsCount-1),gi); if (((gi.XmfHTMLGumpColor[0].Cliloc_id)) = GumpCliloc) then begin Result := True; end else begin Result := False; end; end else begin Result := True; end; end; wait(ShortWait); end; //===== Craft ===== Procedure Craft(Tool:Cardinal;Button,ButtonNum,CatButton:Integer;Args:String); begin if ( CurrentSkill <= 60.0 ) then Status := 'Crafting recall scrolls'; if ( CurrentSkill > 60.0 ) AND ( CurrentSkill < 65.0 ) then Status := 'Crafting mark scrolls'; if ( CurrentSkill >= 65.0 ) AND ( CurrentSkill < 100.0) then Status := 'Crafting spell books'; UpdateMenu; repeat if GumpCheck(CraftingGumpID,InscriptionCliloc) then begin FindType(PenType,BackPack); wait(ShortWait); UseObject(FindItem); GumpWait(CraftingGumpID,InscriptionCliloc); end; if ButtonExistsNot(ButtonNum,Args) then begin NumGumpButton((GetGumpsCount-1),CatButton); end; until GumpWait(CraftingGumpID,InscriptionCliloc); NumGumpButton((GetGumpsCount-1),Button); GumpWait(CraftingGumpID,InscriptionCliloc); end; //===== Check for tools ===== Procedure CheckTools; begin Status := 'Checking for tools'; UpdateMenu; FindType(PenType,BackPack); wait(ShortWait); if (FindCount = 0) then begin Status := 'No pens found. Crafting more' UpdateMenu; repeat FindType(Ingots,BackPack); wait(ShortWait); if ( FindCount = 0) OR (Count(Ingots)<10) then begin FindType(Ingots,Secure); if (FindCount>0) AND (CountEx(Ingots,$FFFF,Secure)>=100) then begin MoveItem(FindItem, 100, BackPack, 0, 0, 0); wait(1100); end; end; FindType(TinkerToolsType,BackPack); wait(ShortWait); if (FindCount = 0) then begin ShowMessage('You must have Tinker Tools inside your bag. Halting.'); exit; end; if (FindCount = 1) then begin Status := 'Found only 1 Tinker Tools in backpack. Crafting more'; UpdateMenu; repeat repeat if GumpCheck(CraftingGumpID,TinkeringCliloc) then begin FindType(TinkerToolsType,BackPack); wait(ShortWait); UseObject(FindItem); GumpWait(CraftingGumpID,TinkeringCliloc); end; if ButtonExistsNot(TinkerElemNum,TinkerArgs) then begin NumGumpButton((GetGumpsCount-1),cat3button); end; until GumpWait(CraftingGumpID,TinkeringCliloc); NumGumpButton((GetGumpsCount-1),TinkerButton); GumpWait(CraftingGumpID,TinkeringCliloc); FindType(TinkerToolsType,BackPack); wait(ShortWait); until (FindCount >= 2); end; Status := 'Crafting more scribe pens'; UpdateMenu; repeat if GumpCheck(CraftingGumpID,TinkeringCliloc) then begin FindType(TinkerToolsType,BackPack); wait(ShortWait); UseObject(FindItem); GumpWait(CraftingGumpID,TinkeringCliloc); end; if ButtonExistsNot(TinkerElemNum,TinkerArgs) then begin NumGumpButton((GetGumpsCount-1),cat3button); end; until GumpWait(CraftingGumpID,TinkeringCliloc); NumGumpButton((GetGumpsCount-1),PenButton); GumpWait(CraftingGumpID,TinkeringCliloc); FindType(PenType,BackPack); wait(ShortWait); until (FindCount >= 3); end; end; //===== Check for Items in backpack and restocks if necessary ===== Procedure CheckItems(CurrentItem:Cardinal;Amount:Integer); begin Status := 'Checking items'; UpdateMenu; FindType(CurrentItem,BackPack); wait(MedWait); if (FindCount = 0) OR (Count(CurrentItem)<10) then begin Status := 'Not enough items inside backpack. Restocking'; UpdateMenu; FindType(CurrentItem,Secure); wait(ShortWait); if (FindCount > 0) AND (CountEx(CurrentItem,$FFFF,Secure)>=Amount) then begin MoveItem(FindItem, Amount, BackPack, 0, 0, 0); wait(1000); end else begin ShowMessage('You are out of material. Halting.'); Exit; end; end; end; //===== GetSkillValue, takes human JoAT into account ===== Function CalculateSkill(SkillName:String):Double; var Skill : Double; begin Skill := GetSkillValue(SkillName); if ( Skill <= 20.0 ) and ( Race = 1 ) then Result := 20.0 else Result := Skill; end; //===== CheckMana ===== Procedure CheckMana(ReqMana:Integer); begin Status := 'Checking mana'; UpdateMenu; if ( Mana <= (ReqMana) ) then begin Status := 'Mana is low. Attempting to meditate'; UpdateMenu; SetEventProc(evBuff_DebuffSystem,'CheckActiveMeditation'); While ( Mana < MaxMana ) do begin if ( IsMeditating = False ) then begin UseSkill('Meditation'); wait(1000); if (IsMeditating = False) then wait(10000); end; if IsMeditating then begin Status := 'Meditating until mana is full'; UpdateMenu; end; end; end; end; //===== Check for Buffs/Debuffs ===== Procedure CheckActiveMeditation(ID,Attribute_ID : Cardinal; IsEnabled : Boolean); begin if ( ( ID = SelfID)) then begin IsMeditating := ((Attribute_ID = ActiveMeditationID) and (IsEnabled <> False) ) end; end; //===== begin ===== begin //===== Array of properties to check for in books, you can add your own if you'd like ===== GoodPropertiesArray:=['Repond Slayer','Demon Slayer','Undead Slayer','Arachnid Slayer','Elemental Slayer','Reptile Slayer']; //===== core below, don't modify :) ===== StartingSkill := CalculateSkill('Inscription'); Init; MenuInit(); UseObject(Secure); wait(1100); StartTime := now; while NOT dead do begin CurrentSkill := CalculateSkill('Inscription'); if ( CurrentSkill >= 32.5 ) then begin if ( CurrentSkill <= 60.0 ) then //use other scrolls instead? begin WeightCheck(RecallScrollType); CheckItems(Ingots,100); CheckItems(BloodMoss,ReagentAmount); CheckItems(BlackPearl,ReagentAmount); CheckItems(MandrakeRoot,ReagentAmount); CheckItems(BlankScroll,ScrollAmount); CheckMana(MinimumMana); CheckTools; Craft(PenType,CraftRecallButton,RecallElemNum,cat2button,RecallArgs); end; if ( CurrentSkill > 60.0 ) AND (CurrentSkill < 65.0) then begin WeightCheck(MarkScrollType); CheckItems(Ingots,100); CheckItems(BlankScroll,ReagentAmount); CheckItems(BloodMoss,ReagentAmount); CheckItems(BlackPearl,ReagentAmount); CheckItems(MandrakeRoot,ScrollAmount); CheckMana(MarkMana); CheckTools; Craft(PenType,CraftMarkButton,MarkElemNum,cat3button,MarkArgs); end; if ( CurrentSkill >= 65.0 ) AND (CurrentSkill < 100.0) then begin WeightCheck(SpellBookType); CheckItems(Ingots,100); CheckItems(BlankScroll,150); CheckTools; Craft(PenType,CraftSpellBookButton,SpellBookElemNum,cat6button,SpellBookArgs); end; if ( CurrentSkill = 100.0 ) then begin LastUnload := True; WeightCheck(SpellBookType); WeightCheck(MarkScrollType); WeightCheck(RecallScrollType); ShowMessage('You have reached the skill cap. Thank you for using this script.'); Exit; end; end else begin ShowMessage('You need at least 32.5 skill to use this script. Halting!'); Exit; end; end; end.