Nerevairine Posted September 10, 2020 Share Posted September 10, 2020 As some of you know, I am working on the new version of "Knights of the Nine: Revelations Continued (Unofficial)" but I seem to have done something wrong with the script for Auriel's Shield. I am trying to make the shield have the same power it has in Skyrim but can't make the script check if the character was hit while blocking with the shield, and so here we are. Is there any expert in Oblivion CS that can help me with this? (I am leaving all the scripts I have for the shield below). By the way "BlockedTimes" is a Global Variable set to "short". Quest Script:scn aaShockwaveQSTScript float fquestdelaytime Ref CasterFloat Timer Begin GameMode if ( GetOBSEVersion < 15 ) MessageBox "Requires Oblivion Script Extender v0015 or higher." returnendif if (fquestdelaytime != 0.01) set fquestdelaytime to 0.01endif if (BlockedTimes == 15)player.pms effectSummonMythicDawnelseplayer.sms effectSummonMythicDawnendif ; V KeyIf ( OnKeyDown 47)Set Timer to Timer + GetSecondsPassedSet Caster to Player.PlaceAtMe ShockwaveCasterCaster.DisableEndIf If ( Timer >= 1 ) && (BlockedTimes >= 15) && (player.GetEquipped aaKOTNRAurielsShield == 1)Caster.Cast aaAurielsShieldPushSpell PlayerSet BlockedTimes to 0EndIf If ( Timer != 0 )If ( Timer < 1 )Set Timer to Timer + GetSecondsPassedElseSet Timer to 0Caster.DeleteReferenceEndIfEndIf End Shield Script:scn aaAurielShieldScriptfloat timeshitBEGIN ONHIT PLAYERif (IsBlocking == 1) && (Player.GetEquipped aaKOTNRAurielsShield == 1) && (BlockedTimes < 15)set BlockedTimes to (timeshit + 1)endifEND Player Effect Script: scn aaAurielShieldPushScript Spell Script: Scriptname aaAurielShieldPushSpellScriptRef TargetBegin ScriptEffectStartSet Target to GetSelfIf (Target != Player)Player.PushActorAway Target 25EndIfEnd Link to comment Share on other sites More sharing options...
DrakeTheDragon Posted September 11, 2020 Share Posted September 11, 2020 Hmm, I'm not exactly an expert in this particular topic, but I do know the way you use the OnHit block it doesn't work. According to the CS wiki documentation the block is used to trigger when the "actor" the script is running on is hit by the actor given as parameter. The script with this block cannot run on the shield. It must run on an actor.However, putting it onto the player actor in the CS also isn't exactly a clean or sane way to go, as only 1 plugin in load order can do that at the same time. I think detecting when the player was hit is nowadays done quite differently. I just can't off the top of my head recall how it's done. And then, your GetEquipped check is totally valid, being executed on "player" specifically. But calling "IsBlocking" when the script runs on the shield will always be false, as the shield will never be in the animation state of blocking. This, too, needs to be called on the player implicitly. I'm sorry I'm not of more help right now. Maybe I'll come back when I stumbled across something more. Can't promise though. Link to comment Share on other sites More sharing options...
Nerevairine Posted September 11, 2020 Author Share Posted September 11, 2020 Hmm, I'm not exactly an expert in this particular topic, but I do know the way you use the OnHit block it doesn't work. According to the CS wiki documentation the block is used to trigger when the "actor" the script is running on is hit by the actor given as parameter. The script with this block cannot run on the shield. It must run on an actor.However, putting it onto the player actor in the CS also isn't exactly a clean or sane way to go, as only 1 plugin in load order can do that at the same time. I think detecting when the player was hit is nowadays done quite differently. I just can't off the top of my head recall how it's done. And then, your GetEquipped check is totally valid, being executed on "player" specifically. But calling "IsBlocking" when the script runs on the shield will always be false, as the shield will never be in the animation state of blocking. This, too, needs to be called on the player implicitly. I'm sorry I'm not of more help right now. Maybe I'll come back when I stumbled across something more. Can't promise though.Thanks for the help you have given, and by the way the "IsBlocking" actually works on the shield since I have a script on another shield with that same parameter and it works, maybe just doesn't work in this case(?). Link to comment Share on other sites More sharing options...
Tharkun221 Posted September 13, 2020 Share Posted September 13, 2020 (edited) I too don't think the OnHit block will work the way you use it. Have you considered using OBSE's onhit event handler function?Once set it will trigger anytime an actor is hit. You can write your code in the function to determine who was hit and if the Auriel shield was equipped at the time. It's pretty straightforward to use: First create the event handler function, (make sure to set it as an object script): Scn aaNerevairineOnHitFunction ref targetref attackerref Pref begin function { target, attacker } set Pref to PlayerRefIf target != Pref ;exit early if it's not the player that was hit ReturnEndIf If target.GetEquipped aaKOTNRAurielsShield != 1 ;exit early if player doesn't have Auriels shield equipped. ReturnEndIf If (target.IsBlocking) && (BlockedTimes < 15) set BlockedTimes to BlockedTimes + 1 ;increment the BlockedTimes global variableEndIf end ;end of function Now register the function by using SetEventHandler, for example you could put this code in the GameMode block of your Quest script: If getgameloaded ;needs to be declared only once when the game is loaded ;set handlers seteventhandler "onhit" aaNerevairineOnHitFunction EndIf You don't need any script on the shield or player.This is just a rough outline, I didn't test the code and I may not have fully understood all the details of what you want to do so it may not do exactly what you want as is. Hope it helps you. Edited September 14, 2020 by Tharkun221 Link to comment Share on other sites More sharing options...
Nerevairine Posted September 15, 2020 Author Share Posted September 15, 2020 I too don't think the OnHit block will work the way you use it. Have you considered using OBSE's onhit event handler function?Once set it will trigger anytime an actor is hit. You can write your code in the function to determine who was hit and if the Auriel shield was equipped at the time. It's pretty straightforward to use: First create the event handler function, (make sure to set it as an object script): Scn aaNerevairineOnHitFunction ref targetref attackerref Pref begin function { target, attacker } set Pref to PlayerRefIf target != Pref ;exit early if it's not the player that was hit ReturnEndIf If target.GetEquipped aaKOTNRAurielsShield != 1 ;exit early if player doesn't have Auriels shield equipped. ReturnEndIf If (target.IsBlocking) && (BlockedTimes < 15) set BlockedTimes to BlockedTimes + 1 ;increment the BlockedTimes global variableEndIf end ;end of function Now register the function by using SetEventHandler, for example you could put this code in the GameMode block of your Quest script: If getgameloaded ;needs to be declared only once when the game is loaded ;set handlers seteventhandler "onhit" aaNerevairineOnHitFunction EndIf You don't need any script on the shield or player.This is just a rough outline, I didn't test the code and I may not have fully understood all the details of what you want to do so it may not do exactly what you want as is. Hope it helps you.That worked!!! Thanks man! Link to comment Share on other sites More sharing options...
Tharkun221 Posted September 16, 2020 Share Posted September 16, 2020 Great! Good luck with your mod. Link to comment Share on other sites More sharing options...
Nerevairine Posted September 21, 2020 Author Share Posted September 21, 2020 I too don't think the OnHit block will work the way you use it. Have you considered using OBSE's onhit event handler function?Once set it will trigger anytime an actor is hit. You can write your code in the function to determine who was hit and if the Auriel shield was equipped at the time. It's pretty straightforward to use: First create the event handler function, (make sure to set it as an object script): Scn aaNerevairineOnHitFunction ref targetref attackerref Pref begin function { target, attacker } set Pref to PlayerRefIf target != Pref ;exit early if it's not the player that was hit ReturnEndIf If target.GetEquipped aaKOTNRAurielsShield != 1 ;exit early if player doesn't have Auriels shield equipped. ReturnEndIf If (target.IsBlocking) && (BlockedTimes < 15) set BlockedTimes to BlockedTimes + 1 ;increment the BlockedTimes global variableEndIf end ;end of function Now register the function by using SetEventHandler, for example you could put this code in the GameMode block of your Quest script: If getgameloaded ;needs to be declared only once when the game is loaded ;set handlers seteventhandler "onhit" aaNerevairineOnHitFunction EndIf You don't need any script on the shield or player.This is just a rough outline, I didn't test the code and I may not have fully understood all the details of what you want to do so it may not do exactly what you want as is. Hope it helps you.That worked!!! Thanks man! Thanks! Link to comment Share on other sites More sharing options...
Recommended Posts