Code:
Scriptname THEW:THEWHitManagerScript extends activemagiceffect
; --- Features ---
; - Plood pool when player is bleeding out
; - Impact Effects on hit, depending on the actor or weapon
; - Impact effect when crippling
; - Dismember possibility on death
Group Common
Actor Property Player Auto
ActorValue Property HealthAV Auto
ObjectReference[] Property THEWObjectBloodPool Auto Const Mandatory
Explosion[] Property THEWExplGoreImpact Auto Const Mandatory
ImpactDataSet BloodSprayImpactSetRed Auto Const Mandatory
FormList Property THEWListHitAggressor1 Auto Const Mandatory
FormList Property THEWListHitAggressor2 Auto Const Mandatory
FormList Property THEWListHitAggressor3 Auto Const Mandatory
FormList Property THEWListHitSource1 Auto Const Mandatory
FormList Property THEWListHitSource2 Auto Const Mandatory
FormList Property THEWListHitSource3 Auto Const Mandatory
FormList Property THEWListHitProjectile1 Auto Const Mandatory
FormList Property THEWListHitProjectile2 Auto Const Mandatory
FormList Property THEWListHitProjectile3 Auto Const Mandatory
EndGroup
Group Settings
Int Property PowerAttackHitFilter Auto Const Mandatory ; -1 Exclude PA, 0 Any, 1 PA only
Int Property BashAttackHitFilter Auto Const Mandatory ; -1 Exclude BA, 0 Any, 1 BA only
EndGroup
; Private members
bool hitBlocked = false ; Block any other hit effect when player is dismembered
; Initialize effects
Event OnEffectStart(Actor Target, Actor Caster)
Player = Game.GetPlayer()
RegisterForHitEvent(Player, aiPowerFilter = PowerAttackHitFilter, aiBashFilter = BashAttackHitFilter)
EndEvent
; Cripple effects
Event OnCripple(ActorValue akActorValue, bool abCrippled)
Debug.Trace("THEW - OnCripple - akActorValue: " + akActorValue + " abCrippled: " + abCrippled)
If abCrippled && hitBlocked == false
SetRumble (0.7, 2)
Debug.Trace("THEW - OnCripple - abCrippled: " + abCrippled)
EndIf
EndEvent
; Hit events by aggressor, source or projectile
; Blood impact, rumble, dismember
; akAggressor List actor type keywords
; akSource List weapon, spell, explosion, ingredient, potion, enchantment
; akProjectile List projectiles, contains an unused dummy projectile currently
Event OnHit(ObjectReference akTarget, ObjectReference akAggressor, Form akSource, Projectile akProjectile, bool abPowerAttack, bool abSneakAttack, bool abBashAttack, bool abHitBlocked, string apMaterial)
Debug.Trace("THEW - OnHit - akAggressor: " + akAggressor + " akSource: " + akSource + " akProjectile: " + akProjectile + " abPowerAttack: " + abPowerAttack + " abBashAttack: " + abBashAttack)
int weaponType = 0 ; 1-3
int effectForce = 0 ; 1-3
int effectChance = 0 ; 0-9
int dismemberChance = 0 ; 0-9
; akSource first because it detect unarmed attacks
; Trying to improve detection and to add sepcial effects for certain actors
If akSource != None
If THEWListHitSource1.HasForm(akSource)
effectForce = 1
effectChance = 1
ElseIf THEWListHitSource2.HasForm(akSource)
effectForce = 1
effectChance = 3
ElseIf THEWListHitSource3.HasForm(akSource)
effectForce = 2
effectChance = 7
EndIf
ElseIf akAggressor != None
If akAggressor.HasKeywordInFormList(THEWListHitAggressor1)
effectForce = 1
effectChance = 1
ElseIf akAggressor.HasKeywordInFormList(THEWListHitAggressor2)
effectForce = 1
effectChance = 3
dismemberChance = 1
ElseIf akAggressor.HasKeywordInFormList(THEWListHitAggressor3)
effectForce = 2
effectChance = 7
dismemberChance = 3
EndIf
ElseIf akProjectile != None
If THEWListHitProjectile1.HasForm(akProjectile)
effectForce = 1
effectChance = 1
ElseIf THEWListHitProjectile2.HasForm(akProjectile)
effectForce = 1
effectChance = 3
ElseIf THEWListHitProjectile3.HasForm(akProjectile)
effectForce = 2
effectChance = 7
dismemberChance = 3
EndIf
EndIf
If abPowerAttack || abBashAttack
If Player.GetValuePercentage(HealthAV) < 0.1
dismemberChance = effectChance
EndIf
dismemberChance = GetChance(dismemberChance)
EndIf
If dismemberChance > 0
SetRumble (0.7, 2)
SetGoreExplosion(effectForce)
SetDismembered(effectForce)
hitBlocked = true
Else
effectChance = GetChance(effectChance)
If effectChance > 0
SetRumble (0.7, 2)
SetGoreExplosion(effectForce)
EndIf
EndIf
Debug.Trace("THEW - OnHit - effectChance: " + effectChance + " dismemberChance: " + dismemberChance + " effectForce: " + effectForce)
If hitBlocked == false
RegisterForHitEvent(Player, aiPowerFilter = PowerAttackHitFilter, aiBashFilter = BashAttackHitFilter)
EndIf
EndEvent
; Dismemberment and blood pools by killer
Event OnDying(Actor akKiller)
Debug.Trace("THEW - OnDying - akKiller: " + akKiller)
If Player.IsDismembered() == false && hitBlocked == false
int effectForce = 0 ; 1-3
int effectChance = 0 ; 0-9
If THEWListHitAggressor1.HasForm(akKiller)
effectForce = 1
effectChance = 1
ElseIf THEWListHitAggressor2.HasForm(akKiller)
effectForce = 2
effectChance = 3
ElseIf THEWListHitAggressor3.HasForm(akKiller)
effectForce = 3
effectChance = 9
EndIf
effectChance = GetChance(effectChance)
SetRumble (0.4, 3)
If effectChance > 0
SetDismembered(effectForce)
SetBloodPool(effectForce)
EndIf
Debug.Trace("THEW - OnDying - effectChance: " + effectChance + " effectForce: " + effectForce)
EndIf
EndEvent
; --- Helper-Methods -----------------------------------------------------
Int Function GetChance (int chance)
If chance > 0
return Utility.RandomInt(1, chance)
Else
return 0;
EndIf
EndFunction
; Adjustable Dismemberment
Function SetDismembered(int effectForce = 1)
int random = Utility.RandomInt(0, 8)
If effectForce == 1
If random < 2
Player.Dismember("Head1", true, true)
ElseIf random < 4
Player.Dismember("Eye", true, true)
ElseIf random < 6
Player.Dismember("LeftArm1", true, true)
ElseIf random < 6
Player.Dismember("RightLeg1", true, true)
EndIf
ElseIf effectForce == 2
If random < 2
Player.Dismember("Head1", true, true)
ElseIf random < 4
Player.Dismember("LeftArm1", true, true)
ElseIf random < 6
Player.Dismember("RightArm2", true, true)
ElseIf random < 6
Player.Dismember("LeftLeg1", true, true)
EndIf
ElseIf effectForce == 3
If random < 2
Player.Dismember("RightLeg1", true, true)
ElseIf random < 4
Player.Dismember("RightArm1", true, true)
ElseIf random < 6
Player.Dismember("Torso", true, true)
ElseIf random < 6
Player.Dismember("Torso", true, true)
EndIf
EndIf
EndFunction
; Adjustable Rumbble
; rumbleStrength: Float 0.1-1.0
; rumbleLength: Float 0.1-1.0
Function SetRumble (float rumbleStrength = 0.1, float rumbleLength = 0.5)
float strengthMod = rumbleStrength / 100 * 5
float strengthLeft = Utility.RandomFloat((rumbleStrength - strengthMod), (rumbleStrength + strengthMod))
float strengtRight = Utility.RandomFloat((rumbleStrength - strengthMod), (rumbleStrength + strengthMod))
Game.ShakeController(strengthLeft, strengtRight, rumbleLength)
EndFunction
; Adjustable Camera Shake
; shakeStrength: Float 0.1-1.0
; shakeLength: Float 0.1-1.0
Function SetCameraShake (float shakeStrength = 0.1, float shakeLength = 1.0)
float shakeMod = shakeStrength / 100 * 5
shakeStrength = Utility.RandomFloat((shakeStrength - shakeMod), (shakeStrength + shakeMod))
Game.ShakeCamera(Player, shakeStrength, shakeLength)
EndFunction
; Adjustable GoreExplosion
; explosionType: Int Explosion amount To Do different gore explosions
Function SetGoreExplosion (int explosionType = 1)
explosionType = explosionType - 1
If explosionType < 0
explosionType = 0
ElseIf explosionType > 2
explosionType = 2
EndIf
Player.PlaceAtMe(THEWExplGoreImpact[explosionType])
EndFunction
; Blood pool on player death
; poolAmount: Int Pools amount
Function SetBloodPool (int poolType = 1)
poolType = poolType - 1
If poolType < 0
poolType = 0
ElseIf poolType > 2
poolType = 2
EndIf
; THEWObjectBloodPool[poolType].MoveTo(Player)
Player.PlayImpactEffect(BloodSprayImpactSetRed, "Torso", 0, 0, -1, 512, true, false)
Debug.Trace("THEW - Blood Pool ated")
EndFunction
; Adjustable Screen Blood
; strength: Int Strength of screen blood
Function SetScreenBlood(int goreAmount = 5)
Game.TriggerScreenBlood((goreAmount * Utility.RandomInt(5, 12)))
EndFunction
; Removes an array of imagespace modifiers
Function RemoveImageSpaceModifiers(ImageSpaceModifier[] objects)
int c = 0
while (c < objects.Length)
objects[c].Remove()
c += 1
endwhile
EndFunction
; Removes an imagespace modifier in an array
Function RemoveImageSpaceModifier(ImageSpaceModifier[] objects, int goreindex)
objects[goreindex].Remove()
EndFunction