qwertypol012 Posted January 16, 2021 Share Posted January 16, 2021 As the title says. I want to know whether OnHit event work inside a Ref Alias script. I have a Ref Alias script to monitor an NPC's conditions, and one of the events i need is OnHit. I also have additional questions btw:Does OnHit event work in an Armor script? I already tried to make it, by extending the script to ObjectReference (attached to the armor), but it didn't seem to work. That's why i changed it to Ref Alias script and also an Active Magic Effect script which seemingky capable to run OnHit event. Any explanation is appreciated. :) Link to comment Share on other sites More sharing options...
IsharaMeradin Posted January 16, 2021 Share Posted January 16, 2021 Reference alias points to an actor. A script on the ref alias will receive the following events:Any ReferenceAlias eventsAny Actor eventsAny ObjectReference eventsAny Form events Reference alias points to a piece of armor. A script on the ref alias will receive the following events:Any ReferenceAlias eventsAny ObjectReference eventsAny Form eventsNote that while stored in a container / inventory some events / functions may not be triggered. Link to comment Share on other sites More sharing options...
qwertypol012 Posted January 16, 2021 Author Share Posted January 16, 2021 Reference alias points to an actor. A script on the ref alias will receive the following events: Any ReferenceAlias eventsAny Actor eventsAny ObjectReference eventsAny Form events Reference alias points to a piece of armor. A script on the ref alias will receive the following events:Any ReferenceAlias eventsAny ObjectReference eventsAny Form eventsNote that while stored in a container / inventory some events / functions may not be triggered.Thanks for the explanation. So it seems like that's the case with my armor script (as ObjectReference). Probably because it's started with OnContainerChanged event, which possibly makes the OnHit didn't work. As for the Ref Alias, i once tried it in a Player Alias script, and the OnHit didn't seem to be triggered. I put some debug.Notification inside the event, but none of them showed in the game whenever i got hit. And of course the alias has been filled with the player reference (i can assure it). Link to comment Share on other sites More sharing options...
maxarturo Posted January 16, 2021 Share Posted January 16, 2021 (edited) IsharaMeradin already said most, i'll just add 2 things. - Once an object is inside a container or inventory it can no longer run a "Self" function, but it can run the function if it is targeting something else. Example: This will never fire ObjecReference Property MyREF01 Auto Event OnContainerChanged() If ( akNewContainer == PlayerREF ) MyREF01.Activate(self) EndIf Endevent But this will ObjecReference Property MyREF01 Auto ObjecReference Property MyREF02 Auto Event OnContainerChanged() If ( akNewContainer == PlayerREF ) MyREF01.Activate(MyREF02) EndIf Endevent When you add an "OnHit" event to the armor that event will also fire when you throw to the ground and hit the armor. The best way to have an "OnHit" event attach directly to the armor is to: - Create an Ability Spell with archetype 'Script'. - Add your script to your magic effect with archetype 'Script' that it will run the "OnHit" event. - Then add/remove the ability on "OnEquipped()" > "OnUnequipped()" I hope it helps and have a happy modding. Edited January 16, 2021 by maxarturo Link to comment Share on other sites More sharing options...
qwertypol012 Posted January 17, 2021 Author Share Posted January 17, 2021 IsharaMeradin already said most, i'll just add 2 things.- Once an object is inside a container or inventory it can no longer run a "Self" function, but it can run the function if it is targeting something else.Example:This will never fire ObjecReference Property MyREF01 Auto  Event OnContainerChanged()   If ( akNewContainer == PlayerREF )     MyREF01.Activate(self) EndIf Endevent But this will ObjecReference Property MyREF01 Auto ObjecReference Property MyREF02 Auto  Event OnContainerChanged()   If ( akNewContainer == PlayerREF )     MyREF01.Activate(MyREF02) EndIf Endevent When you add an "OnHit" event to the armor that event will also fire when you throw to the ground and hit the armor.The best way to have an "OnHit" event attach directly to the armor is to:- Create an Ability Spell with archetype 'Script'.- Add your script to your magic effect with archetype 'Script' that it will run the "OnHit" event.- Then add/remove the ability on "OnEquipped()" > "OnUnequipped()" I hope it helps and have a happy modding. So, that's why it didn't work in my case. I still don't understand properly about making the armor "targeting something else". Not really sure about its implementation. But thanks for the insight. I think i understand OnHit more now. In writing scripts, i mainly followed instructions and infos from the CK site's papyrus functions, and unfortunately they don't have much info (just like what you've explained above) Link to comment Share on other sites More sharing options...
maxarturo Posted January 17, 2021 Share Posted January 17, 2021 Why don't you explain with simple words and in order what are you trying to achieve. There are different ways to do certain things and in some cases only one way. Link to comment Share on other sites More sharing options...
qwertypol012 Posted January 18, 2021 Author Share Posted January 18, 2021 (edited) Why don't you explain with simple words and in order what are you trying to achieve. There are different ways to do certain things and in some cases only one way.Alright, I'll try to explain what I'm trying to achieve. It'll be a bit long though. I'm in the process of adding a feature to my mod. To put it short, my mod is an armor mod which has some features when being worn; and one of the features is:"When being worn AND the player is in combat, check if the player is facing a strong enemy (by simply comparing his/her level with player's level, which one is higher) OR if the player is in a critical condition (ie. Health below a certain threshold, for example). If one of these conditions is fulfilled, then run X function" X function is: Transforming the armor into a more enhanced version of the armor. That's it. Do you have any suggestions on how to do it properly without using too many resource intensive papyrus functions?I want my scripts to only use papyrus functions as lightweight as possible. Edited January 18, 2021 by qwertypol012 Link to comment Share on other sites More sharing options...
maxarturo Posted January 18, 2021 Share Posted January 18, 2021 (edited) "Do you have any suggestions on how to do it properly without using too many resource intensive papyrus functions?" Unfortunately no, what you want to do needs to use a bunch of things in order to be achieved, but i'll post the most light version of it, in my opinion. NOTE: There are other ways to do this and maybe some else can suggest another way to do it. * I will use the "if the player is in a critical condition". 1) Create a "BoostPerk", a perk that will modify the incoming damage, you can see how the vanilla "Ghost Half Damage Perk" is made, you might need to also add to your perk a "Mod Incoming Spell Damage". The vanilla "Ghost Half Damage Perk" modifies only one kind of incoming damage. 2) Create an "Ability Spell". 3) In its 'Magic Effect" add this script: * It fires when the Player's health is under 20%. Perk Property BoostPerk Auto {The perk that modifies the Incoming Damage} EffectShader Property BoostVFX Auto [The Visual FX Shader that will play once the Boost has been triggered} Message Property BoostOffMSG Auto {The message that notifies that the Armor's Boost is OFF} Message Property BoostOnMSG Auto {The message that notifies that the Armor's Boost is ON} Bool Property PerkApplied = False Auto Hidden EVENT OnHit(ObjectReference akAggressor, Form akSource, Projectile akProjectile, bool abPowerAttack, bool abSneakAttack, bool abBashAttack, bool abHitBlocked) float ActorPlayer = Self.GetAVPercentage("Health") If ( PerkApplied == False ) && ( ActorPlayer < 0.2 ) If ( Self.HasPerk(BoostPerk) == False ) PerkApplied = True Self.AddPerk(BoostPerk) BoostVFX.Play(Self, -1.0) RegisterForSingleUpdate(10.0) BoostOnMSG.Show() EndIf EndIf ENDEVENT EVENT OnEffectFinish(Actor akTarget, Actor akCaster) If ( Self.HasPerk(BoostPerk) ) Self.RemovePerk(BoostPerk) EndIf If ( PerkApplied == True ) PerkApplied = False EndIf BoostVFX.Stop(Self) ENDEVENT EVENT OnUpdate() If ( Self.IsInCombat() ) RegisterForSingleUpdate(10.0) Else If ( Self.HasPerk(BoostPerk) ) Self.RemovePerk(BoostPerk) BoostVFX.Stop(Self) PerkApplied = False BoostOffMSG.Show() EndIf EndIf ENDEVENT 4) Add to your script's property the "Perk" you created. 5) Add to your Armor this script: Import Game Spell Property BoostAB Auto EVENT OnEquipped(Actor akActor) If ( akActor == GetPlayer() ) akActor.AddSpell(BoostAB, False) EndIf ENDEVENT EVENT OnUnequipped(Actor akActor) If ( akActor == GetPlayer() ) akActor.RemoveSpell(BoostAB) EndIf ENDEVENT 6) Assign the "Boost Ability Spell" to your Armpr's script. You are done !. Edited January 18, 2021 by maxarturo Link to comment Share on other sites More sharing options...
qwertypol012 Posted January 19, 2021 Author Share Posted January 19, 2021 "Do you have any suggestions on how to do it properly without using too many resource intensive papyrus functions?"Unfortunately no, what you want to do needs to use a bunch of things in order to be achieved, but i'll post the most light version of it, in my opinion.NOTE: There are other ways to do this and maybe some else can suggest another way to do it. * I will use the "if the player is in a critical condition". 1) Create a "BoostPerk", a perk that will modify the incoming damage, you can see how the vanilla "Ghost Half Damage Perk" is made, you might need to also add to your perk a "Mod Incoming Spell Damage".The vanilla "Ghost Half Damage Perk" modifies only one kind of incoming damage. 2) Create an "Ability Spell". 3) In its 'Magic Effect" add this script:* It fires when the Player's health is under 20%. Perk Property BoostPerk Auto {The perk that modifies the Incoming Damage}  EffectShader Property BoostVFX Auto [The Visual FX Shader that will play once the Boost has been triggered}  Message Property BoostOffMSG Auto {The message that notifies that the Armor's Boost is OFF}  Message Property BoostOnMSG Auto {The message that notifies that the Armor's Boost is ON}  Bool Property PerkApplied = False Auto Hidden   EVENT OnHit(ObjectReference akAggressor, Form akSource, Projectile akProjectile, bool abPowerAttack, bool abSneakAttack, bool abBashAttack, bool abHitBlocked)       float ActorPlayer = Self.GetAVPercentage("Health")      If ( PerkApplied == False ) && ( ActorPlayer < 0.2 )        If ( Self.HasPerk(BoostPerk) == False )          PerkApplied = True         Self.AddPerk(BoostPerk)         BoostVFX.Play(Self, -1.0)          RegisterForSingleUpdate(10.0)         BoostOnMSG.Show()      EndIf    EndIf ENDEVENT  EVENT OnEffectFinish(Actor akTarget, Actor akCaster) If ( Self.HasPerk(BoostPerk) ) Self.RemovePerk(BoostPerk) EndIf If ( PerkApplied == True ) PerkApplied = False EndIf BoostVFX.Stop(Self) ENDEVENT  EVENT OnUpdate()     If ( Self.IsInCombat() )       RegisterForSingleUpdate(10.0)    Else      If ( Self.HasPerk(BoostPerk) )          Self.RemovePerk(BoostPerk)          BoostVFX.Stop(Self)          PerkApplied = False         BoostOffMSG.Show()     EndIf   EndIf ENDEVENT  4) Add to your script's property the "Perk" you created. 5) Add to your Armor this script: Import Game Spell Property BoostAB Auto  EVENT OnEquipped(Actor akActor)   If ( akActor == GetPlayer() )     akActor.AddSpell(BoostAB, False)  EndIf ENDEVENT  EVENT OnUnequipped(Actor akActor)   If ( akActor == GetPlayer() )     akActor.RemoveSpell(BoostAB)  EndIf ENDEVENT  6) Assign the "Boost Ability Spell" to your Armpr's script. You are done !. Thanks. I tried some methods too, but this one is a bit different. I'll try it out :) And, how about the "player facing a strong enemy" (ie. has higher level)?Do you know the most lightweight method for it? Link to comment Share on other sites More sharing options...
Recommended Posts