Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- Heimskr - Customized AI Code
- This is a old version, its being redone and cleaned up. AI is a test module to implement into a Morag Tong mod
- ScriptName PDC1FollowerAliasAICombatScript Extends ReferenceAlias
- ;=================================================================================
- ;PROXiCide aka Taewon
- ;Steam: http://steamcommunity.com/id/PROXiCiDE
- ;Nexus: http://skyrim.nexusmods.com/users/3018315
- ;Bethesda: http://forums.bethsoft.com/user/425376-taewon/
- ;=================================================================================
- ;Code Needs Cleaned up Baddly
- ;Documented as well
- ;=================================================================================
- ; Properties
- ;=================================================================================
- Keyword Property PDC1MagicBuffTalosBlessing Auto
- Keyword Property PDC1MagicBuffGroupShield Auto
- Keyword Property PDC1MagicBuffGroupResist Auto
- Keyword Property PDC1MagicPriestDamage Auto
- GlobalVariable Property PDC1HealCombatActiveHealthPercent Auto
- GlobalVariable Property PDC1HealHandsCombatActiveHealthPercent Auto
- GlobalVariable Property PDC1HealCombatNotActiveHealthPercent Auto
- FormList Property PDC1PlayerFollowerExcludeResetSpells Auto
- FormList Property PDC1PlayerFollowerSpellDamageKeywords Auto
- FormList Property PDC1PlayerFollowerSpellResistKeywords Auto
- FormList Property PDC1PlayerFollowerSpellHealing Auto
- FormList Property PDC1PlayerFollowerSpellBuffs Auto
- Quest Property PDC1AssaultDetection Auto
- PDC1HeimskrShellScript Property pShellScript Auto
- GlobalVariable Property PDC1PlayerFollowerCount Auto
- Faction Property PDC1WaitFollowerFaction Auto
- GlobalVariable Property PlayerFollowerCount Auto
- GlobalVariable Property PDC1PlayerFollowerCastBuffType Auto
- GlobalVariable Property PDC1PlayerFollowerCastHealType Auto
- GlobalVariable Property PDC1PlayerFollowerCastDaulCast Auto
- GlobalVariable Property PDC1PlayerFollowerCastingSpell Auto
- GlobalVariable Property PDC1PlayerFollowerDaulCastChange Auto
- FormList Property PDC1PlayerFollowerPackageBuff Auto
- FormList Property PDC1PlayerFollowerPackageHeal Auto
- ;=================================================================================
- ; Globals
- ;=================================================================================
- Actor pCurrentFollower = None
- Actor pCastingTarget = None
- ;=================================================================================
- ; AI Data
- ;=================================================================================
- Event OnUpdate()
- Actor pSelf = GetActorRef()
- If pShellScript.IsFollowerPreachSceneRunning()
- Return
- EndIf
- ; Debug.Trace("PDC1 - OnUpdate - AI Combat Alias")
- If pSelf.GetPlayerControls() || pSelf.IsDead() || pSelf.IsDisabled() || pSelf.GetCombatTarget() == Game.GetPlayer() ||\
- !pShellScript.IsFollower(Self.GetRef()) || pShellScript.IsFollowerDismissed()
- Return
- EndIf
- If pShellScript.IsFollowerWaiting()
- If (Game.GetPlayer().GetDistance(pSelf) > 2000)
- Return
- EndIf
- EndIf
- If Game.GetPlayer().IsInCombat()
- Debug.Trace("PDC1 - OnUpdate - Player In Combat")
- RunAI()
- Else
- If pSelf.IsInCombat()
- pSelf.StopCombatAlarm()
- pSelf.StopCombat()
- EndIf
- Debug.Trace("PDC1 - OnUpdate - Player Not In Combat")
- ;Update Follower Reference
- UpdateFollowers()
- EndIf
- EndEvent
- ;=================================================================================
- ; Events
- ;=================================================================================
- Function ResetSpellCasting()
- PDC1PlayerFollowerCastingSpell.SetValue(0)
- PDC1PlayerFollowerCastBuffType.SetValue(0)
- PDC1PlayerFollowerCastDaulCast.SetValue(0)
- PDC1PlayerFollowerCastHealType.SetValue(0)
- EndFunction
- Event OnSpellCast(Form akSpell)
- Spell akSpellCast = akSpell As Spell
- If akSpellCast
- ; Debug.Trace("PDC1 - Casting Spell - " + akSpellCast.GetName())
- Bool bReset = False
- If PDC1PlayerFollowerExcludeResetSpells.HasForm(akSpellCast)
- bReset = True
- ;Determine if a healing spell is casted, if so make sure we have enough health before
- ;resetting spell casting, so spells like healing hands do not get packages interrupted
- If PDC1PlayerFollowerSpellHealing.HasForm(akSpellCast)
- If IsCastingSpell() && pCastingTarget != None
- If IsHealthValidForHealing(pCastingTarget)
- bReset = False
- EndIf
- EndIf
- EndIf
- EndIf
- If bReset
- ResetSpellCasting()
- AIEvaluate()
- Utility.Wait(1)
- EndIf
- EndIf
- EndEvent
- Event OnCombatStateChanged(Actor akTarget, Int aeCombatState)
- Actor pSelf = Self.GetActorRef()
- If !pSelf || pSelf.IsDead()
- Return
- EndIf
- If akTarget && (akTarget.IsPlayerTeammate() || akTarget == Game.GetPlayer())
- Return
- EndIf
- If aeCombatState == 0 ; Not in combat
- ; Debug.Trace("PDC1 - OnCombatStateChanged - Combat Ended")
- ResetStats()
- ResetSpellCasting()
- AIEvaluate()
- Utility.Wait(1)
- ElseIf aeCombatState == 1 ; In Combat
- ;Start Group Buff First
- ; Debug.Trace("PDC1 - OnCombatStateChanged - Combat Started")
- pCurrentFollower = pShellScript.SelectCorrectActor(2)
- ;Check Follower Vanilla Combat
- ElseIf aeCombatState == 2 ; Searching
- ; Debug.Trace("PDC1 - OnCombatStateChanged - Combat Searching")
- RunAI()
- EndIf
- EndEvent
- Event OnDeath(Actor akKiller)
- ResetSpellCasting()
- EndEvent
- Event OnLoad()
- ResetSpellCasting()
- EndEvent
- Event OnUnload()
- ResetSpellCasting()
- EndEvent
- Event OnHit(ObjectReference akAggressor, Form akSource, Projectile akProjectile, Bool abPowerAttack, Bool abSneakAttack, Bool abBashAttack, Bool abHitBlocked)
- ; Do Onhit code
- Actor pSelf = Self.GetActorRef()
- If !pSelf
- Return
- EndIf
- If pSelf.IsDead()
- Return
- EndIf
- ;Manage Preaching Scene
- If pShellScript.PDC1PlayerFollowerPreaching.GetValueInt()
- EndIf
- ;Manage Buffs
- AICastBuffResistGroupKeyword(akSource)
- EndEvent
- ;=================================================================================
- ; AI
- ;---------------------------------------------------------------------------------
- ; Routines
- ;=================================================================================
- Function AIEvaluate()
- Actor pSelf = Self.GetActorRef()
- If !pSelf
- Return
- EndIf
- pSelf.EvaluatePackage()
- EndFunction
- Function UpdateFollowers()
- Debug.Trace("PDC1 - UpdateFollowers")
- Actor pFollower = pShellScript.SelectCorrectActor(2)
- If pFollower && !pFollower.IsDead()
- If !pShellScript.pSkyrimFollower.GetActorRef()
- pShellScript.pSkyrimFollower.ForceRefTo(pFollower)
- EndIf
- EndIf
- EndFunction
- ;Specific AI Order
- Function RunAI()
- Actor pSelf = Self.GetActorRef()
- If !pSelf
- Return
- EndIf
- UpdateFollowers()
- ;Madetory Buff, at start of Combat
- AICastBuffShieldGroup()
- AICastHealing()
- If IsCastingSpell()
- ;Check for Reset
- If IsCastingHeal()
- Actor pTarget = GetSpellCastTarget()
- If pTarget
- If !IsHealthValidForHealing(pTarget)
- ResetSpellCasting()
- EndIf
- Else
- ;Invalid Target
- ResetSpellCasting()
- EndIf
- EndIf
- AIEvaluate()
- EndIf
- ;When Heimskr has no Target, and is not Casting
- If pSelf && pSelf.GetCombatTarget() == None && !IsCastingSpell() && Game.GetPlayer().IsInCombat()
- Actor pTarget = pShellScript.GetActiveHitTarget()
- If pTarget != None
- If pTarget.IsDead() || pTarget.GetAV("Health") <= 0
- pShellScript.ClearDeadHitTargets()
- Else
- pSelf.StartCombat(pTarget)
- EndIf
- EndIf
- EndIf
- ;Let Update & AI Catchup
- Utility.Wait(1)
- EndFunction
- ;=================================================================================
- ; AI
- ;---------------------------------------------------------------------------------
- ; Spell Casting
- ;=================================================================================
- EffectShader Property HealMysticFXS Auto
- Spell[] Property PDC1Spells Auto
- Sound[] Property PDC1SpellSounds Auto
- Perk Property Respite Auto
- ;=================================================================================
- ; ResetStats()
- ;
- ; Priest Only
- ; Used to Reset the Stats [Health / Stamina / Magicka] when not in Combat
- ;=================================================================================
- Function ResetStats()
- Actor pSelf = Self.GetActorRef()
- If !pSelf
- Return
- EndIf
- pSelf.RestoreAV("Health",10000)
- pSelf.RestoreAV("Magicka",10000)
- pSelf.RestoreAV("Stamina",10000)
- EndFunction
- ;=================================================================================
- ; CastSpellByName(String sTarget, String sSpellName, Bool abDualCast = False)
- ;
- ; Depending on the way the AI is set up, it will cast Scripted or Packaged Spells
- ; Does not cast any spells if the AI is already casting a spell
- ;=================================================================================
- Function CastSpellByName(String sTarget, String sSpellName, Bool abDualCast = False)
- If IsCastingSpell()
- Return
- EndIf
- CastSpellByPackage(sTarget,sSpellName, abDualCast)
- EndFunction
- ;=================================================================================
- ; Scripted AI Casting
- ; Need to find a way how to play Casting IDLES, ive tested plenty and none seem to work
- ; Even if i placed Heimskr out of Combat
- ;=================================================================================
- Function CastSpellByScript(String sTarget, String sSpellName, Bool abDualCast = False)
- Spell pSpell = None
- Sound pSound = None
- EffectShader pFX = None
- Idle pIdle = None
- Actor pTarget = None
- Actor pSelf = Self.GetActorRef()
- Actor pPlayer = Game.GetPlayer()
- Int iTarget = 1
- Bool bTargetSelf = False
- If sTarget == "Player"
- pTarget = pPlayer
- ElseIf sTarget == "Self"
- pTarget = pSelf
- bTargetSelf = True
- ElseIf sTarget == "Follower"
- If pCurrentFollower && pCurrentFollower.IsDead()
- pTarget = pCurrentFollower
- Else
- pTarget = pShellScript.SelectCorrectActor(2)
- EndIf
- EndIf
- If !pTarget
- Return
- EndIf
- ;Heals
- Bool bHasRespitePerk = False
- If sSpellName == "Healing Hands"
- If sTarget == "Player"
- pSpell = PDC1Spells[0] ;PDC1HealingHands
- ElseIf sTarget == "Self"
- pSpell = PDC1Spells[0] ;PDC1HealingHands
- EndIf
- ElseIf sSpellName == "Heal"
- pSpell = PDC1Spells[2] ;PDC1HealOther
- ElseIf sSpellName == "Heal All"
- pSpell = PDC1Spells[3] ;PDC1HealEx
- ElseIf sSpellName == "Resurrect"
- pSpell = PDC1Spells[6] ;PDC1ResurrectLeftHand
- EndIf
- ;Buffs
- Bool bBuff = False
- If sSpellName == "Shield Buff"
- pSpell = PDC1Spells[4] ;PDC1ShieldBuff
- pSound = PDC1SpellSounds[4]
- bBuff = True
- ElseIf sSpellName == "Resist Buff"
- pSpell = PDC1Spells[5] ;PDC1ResistBuff
- pSound = PDC1SpellSounds[5]
- bBuff = True
- EndIf
- If PDC1PlayerFollowerSpellHealing.Find(pSpell) >= 0
- bHasRespitePerk = pSelf.HasPerk(Respite)
- pSound = PDC1SpellSounds[1]
- pFX = HealMysticFXS
- ; Debug.Trace("PDC1 - PDC1PlayerFollowerSpellHealing - Has Spell in Form")
- EndIf
- pSelf.StopCombat()
- Utility.Wait(2)
- pCastingTarget = pTarget
- If bTargetSelf
- pSpell.Cast(pSelf,pTarget)
- Else
- pSelf.DoCombatSpellApply(pSpell,pTarget)
- EndIf
- If pFX != None
- pFX.Play(pTarget)
- EndIf
- If pSound != None
- pSound.PlayAndWait(pTarget)
- EndIf
- Utility.Wait(2)
- If pFX != None
- pFX.Stop(pTarget)
- EndIf
- EndFunction
- ;=================================================================================
- ; Package AI Casting Functions
- ; This has a more imersive feel to it, because it plays Casting Animations
- ;=================================================================================
- Bool Function IsCastingSpell()
- If PDC1PlayerFollowerCastingSpell.GetValue() > 0
- Return True
- EndIf
- Return False
- EndFunction
- Actor Function GetSpellCastTarget()
- If !IsCastingSpell()
- Return None
- EndIf
- Actor pSelf = Self.GetActorRef()
- Actor pPlayer = Game.GetPlayer()
- Actor pTarget = None
- Int iTarget = PDC1PlayerFollowerCastingSpell.GetValueInt()
- If iTarget == 1
- pTarget = pPlayer
- ElseIf iTarget == 2
- pTarget = pSelf
- ElseIf iTarget == 3
- If pCurrentFollower && pCurrentFollower.IsDead()
- pTarget = pCurrentFollower
- Else
- pTarget = pShellScript.SelectCorrectActor(2)
- EndIf
- EndIf
- Return pTarget
- EndFunction
- Int Function DetermineTarget()
- Int nResults = 1
- Actor pPlayer = Game.GetPlayer()
- Actor pSelf = Self.GetActorRef()
- Float CurPlayerHP = pPlayer.GetActorValuePercentage("Health")
- Float CurSelfHP = pSelf.GetActorValuePercentage("Health")
- If CurPlayerHP > CurSelfHP
- Return 2
- EndIf
- Return nResults
- EndFunction
- Bool Function IsHealthValidForHealing(Actor akTarget)
- If akTarget && !akTarget.IsDead()
- Float fCurHealthPercent = akTarget.GetActorValuePercentage("Health")
- If fCurHealthPercent <= PDC1HealCombatActiveHealthPercent.GetValue()
- Return True
- ElseIf fCurHealthPercent <= PDC1HealHandsCombatActiveHealthPercent.GetValue()
- Return True
- EndIf
- EndIf
- Return False
- EndFunction
- Function CastSpellByPackage(String sTarget, String sSpellName, Bool abDualCast = False)
- Spell pSpell = None
- Sound pSound = None
- EffectShader pFX = None
- Idle pIdle = None
- Actor pTarget = None
- Actor pSelf = Self.GetActorRef()
- Actor pPlayer = Game.GetPlayer()
- Int iTarget = 1
- Int iSpell = 0
- Bool bAllowedDualCast = abDualCast
- Bool bTargetSelf = False
- If sTarget == "Player"
- pTarget = pPlayer
- iTarget = 1
- ElseIf sTarget == "Self"
- iTarget = 2
- pTarget = pSelf
- ElseIf sTarget == "Follower"
- iTarget = 3
- If pCurrentFollower && pCurrentFollower.IsDead()
- pTarget = pCurrentFollower
- Else
- pTarget = pShellScript.SelectCorrectActor(2)
- EndIf
- EndIf
- If !pTarget
- Return
- EndIf
- ;Heals
- If sSpellName == "Healing Hands"
- If sTarget == "Player"
- iSpell = 1
- ElseIf sTarget == "Self"
- iSpell = 1
- EndIf
- ElseIf sSpellName == "Heal"
- iSpell = 2
- ElseIf sSpellName == "Heal All"
- iSpell = 3
- ElseIf sSpellName == "Resurrect"
- ispell = 4
- EndIf
- If iSpell
- If !IsHealthValidForHealing(pTarget)
- iSpell = 0
- EndIf
- If iTarget == 2
- iSpell = 1
- EndIf
- EndIf
- ;Buffs
- Bool bBuff = False
- If sSpellName == "Shield Buff"
- iSpell = 1
- bBuff = True
- ElseIf sSpellName == "Resist Buff"
- iSpell = 2
- bBuff = True
- EndIf
- If iSpell > 0
- pCastingTarget = pTarget
- If bBuff
- PDC1PlayerFollowerCastBuffType.SetValue(iSpell)
- Else
- PDC1PlayerFollowerCastHealType.SetValue(iSpell)
- EndIf
- If bAllowedDualCast
- PDC1PlayerFollowerCastDaulCast.SetValue(1)
- Else
- PDC1PlayerFollowerCastDaulCast.SetValue(0)
- EndIf
- PDC1PlayerFollowerCastingSpell.SetValue(iTarget)
- Else
- ResetSpellCasting()
- EndIf
- EndFunction
- Bool Function IsUsingAIPackageFromList(FormList pList)
- Actor pSelf = Self.GetActorRef()
- If !pSelf || !pList
- Return False
- EndIf
- If IsCastingSpell() && pList.HasForm(pSelf.GetCurrentPackage())
- Return True
- EndIf
- Return False
- EndFunction
- ;=================================================================================
- ; AI
- ;---------------------------------------------------------------------------------
- ; HEALING
- ;=================================================================================
- Bool Function IsCastingHeal()
- If !IsCastingSpell()
- Return False
- EndIf
- If PDC1PlayerFollowerCastHealType.GetValueInt() >= 1
- Return True
- EndIf
- Return False
- EndFunction
- Bool Function IsCastingBuff()
- If !IsCastingSpell()
- Return False
- EndIf
- If PDC1PlayerFollowerCastBuffType.GetValueInt() >= 1
- Return True
- EndIf
- Return False
- EndFunction
- Bool Function IsUsingHealPackage()
- Actor pSelf = Self.GetActorRef()
- If !pSelf
- Return False
- EndIf
- Return IsUsingAIPackageFromList(PDC1PlayerFollowerPackageHeal)
- EndFunction
- Function AICastHealing(Bool bIgnoreBuff = False)
- Actor pSelf = GetActorRef()
- Actor pPlayer = Game.GetPlayer()
- If !pSelf
- Return
- EndIf
- If bIgnoreBuff
- If pSelf.IsDead() || IsCastingBuff()
- Return
- EndIf
- Else
- If !IsPartyHaveShieldBuff() || pSelf.IsDead() || IsCastingBuff()
- Return
- EndIf
- EndIf
- ;-------------------------------------
- ;Player Health
- ;-------------------------------------
- Float fCurHealthPercent = pPlayer.GetActorValuePercentage("Health")
- Int iHealTargetCount = 0
- String sTarget = "Player"
- String sSpell = None
- Bool bDualCast = False
- If Utility.RandomFloat(0.0,1.0) <= PDC1PlayerFollowerDaulCastChange.GetValue()
- bDualCast = True
- EndIf
- ;-------------------------------------
- ;Player Health
- ;-------------------------------------
- If (fCurHealthPercent > PDC1HealCombatActiveHealthPercent.GetValue()) && (fCurHealthPercent <= PDC1HealHandsCombatActiveHealthPercent.GetValue())
- iHealTargetCount += 1
- sSpell = "Healing Hands"
- ElseIf (fCurHealthPercent <= PDC1HealCombatActiveHealthPercent.GetValue())
- iHealTargetCount += 1
- sSpell = "Heal"
- bDualCast = False
- EndIf
- ;-------------------------------------
- ;Follower Health
- ;-------------------------------------
- If pCurrentFollower && !pCurrentFollower.IsDead() && iHealTargetCount == 0
- sTarget = "Follower"
- fCurHealthPercent = pCurrentFollower.GetActorValuePercentage("Health")
- If (fCurHealthPercent > PDC1HealCombatActiveHealthPercent.GetValue()) && (fCurHealthPercent <= PDC1HealHandsCombatActiveHealthPercent.GetValue())
- iHealTargetCount += 1
- sSpell = "Healing Hands"
- ElseIf (fCurHealthPercent <= PDC1HealCombatActiveHealthPercent.GetValue())
- iHealTargetCount += 1
- sSpell = "Heal"
- bDualCast = False
- EndIf
- EndIf
- ;-------------------------------------
- ;Self Health
- ;-------------------------------------
- fCurHealthPercent = pSelf.GetActorValuePercentage("Health")
- If iHealTargetCount > 1 && (fCurHealthPercent <= PDC1HealCombatActiveHealthPercent.GetValue())
- iHealTargetCount += 1
- sTarget = "Self"
- sSpell = "Heal All"
- bDualCast = False
- EndIf
- If iHealTargetCount == 0
- sTarget = "Self"
- If (fCurHealthPercent > PDC1HealCombatActiveHealthPercent.GetValue()) && (fCurHealthPercent <= PDC1HealHandsCombatActiveHealthPercent.GetValue())
- iHealTargetCount += 1
- sSpell = "Healing Hands"
- EndIf
- EndIf
- If iHealTargetCount > 0
- CastSpellByName(sTarget,sSpell,bDualCast)
- EndIf
- EndFunction
- ;=================================================================================
- ; AI
- ;---------------------------------------------------------------------------------
- ; BUFFS
- ;=================================================================================
- Bool Function IsUsingBuffackage()
- Actor pSelf = Self.GetActorRef()
- If !pSelf
- Return False
- EndIf
- Return IsUsingAIPackageFromList(PDC1PlayerFollowerPackageBuff)
- EndFunction
- Bool Function IsPartyHaveShieldBuff()
- Actor pActor = Self.GetActorRef()
- If pActor && pActor.HasMagicEffectWithKeyword(PDC1MagicBuffGroupShield)
- Return True
- EndIf
- Return False
- EndFunction
- Bool Function IsPartyHaveResistBuff()
- Actor pActor = Self.GetActorRef()
- If pActor && pActor.HasMagicEffectWithKeyword(PDC1MagicBuffGroupResist)
- Return True
- EndIf
- Return False
- EndFunction
- Bool Function HasMagicEffectWithKeywordFromList(FormList fmList)
- If fmList != None
- Int iSize = fmList.GetSize()
- While iSize > 0
- iSize -= 1
- Keyword kEffect = fmList.GetAt(iSize) As Keyword
- If kEffect
- If (pShellScript.SelectCorrectActor(1).HasMagicEffectWithKeyword(kEffect) ||\
- Game.GetPlayer().HasMagicEffectWithKeyword(kEffect))
- Return True
- EndIf
- Actor pFollower = pShellScript.SelectCorrectActor(2)
- If pFollower
- If pFollower.HasMagicEffectWithKeyword(kEffect)
- Return True
- EndIf
- EndIf
- EndIf
- EndWhile
- EndIf
- Return False
- EndFunction
- Bool Function HasKeywordFromList(Form akSource, FormList fmList)
- If fmList != None
- Int iSize = fmList.GetSize()
- While iSize > 0
- iSize -= 1
- Keyword kEffect = fmList.GetAt(iSize) As Keyword
- If kEffect
- If akSource.HasKeyword(kEffect)
- Return True
- EndIf
- EndIf
- EndWhile
- EndIf
- Return False
- EndFunction
- Function AICastBuffResistGroupKeyword(Form akSource)
- Int iDebuffCount = 0
- If IsPartyHaveResistBuff() || !Game.GetPlayer().IsInCombat()
- Return
- EndIf
- If akSource.HasKeyword(PDC1MagicPriestDamage)
- Return
- EndIf
- If HasKeywordFromList(akSource, PDC1PlayerFollowerSpellDamageKeywords)
- CastSpellByName("Self","Resist Buff")
- EndIf
- EndFunction
- Function AICastBuffShieldGroup()
- If IsPartyHaveShieldBuff() || !Game.GetPlayer().IsInCombat()
- Return
- EndIf
- ; Debug.Trace("PDC1 - AICastBuffShieldGroup True")
- CastSpellByName("Self","Shield Buff")
- EndFunction
- ;=================================================================================
- ; Current Follower Data
- ;=================================================================================
Advertisement
Add Comment
Please, Sign In to add comment