All pastes #978825 Raw Edit

Anonymous

public text v1 · immutable
·published 2008-04-09 21:01 UTC
rendered paste body
/*
	Miner Class
	
	Primary Miner hebavior module for EVEBot
	
	-- CyberTech

*/

objectdef obj_Miner
{
	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 bool SocialAbort = FALSE
	variable int SanityCheckCounter = 0
	variable bool SanityCheckAbort = FALSE
	variable float64 LastUsedCargoCapacity = 0

	/* Used by This.Defend */
	variable bool HaveResetTargets = FALSE
	variable index:entity TargetList
	variable iterator TargetIterator

	; Are we running out of asteroids to target?
	variable bool ConcentrateFire = FALSE
	variable bool StartedAttack = FALSE
	
	method Initialize()
	{
		This.TripStartTime:Set[${Time.Timestamp}]
		BotModules:Insert["Miner"]
		Event[OnFrame]:AttachAtom[This:Pulse]
		UI:UpdateConsole["obj_Miner: Initialized"]
	}
	
	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
		}

		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 DEFEND
				call This.Defend
				break
			case RECALL_DRONES
				call Ship.Drones.ReturnAllToDroneBay
				This.HaveResetTargets:Set[FALSE]
				This.StartAttack:Set[FALSE]
				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
		}	
	}

	member:bool RatsOnMe()
	{
		Me:DoGetTargetedBy[TargetList, CategoryID, 11]
		TargetList:GetIterator[TargetIterator]
		if (${TargetIterator:First(exists)})
		{
			return TRUE
		}
		return FALSE
	}

	function Defend()
	{
		/* First up, unlock all targets. */
		UI:UpdateConsole["Defend: MyTargets ${Me.GetTargets}, HaveReset ${This.HaveResetTargets}"]
		if (${Me.GetTargets} >= 0 && !${This.HaveResetTargets})
		{
			Me:DoGetTargets[LockedTargets]
			LockedTargets:GetIterator[Target]
			if (${Target:First(exists)})
			{
				do
				{
					Target.Value:UnlockTarget
					wait 2
				}
				while (${Target:Next(exists)})
			}
			UI:UpdateConsole["Defend: HaveResetTargets = TRUE"]
			This.HaveResetTargets:Set[TRUE]
			return
		}
		elseif (${This.HaveResetTargets} && ${This.StartedAttack})
		{
			if (${TargetIterator.Value.StructurePct} > 0)
			{
				Ship.Drones:SendDrones
				wait 5
				return
			}
			else
			{
				This.StartedAttack:Set[FALSE]
				return
			}
		}

		UI:UpdateConsole["${Ship.Drones.DronesInSpace} DIS"]
		/* Send out our drones! */
		if (${Ship.Drones.DronesInSpace} == 0)
		{
			Ship.Drones:LaunchAll[]
			wait 5
			return
		}

		/* If all targets are cleared, re-lock on rats */
		Me:DoGetTargetedBy[TargetList, CategoryID, 11]
		TargetList:GetIterator[TargetIterator]
		/* Target something to send our drones after */
		if ${TargetIterator:First(exists)} && !${This.StartedAttack}
		{
			UI:UpdateConsole["Locking a target"]
			TargetIterator.Value:LockTarget
			while (${Me.GetTargeting} > 0)
			{
				wait 20
			}
			/* Send the drones in for some fun */
			Ship.Drones:SendDrones
			This.StartedAttack:Set[TRUE]
		}
		elseif !${TargetIterator:First(exists)}
		{
			/* If there are no targets, all the rats are done... clean up */
			call Ship.Drones.ReturnAllToDroneBay
		}
	}
	
	method SetState()
	{
		/* Run if we have to, which is our highest priority */
		if ((${EVEBot.ReturnToStation} || !${Social.IsSafe}) && ${Me.InStation} == FALSE)
		{
			if (!${Social.IsSafe})
			{
				This.SocialAbort:Set[TRUE]
			}
			This.CurrentState:Set["ABORT"] 
			return
		}
	
		if ${EVEBot.ReturnToStation}
		{
			This.CurrentState:Set["IDLE"]
			return
		}
		
		if ${Me.InStation} == TRUE
		{
	  		This.CurrentState:Set["BASE"]
	  		return
		}

		if (${Config.Combat.LaunchCombatDrones} && ${Me.Ship.ShieldPct} < 100)
		{
			if (${This.RatsOnMe})
			{
				This.CurrentState:Set["DEFEND"]
				return
			}
		}

		if (${Ship.Drones.DronesInSpace} > 0 && !${This.RatsOnMe})
		{
			This.CurrentState:Set["RECALL_DRONES"]
			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
			}
			
		if (${This.SocialAbort})
		{
			UI:UpdateConsole["Social: Paused: Social unsafe detection, staying docked until it's safe"]
			while (!${Social.IsSafe})
			{
				UI:UpdateConsole["Social: Paused: Still waiting..."]
				wait 100
			}
		}

		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 ( !${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 ${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.PlayerDetection}
			{
				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		
			}
			
			/* TODO - CyberTech: clean up this code when ArmorPct/ShieldPct wierdness is gone */
			if ( !${Me.Ship.ArmorPct(exists)} || !${Me.Ship.ShieldPct(exists)} )
			{
				do
				{
					UI:UpdateConsole["Me.Ship.ArmorPct OR Me.Ship.ShieldPct was NULL.  Waiting 2 seconds and checking again..."]
					wait 20
					Counter:Inc[20]
					if ${Counter} > 600
					{
						UI:UpdateConsole["Me.Ship.ArmorPct OR Me.Ship.ShieldPct returned NULL for longer than a minute, aborting..."]
						EVEBot.ReturnToStation:Set[TRUE]
						return
					}
				}
				while (!${Me.Ship.ArmorPct(exists)} || !${Me.Ship.ShieldPct(exists)})
				
				Counter:Set[0]
				if ( ${Me.Ship.ArmorPct} < 0 || ${Me.Ship.ShieldPct} < 0 )
				{
					do
					{
						UI:UpdateConsole["Me.Ship.ArmorPct OR Me.Ship.ShieldPct was less than zero.  Waiting 2 seconds and checking again..."]
						wait 20
						Counter:Inc[20]
						if ${Counter} > 600
						{
							UI:UpdateConsole["Me.Ship.ArmorPct OR Me.Ship.ShieldPct returned a value less than zero for longer than a minute, aborting..."]
							EVEBot.ReturnToStation:Set[TRUE]
							return
						}					
					}
					while (${Me.Ship.ArmorPct} < 0 || ${Me.Ship.ShieldPct} < 0)
				}
			}
			
			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}"]
				UI:UpdateConsole["Shield is at ${Me.Ship.ShieldPct}: ${Me.Ship.Shield}/${Me.Ship.MaxShield}"]
				UI:UpdateConsole["Aborting due to defensive status"]
				
				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
		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

	}

	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"
		 */
	}
	
}