// PB_STATES.JS // // // Author: Maud-Dib // Version: 2.03 // // Modification History // // Who Date Version Description // // MD 06/23/02 1.01 Initial version // // // Description: // // This module processes all the states for the Finite State Machine (FSM). See AAA_README.TXT and // CHANGE.TXT files for more details //
// After log on, this state is executed once function DoState_Init() { if (debug||debugInit) Log.OutD("DoState_Init: Begin");
// Update time toon was logged on and login count Toon[AccCurChar].LastLogin = new Date(); Toon[AccCurChar].LoginCnt++;
// If we have previsouly logged on (which means we potentially cast buffs), then fix up the // item buff expirations. We need to do this since our buffs expirations are absolute times, // but the server uses relative times (ie when your toon is logged out buffs don't rundown). if (Toon[AccCurChar].LoginCnt > 1) { // if toon previously logged on... var AddTime = Toon[AccCurChar].LastLogin - Toon[AccCurChar].LastLogoff; if (debug3) { Log.OutD("DoState_Init: Toon previously logged on" ); Log.OutD("DoState_Init: LastLogoff [" + Toon[AccCurChar].LastLogoff + "]" ); Log.OutD("DoState_Init: LastLogin [" + Toon[AccCurChar].LastLogin + "]" ); Log.OutD("DoState_Init: add_time [" + AddTime + "]" ); } // endif Buff[AccCurChar].Extend(AddTime); // Extend expirations for item buffs } else { if (debug3) Log.OutD("DoState_Init: First time toon logged on" ); } // endif
Log.OutD("DoState_Init: Character name [" + skapi.szName + "] World [" + skapi.szWorld + "]"); Log.OutD("DoState_Init: Char lvl [" + skapi.lvl + "] CHOP [" + Util.Hex(skapi.chop) + "]"); skItem = skapi.SkinfoFromSkid(skidItemEnchantment); skLife = skapi.SkinfoFromSkid(skidLifeMagic); skCre = skapi.SkinfoFromSkid(skidCreatureEnchantment); Log.OutD("DoState_Init: Base magic skills, Item [" + skItem.lvlUnbuffed + "] Life [" + skLife.lvlUnbuffed + "] Cre [" + skCre.lvlUnbuffed + "]");
// Initialize spell casting context Log.OutDM("Main", "Initing spell casting context..."); if (debugCast) Cast.SetDebug(true); CastInit();
// See what equipment we are wearing. Log.OutDM("Main", "Checking equipment..."); // Buff[AccCurChar].SetDebug(true); // for testing Buff[AccCurChar].CheckEquip();
// Now warn the user if stealth mode or peacemode set if (!SummonMode) Chat.Screen("WARNING!!! SummonMode disabled, no portals will be summoned!", cmcYellow);
// Record location LastRecordedLoc = 0; // Used to determine when our location changes enough to record it HomeLoc = skapi.maplocCur; Log.OutD("DoState_Init: Start coords: [" + Util.FormatCoords(HomeLoc,2) + "]");
// Make sure known all buffs Buff[AccCurChar].Verify();
// Make sure we know all the spells needed for proper macro operation. First build // the spellbook for the current character Cast.BuildSpellBook(); SpellCheck(true);
// If reduce burden flag set then see if strength spell active if (flagReduceBurden) { if (debugInit) Log.OutD("DoState_Init: Checking for active strength spell..."); for (var z=0; z < skapi.cospell.Count; z++) { if (skapi.cospell(z).spellid == SpellObj_Strength.spellid) { if (debugInit||logBurden) Log.OutD("DoState_Init: Strength active, resetting expiration time..."); var Remain = skapi.cospell(z).csecRemain var CurTime = new Date(); StrengthExp = CurTime.getTime() + (Remain*1000); if (debugInit) Log.OutD("DoState_Init: New expiration time: " + new Date(StrengthExp)); break; } // endif } // end for if (debugInit && (z==skapi.cospell.Count)) Log.OutD("DoState_Init: Strength spell not active."); } // endif // If user specified a inactivity timeout, then set it. Used to prevent macro from logging off // due to inactivity, but this should not be necessary since the macro presses the S key every // 10 minutes. if (inactTimer > 0) skapi.SetIdleTime(inactTimer);
// Make sure we are in peace mode if (debugInit) Log.OutD("DoState_Init: Ensuring Peace Mode..."); Player.EnsureCombatMode(false);
// If fellowship creation desired at macro start, set flag to do it in a few seconds. // For efficiency we want to summon the portal first if (creFellow) { var CurTime = new Date(); CreFellowTime = CurTime.getTime() + fellowInt; } // endif
// Set flag to initialize decal panels next IdleInit state. InitPanels = true;
Log.OutDM("DoState_Init", "Startup sequence done, macro active!", ToChat);
if (Restricted) { // Change state to IdleInit if (debug||debugInit) Log.OutD("DoState_Init: End, setting state to IdleInit"); StateChange(stateIdleInit,NoCheck); } else { // Change state to SummonInit if (debug||debugInit) Log.OutD("DoState_Init: End, setting state to SummonInit"); StateChange(stateSummonInit,NoCheck); } // endif } // end function
function DoState_IdleInit() { if (debug||debugIdle) Log.OutD("DoState_IdleInit: Start");
// Make sure we have latest event info skapi.WaitEvent(10);
// Press a key every once in a while so we don't log out from inactivity if ((new Date()-LastKeyPress) > keyPressInt) { skapi.Keys(cmidWave, kmoDown); skapi.Sleep(250); skapi.Keys(cmidWave, kmoUp); LastKeyPress = new Date(); } //endif
// Make sure we are in peace mode Player.EnsureCombatMode(false);
if (InitPanels) { InitPanels = false;
// Disable messages generated from OnControlEvent. Needed because when we set a choice box a event // is generated. No event is generated when a text or checkbox is modified. var saveVerbose = flagVerbose; flagVerbose = false;
// Define command interface Log.OutDM("DoState_Init", "Displaying decal interface...", ToChat); DisplayInterface();
var PeaSplitFound = Comp[AccCurChar].VerifyTool(false); if (flagSplitPeas && !PeaSplitFound) { flagSplitPeas = false; skapi.SetControlProperty(szPanelConfig, "chkSplitPeas", "checked", false); if (!Comp[AccCurChar].SplitWarn) { Comp[AccCurChar].SplitWarn = true; Log.OutDM("DoState_Init","Pea split option enabled but no splitting tool found, option disabled.", ToChat); } // endif } // endif
// Restore verbose flag setting if the original setting was true if (saveVerbose) { flagVerbose = true; skapi.SetControlProperty(szPanelConfig, "chkVerbose", "checked", flagVerbose); } // endif } // endif
if (SwitchChar >= 0) { // Someone requested us to switch to another character AccNewChar = SwitchChar; SwitchChar = -1; StateChange(stateReset); return; } // endif
// If we don't know one or more spells necessary for macro operation, then the Restricted flag is set. // Only manual decal panel functions can be done when in this mode, so just return for now if (Restricted) return;
// If Advertise flag is set and portal summoning is enabled then output advertisement spam if time if (flagAdvertise && SummonMode) { if ((new Date() - BroadLastAdver) > broadIntAdver) { BroadLastAdver = new Date(); Chat.Local(broadAdverMsg); } // endif } // endif if (flagLogStats) { if ((new Date() - StatLastDump) > statDumpInt) { BuildPortalStats(true); StatLog.WriteLineD(" "); for (x=0; x<StatList.length; x++) StatLog.WriteLineD(StatList[x]); StatLastDump = new Date(); } // endif } // endif
// If flag set to try to reduce burden then see if we are overburdened and // there is no active strength spell on us if (flagReduceBurden) { if (debugIdle) Log.OutD("DoState_IdleInit: Seeing if time to cast strength self spell..."); // If strength spell expired then if ((new Date() - StrengthExp) > 0) { if (debugIdle) Log.OutD("DoState_IdleInit: Strength spell expired, seeing if we are overburdened..."); // See if we are overburdened. Get our current strength and 100% burden units var skStrength = skapi.SkinfoFromAttr(attrStrength); var CharCurStrength = skStrength.lvlCur; var Burden100 = CharCurStrength * 150;
// Now see if we are overburdened var OverBurden = skapi.burdenCur - Burden100; if (OverBurden > 0) { // We are overburdened, log event and cast strength self spell if (debugIdle||logBurden) Log.OutD("DoState_IdleInit: Overburdened by [" + OverBurden + "] units, 100Burden [" + Burden100 + "] casting strength spell..."); Cast.Cast(SpellObj_Strength);
// If spell cast successful, update expiration date if (CastCode == castCodeSuccess) { var CurTime = new Date(); StrengthExp = CurTime.getTime() + (SpellObj_Strength.csecDuration*1000); if (debugIdle||logBurden) Log.OutD("DoState_IdleInit: Strength cast successful, exp [" + new Date(StrengthExp) + "]"); } else { if (debugIdle||logBurden) Log.OutD("DoState_IdleInit: Strength spell cast failed. " + SpellFailText()); } // endif } else { if (debugIdle) Log.OutD("DoState_IdleInit: We are not overburdened."); } // endif } // endif } // endif
if ((CreFellowTime > 0) && (new Date() > CreFellowTime)) { CreFellowTime = 0; // var cofellow = skapi.cofellow; // if (cofellow.Count > 0) { // Log.OutDM("DoState_IdleInit", "Fellow already exists, not created", ToChat); // } else { // Log.OutDM("DoState_IdleInit", "Creating Fellow...", ToChat); // Player.CreateFellow(fellowName); // } // endif // Sometimes doesn't detect fellowship status correctly so for now just // blindly try to create a fellow Log.OutDM("DoState_IdleInit", "Creating Fellow...", ToChat); Player.CreateFellow(fellowName); } // endif
// Set flag that to indicate buff check has not been completed yet BuffCheckDone = false; if (debugIdle) Log.OutD("DoState_IdleInit: Changing state to IDLE..."); StateChange(stateIdle); if (debug||debugIdle) Log.OutD("DoState_IdleInit: End"); } // end function
function DoState_Idle() { if (debug||debugIdle) Log.OutD("DoState_Idle: Begin, BuffCheckDone [" + BuffCheckDone + "]");
// If creature close to us, then cancel Idle state and hide from danger if option enabled if (Danger) { if (debug||debugIdle) Log.OutD("DoState_IdleInit: Danger detected, hiding..."); StateChange(stateHide); return; } // endif
// If pointer is busy, then wait a few seconds to see if pointer becomes // nonbusy. If it doesn't clear up, then hit the escape key a couple times // in case we are 'stuck' doing an action. if (skapi.fPointerBusy) PossiblyResetToon();
// If we are checking spell component levels... if (flagCompCheck) { if (debugIdle) Log.OutD("DoState_Idle: Comp checking enable, seeing it time to check..."); if ((new Date() - CompLastCheck) > compInterval) { if (debugIdle) Log.OutD("DoState_Idle: Checking comps..."); var AllOk = Comp[AccCurChar].CheckAmounts(); if (AllOk) { CompLastCheck = new Date(); // If macro previously suspended because of low comps, then resume macro since comps are ok now. if (CompSusp) { Log.OutDM("DoState_Idle", "Comps ok now, resuming summoning...", ToChat); CompSusp = false; // If SummonMode was disabled, then turn it back on if (SuspSummonMode) { SummonMode = true; skapi.SetControlProperty(szPanelControl, "btnSummonMode", "Text", "Disable Summoning"); } // endif } //endif } else { // Some comp is not at desired level, go check each one CompStartCheck = new Date(); // Time component check started CompIndex = 0; // Index # of first comp we will be checking AlarmSounded = false; StateChange(stateCheckComps); return; } // endif } else { if (debugIdle) Log.OutD("DoState_Idle: Not time to check comps."); } // endif } // endif
// If buffs are enabled and haven't been checked yet, then go check buffs. BuffCheckCnt is set to 0 in // the IdleInit state and incremented everytime the buff routine finishes successfully. if (BuffMode && !BuffCheckDone) { if (skapi.manaCur<threshBuffMana) { if (debugIdle||debugBuffs) Log.OutD("DoState_Idle: Mana too low to buff."); BuffCheckDone = true; } else { // Mana high enough, so cast one buff. If no buffs needed then Buff[AccCurChar].Cast method returns // false and buffing will be marked as completed for this idle pass if (debugBuffs) Log.OutD("DoState_Idle: Casting up to 1 buff..."); Buff[AccCurChar].UpdateExpire(); // Update expiration times of creature and life buffs from active spell list var BuffCast = Buff[AccCurChar].Cast(logBuffs) if (BuffCast) { if (debugIdle||debugBuffs) Log.OutD("DoState_Idle: Buff cast attempted, continuing with FSM."); return; } else { // No buffs were cast, we are all done with buffs this IDLE pass if (debugIdle||debugBuffs) Log.OutD("DoState_Idle: No buffs to cast."); BuffCheckDone = true; } // endif } // end if } // endif // Check for requests, set state to SummonInit if so if (PortalReq) { if (debug) Log.OutD ("DoState_Idle: End, Portal request. Switching state to SummonInit"); StateChange(stateSummonInit); return; } // endif // If we make it here then go back to the IdleInit state // since no portal summon requests have been received. StateChange(stateIdleInit);
if (debug||debugIdle) Log.OutD("DoState_Idle: End"); } // end func
function DoState_SummonInit() { if (debug||debugSummon) Log.OutD("DoState_SummonInit: Begin");
if (debug) Log.OutD ( "DoState_SummonInit: Begin"); // Determine portal to summon. Go through all Toons to find oldest portal request. var OldTime = new Date(); // Time of oldest portal NextChar = -1; NextPortal = -1; NextGem = -1; for (var x=0; x<skapi.cchar; x++) { for (var y=0; y<2; y++) { if (Toon[x].plist[y].Enabled && Toon[x].plist[y].RqPending) { if (debug) Log.OutD ( "DoState_SummonInit: Portal Req, Toon [" + x + "] Portal [" + y + "]" ); if (Toon[x].plist[y].RqTime <= OldTime) { NextChar = x; NextPortal = y; OldTime = Toon[x].plist[y].RqTime; } // endif } // endif } // end for } // end for
// Now check gem list to see if older request exists for (var x=0; x<GemCount; x++) { if ((GemList[x].RqPending) && (GemList[x].RqTime < OldTime)) { // If older gem request found then set flags NextGem = x; OldTime = GemList[x].RqTime; } // endif } // end for
// If we can't find any more portals than reset PortalReq flag and abort if ((NextChar == -1) && (NextGem == -1)) { if (debug) Log.OutD ( "DoState_SummonInit: No more portals to summon or gems to use."); PortalReq = false; StateChange(stateIdleInit); return; } else { if (debug) { Log.OutD ( "DoState_SummonInit: NextChar [ " + NextChar + "]" ); Log.OutD ( "DoState_SummonInit: NextPortal [ " + NextPortal + "]" ); Log.OutD ( "DoState_SummonInit: NextGem [ " + NextGem + "]" ); } // endif } // endif // If portal gem is oldest request, then pop the requested gem, else we have a portal to summon StateChange(stateSummon); if (NextGem >= 0) { // Use gem SubState = stateSummonGem; } else { // If portal tied on different character, then need to switch characters. Upon login the // idle state will detect the portal request, redo the above code, and we will get pass this spot // since the new char will be able to summon the portal. if (NextChar != AccCurChar) { if (debug) Log.OutD ( "DoState_SummonInit: NextChar != CurChar, switching..." ); Chat.Local("Portal you requested controlled by another character. Be back shortly..."); AccNewChar = NextChar; ,,m if (debug||debugIdle) Log.OutD("DoState_SummonInit: End, portal on another char, relogging..."); return; } // endif // Portal to summon is on this char. if (debug) Log.OutD ( "DoState_SummonInit: Portal requested on this char" ); StateChange(stateSummon); SubState = stateSummonPortal; CastFailures = 0; // Initialize count of failures this summon attempt } // endif // If enabled, turn a little to the left so portals will not overlap. if (flagAutoRotate) { skapi.Keys(cmidTurnLeft, kmoDown); skapi.Sleep(autoRotateTime); skapi.Keys(cmidTurnLeft, kmoUp); } // endif if (debug||debugIdle) Log.OutD("DoState_SummonInit: End"); } // end func
function DoState_Summon() { if (debug||debugSummon) Log.OutD("DoState_Summon: Begin, Processing SubState [" + SubState + "]"); if (SubState == stateSummonPortal) { if (debug) Log.OutD("DoState_Summon: Calling Summon_Portal..."); // Summon primary or secondary portal based on value of NextPortal. 0=primary, 1=secondary if (NextPortal == 0) { Cast.Cast(skapi.SpellInfoFromSpellid(summonPrimary[Toon[AccCurChar].plist[0].SummonLvl])); } else { Cast.Cast(skapi.SpellInfoFromSpellid(summonSecondary[Toon[AccCurChar].plist[1].SummonLvl])); } // endif if (CastCode == castCodeSuccess) { if (debug) Log.OutD ("DoState_Summon: Portal summoned successfully"); Toon[AccCurChar].plist[NextPortal].SumLast = new Date(); Toon[AccCurChar].plist[NextPortal].SumCnt++; // Build message to broadcast via local chat var Msg = "Portal to " + Toon[NextChar].plist[NextPortal].Keyword; if (Toon[NextChar].plist[NextPortal].Dest != null) Msg += " " + Toon[NextChar].plist[NextPortal].Dest; Msg += " open!"; if (flagOpenMsg) Msg = Msg + " " + broadOpenMsg; Chat.Local(Msg); Toon[NextChar].plist[NextPortal].RqPending = false; SubState = stateSummonDone; } else { if (debug) Log.OutD ("DoState_Summon: Failed to summon, CastFail [" + CastFail + "]" ); CastFailures++; if (CastFailures>3) { Log.OutD("DoState_Summon: Failed to summon portal 3 times, CastCode [" + CastCode + "]"); Chat.Local("I failed to summon the portal. I give up" ); Toon[NextChar].plist[NextPortal].RqPending = false; SubState = stateSummonDone; } // endif } // endif } // endif
if (SubState == stateSummonGem) { // Use a portal gem GemAco = skapi.AcoFindInInv(GemList[NextGem].Name + portalGemPost); if ((GemAco == undefined) || (GemAco == null)) { Chat.Local("Failed to use portal gem, can't locate gem in inventory"); Log.OutD("DoState_Summon: Failed to use portal gem, can't locate gem in inventory"); } // endif GemAco.Use(); var Msg = "Portal to " + GemList[NextGem].Name + " open!"; if (flagOpenMsg) Msg = Msg + " " + broadOpenMsg; Chat.Local(Msg); GemList[NextGem].RqPending = false; SubState = stateSummonDone; } // endif
if (SubState == stateSummonDone) { // All done, cleanup if (debug) Log.OutD("DoState_Summon: Cleaning up"); // Set state to SummonInit so that we avoid the Idle processing if multiple // portal request in queue. StateChange(stateSummonInit); } // end if // If we reach here than summon attempt failed. Let FSM execute and retry cast if (debug||debugIdle) Log.OutD("DoState_Summon: End [" + State + "]"); } // end func
function DoState_Reset(WaitInt) { Log.OutD("DoState_Reset: Begin, WaitInt [" + WaitInt + "]"); // If wait interval between logoff and logon is not specified, then use default if ((WaitInt == undefined) || (WaitInt==0)) WaitInt = accLogonWait; // Due to Windows-98/ME limitations, move the cursor to the spot on the screen // where we need to doubleclick to log back in BEFORE we log off. Mouse movement // commands don't work at login screen for Winblows-98/Me // Compute x and y screen coords of slots name var xOffset = 130; var yOffset = 140; yOffset += ( AccNewChar * 17 ); // Move mouse to coordinates of players name on logon screen. We do this here in an effort // to get this macro to work under windows-98. Skunkwork mouse positioning commands don't // seem to work at login screen, so we position the mouse pointer before we log if (debug) Log.OutD("DoState_Reset: Moving mouse to coords (" + xOffset + "," + yOffset + ")"); skapi.MouseMove(xOffset, yOffset);
for (index=0; index<playerLogoutAttempts; index++) { Log.OutD ("DoState_Reset: Attempt [" + index + "] Logging character..." ); var status = Player.LogOff(); if (status) { Log.OutD("DoState_Rest: Toon successfully logged out"); Toon[AccCurChar].LastLogoff = new Date(); break; // exit for loop } else { Log.OutD("DoState_Reset: Error logging out Toon. Attempt [" + index + "]"); } // endif } // endfor if (!status) { // We failed to logout, so end macro Log.OutD("DoState_Reset: Failed to logout player, aborting macro..."); State = stateLog; // Make sure we are logged off and macro stops return; } // endif Log.OutD ("DoState_Reset: Logoff complete."); // Now wait a few seconds to make sure login screen ready to accept mouse movements if (debug) Log.OutD ("DoState_Rest: Waiting [" + WaitInt + "] ms to login..." ); skapi.Sleep(WaitInt);
// Now try up to playerLoginAttempts tries to log back on for (index=0; index<playerLoginAttempts; index++) { // Log back on Log.OutD("DoState_Reset: Attempt [" + index + "] Logging back on..."); var status = Player.LogOn(AccNewChar); if (status) { // Character successfuly logged on Log.OutD("DoState_Reset: End, Toon successfully Logged on"); AccCurChar = AccNewChar; Toon[AccCurChar].LastLogin = new Date(); StateChange(stateInit, NoCheck); return; } else { Log.OutD("DoState_Reset: Error logging on toon, state [" + skapi.plig + "]"); } // endif } // endfor
// If we make it here than we couldn't log in char, so abort macro Log.OutD("DoState_Reset: End, Error logging on toon, state [" + skapi.plig + "]"); StateChange(stateLog, NoCheck); // Logoff and stop macro } // end func
function DoState_CheckComps() { if (debug||debugComps) Log.OutD("DoState_CheckComps: Begin");
// If creature close to us, then cancel comp checking and deal with the danger if (Danger) { if (debug||debugComps) Log.OutD("DoState_CheckComps: Danger detected, aborting check..."); StateChange(stateSelect); return; } // endif
// If we have reached the maximum amount of time permitted in this routine, then exit if ((new Date()-CompStartCheck) > compCheckMax) { if (debugComps) Log.OutD("DoState_CheckComps: Timeout, aborting CheckComps..."); CompLastCheck = new Date(); if (debug||debugComps) Log.OutD("DoState_CheckComps: Changing state to IDLE..."); StateChange(stateIdle); return; } // endif
// Find the next comp that is low if (debugComps) Log.OutD("DoState_CheckComps: CompIndex [" + CompIndex + "]"); while ((CompIndex < Comp[AccCurChar].Count) && ((!Comp[AccCurChar].Info[CompIndex].Enabled) || ((Comp[AccCurChar].Info[CompIndex].Stock >= Comp[AccCurChar].Info[CompIndex].SplitLvl) && (Comp[AccCurChar].Info[CompIndex].Stock >= Comp[AccCurChar].Info[CompIndex].CritLvl) && (Comp[AccCurChar].Info[CompIndex].Stock >= Comp[AccCurChar].Info[CompIndex].WarnLvl)))) CompIndex++;
if (debugComps) Log.OutD("DoState_CheckComps: CompIndex [" + CompIndex + "] End [" + Comp[AccCurChar].Count + "]");
// If we have reached the end of the list then exit if (CompIndex == Comp[AccCurChar].Count) { if (debugComps) Log.OutD("DoState_CheckComps: Done checking, changing state to IDLE..."); CompLastCheck = new Date(); StateChange(stateIdle); return; } // endif
with (Comp[AccCurChar].Info[CompIndex]) { if (flagSplitPeas && (Stock < SplitLvl)) { // We found a component below the required level and pea splitting has been enabled so // try to split peas. if (debugComps) Log.OutD("DoState_CheckComps: Comp [" + Name + "/" + CompIndex + "] below split lvl [" + SplitLvl+ "]");
// Now try to split a pea var Status = Comp[AccCurChar].Split(Name); if (Status == compSuccess) { // Split was successful, now see if we need more of this comp skapi.WaitEvent(200, wemFullTimeout); // Make sure inventory information updated var NewAmount = skapi.CitemOfKindInInv(Name); if (Stock == NewAmount) { // Component level didn't change even though status code indicated success. // Let program continue to next section for error processing if (debugComps) Log.OutD("DoState_CheckComps: Error, status success but comp lvl didnt change"); } else { // If we still don't have enough comps, then don't increment CompIndex which we do by // returning from this function now. This will cause the same component to be checked // again Comp[AccCurChar].Info[CompIndex].Stock = NewAmount; if (NewAmount >= Comp[AccCurChar].Info[CompIndex].SplitLvl) { if (debugComps) Log.OutD("DoState_CheckComps: Comp level above min, checking critical and warning levels"); } else { if (debugComps) Log.OutD("DoState_CheckComps: Comp still low, rechecking"); return; } // endif } // endif } // endif } // endif
// Now see if the critical level for the comp has been reached. If we are equal or below the // critical limit then either logout our toon or go into defense mode depending on the setting // of the variable 'flagCompLogOff' if (Stock < CritLvl) { if (flagCompLogOff) { Log.OutDM("DoState_CheckComps", "Comp " + Name + " is below critical level, logging...", ToChat); NotifySupport(Util.FormatTime() + " Comp " + Name + " is below critical threshold, logging..."); StateChange(stateLog,NoCheck); return; } // endif if (!CompSusp) { CompSusp = true; Log.OutDM("DoState_CheckComps", "One or more comps below critical level, macro suspended.", ToChat); NotifySupport(Util.FormatTime() + " One or more comps below critical level, macro suspended");
// Save current SummonMode SuspSummonMode = SummonMode;
// Disable summoning if currently enabled if (SummonMode) { SummonMode = false; skapi.SetControlProperty(szPanelControl, "btnSummonMode", "Text", "Enable Summoning"); } // endif // Play audible alert if enabled if (alertComps && !AlarmSounded) { alertCompsWav.Play(); AlarmSounded = true; // Only play alarm once per comp check run } // endif
// If an alarm hasn't been spammed recently for this comp, then alarm it if (new Date()-LastAlarm > compSpamInt) { LastAlarm = new Date(); var Msg = Util.FormatCoords(skapi.maplocCur,2) + " Comp " + Name + " below critical level. Remaining: " + Stock + " Resume level: " + Math.max(SplitLvl,WarnLvl);
// Spam comp low condition Log.OutDM("DoState_CheckComps", Msg, ToChat); NotifySupport(Util.FormatTime() + " " + Msg); } // endif
// Check next comp CompIndex++; } // endif return; } // endif
// If variable 'flagCompAssist' is true, then see if component level is below // its warning level. If it is, then broadcast our shortage to the fellow. // Hopefully some helpful fellow member will resupply us.
// If component below warning level, then spam message to fellowship and/or play audible alert if (Stock < WarnLvl) { if (debugComps) Log.OutD("DoState_CheckComps: Comp [" + Name + "/" + CompIndex + "] below warnlvl [" + WarnLvl + "] Critical Thresh [" + CritLvl + "]");
if (flagCompAssist) { if (logComp) Log.OutD("DoState_CheckComps: Comp [" + Name + "/" + CompIndex + "] Amount [" + Stock + "] is below warnlvl [" + WarnLvl + "] Log Thresh [" + CritLvl + "] spamming fellow..."); var OurLoc = skapi.maplocCur; NotifySupport(Util_FormatTime() + " Comp request at location " + Util.FormatCoords(OurLoc,2) + ". Low on " + Name + ", Amount Left: " + Stock + " Critical Thresh: " + CritLvl); } // endif
if (alertComps) alertCompsWav.Play(); Chat.Screen("Low on " + Name + ", Amount Left: " + Stock + " Critical Thresh: " + CritLvl); } // endif } // end with
// Check next comp CompIndex++;
if (debug||debugComps) Log.OutD("DoState_CheckComps: End"); return true; } // end function
// Creature detected in vicinity, log for a while function DoState_Hide() { Log.OutD("DoState_Hide: Begin"); // Don't use MD_PLAYEROBJ logoff function since we may need to integrate sound alert with logout action
Log.OutDM("DoState_Hide", "Nearby creature detected. Hiding for [" + Util.Round(hideInt/(1000*60),0) + "] minutes.", ToChat ); HideTime = hideInt; PB_PlayerLogOff(true); // Log out toon. Play sound if enabled
// Record logout time HideStart = new Date();
// Just process events until hide time expires while ((new Date() - HideStart) < HideTime) skapi.WaitEvent(250);
Log.OutD("State_Hide: Evasion Period Expired. Logging back on and setting state to INIT..."); StateChange(stateInit,NoCheck);
Player.LogOn(AccCurChar); // Log back on
// Update expiration times for buffs since they are absolute times but game uses relative times (ie // spells don't expire when character is logged) var ActualHideTime = new Date() - HideStart; Buff[AccCurChar].Extend(ActualHideTime); return; } // end function DoState_Hide
function DoState_PortalStormed() { Log.OutD("DoState_PortalStormed: Begin"); // For now just log off. Eventually might try to get bot back to starting point by navigation or recall spells. Player.LogOff(); RunFlag = false; // Stop macro Log.OutD("DoState_PortalStormed: End"); } // end func
// Log off AC and stop macro function DoState_Log() { Log.OutD("State_Log: Logging character..." ); Player.LogOff(); RunFlag = false; // Stop macro } // end func
// We died, exit macro if desired, otherwise rebuff and wait for macroer to move us back to kill loc. Optional // timer can be set for autologging. function DoState_Died() { Log.OutDM("State_Died", "We just died.", ToChat);
// Sound audible alarm and spam death to support channel if enabled if (alertDeath) alertDeathWav.Play(); NotifySupport("I just died.");
// If flag set to log on death then do it if (flagDeathLog) { Log.OutDM("State_Died", "We died, logging...", ToChat); Player.LogOff(); RunFlag = false; return; } // endif
// If we make it here, then player doesn't want to log off immediately after death. Wait a little // bit so that we exit portal space. Eventually we will check PLIG to see when we materialize in world skapi.WaitEvent(deathWait, wemFullTimeout);
// Reset cast cast count to 0 on all creature and life spells so randomize feature spreads out spells Buff[AccCurChar].ResetCreLife(); StrengthExp = 0; // Expire strength self spell
StateChange(stateIdleInit,NoCheck); return; } // end func DoState_Died
|