Jump to content

Papyrus Scripting


Gorgopis

Recommended Posts

10 hours ago, xkkmEl said:

Now this is just the start of it... to detect when you hit your target... and can start counting hits.  Well... if I didn't make any typos... or forgot to mention some detail.

thanks. i'll implement this in a fresh plugin and see if it works in game, also no worries about the typos, i'll refine any missing letters, etc without much issues as i edit my scripts in Notepad++ not CK.

Link to comment
Share on other sites

On 3/4/2025 at 1:39 AM, xkkmEl said:

Unless someone has a better idea... what I have in mind is not trivial.

You want to use the OnHit event.  Since this requires a script on the target, we'll use a magiceffect to hold the script, and an ability to start a stable magiceffect:

  1. Create a "script", "constant effect", "self" magic effect.
  2. Create a "ability", "constant effect", "self" spell, and assign it the previously created magiceffect.
  3. Create a 2nd "script", "fire and forget", "contact" magic effect.
  4. Create a "enchantment", "fire and forget", "contact" enchantment, and assign it the 2nd magiceffect.
  5. Add the enchantment to your test weapon.

Now you need to create two scripts, one for each magic effect, then add the script to the magiceffect and populate its properties.

The 1st script, I call "MyHitDetectionMagicEffectScript":

Script MyHitDetectionMagicEffectScript extends ActiveMagicEffect

Spell property	MyHitDetectionSpell	Auto

Actor target = None

event OnEffectStart( Actor akCaster, Actor akTarget)
	target = akTarget
	registerForSingleUpdate( 20.0)
endevent

event OnHit(ObjectReference akAggressor, Form akSource, Projectile akProjectile, bool abPowerAttack, bool abSneakAttack, bool abBashAttack, bool abHitBlocked)
	Debug.messageBox( "Hit on " + target.getDisplayName() + "!")
endevent

event OnUpdate()
	target.removeSpell( MyHitDetectionSpell)
endevent

The 2nd script, I call "MyHitCounterMagicEffectScript":

Script MyHitCounterMagicEffectScript extends ActiveMagicEffect

Spell property	MyHitDetectionSpell	Auto

event OnEffectStart( Actor akCaster, Actor akTarget)
	akTarget.addSpell( MyHitDetectionSpell)
endevent

Now this is just the start of it... to detect when you hit your target... and can start counting hits.  Well... if I didn't make any typos... or forgot to mention some detail.

 

there is a problem with a specific part of the script for detection spell, the event:

event OnHit(ObjectReference akAggressor, Form akSource, Projectile akProjectile, bool abPowerAttack, bool abSneakAttack, bool abBashAttack, bool abHitBlocked)
	Debug.messageBox( "Hit on " + target.getDisplayName() + "!")
endevent

will not be saved/compiled because of an error with the target.getDisplayName().

 

here is an image of the error:

https://www.mediafire.com/view/rd0y0lm5uut595v/123345.png/file

Edited by ThalmorJusticiar7th
Link to comment
Share on other sites

44 minutes ago, xkkmEl said:

Not sure how/why you'd get an error there.

the error says "GetDisplayName()" is not a function (or does not exist). i assume, CK does not recognize getdisplayname as a default function in the game's script, either because the name should be different or maybe because it was never written as a function in game's default script.

 

here is an image of the error (i posted the wrong image in the post above, now i've edited it):

https://www.mediafire.com/view/rd0y0lm5uut595v/123345.png/file

Edited by ThalmorJusticiar7th
Link to comment
Share on other sites

Ishara is almost right. Form.GetName is from SKSE.  However, SKSE also has ObjectReference.getDisplayName.  I use it and it does compile and return a valid string, on LE.

In any case, the direct reference to "target" will be good enough to get started.  It's just a little uglier than getName or getDisplayName. Note however that it does not work well if you replace Debug.messageBox with Debug.notification.

Link to comment
Share on other sites

12 hours ago, xkkmEl said:

Ishara is almost right. Form.GetName is from SKSE.  However, SKSE also has ObjectReference.getDisplayName.  I use it and it does compile and return a valid string, on LE.

In any case, the direct reference to "target" will be good enough to get started.  It's just a little uglier than getName or getDisplayName. Note however that it does not work well if you replace Debug.messageBox with Debug.notification.

so i implemented the script, and tried it in game, when i first hit anybody in the game, it says the hitdetectionspell started, then upon hitting anyone else, instead of it being a simple notification or a stack of the debuff on enemy's hp bar,

 

it instead appears as a prompt in the middle of the screen, and announces the NPC's FormdID instead of its name, take a look:

https://www.mediafire.com/view/em5oaq75xgbowse/ScreenShot343.png/file

 

EDIT: so i just realized, you talked about debug.messagebox & debug.notification. the thing is, a messagebox, aka a prompt, will stop the game to tell you, you have attacked a corresponding NPC, that's obviously not what i want, what i was going for was how to apply a debuff on the opponent, that stacks up to 4, and disappears 1 at a time, after a set duration, so going up from 1 to 4, and then fades away to 3, 2, 1 and then disappears from the opponent after each stack's set duration is over. i did not want a notification or prompt that tells you it is stacking up. how do you think that is achievable in skyrim ?

Edited by ThalmorJusticiar7th
Link to comment
Share on other sites

6 hours ago, xkkmEl said:

Ishara is almost right. Form.GetName is from SKSE.  However, SKSE also has ObjectReference.getDisplayName.  I use it and it does compile and return a valid string, on LE.

In any case, the direct reference to "target" will be good enough to get started.  It's just a little uglier than getName or getDisplayName. Note however that it does not work well if you replace Debug.messageBox with Debug.notification.

I had to dig into an archived copy of SKSE (as the game is not installed), and you are correct. It is on the ObjectReference script. I guess the wiki needs to be updated to include its presence.  Unsure how that works with the backup copy on UESP.

Link to comment
Share on other sites

Oops! 🙂

"Actor 14" is the player.

I got the order of the event parameters wrong.  Change both scripts to use:

Event OnEffectStart(Actor akTarget, Actor akCaster)

Now it should id correctly the victim NPC.

The popup is just to show what events you are detecting.  You'll want to replace the "Debug.messageBox" call with appropriate code to count the hits and buff/debuff your weapon enchantment.  We can tackle that next.

For early debugging, I recommend using "Debug.messageBox" or "Debug.trace".  In this case, I chose the former because it is easier to access, though it is annoying in game.  You can also try replacing it with "Debug.notification" but you'll see that the notification message is truncated and much less informative; it would not have caught my parameter-order-confusion error.

Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...