/*
Acidently deleted the old one and its back up, this one I pulled from an old file and made all the changes
I think I made before, may have some bugs still in it that I had to correct before.
Hess
#ifndef __OBJ_COMBAT__
#define __OBJ_COMBAT__
/*
The combat object
The obj_Combat object is a bot-support module designed to be used
with EVEBOT. It provides a common framework for combat decissions
that the various bot modules can call.
USAGE EXAMPLES
--------------
objectdef obj_Miner
{
variable string SVN_REVISION = "$Rev$"
variable int Version
variable obj_Combat Combat
method Initialize()
{
;; bot module initialization
;; ...
;; ...
;; call the combat object's init routine
This.Combat:Initialize
;; set the combat "mode"
This.Combat:SetMode["DEFENSIVE"]
}
method Pulse()
{
if ${EVEBot.Paused}
return
if !${Config.Common.BotModeName.Equal[Miner]}
return
;; bot module frame action code
;; ...
;; ...
;; call the combat frame action code
This.Combat:Pulse
}
function ProcessState()
{
if !${Config.Common.BotModeName.Equal[Miner]}
return
; call the combat object state processing
call This.Combat.ProcessState
; see if combat object wants to
; override bot module state.
if ${This.Combat.Override}
return
; process bot module "states"
switch ${This.CurrentState}
{
;; ...
;; ...
}
}
}
COMBAT OBJECT "MODES"
---------------------
* DEFENSIVE -- If under attack (by NPCs) AND damage taken exceeds threshold, fight back
* AGGRESSIVE -- If hostile NPC is targeted, destroy it
* TANK -- Maintain defenses but attack nothing
NOTE: The combat object will activate and maintain your "tank" in all modes.
It will also manage any enabled "flee" state.
-- GliderPro
*/
objectdef obj_Combat
{
variable bool InCombat = FALSE
variable bool Running = FALSE
variable bool CombatPause = FALSE
variable index:entity TargetList
variable iterator NextTargetIterator
variable string SVN_REVISION = "$Rev$"
variable int Version
variable time NextPulse
variable int PulseIntervalInSeconds = 1
variable bool Override
variable string CombatMode
variable string CurrentState
variable bool Fled
variable bool wait_timex
method Initialize()
{
call UpdateHudStatus "obj_Combat: Initialized"
{
This.CurrentState:Set["IDLE"]
This.Fled:Set[FALSE]
UI:UpdateConsole["obj_Combat: Initialized", LOG_MINOR]
}
method Shutdown()
{
/* Nothing to shutdown */
}
method InCombatState()
method Pulse()
{
Call UpdateHudStatus "Now In Combat"
Call This.Fight
InCombat:Set[TRUE]
if ${EVEBot.Paused}
{
return
}
if ${Time.Timestamp} >= ${This.NextPulse.Timestamp}
{
This:SetState
This.NextPulse:Set[${Time.Timestamp}]
This.NextPulse.Second:Inc[${This.PulseIntervalInSeconds}]
This.NextPulse:Update
}
}
method ExitCombatState()
method SetState()
{
Call UpdateHudStatus "Debug: ExitCombatState"
InCombat:Set[FALSE]
if ${_Me.InStation} == TRUE
{
This.CurrentState:Set["INSTATION"]
return
}
if ${EVEBot.ReturnToStation}
{
This.CurrentState:Set["FLEE"]
return
}
if ${_Me.GetTargets} > 0
{
This.CurrentState:Set["FIGHT"]
}
else
{
This.CurrentState:Set["IDLE"]
}
}
method Pause()
method SetMode(string newMode)
{
Call UpdateHudStatus "Pausing Bot to Deal with Combat"
CombatPause:Set[TRUE]
This.CombatMode:Set[${newMode}]
}
method UnPause()
member:string Mode()
{
call UpdateHudStatus "Bot Resumed"
CombatPause:Set[FALSE]
return ${This.CombatMode}
}
function UpdateList()
{
This.TargetList:Clear
Me:DoGetTargetedBy[This.TargetList]
if ${This.TargetList.Used}
{
echo "DEBUG: obj_Combat:UpdateList - Found ${This.TargetList.Used}"
}
}
method NextTarget()
member:bool Override()
{
return ${This.Override}
}
function ProcessState()
{
This.Override:Set[FALSE]
if ${This.CurrentState.NotEqual["INSTATION"]}
{
if ${_Me.ToEntity.IsWarpScrambled}
{
; TODO - we need to quit if a red warps in while we're scrambled -- cybertech
UI:UpdateConsole["Warp Scrambled: Ignoring System Status"]
}
elseif !${Social.IsSafe}
{
This.CurrentState:Set["FLEE"]
call This.Flee
This.Override:Set[TRUE]
This.wait_timex:Set[TRUE]
return
}
elseif ${wait_timex} == TRUE
{
This.wait_timex:Set[FALSE]
variable int Countx=0
while ${Countx:Inc}<=988
{
UI:UpdateConsole["WARTEZEIT AKTIVIERT"]
wait 10
if !${Social.IsSafe}
break
}
}
elseif (!${Ship.IsAmmoAvailable} && ${Config.Combat.RunOnLowAmmo})
{
; TODO - what to do about being warp scrambled in this case?
This.CurrentState:Set["FLEE"]
call This.Flee
This.Override:Set[TRUE]
return
}
call This.ManageTank
}
switch ${This.CurrentState}
{
case INSTATION
if ${Social.IsSafe}
{
call Station.Undock
}
break
case IDLE
break
case FLEE
call This.Flee
This.Override:Set[TRUE]
break
case FIGHT
call This.Fight
break
}
}
function Fight()
{
TargetList:GetSettingIterator
Ship:Deactivate_Cloak
while ${Ship.IsCloaked}
{
waitframe
}
;Ship:Offline_Cloak
;Ship:Online_Salvager
; Reload the weapons -if- ammo is below 30% and they arent firing
Ship:Reload_Weapons[FALSE]
; Activate the weapons, the modules class checks if there's a target (no it doesn't - ct)
Ship:Activate_StasisWebs
Ship:Activate_Weapons
Ship.Drones:SendDrones
}
function:bool TargetNext()
function Flee()
{
variable iterator TargetIterator
if ${This.TargetList.Used} == 0
This.Fled:Set[TRUE]
if ${Config.Combat.RunToStation}
{
call This.FleeToStation
}
else
{
call This.FleeToSafespot
}
}
function FleeToStation()
{
if !${Station.Docked}
{
call Station.Dock
}
}
function FleeToSafespot()
{
if ${Safespots.IsAtSafespot}
{
if !${Ship.IsCloaked}
{
call This.UpdateList
Ship:Activate_Cloak[]
}
This.TargetList:GetIterator[TargetIterator]
if ${TargetIterator:First(exists)}
{
do
}
else
{
; Are we at the safespot and not warping?
if ${_Me.ToEntity.Mode} != 3
{
if ${Entity[${TargetIterator.Value}](exists)} && \
!${TargetIterator.Value.IsLockedTarget} && \
!${TargetIterator.Value.BeingTargeted}
{
break
}
call Safespots.WarpTo
wait 30
}
while ${TargetIterator:Next(exists)}
if ${Entity[${TargetIterator.Value}](exists)}
}
}
method CheckTank()
{
if ${This.Fled}
{
/* don't leave the "fled" state until we regen */
if (${_Me.Ship.ArmorPct} < 50 || \
(${_Me.Ship.ShieldPct} < 80 && ${Config.Combat.MinimumShieldPct} > 0) || \
${_Me.Ship.CapacitorPct} < 80 )
{
if ${TargetIterator.Value.IsLockedTarget} || \
${TargetIterator.Value.BeingTargeted}
{
return TRUE
}
call UpdateHudStatus "Locking Target ${TargetIterator.Value.Name}: ${Misc.MetersToKM_Str[${TargetIterator.Value.Distance}]}"
wait 20
TargetIterator.Value:LockTarget
echo "DEBUG: Locking Target"
do
{
wait 30
}
while !${TargetIterator.Value.IsLockedTarget}
call This.UpdateList
return TRUE
}
return FALSE
This.CurrentState:Set[""]
}
else
{
This.Fled:Set[FALSE]
This.CurrentState:Set["IDLE"]
}
}
elseif (${_Me.Ship.ArmorPct} < ${Config.Combat.MinimumArmorPct} || \
${_Me.Ship.ShieldPct} < ${Config.Combat.MinimumShieldPct} || \
${_Me.Ship.CapacitorPct} < ${Config.Combat.MinimumCapPct})
{
UI:UpdateConsole["Armor is at ${_Me.Ship.ArmorPct.Int}%: ${Me.Ship.Armor.Int}/${Me.Ship.MaxArmor.Int}", LOG_CRITICAL]
UI:UpdateConsole["Shield is at ${_Me.Ship.ShieldPct.Int}%: ${Me.Ship.Shield.Int}/${Me.Ship.MaxShield.Int}", LOG_CRITICAL]
UI:UpdateConsole["Cap is at ${_Me.Ship.CapacitorPct.Int}%: ${Me.Ship.Capacitor.Int}/${Me.Ship.MaxCapacitor.Int}", LOG_CRITICAL]
if !${Config.Combat.RunOnLowTank}
{
UI:UpdateConsole["Run On Low Tank Disabled: Fighting", LOG_CRITICAL]
}
elseif ${_Me.ToEntity.IsWarpScrambled}
{
UI:UpdateConsole["Warp Scrambled: Fighting", LOG_CRITICAL]
}
else
{
UI:UpdateConsole["Fleeing due to defensive status", LOG_CRITICAL]
This.CurrentState:Set["FLEE"]
}
}
}
function Fight()
function ManageTank()
{
This:Pause
call This.TargetNext
while ${Me.GetTargetedBy} > 0
{
Me:DoGetTargets[LockedTargets]
LockedTargets:GetIterator[Target]
if ${Target:First(exists)}
do
{
if ${Target.Value.CategoryID} == ${Asteroids.AsteroidCategoryID}
{
continue
}
variable int TargetID
TargetID:Set[${Target.Value.ID}]
Target.Value:MakeActiveTarget
wait 20
call Ship.Drones.SendDrones
;To do
;call Ship.CombatLasers
}
while ${Target:Next(exists)}
if ${Math.Calc[${Me.GetTargets} + ${Me.GetTargeting}]} < ${Ship.MaxLockedTargets}
if ${_Me.Ship.ArmorPct} < 100
{
/* Turn on armor reps, if you have them
Armor reps do not rep right away -- they rep at the END of the cycle.
To counter this we start the rep as soon as any damage occurs.
*/
Ship:Activate_Armor_Reps[]
}
elseif ${_Me.Ship.ArmorPct} > 98
{
Ship:Deactivate_Armor_Reps[]
}
if ${_Me.Ship.ShieldPct} < 85 || ${Config.Combat.AlwaysShieldBoost}
{ /* Turn on the shield booster, if present */
Ship:Activate_Shield_Booster[]
}
elseif ${_Me.Ship.ShieldPct} > 95 && !${Config.Combat.AlwaysShieldBoost}
{
Ship:Deactivate_Shield_Booster[]
}
if ${_Me.Ship.CapacitorPct} < 20
{ /* Turn on the cap booster, if present */
Ship:Activate_Cap_Booster[]
}
elseif ${_Me.Ship.CapacitorPct} > 80
{
Ship:Deactivate_Cap_Booster[]
}
; Active shield (or armor) hardeners
; If you don't have hardeners this code does nothing.
if ${_Me.GetTargetedBy} > 0
{
Ship:Activate_Hardeners[]
/* We have aggro now, yay! Let's launch some drones */
if !${This.Fled} && ${Config.Combat.LaunchCombatDrones} && \
${Ship.Drones.DronesInSpace} == 0 && \
!${Ship.InWarp}
{
call This.TargetNext
}
}
This:UnPause
while ${Me.GetTargetedBy} == 0 && \
${Me.Ship.ShieldPct} < 100
Ship.Drones:LaunchAll[]
}
}
else
{
wait 10
Ship:Deactivate_Hardeners[]
}
This:ExitCombatState
}
}
This:CheckTank
}
}
#endif /* __OBJ_COMBAT__ */