Jump to content

Getting a corpse to float above the Ground


jamochawoke

Recommended Posts

Ok I have a scripted event in mind where I want a corpse of an NPC after you kill it and upon activation of the corpse that the corpse will float in the air for a second or two, play a magic shader effect and a sound, and then drop back down to its corpse state.

 

Now I have the onactivation and playing the sound and shader effect down. It looks really good.

 

Yet I can't for the life of me figure out how to get the NPC to float above the ground.

 

Do I use an animation and force an animation on the actor reference?

 

Is there somehow a console command to change an actor's z axis?

 

I've seen it done in a few mods (Midas Magic and Mannimarco Revisited) but after a few hours searching I can't figure out how they did it.

 

Any help would be appreciated and I'll definitely list you as helping me in my mod!

Link to comment
Share on other sites

Ok since apparently nobody knows the answer to that one I went ahead and tried messing with the Z position. There's only one problem... for some reason on death it stretches the model and sends them FLYING! VERY FAR, VERY FAST.

 

Here's what I've got. It's supposed to, on the NPC's death make their corpse rise above the ground steadily for 5 seconds then drop down again. I wish I could YouTube what actually happens... because it's kind of funny. But whatever. What I'd like to know is why this doesn't work :/. NPCRef is the reference to the test NPC.

 

ScriptName CorpseScriptz


short Dead
float timer
float zmove
float endzmove


Begin GameMode

set endzmove to NPCRef.GetPos z

if (Dead == 1)
set timer to getSecondsPassed

if (timer < 5)
	set zmove to NPCRef.GetPos z
	set zmove to zmove + timer
	NPCRef.SetPos z zmove
endif

if (timer > 5)
	NPCRef.SetPos z endzmove
endif
endif

End


Begin OnDeath

if (Dead == 0)
set Dead to 1
endif

End

Link to comment
Share on other sites

set endzmove to NPCRef.GetPos z

 

This part should be in the OnDeath block. Otherwise you're setting this to the corpse's current height every time the GameMode block runs.

 

if (timer < 5)
       set zmove to NPCRef.GetPos z
       set zmove to zmove + timer
       NPCRef.SetPos z zmove
endif

 

This could explain why your corpse flies off so fast. GameMode runs every frame the game is not in a menu. So let's assume the corpse starts out at 0 on the z axis and you get 10 frames per second (just to make the math a bit easier). After the first frame, zmove is 0.1. After the second frame, it's 0.3 (0.1 + 0.2). After the third frame, it's 0.6 (0.3 + 0.3). Then it goes to 1, 1.5, 2.1, 2.8, 3.6, 4.5, and 5.5 in the first second. In the next second, it's 6.1, 7.3, 8.6, 10, 11.5, 13.1, 14.8, 16.6, 18.5, 20.5. As you can see, it keeps going up faster and faster. And this is only assuming you get 10 frames per second, which I'm sure is not the case.

 

 

This script would probably work for your original request:

 

scriptname CorpseScriptZ

short control_var
float startz
float endz
float currentz
float timer

Begin OnActivate

if (control_var > 0)
	Return
endif

if (GetDead)
	set startz to GetPos Z
	set timer to 0
	set control_var to 1
else
	Activate
endif

End

Begin GameMode

if (control_var == 1)
	set timer to (timer + GetSecondsPassed)
	set currentz to (startz + timer)
	SetPos Z currentz
	if (timer >= 5)
		set timer to 0
		set control_var to 2
	endif
	Return
elseif (control_var == 2)
	set timer to (timer + GetSecondsPassed)
	if (timer > = 5)
		set endz to GetPos Z
		set timer to 0
		set control_var to 3
	endif
	Return
elseif (control_var == 3)
	set timer to (timer + GetSecondsPassed)
	set currentz to (endz - timer)
	SetPos Z currentz
	if (timer >= 5) || (startz >= currentz)
		SetPos Z startz
		set timer to 0
		set control_var to 0
	endif
	Return
endif

End

 

