I want to say thanks again, your pointers were very helpful, and I was able to achieve exactly what I sought out to. Here is how I ended up doing it:
First, I created a quest with start game enabled checked, and added this as the quest script:
scn phiEventsQS
begin GameMode if GetGameRestarted SetEventHandler "OnHit" phiFunctionOnHit player.additem phiBKshield01a 1 ; this is just to add the shield for testing endifend
I then put the object script below on the shield itself, which basically adds a magic script effect to the player when the shield is equipped as an ability (passive effect always active), to handle the timers for building back charges of the shield's magic knockback stun effect over time after they've been used.
scn phiBKshield01aSbegin OnEquip player.addspell phiBKshield01aM ; adds passive spell to player to rebuild charges when equippedendbegin OnUnEquip player.removespell phiBKshield01aM ; removes the above passive charge system when unequippedend
Then the fun part. Here is the function script target of the first event handler quest script:
scn phiFunctionOnHitref targetref attackerbegin Function { target, attacker } if target == PlayerRef ; check if the hit character is the player if player.IsBlocking ; check if the player had a block up when they were hit if player.GetEquipped phiBKshield01a ; make sure the knockback shield is equipped, could have multiple loops for multiple item checks if phicharge == 3 ; the shield starts out with 3 charges, defined as a global variable if attacker.GetDistance player < 195 ; if the attacker is in mele-ish range, apply the knockback player.PlaySound3D splrestorationhit attacker.PlaySound3D splfrosthit attacker.pms effectFrostDamage 10 ; these three lines just play sounds and visual effects player.PushActorAway attacker 25 ; apply the knockback set phitimer1 to 1 ; starts the charge cooldown timer counting on the global phitimer which is counted in the player magic effect script. set phicharge to phicharge - 1 ; subtract one charge from the current total message "Shield lost 1 charge, %.0f remaining!", phicharge, 1 ; briefly notify of event and current charge set target to 0 ; reset target so checks won't run until another blocked hit, allowing the loss of charge and other effects to process first else set target to 0 endif elseif phicharge == 2 ; the next two loops are a repeat of the above as charges are lost if attacker.GetDistance player < 195 player.PushActorAway attacker 25 player.PlaySound3D splrestorationhit attacker.PlaySound3D splfrosthit attacker.pms effectFrostDamage 10 set phitimer2 to 1 set phicharge to phicharge - 1 message "Shield lost 1 charge, %.0f remaining!", phicharge, 1 set target to 0 else set target to 0 endif elseif phicharge == 1 if attacker.GetDistance player < 195 player.PushActorAway attacker 25 player.PlaySound3D splrestorationhit attacker.PlaySound3D splfrosthit attacker.pms effectFrostDamage 10 set phitimer3 to 1 set phicharge to phicharge - 1 message "Shield lost 1 charge, %.0f remaining!", phicharge, 1 set target to 0 else set target to 0 endif elseif phicharge <= 0 set target to 0 endif endif endif endifend
Finally there is the magic effect script which handles the global variable timers set above, and adds back one charge for each timer after a certain interval:
scn phiBKshield01aMSbegin ScriptEffectUpdate if phitimer1 > 0 ; won't run unless the timer has been set by the charge use function if phitimer1 < 10 set phitimer1 to phitimer1 + GetSecondsPassed ; count up to ten, so in this example, nine seconds pass before a charge is returned. else set phicharge to phicharge + 1 message "Shield built 1 charge, %.0f remaining!", phicharge, 1 ; notify of charge gain and total set phitimer1 to 0 ; reset timer so it isn't checked until the next time that charge level is expended endif endif if phitimer2 > 0 ; repeat for each charge state if phitimer2 < 10 set phitimer2 to phitimer2 + GetSecondsPassed else set phicharge to phicharge + 1 message "Shield built 1 charge, %.0f remaining!", phicharge, 1 set phitimer2 to 0 endif endif if phitimer3 > 0 if phitimer3 < 10 set phitimer3 to phitimer3 + GetSecondsPassed else set phicharge to phicharge + 1 message "Shield built 1 charge, %.0f remaining!", phicharge, 1 set phitimer3 to 0 endif endifend
So basically, you start out with three charges, and if something in mele range uses a physical attack against you and you are blocking when it hits, the shield uses one charge to invoke a knockback with some spell visuals, stunning the recipient briefly. Each time you block you lose one charge, until you run out, and blocking works as normal.
After each charge is used an internal cooldown begins counting down nine seconds, after which point the charge is returned and timer reset, sort of like Death Knight runes in wow. Each charge you use has a separate cooldown.
Here's a video of the current shield in action. (Contains Deadly Reflex 5 blood and gore.) You can see how it notifies you how many charges you currently have. This could easily be tweaked into some better UI element, even a behind the scenes swap so the graphical appearance of the shield changes (glow maps possibly) based on how many charges were available.
I was mainly testing this function call method and as you can see, it is totally realtime. I gain a 2nd charge right as two characters hit me simultaneously, and the code is such that it registers each and appropriately sets the charge to zero after they both hit. There is some lag with the message display, but you can see the third guy is hitting me after that and I am blocking normally without charges.
The fire related effects are part of another scripted spell set I made.
http://www.youtube.com/watch?v=HwqANChQlkk
Fun to see the sorts of cool features available this generation of the CS and community of extension projects, as we await the release of Skyrim.