Jump to content

Hanged Man Example


Jebbalon

Recommended Posts

First here is link to My Stuff page - Jebbalon's Stuff
That is where I uploaded an example of how to Hang NPCs in Skyrim. (there's other stuff on the page - or - will be)

Here I'd like to discuss it more, maybe answer questions and offer other uses for the technique used.

Vanilla Skyrim comes with an attempt to provide a method of Hanging NPCs. However, it is not used - because it doesn't work.

Following objects and scripts are involved...
hangedManRopeTRIG [ACTI:00035328]
rigidBodyDummy [MSTT:000D19BA]
fakeForceBallNudge [EXPL:000C800D]
HangedManScript.psc

Spoiler

Scriptname hangedManScript extends objectReference  
{Script for noose ropes.  Point to an attach dummy and a corpse}

objectReference property nooseDummy auto
{Point to a rigidBodyDummy placed at the end of the rope.}
objectreference property corpse auto
{the hung person}
explosion property fakeForceBallNudge auto

bool shotDown

EVENT onLoad()
	; this gets the guy actually hanging when the 3D is loaded up.
	if shotDown == FALSE
		;game.addHavokBallAndSocketConstraint(corpse,"NPC Neck [Neck]",nooseDummy,"AttachDummy",0,0,16)
		game.addHavokBallAndSocketConstraint(corpse,"NPC Neck [Neck]",self,"JointHelper01",0,0,16)
	endif
endEVENT

EVENT onHit(ObjectReference akAggressor, Form akSource, Projectile akProjectile, bool abPowerAttack, bool abSneakAttack, bool abBashAttack, bool abHitBlocked)
; 		debug.trace("Noose Rope Hit by: "+akAggressor)
; 		debug.trace("Noose Rope Hit by: "+akProjectile)
; 		debug.trace("Noose Rope Hit by: "+akSource)
		game.removeHavokConstraints(corpse,"NPC Neck [Neck]",self,"JointHelper01")
		nooseDummy.placeatme(fakeForceBallNudge)
		shotDown == TRUE
endEVENT

 


DefaultWerewolfAttachPointSCRIPT.psc
 

Spoiler

scriptName DefaultWerewolfAttachPointSCRIPT extends objectReference

objectReference property RHand auto
objectReference property LHand auto
;objectReference property RFoot auto
;objectReference property LFoot auto

EVENT onLoad()
	forceAddRagdollToWorld()
	if RHand 
		game.addHavokBallAndSocketConstraint(self,"NPC R Hand [RHnd]",RHand,"AttachDummy",0,0,16)
	endif
	if LHand
		game.addHavokBallAndSocketConstraint(self,"NPC L Hand [RHnd]",LHand,"AttachDummy",0,0,16)
	endif
	;if RFoot
	;	game.addHavokBallAndSocketConstraint(self,"NPC R Foot [Rft ]",RFoot,"AttachDummy")
	;endif
	;if LFoot
	;	game.addHavokBallAndSocketConstraint(self,"NPC L Foot [Lft ]",LFoot,"AttachDummy")
	;endif	
	applyHavokImpulse(0,0,1,10)
endEVENT

 

That last script is what I used to combine with the HangedManScript to make my example mod. It is used on a Werewolf in Gallows Rock - he is hanging by one hand. This works and it was not hard to figure out how to combine the two.

Here is my final script to use on corpses you want to send to the gallows!!

Spoiler

Scriptname HangedManScript_Corrected extends objectReference  
{Script to hang corpse from rope
Attach this script to the corpse}

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Script edited / corrected by Jebbalon - Original is at end.
;;; Major changes are - attaching this script to the corpse instead of
;;; dummy node, the forceAddRagdollToWorld and ApplyHavokImpulse help cure
;;; several problems with dead body actually attaching to the rope.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

objectReference property nooseDummy auto
{Point to the Moveable Static (MSTT) rigidBodyDummy placed at the end of the rope.}

explosion property fakeForceBallNudge auto
{Helps in detatchment from rope.}

bool shotDown

Book Property Letter auto
{Item to be removed from corpse}

EVENT OnLoad()
	; this gets the corpe actually hanging when the 3D is loaded up.
	Self.forceAddRagdollToWorld()
	if shotDown == FALSE
		game.addHavokBallAndSocketConstraint(Self, "NPC Neck [Neck]", nooseDummy, "AttachDummy", 0, 0, 16)
		; tiny nudge is needed on load to force body to jump up to rope - it's a havoc thing
		Self.ApplyHavokImpulse(0.0, 0.0, 1.0, 0.1)
	endif
endEVENT

;;; OPTIONAL - if you want corpse to be shot down - comment out if you want body to stay attached
EVENT onHit(ObjectReference akAggressor, Form akSource, Projectile akProjectile, bool abPowerAttack, bool abSneakAttack, bool abBashAttack, bool abHitBlocked)
		game.removeHavokConstraints(Self, "NPC Neck [Neck]", nooseDummy, "AttachDummy")
		nooseDummy.placeatme(fakeForceBallNudge)
		shotDown = TRUE
endEVENT

;;; OPTIONAL - if you want coprse to drop after removing item from inventory
Event OnItemRemoved(Form akBaseItem, int aiItemCount, ObjectReference akItemReference, ObjectReference akDestContainer)
	AddInventoryEventFilter(Letter)
	If Letter != None && akBaseItem == Letter && shotDown == False
		game.removeHavokConstraints(Self, "NPC Neck [Neck]", nooseDummy, "AttachDummy")
		nooseDummy.placeatme(fakeForceBallNudge)
		shotDown = TRUE
	EndIf
EndEvent

 

 

You'll notice I made comments in some places. The OnHit and OnItemRemoved events are optional - if you just want the hanging you can comment them out. 

OnHit event currently just drops the body but you could add the ApplyHavokImpulse to hit the corpse and make it move instead.

The OnItemRemoved is setup to have a letter placed in inventory and when removed the body drops. You can easily change that to any item, use OnItemAdded instead, or have some other action take place instead of dropping corpse.

Original setup used the activator hangedManRopeTRIG - I think they wanted the cool effect of Robin Hood shooting the rope and saving his friends! But this doesn't work. One reason is that the rope mesh has collision on it. This makes the NPCs head sit all weird and causes it to flip out. In my example mod I used a rope that doesn't have collison DockColStrSignRope01 [STAT:00093480]
As seen in the Werewolf example - it's script is attached to the corpse, not the rope. This works much better. If you still want the Robin Hood effect you could add small collision box around rope and attach an OnHit() script to that.

Now for the other script I included in my example mod.....
 

Spoiler

Scriptname HangedMan_SwayingScript extends ObjectReference 
{Attach this to the dummy node (rigidbodydummy) 
This will add subtle sway to the corpse}

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Written by Jebbalon to go with HangedManScript_Corrected
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Float StartPosX
Float StartPosY
Float StartPosZ
Float StartAngleX
Float StartAngleY
Float StartAngleZ
float afSpeed = 0.1 ; rate of swing
Float Swing = 1.0 ; distance of swing

Event OnCellAttach()
	GoToState("WaitingForLoad")
	RegisterForSingleUpdate(2.5)
EndEvent

Event OnLoad()
	GoToState("WaitingForLoad")
	RegisterForSingleUpdate(2.5)
EndEvent

State WaitingForLoad
	Event OnUpdate()
		If Self.IsDisabled() || (Self.GetDistance(Game.GetPlayer()) > 4000)
			RegisterForSingleUpdate(60.0)
		Else
			StartPosition()
			GoToState("Swaying")
		EndIf
	EndEvent
EndState


State Swaying
	Event OnUpdate()
		if (Self.GetDistance(Game.GetPlayer()) < 4000) && Self.IsEnabled()
			Float CurrentX = Self.GetPositionX()
			If CurrentX == StartPosX || CurrentX == StartPosX - Swing
				Self.TranslateTo(StartPosX + Swing, StartPosY, StartPosZ, StartAngleX, StartAngleY, StartAngleZ, afSpeed, 0.0)
				RegisterForSingleUpdate(1.0)
			ElseIf CurrentX == StartPosX + Swing
				Self.TranslateTo(StartPosX - Swing, StartPosY, StartPosZ, StartAngleX, StartAngleY, StartAngleZ, afSpeed, 0.0)
				RegisterForSingleUpdate(1.0)
			Else
				RegisterForSingleUpdate(2.0)
			EndIf
		Else
			GoToState("WaitingForLoad")
			RegisterForSingleUpdate(60.0)
		EndIf
	EndEvent
EndState


Function StartPosition()
	While Self.Is3DLoaded() == False ; check to avoid papyrus log errors on the move and translate commands
		Utility.Wait(1.0)
	EndWhile
	Self.MoveToMyEditorLocation()
	Utility.Wait(0.5)
	StartPosX = Self.GetPositionX()
	StartPosY = Self.GetPositionY()
	StartPosZ = Self.GetPositionZ()
	StartAngleX = Self.GetAngleX()
	StartAngleY = Self.GetAngleY()
	StartAngleZ = Self.GetAngleZ()
	RegisterForSingleUpdate(3.0)
EndFunction

 

This is attached to the rigidBodyDummy and will translate the node back and forth slightly to simulate the body swaying while hung.

Okay, that's all I have for now. Any questions or comments ?

Thanks all,
-Jebbalon

Link to comment
Share on other sites

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
×
×
  • Create New...