I didn't really want to post anything because I'm sure it would look ugly. Much better if it's possible to play an animation. If you find the corpse rising too slowly or not high enough, you can always change it to "set currentz to startz + 2 * timer".

Edited by fg109
Link to comment
Share on other sites

Ok, I used your script.

 

Still sent the NPC FLYING!

 

I decided to look into seeing how Miltiades did it in his Mannimarco mod and he used a pretty convoluted system. You have to loot robes which will give the player an ability with a script which will move Mannimarco's corpse up and dissapear while playing sounds. It's a neat effect but a strange way of doing it. His equations to move the z axis were also similar to my first attempt a few posts up and he even multiplied it by 5 every time he set the z axis... which to me seems crazy from the effects I was getting... But I also noticed he disabled the actor and actor AI and reenabled it on script effect finish. Maybe that has something to do with moving the z axis beings when an NPC actor goes into the death state they are governed by Havok??

 

So I thought I'd try it his way and when my NPC goes into OnDeath state I'd cast a spell with a script containing your script... just to test it out.

 

Nothing happened.

 

Maybe I should resurrect the NPC (it shows a getting up animation when used from script), disable their AI, then try to force the animation to float, then kill them again?

 

I'm just very confused at this point.

Link to comment
Share on other sites

Set a variable to the corpse's z position, then spam 'setpos z' on the corpse, adding a bit to the variable every frame as needed to make it rise; that's how I did it for my corpse carry script. This will have to be in a quest or object script as magic effects get removed from corpses, which means you'll need to set a ref variable to the corpse in question.

Some bodies, for whatever reason, will just flip out and stretch into infinity. There does not seem to be any pattern as to which bodies or the conditions.

Link to comment
Share on other sites

That's weird, I just tried out my script and it worked... after some tweaking. It definitely didn't send the corpse flying off.

 

When I first tried it, nothing happened except for the corpse twitching a couple of times. So I went back to the script and modified the lines to "currentz + 10 * timer", and when I went back, the corpse rose to around head level.

 

I also found out that unlike objects, corpses do fall down if you don't use SetPos every frame. So after 5 seconds, it just dropped onto the floor. So I decided to add in some "RunScriptLine "ToggleActorsAI"" after reading your post, and now it sort of worked. But it wasn't reliable, and sometimes the corpse just fell back onto the ground again. This seemed to happen more when I was indoors or when I kept hitting the corpse while it was floating.

 

So I went back and changed the script again. This time everything seemed to work perfectly.

 

scriptname CorpseScriptZ

short control_var
float startz
float endz
float currentz
float timer

Begin OnActivate

if (control_var > 0)
	Return
endif

if (GetDead)
	set startz to GetPos Z
	set timer to 0
	set control_var to 1
else
	Activate
endif

End

Begin GameMode

if (control_var == 1)
	set timer to (timer + GetSecondsPassed)
	set currentz to (startz + 10 * timer)
	SetPos Z currentz
	if (timer >= 5) || (currentz >= 300)
		set timer to 0
		set control_var to 2
	endif
	Return
elseif (control_var == 2)
	set timer to (timer + GetSecondsPassed)
	SetPos Z currentz
	if (timer >= 5)
		set endz to GetPos Z
		set timer to 0
		set control_var to 3
	endif
	Return
elseif (control_var == 3)
	set timer to (timer + GetSecondsPassed)
	set currentz to (endz - 10 * timer)
	SetPos Z currentz
	if (timer >= 5) || (startz >= currentz)
		SetPos Z startz
		set timer to 0
		set control_var to 0
	endif
	Return
endif

End

 

There's barely any difference from what I posted before. Not sure why it didn't work for you. Did you try making a clean save?

 

EDIT: whalecakes beat me to saying that spamming SetPos every frame is the key.

Edited by fg109
Link to comment
Share on other sites

Ok I just couldn't get your script to work when I embedded it within my NPC's main script.

 

So what I did was OnActivate using (GetDead) I added an ability spell named NPCFloatz with a magic effect script attached named NPCFloat to the player's inventory.

 

