/* Miner Class Primary Miner hebavior module for EVEBot -- CyberTech */ objectdef obj_Miner { variable obj_Combat Combat variable string SVN_REVISION = "$Rev: 709 $" variable int Version variable time NextPulse variable int PulseIntervalInSeconds = 2 variable index:entity LockedTargets variable iterator Target variable int TotalTrips = 0 /* Total Times we've had to transfer to hanger */ variable time TripStartTime variable int PreviousTripSeconds = 0 variable int TotalTripSeconds = 0 variable int AverageTripSeconds = 0 variable string CurrentState variable bool CombatAbort = FALSE variable int SanityCheckCounter = 0 variable bool SanityCheckAbort = FALSE variable float64 LastUsedCargoCapacity = 0 ; Are we running out of asteroids to target? variable bool ConcentrateFire = FALSE method Initialize() { BotModules:Insert["Miner"] This.TripStartTime:Set[${Time.Timestamp}] Event[OnFrame]:AttachAtom[This:Pulse] UI:UpdateConsole["obj_Miner: Initialized", LOG_MINOR] /* Initialize combat */ This.Combat:Initialize /* Set it to defensive */ This.Combat.CurrentState:Set["IDLE"] This.Combat:SetMode["DEFENSIVE"] } method Shutdown() { Event[OnFrame]:DetachAtom[This:Pulse] } method Pulse() { if ${EVEBot.Paused} { return } if !${Config.Common.BotModeName.Equal[Miner]} { ; There's no reason at all for the miner to check state if it's not a miner return } if ${Time.Timestamp} >= ${This.NextPulse.Timestamp} { This:SetState[] SanityCheckCounter:Inc This.NextPulse:Set[${Time.Timestamp}] This.NextPulse.Second:Inc[${This.PulseIntervalInSeconds}] This.NextPulse:Update } } function ProcessState() { if !${Config.Common.BotModeName.Equal[Miner]} { ; There's no reason at all for the miner to check state if it's not a miner return } /* No reason to do our shit if we're not safe */ if !${Social.IsSafe} { UI:UpdateConsole["Miner: Social unsafe! Cleaning up and fleeing"] call This.Cleanup_Environment call Combat.Flee Combat.Override:Set[TRUE] return } switch ${This.CurrentState} { case IDLE break case ABORT Call Station.Dock Call This.Abort_Check break case BASE call Cargo.TransferOreToHangar ;call Station.CheckList SanityCheckCounter:Set[0] SanityCheckAbort:Set[FALSE] LastUsedCargoCapacity:Set[0] call Station.Undock break case MINE call This.Mine break case HAUL UI:UpdateConsole["Hauling"] call Hauler.Haul break case DROPOFF switch ${Config.Miner.DeliveryLocationTypeName} { case Station ; Gets info about the crystals currently loaded call Ship.SetActiveCrystals if ${EVE.Bookmark[${Config.Miner.DeliveryLocation}](exists)} { call Ship.WarpToBookMarkName "${Config.Miner.DeliveryLocation}" } else { call Station.Dock } break case Hangar Array call Ship.WarpToBookMarkName "${Config.Miner.DeliveryLocation}" call Cargo.TransferOreToCorpHangarArray break case Jetcan UI:UpdateConsole["Warning: Cargo filled during jetcan mining, delays may occur"] call Cargo.TransferOreToJetCan This:NotifyHaulers[] break Default UI:UpdateConsole["ERROR: Delivery Location Type ${Config.Miner.DeliveryLocationTypeName} unknown"] EVEBot.ReturnToStation:Set[TRUE] break } SanityCheckCounter:Set[0] SanityCheckAbort:Set[FALSE] LastUsedCargoCapacity:Set[0] break case RUNNING UI:UpdateConsole["Running Away"] call Station.Dock EVEBot.ReturnToStation:Set[TRUE] break } } method SetState() { if ${EVEBot.ReturnToStation} && ${_Me.InStation} == FALSE { This.CurrentState:Set["ABORT"] return } if ${EVEBot.ReturnToStation} { This.CurrentState:Set["IDLE"] return } if ${_Me.InStation} == TRUE { This.CurrentState:Set["BASE"] return } if ${_Me.Ship.UsedCargoCapacity} <= ${Config.Miner.CargoThreshold} && \ ${SanityCheckAbort} == FALSE { This.CurrentState:Set["MINE"] return } if ${_Me.Ship.UsedCargoCapacity} > ${Config.Miner.CargoThreshold} || \ ${EVEBot.ReturnToStation} || \ ${SanityCheckAbort} == TRUE { This.CurrentState:Set["DROPOFF"] return } This.CurrentState:Set["Unknown"] } function Abort_Check() { call Config.Common.IncAbortCount ; abort check, this will allow the bot to continue botting if it is a temp abort or something that can ; if there is no abort type it will pause the script like before and wait... if ${This.CombatAbort} { UI:UpdateConsole["Warning: Paused. Combat type abort."] if ((${_Me.Ship.ArmorPct} < ${Config.Combat.MinimumArmorPct}) && ${Ship.ArmorRepairUnits} == 0) { UI:UpdateConsole["Warning: Script paused due to Armor Precentage."] Script:Pause } ; To.Do NEED TO ADD CHECK FOR HULL REPAIRER in SHIP OBJECT. if ((${_Me.Ship.StructurePct} < 100)) { UI:UpdateConsole["Warning: Aborted. Script paused due to Structure Percentage."] Script:Pause } if ${_Me.Ship.ShieldPct} < 100 { UI:UpdateConsole["Warning: Waiting for Shields to Regen."] while ${_Me.Ship.ShieldPct} < 95 { wait 20 } } UI:UpdateConsole["Continuing"] EVEBot.ReturnToStation:Set[FALSE] This.CombatAbort:Set[FALSE] Return } UI:UpdateConsole["Warning: Aborted - Script Paused - Check Logs "] Script:Pause } ; Enable defenses, launch drones function Prepare_Environment() { call Ship.OpenCargo } function Cleanup_Environment() { call Ship.Drones.ReturnAllToDroneBay ;;;call Ship.CloseCargo } function Statslog() { variable string Hours = ${Math.Calc[(${Script.RunningTime}/1000/60/60)%60].Int.LeadingZeroes[2]} variable string Minutes = ${Math.Calc[(${Script.RunningTime}/1000/60)%60].Int.LeadingZeroes[2]} variable string Seconds = ${Math.Calc[(${Script.RunningTime}/1000)%60].Int.LeadingZeroes[2]} UI:UpdateStatStatus["Run ${This.TotalTrips} Done - Took ${ISXEVE.SecsToString[${This.PreviousTripSeconds}]}"] UI:UpdateStatStatus["Total Run Time: ${Hours}:${Minutes}:${Seconds} - Average Run Time: ${ISXEVE.SecsToString[${Math.Calc[${This.TotalTripSeconds}/${This.TotalTrips}]}]}"] } function Mine() { variable int TargetJammedCounter=0 variable int BuddyCounter variable string buddyTest variable bool buddyOnline if ${_Me.InStation} != FALSE { UI:UpdateConsole["DEBUG: obj_Miner.Mine called while zoning or while in station!"] return } This.TripStartTime:Set[${Time.Timestamp}] ; Find an asteroid field, or stay at current one if we're near one. call Asteroids.MoveToField FALSE call This.Prepare_Environment call Asteroids.UpdateList variable int DroneCargoMin = ${Math.Calc[(${Ship.CargoMinimumFreeSpace}*1.4)]} variable int Counter = 0 UI:UpdateConsole["Mining"] while (${Social.IsSafe} && !${EVEBot.ReturnToStation} && \ ${_Me.Ship.UsedCargoCapacity} <= ${Config.Miner.CargoThreshold} ) { if ${Ship.TotalMiningLasers} == 0 { UI:UpdateConsole["Warning: No mining lasers detected, docking"] EVEBot.ReturnToStation:Set[TRUE] return } if ${Config.Combat.LaunchCombatDrones} && \ ${Ship.Drones.CombatDroneShortage} { /* TODO - This should pick up drones from station instead of just docking */ UI:UpdateConsole["Warning: Drone shortage detected, docking"] EVEBot.ReturnToStation:Set[TRUE] return } if ${_Me.Ship.UsedCargoCapacity} != ${LastUsedCargoCapacity} { ;UI:UpdateConsole["DEBUG: ${_Me.Ship.UsedCargoCapacity} != ${LastUsedCargoCapacity}"] SanityCheckCounter:Set[0] LastUsedCargoCapacity:Set[${_Me.Ship.UsedCargoCapacity}] } if (!${Config.Miner.IceMining} && \ ${SanityCheckCounter} > MINER_SANITY_CHECK_INTERVAL) { UI:UpdateConsole["Warning: Cargo volume hasn't changed in a while, docking"] SanityCheckAbort:Set[TRUE] break } if ${Config.Combat.LaunchCombatDrones} && \ ${Ship.Drones.DronesInSpace} == 0 && \ !${Ship.InWarp} { Ship.Drones:LaunchAll[] } if ${_Me.Ship.MaxLockedTargets} == 0 && \ ${Ship.Drones.DronesInSpace} == 0 { TargetJammedCounter:Inc if ${TargetJammedCounter} > 200 { TargetJammedCounter:Set[0] UI:UpdateConsole["Warning: Ship target jammed, no drones available. Changing Belts"] call Asteroids.MoveToField TRUE } } else { TargetJammedCounter:Set[0] } if ${Social.PlayerInRange[${Config.Miner.AvoidPlayerRange}]} { UI:UpdateConsole["Avoiding player: Changing Belts"] call This.Cleanup_Environment call Asteroids.MoveToField TRUE call This.Prepare_Environment } /* TODO: CyberTech: Move this to the state machine, have it check for when the system is clear */ if ${Config.Miner.StandingDetection} && \ ${Social.StandingDetection[${Config.Miner.LowestStanding}]} { EVEBot.ReturnToStation:Set[TRUE] UI:UpdateConsole["Warning: Low Standing player in system, docking"] } if ${Config.Miner.DeliveryLocationTypeName.Equal[Jetcan]} && ${Ship.CargoHalfFull} { call Cargo.TransferOreToJetCan This:NotifyHaulers[] /* needed a wait here because it would try to move the same item more than once */ wait 20 } if (${_Me.Ship.ArmorPct} < ${Config.Combat.MinimumArmorPct} || \ ${_Me.Ship.ShieldPct} < ${Config.Combat.MinimumShieldPct}) { /* TODO - CyberTech: This should be checked in a defensive class that runs regardless of which bot module is active instead of being checked in each module */ UI:UpdateConsole["Armor is at ${_Me.Ship.ArmorPct}: ${Me.Ship.Armor}/${Me.Ship.MaxArmor}", LOG_CRITICAL] UI:UpdateConsole["Shield is at ${_Me.Ship.ShieldPct}: ${Me.Ship.Shield}/${Me.Ship.MaxShield}", LOG_CRITICAL] UI:UpdateConsole["Miner aborting due to defensive status", LOG_CRITICAL] EVEBot.ReturnToStation:Set[TRUE] This.CombatAbort:Set[TRUE] return } if ${Ship.InWarp} { wait 10 continue } if ${Ship.TotalActivatedMiningLasers} < ${Ship.TotalMiningLasers} { ; We've got idle lasers, and available targets. Do something with them. while ${_Me.GetTargeting} > 0 { wait 10 } Me:DoGetTargets[LockedTargets] LockedTargets:GetIterator[Target] if ${Target:First(exists)} do { if ${_Me.Ship.UsedCargoCapacity} > ${Config.Miner.CargoThreshold} { break } if ${Target.Value.CategoryID} != ${Asteroids.AsteroidCategoryID} { continue } variable int TargetID TargetID:Set[${Target.Value.ID}] /* TODO: CyberTech - this concentrates fire fine if there's only 1 target, but if there's multiple targets it still prefers to distribute. Ice mining shouldn't distribute */ if (${This.ConcentrateFire} || \ ${Config.Miner.IceMining} || \ !${Config.Miner.DistributeLasers} || \ !${Ship.IsMiningAsteroidID[${TargetID}]}) { Target.Value:MakeActiveTarget while ${Target.Value.ID} != ${Me.ActiveTarget.ID} { wait 5 } if ${_Me.Ship.UsedCargoCapacity} > ${Config.Miner.CargoThreshold} { break } call Ship.Approach ${TargetID} ${Ship.OptimalMiningRange} call Ship.ActivateFreeMiningLaser if (${Ship.Drones.DronesInSpace} > 0 && \ ${Config.Miner.UseMiningDrones}) { Ship.Drones:ActivateMiningDrones } } } while ${Target:Next(exists)} } if (!${Config.Miner.IceMining} || \ (${Ship.TotalActivatedMiningLasers} == 0)) { if ${Math.Calc[${_Me.GetTargets} + ${_Me.GetTargeting}]} < ${Ship.SafeMaxLockedTargets} { call Asteroids.TargetNext This.ConcentrateFire:Set[!${Return}] ;echo DEBUG: Target Locking: ${Math.Calc[${_Me.GetTargets} + ${_Me.GetTargeting}].Int} out of ${Ship.SafeMaxLockedTargets} (Limited Asteroids: ${This.ConcentrateFire}) } else { if ( ${_Me.GetTargets} >= ${Ship.SafeMaxLockedTargets} && \ ${Ship.TotalMiningLasers} > ${Ship.SafeMaxLockedTargets} ) { This.ConcentrateFire:Set[TRUE] } } } wait 10 } if ${Config.Miner.BookMarkLastPosition} { Bookmarks:StoreLocation } call This.Cleanup_Environment if ${Social.IsSafe} { This.TotalTrips:Inc This.PreviousTripSeconds:Set[${This.TripDuration}] This.TotalTripSeconds:Inc[${This.PreviousTripSeconds}] This.AverageTripSeconds:Set[${Math.Calc[${This.TotalTripSeconds}/${This.TotalTrips}]}] UI:UpdateConsole["Cargo Hold has reached threshold, returning"] call ChatIRC.Say "Cargo Hold has reached threshold" call This.Statslog } else { Combat.Override:Set[TRUE] call Combat.Flee } } member:int TripDuration() { return ${Math.Calc64[${Time.Timestamp} - ${This.TripStartTime.Timestamp}]} } member:float VolumePerCycle(string AsteroidType) { } method NotifyHaulers() { /* notify hauler there is ore in space */ variable string tempString tempString:Set["${_Me.CharID},${_Me.SolarSystemID},${Entity[GroupID, GROUP_ASTEROIDBELT].ID}"] relay all -event EVEBot_Miner_Full ${tempString} /* TO MANUALLY CALL A HAULER ENTER THIS IN THE CONSOLE * relay all -event EVEBot_Miner_Full "${Me.CharID},${Me.SolarSystemID},0" */ } }