Jump to content
Omny87

Need Help With Scripting A Skeletonizing Mod!

Recommended Posts

So I'm working on a mod that will turn human NPCs into charred skeletons when killed via energy weapons. I've got the skeleton models all ready to go, but now I need to actually make the scripts.

 

So what I have at the moment are a set of non-playable "outfits" that, when equipped to an NPC, makes them turn into a charred skeleton. I've tested these outfits in-game and they look fine. The only thing I need to do now is work on the script itself.

 

That's where I've hit a snag. I have no idea what the hell I'm doing when it comes to scripting. I know what I WANT to happen- I want this script to do the following three things:

 

  1. Detect if an NPC is killed via an energy weapon
     
  2. If they are (and they're not essential), to apply the classic laser-burning effect upon death
     
  3. add and equip the skeleton outfit to their inventory, so it looks like they've been skeletonized

 

The trouble is, I can't translate that into a script form, and I'm completely at a loss. I've tried looking on the GECK wiki and looking at other similar scripts, but it's all gobbledegook to me. Can anyone more fluent in script language lend me any kind of help in this regard?

 

(Before you ask, yes I have seen the EVE mod. It almost does what I want, but personally I find it adds a bit too much needless stuff that I can't easily get rid of without breaking it entirely)

 

 


 

Share this post


Link to post

I've been looking into it and it seems pretty straight forward. I'm just stumped on the actual details.

 

Like, what I'm trying to figure out is if there's a specific script function for detecting if a human is killed via a particular energy weapon, so I can apply the death effect afterwards. Like a "GetIsKilledByLasers" or something like that. I've been sifting through the GECK wiki and the closest thing I've found is "GetCauseOfDeath", but that doesn't work the way it sounds.

 

Or am I going at this the wrong way?

Share this post


Link to post

Dropping a couple of thoughs. I never tried it but this is what I'd try to do.

 

I would first use an event to detect the death. Doctasax made a tutorial to show how to use them, it should be reachable from that page, it also should be here in LL somewhere. If you have troubles we try to set it together.

One death event is on NVSE, the OnDeath.

Another is on JohnnyGuitar plugin, OnDyingEventHandler

During the event it should be possible to retrieve the killer.

It's then possible to retrieve the weapon of the killer

And with the known weapon, it should be possible to understand if it's an energy weapon.

Share this post


Link to post

Ah, now we're getting somewhere!
 

Although I should note that I ultimately want this mod to drop different-colored skeletons depending on the type of energy weapon- red ones for lasers, green for plasma, black for fire, and blue for electrical (pulse gun, tesla cannon, arc welder, etc).

 

Here are the skeletons in question so you can see what I mean:

image.png.26eb38b11464559bdefa867b3e5d5475.pngimage.png.da6df169d3f4d944eb95c55f059a72b7.pngimage.png.785c14cb57270252583a61d15ec44ea3.pngimage.png

 

Although, now that I look again, I see there's a command called "IsInList", which checks to see if something's in a particular form list. Maybe I could make a few form lists that include the weapons I want?

 

 

Share this post


Link to post
4 hours ago, Omny87 said:

Although, now that I look again, I see there's a command called "IsInList", which checks to see if something's in a particular form list. Maybe I could make a few form lists that include the weapons I want?

 

 

Yes. It's just a method I personally tend to not use because it implies that every weapon mod would require a patch. Another though: what happens when the game will attach a ashpile instead? I think it's another thing to take in account. And last, did you try to equip that skeleton to a dead enemy? even just using the console, in game.

Share this post


Link to post
18 hours ago, A.J. said:

Yes. It's just a method I personally tend to not use because it implies that every weapon mod would require a patch.

I suppose, but I'm making this mod more for myself than anyone else. If other people want to add other weapons they can use FNVEdit to add their weapon to the appropriate list easily.

 

Quote

Another though: what happens when the game will attach a ashpile instead? I think it's another thing to take in account.

You mean a critical kill? I thought about just keeping it as-is, but I'd personally rather have it always result in skeletons. I'll cross that bridge when I get to it.

 

Quote

And last, did you try to equip that skeleton to a dead enemy? even just using the console, in game.

Yes I have, and they work just as I had hoped!

 

Funny enough, even when they're skeletonized, their main clothes disappear but some accessory-type clothing (hats, masks, backpacks, etc) remain, which is pretty funny to see (I don't have screenshots sadly). I'm gonna mess around with the outfits a bit to see if I can have them still wearing all their clothes afterwards.

Share this post


Link to post

Alright, here's my latest attempt at making this script work:


 

Quote

 

ScriptName OMNYLaserSkeletonizerScript

;Human NPCs hit with lasers will be turned into red skeletons

 

scn OnDyingUDF

 

ref rActor

 

begin SetJohnnyOnDyingEventHandler

 

    if IsHitWith OMNYListOLasers
    PMS LaserCritGlowFXShader
    PMS effectLaserDisintegration
    Set Timer to 1.8
    Set DoOnce to 0
    additem OMNYLaserSkellySuit 1
    equipitem OMNYLaserSkellySuit 1
    endif

end

 

The "OmnyListOLasers" is a form list containing all the laser-type energy weapons. I also took a few lines from the vanilla Laser Disintegration Effect script so that it would be applied here as well.

 

It doesn't seem to want to save though; so I'm definitely missing something. What am I doing wrong?

Share this post


Link to post

EDIT: I've also tried this smaller, simpler script here:

 

 

ScriptName OMNYLaserSkeletonizerScript

ref rActor

Begin OnHitWith == WeapLaserPistol

    If rActor.GetIsCreature == 0
        additem OMNYLaserSkellySuit 1
        equipitem OMNYLaserSkellySuit 1
    endif

end

It actually saves, but in-game, doesn't do anything. It should turn people into skeletons whenever they get shot with the laser pistol, but nothing happens. I've double-checked the laser pistol itself and the outfits and they both work fine. I am so fucking confused! What am I missing?

Share this post


Link to post
5 hours ago, Omny87 said:

ScriptName OMNYLaserSkeletonizerScript

ref rActor

Begin OnHitWith == WeapLaserPistol

    If rActor.GetIsCreature == 0
        additem OMNYLaserSkellySuit 1
        equipitem OMNYLaserSkellySuit 1
    endif

end

It actually saves, but in-game, doesn't do anything. It should turn people into skeletons whenever they get shot with the laser pistol, but nothing happens. I've double-checked the laser pistol itself and the outfits and they both work fine. I am so fucking confused! What am I missing?

Documentation says that OnHitWith blocktype should run on a specific actor reference. So, if you create a specific npc, and attach to it a script like this, then that npc should turn to a skeleton. It's not the best choice for your case.

Also rActor is not defined anywhere, so the first IF statement isn't really good. If you're lucky it will resolve with 0 == 0 then will execute the two lines later.

Share this post


Link to post

Regarding the first script, I'd suggest reading few basics of scripting first. Without these, it'll be hard to even debug where the problem is.

 

Anyway:

- SCN is the shortcut of ScriptName, so you're writing it twice

- An Event handler has a block type named Function, so its header should be something like:

begin Function {rActor}

 

- That "SetJohnnyOnDyingEventHandler" is the declaration of the event handler, it must be introduced on another script, for example a quest script, something that runs on its own everytime that you go in game.

So you create a quest and you attach a script like this:

Scn MyQuestScript

 

Begin GameMode

   If GetGameLoaded

       SetJohnnyOnDyingEventHandler 1 OnDyingUDFOrWhateverScriptNameYouGaveIt 0

   endif

end

 

- Do you have a link for that IsHitWith function? Where it comes from?

Share this post


Link to post

Okay, after a bit of re-reading and cracking open other, similar mods, I changed it to this:


 

ScriptName OMNYLaserSkeletonizerScript

ref rActor

Begin OnHit

    Set rActor to Player.GetOwnerLastTarget
    
    If rActor.GetIsCreature == 0
        additem OMNYLaserSkellySuit 1
        equipitem OMNYLaserSkellySuit 1
    EndIf
end

And I attached this script to the laser pistol itself (it's not ideal nor is it what I'm going for, I just want some goddamn results).

 

Still nothing happens in game.

 

sigh...

 

This has gone from frustrating to depressing. I know exactly what I want this script to do, but nothing I do works. I don't want to just give up or beg someone else to write the script for me. I just can't seem to wrap my head around more than the bare-bones basics of scripting.

Share this post


Link to post
Quote

Regarding the first script, I'd suggest reading few basics of scripting first. Without these, it'll be hard to even debug where the problem is.

I've been trying. Beyond the very basic stuff I'm failing to grasp the more complex aspects of scripting. Still, I want to do this myself so I'll press on.

 

21 minutes ago, A.J. said:

Anyway:

- SCN is the shortcut of ScriptName, so you're writing it twice

- An Event handler has a block type named Function, so its header should be something like:

begin Function {rActor}

Yeah, I've spoken with a couple people over on the Nexus forums and they pointed out the same problem.

 

Quote

 

- That "SetJohnnyOnDyingEventHandler" is the declaration of the event handler, it must be introduced on another script, for example a quest script, something that runs on its own everytime that you go in game.

So you create a quest and you attach a script like this:

Scn MyQuestScript

 

Begin GameMode

   If GetGameLoaded

       SetJohnnyOnDyingEventHandler 1 OnDyingUDFOrWhateverScriptNameYouGaveIt 0

   endif

end

 

Like this?

 

scn OMNYSkellyQuestScript

Begin GameMode

   If GetGameLoaded

       SetJohnnyOnDyingEventHandler 1 OnDyingOMNYLaserSkeletonizerScript 0

   endif

end 

 

Quote

- Do you have a link for that IsHitWith function? Where it comes from?

That was a typo- it was supposed to be "OnHitWith". Doesn't work either way.

Share this post


Link to post
18 minutes ago, Omny87 said:

That was a typo- it was supposed to be "OnHitWith". Doesn't work either way.

Because that's a block type and not a function. I don't usually script about weapons so I can be wrong, but I don't think there's a function to do that, hence why in the fourth post I did all these passages to retrieve the killer, then check the form of the weapon he was wearing, and then if it was an energy weapon. If there's something shorter and faster, even better.

EDIT: also, maybe if you link the thread on nexus we could stick the answers all in the same place

Share this post


Link to post

Ooooooh, I'm so close I can almost TASTE it!

 

So I took your advice and made a second quest script, along with a quest to attach it to, "OMNYSkellyQuest".

 

The Quest script is thus:

ScriptName OMNYSkellyQuestScript

Begin GameMode

    If GetGameLoaded

    SetJohnnyOnDyingEventHandler 1 OMNYLaserSkeletonizerScript 0

    endif

end

Then, after looking at the Fatigue Damage script for the Boxing Gloves, I took a page from that and worked it into the main script:


 

ScriptName OMNYLaserSkeletonizerScript

;Turns human enemies into red skeletons when hit by lasers.

Begin OnHit
    
    ref rActor
    Set rActor to GetOwnerLastTarget

    If PlayerREF.IsWeaponInList OMNYListOfLasers
        If (rActor != PlayerRef) && (rActor.GetIsCreature == 0)
            If rActor.IsKiller Player
                additem OMNYLaserSkellySuit 1
                equipitem OMNYLaserSkellySuit 1
            EndIf
        EndIf
    EndIf
end

Both of them saved just fine in the GECK, but in-game is where things got interesting.

 

There was no effect when I killed someone with a laser pistol, but this time, when I opened up the console, there was an error message this time!

Quote

 

Error in Script 3800137A (the skeletonizer script)

Could not look up argument variable for function script

 

So yeah, this was another flop, but at least this time the game is actually acknowledging it! I think it just needs a bit more retooling and it might actually work!

 

Share this post


Link to post

try deleting your second script and make a script like this instead (the quest script instead is fine, keep it):

scn OMNYLaserSkeletonizerScript

ref rActor
ref rKiller
ref rWeap

begin Function {rActor} 

	Print "The event fired"
	set rKiller to rActor.GetKiller
	set rWeap to rKiller.GetEquippedObject 5

	if rWeap.IsWeaponInList OMNYLaserSkellySuit
		Print "the killer's weapon is eligible"
		if (rActor != PlayerRef) && (rActor.GetIsCreature == 0)
			Print "the victim is eligible"
			rACtor.additem OMNYLaserSkellySuit 1
			rACtor.equipitem OMNYLaserSkellySuit 1
		endif
	endif

end

Do not attach it to anything, just leave it as object script and compile and save, the quest script will register it. If things are working, you should see those Print lines in console, it helps understanding what's happening.

Share this post


Link to post

Well I tested it out (had to change the IsWeaponInList to point to OMNYListOfLasers though); saves just fine.

 

In-game I tested it out- I killed an NPC with all the weapons in my laser list (laser pistol/rifle/RCW, gatling laser, etc) and though the text "the event fired" appeared, "the victim is eligible" did not.

 

It also appeared when I killed a Bighorner, so it doesn't seem like it's registering the part where it detects if they're a human. Gonna have to retool those lines I think.

 

On a side note, I just want to thank you a bunch, A.J. I've been tearing my hair out over this all week and you're one of the few people who's offered some solid advice and assistance.

 

EDIT: IT WORKS!

image.png.064593e3286c8ffb3c3a0d2b7acd3d84.png

 

Alright, so here's what I did:

 


 

scn OMNYLaserSkeletonizerScript

ref rActor
ref rKiller
ref rWeap

begin Function {rActor}

    Print "The event fired"
    set rKiller to rActor.GetKiller
    set rWeap to rKiller.GetEquippedObject 5

    if rKiller.IsWeaponInList OMNYListOfLasers
        Print "the killer's weapon is eligible"
        if (rActor.GetIsCreature == 0) && (rActor != PlayerRef)
            Print "the victim is eligible"
            rActor.additem OMNYLaserSkellySuit 1
            rActor.equipitem OMNYLaserSkellySuit 1
        endif
    endif
end

 

I changed the line "if rWeap.IsWeaponInList OMNYLaserSkellySuit" to "if rKiller.IsWeaponInList OMNYListOfLasers" so that it registers the killer and what weapon they're holding, rather than the weapon itself.

 

Now I just need to figure out how to apply the disintegration effect on top of that. Holy shit I'm so excited :D

Share this post


Link to post

UPDATE: Been tooling around with the disintegration glow effects; only trouble I'm having is keeping the glowing texture effects from persisting after death, resulting in skeletons/accessories still translucent and glowing.

 

Another unforeseen snag I've found is with the skeletons themselves:

 

image.png.ac0ff458afe4f1c0f557fbc92ef3ec14.png

 

Its seems that the skeletons don't play well with dismemberment. That big ball of bones on the left there is supposed to be that guy's head, having popped off after I shot him with a Tri-Beam Laser Rifle. Definitely going to have to fix that somehow.

 

limbs will also burst into bloody bits of gore like in the vanilla game if struck with blunt force. I wonder if there's a way to just disable dismemberment effects for skeletons only.

Share this post


Link to post
8 hours ago, Omny87 said:

Well I tested it out (had to change the IsWeaponInList to point to OMNYListOfLasers though); saves just fine.

 

In-game I tested it out- I killed an NPC with all the weapons in my laser list (laser pistol/rifle/RCW, gatling laser, etc) and though the text "the event fired" appeared, "the victim is eligible" did not.

 

It also appeared when I killed a Bighorner, so it doesn't seem like it's registering the part where it detects if they're a human. Gonna have to retool those lines I think.

 

On a side note, I just want to thank you a bunch, A.J. I've been tearing my hair out over this all week and you're one of the few people who's offered some solid advice and assistance.

 

EDIT: IT WORKS!

image.png.064593e3286c8ffb3c3a0d2b7acd3d84.png

 

Alright, so here's what I did:

 


 


scn OMNYLaserSkeletonizerScript

ref rActor
ref rKiller
ref rWeap

begin Function {rActor}

    Print "The event fired"
    set rKiller to rActor.GetKiller
    set rWeap to rKiller.GetEquippedObject 5

    if rKiller.IsWeaponInList OMNYListOfLasers
        Print "the killer's weapon is eligible"
        if (rActor.GetIsCreature == 0) && (rActor != PlayerRef)
            Print "the victim is eligible"
            rActor.additem OMNYLaserSkellySuit 1
            rActor.equipitem OMNYLaserSkellySuit 1
        endif
    endif
end

 

I changed the line "if rWeap.IsWeaponInList OMNYLaserSkellySuit" to "if rKiller.IsWeaponInList OMNYListOfLasers" so that it registers the killer and what weapon they're holding, rather than the weapon itself.

 

Now I just need to figure out how to apply the disintegration effect on top of that. Holy shit I'm so excited :D

EDIT: no way, you did good. Never script when you're tired... (and I'm here at night when I'm so tired).

So, sorry.

 

Then you don't even need to retrieve rWeap, you can delete that Set rWeap to rKiller.GetEquipped etc.etc. since it's not necessary. It was intended if you were using IsInList instead. Another mistake from my part.

 

Also, all the prints are for debug, once you see everything works you can delete them too

 

 

Share this post


Link to post

About the dismember, I guess it's because the mesh itself. Where did that skeleton comes from? because I suppose if dismemberment was made correctly then it had to have a skull on the head, not the torso, it's like if they have assigned vertices to the wrong parts. But maybe being an armor... I don't know...

Share this post


Link to post

"I wonder if there's a way to just disable dismemberment effects for skeletons only. "

Maybe if all the vertices of the skeleton are assigned to Torso

Share this post


Link to post
Quote

Then you don't even need to retrieve rWeap, you can delete that Set rWeap to rKiller.GetEquipped etc.etc. since it's not necessary. It was intended if you were using IsInList instead. Another mistake from my part.

Yeah, I noticed a few errors there in your suggested script, but I managed to fix them. Don't worry about it- if anything, I feel slightly more confident about scripting than I did before fixing them.

 

Quote

Where did that skeleton comes from?

Well the skeleton suits have four parts each- the armor (the body with no head or hands) and an attached form list of three armor addons (the head and left/right hand). As for where I got it, I took the models from the Skully the Skeleton Companion Mod and added my own textures to them.

 

Though I think I may have to remake the skeletons, as I recently noticed there's some weird mesh distortion caused by a couple missing bones (specifically the left forearm-twist bone and hand bone). I'll see if I can fix them.

 

Quote

Maybe if all the vertices of the skeleton are assigned to Torso

I've also found that if you select "No Dismemberment/explode" on the weapons themselves, they won't cause any dismemberment. Of course, that would involve editing all the energy weapons and possibly causing conflicts with other mods. I'll see if there's a way to apply that anti-dismemberment across the board via scripts, or at least to skeletons. Maybe there's a way to make corpses immune to dismemberment if they're wearing certain outfits?

Share this post


Link to post

UPDATE: Well, after a bit of fussing about in Nifskope I finally managed to get the dang dismemberment working, as well as fix a couple weird mesh issues with missing bones:

s3w1tox.jpg


It just needs a bit more polish regarding the effect shaders. What I'd prefer is that when an NPC dies, their body goes all glowy and disintegrated, and then gets replaced by a skeleton, to make it look like there's an actual transition between being fleshy and not-fleshy.

Whether that's possible is another bridge to cross later- right now I'm just trying to fix this one annoying little visual bug:

skZpEFS.jpg

Right after the effect shaders do their thing and the skeleton ragdolls on the ground, the body suddenly becomes transparent like this for about 1 second, and then snaps back to being opaque. I think it has something to do with the timer function in the scripts; I'm trying to figure it out myself.

 

I also noticed that, for some reason, the first line of my debug text shows up three times in the console:

 

f9dxCAz.jpg

Not sure what the deal is there. Mayhaps this and the previous bug are related?

 

I'll try to figure this out on my end. Here's what I got so far with the laser skeletonizer script if anyone wants to give it a look-over:

scn OMNYLaserSkeletonizerScript

Float Timer
Short DoOnce
ref rActor
ref rKiller

begin Function {rActor}

	Print "The event fired"
	set rKiller to rActor.GetKiller

	if rKiller.IsWeaponInList OMNYListOfLasers
		Print "the killer's weapon is eligible"
			if (rActor.GetIsCreature == 0) && (rActor != PlayerRef)
				Print "the victim is eligible"
				rActor.PMS LaserCritGlowFXShader 1.8
				rActor.PMS effectLaserDisintegration 1
				rActor.additem OMNYLaserSkellySuit 1
				rActor.equipitem OMNYLaserSkellySuit 1
				Set Timer to 1.8
				Set DoOnce to 0
			endif
	Print "welcome to the bone zone"
		If Timer <= 0.5
			rActor.SMS LaserCritGlowFXShader
			rActor.SMS effectLaserDisintegration	
			Set DoOnce to 1
		EndIf
	endif
end

Share this post


Link to post

You can use ; to skip lines, i.e. :

; This line won't be read by the game

So you can easily put ; in front of some lines of the script to narrow down the problem.

 

Now the first important question is: was the event firing 4 times since the begin? because if it was then you would have probably noticed it, but you never mentioned it.

 

And second, the timer doesn't work on a function which is executed in a single frame, it can't calculate the time since it leasts 0.02 seconds

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...