The spell has a duration of 20 seconds (giving plenty of time to make it work), is set as ability, and this is the script:

 

scn NPCFloat

short control_var
float startz
float endz
float currentz
float timer


Begin ScriptEffectStart

set startz to NPCRef.GetPos Z
set timer to 0
set control_var to 1

End


Begin ScriptEffectUpdate

NPCRef.SetPos Z currentz

if (control_var == 1)
set timer to (timer + GetSecondsPassed)
set currentz to (startz + (10 * timer))
NPCRef.SetPos Z currentz
if (timer >= 5) || (currentz >= 300)
	set timer to 0
	set control_var to 2
endif
elseif (control_var == 2)
set timer to (timer + GetSecondsPassed)
NPCRef.SetPos Z currentz
if (timer >= 5)
	set endz to NPCRef.GetPos Z
	set timer to 0
	set control_var to 3
endif
elseif (control_var == 3)
set timer to (timer + GetSecondsPassed)
set currentz to (endz - (10 * timer))
NPCRef.SetPos Z currentz
if (timer >= 5) || (startz >= currentz)
	NPCRef.SetPos Z startz
	set timer to 0
	set control_var to 0
endif
endif

End


Begin ScriptEffectFinish

NPCRef.resurrect 1
Player.RemoveSpell NPCFloatz

End

 

I took out the returns because I heard if a magic effect script has a return in the Update section it will never use the Finish section.

 

However... what actually happens is strange.

 

The NPC starts doing cartwheels at me, going faster and faster and faster until it's spinning at a million miles an hour then stretches off to infinity.

 

Also the Ability Spell never wears off, even though it has a duration of 20 seconds (I don't think ability spells ever run down though...) and the EffectFinish is supposed to remove the Ability.

 

 

SO I've learned from this:

 

Using references you can get a magic effect cast on the player to affect an NPC.

 

This still doesn't work for some reason at making them do what I need it to do :/.

Link to comment
Share on other sites

That script was not meant to be used as an ability... I'm not even sure that ScriptEffectUpdate works for an ability (I know ScriptEffectFinish only runs when you remove the ability).

 

As for why you can't use the script I posted on your NPC, I don't know. It could be there's some conflict with the rest of your NPC's script, or it might just be something fundamentally different in our games (some mods maybe).

Link to comment
Share on other sites

Ok I noticed I did something really wrong beings it's an ability script so I fixed it.

 

Now the NPC only does cartwheels but they do resurrect and they FINALLY STOP spinning into infinity lol. Just the cartwheels into the face is so odd (that and sometimes a little dance caused by havok).

 

Is there any way to toggle Havok on/off via script?

 

 

Here's the "working" script:

 

scn NPCFloat

short control_var
float startz
float endz
float currentz
float timer


Begin ScriptEffectStart

set startz to NPCRef.GetPos Z
set timer to 0
set control_var to 1

End


Begin ScriptEffectUpdate

if (control_var == 1)
set timer to (timer + GetSecondsPassed)
set currentz to (startz + 5 * timer)
NPCRef.SetPos Z currentz
if (timer >= 5) || (currentz >= 300)
	set timer to 0
	set control_var to 2
endif
Return
elseif (control_var == 2)
set timer to (timer + GetSecondsPassed)
NPCRef.SetPos Z currentz
if (timer >= 5)
	set endz to NPCRef.GetPos Z
	set timer to 0
	set control_var to 3
endif
Return
elseif (control_var == 3)
set timer to (timer + GetSecondsPassed)
set currentz to (endz - 5 * timer)
NPCRef.SetPos Z currentz
if (timer >= 5) || (startz >= currentz)
	NPCRef.SetPos Z startz
	set timer to 0
	set control_var to 4
endif
Return
elseif (control_var == 4)
Player.RemoveSpell NPCFloatz
NPCRef.resurrect 1
endif

End

Edited by jamochawoke
Link to comment
Share on other sites

  • Recently Browsing   0 members

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