Jump to content

How to script this?


Prometheus

Recommended Posts

Hello , I created a script set that needs to do the following :

 

 

1 Transform into a new race the NPC if attacked

2 Transform back the NPC into human if the attack stops or if dies or enters bleedout ...

 

 

The problems I am having is that

 

1 When the player starts interaction with the npc attacking it it starts combat then after  when the transformationhappens it stops to fight , instead gets to non aggressive state ...

 

2 IF the player keeps attacking the transformed NPC and reaches the bleedout stage or death stage , the NPC transforms to human but soon after transforms back to monster state....

 

As starting base I used a mix of wolf and vampire transfomations , I created a different race for the monster so I adapted to that .

 

How can I fix those errors?

 

 

This is the first script that is attached to the npc

Scriptname Prom_Wolfwitchtransformation extends Actor  
Quest Property PROM_Wolfwitchgreet Auto 
SPELL Property WolfWitchChange  Auto
SPELL Property WolfWitchChangeback  Auto






Function Transform()
	; do nothing by default
 EndFunction

Function Transformback()
			; do nothing by default
EndFunction


Auto State human
	Function Transform()
		GoToState("wolf")
		StopCombat()
		StopCombatAlarm()
		WolfWitchChange.Cast(self)
		; SetAv("aggression", 3)
		; SetAv("confidence", 4)
		StartCombat(Game.GetPlayer())
	 EndFunction	



	Event OnHit(ObjectReference akAggressor, Form akSource, Projectile akProjectile, bool abPowerAttack, bool abSneakAttack, bool abBashAttack, bool abHitBlocked)
		Transform()
	EndEvent
 
EndState

State wolf

Function Transformback()
			GoToState("human")
			StopCombatAlarm()
			WolfWitchChangeback.Cast(self)
			StopCombat()
EndFunction	

	

	Event OnEnterBleedout()
			Transformback()
  			Debug.Trace("We entered bleedout...")
		 SetAv("aggression", 0) 

	endEvent 

Event OnDeath(Actor akKiller)
  		Debug.Trace("We entered bleedout...")		
			Transformback()
		; SetAv("aggression", 0) 

	endEvent 

Event OnBeginState()
		UnregisterForUpdate() ; being overly cautious
	EndEvent 
EndState

State human
	Event OnBeginState()
		UnregisterForUpdate() ; being overly cautious
	EndEvent
EndState


Event OnLoad()
	RegisterForSingleUpdate(1)
EndEvent


Thenthe other scrit that is instead for the animation fx tranformations

 

one from human to monster

Scriptname Prom_ZelataChange extends activemagiceffect  

VisualEffect property FeedBloodVFX auto
Idle Property IdleVampireTransformation auto
Sound Property NPCVampireTransformation auto
Sound Property NPCVampireTransformationB2D auto
Sound Property NPCVampireTransformationB3D auto
Explosion Property FXVampChangeExplosion auto
Race Property Zelatarace  Auto  
Race Property human  Auto  



Event OnEffectStart(Actor Target, Actor Caster)
    Debug.Trace("VAMPIRE: Starting change anim...")


    if (Target.GetActorBase().GetRace() != Zelatarace  )
		; Add the tranformation wolf skin Armor effect 
		; Target.equipitem(VampireSkinFXArmor,False,True)

		
        RegisterForAnimationEvent(Target, "SetRace")
        Target.PlayIdle(IdleVampireTransformation)
        Utility.Wait(10)
        TransformIfNecessary(Target)
    endif
 


EndEvent


Event OnAnimationEvent(ObjectReference akSource, string asEventName)
    Debug.Trace("VAMPIRE: Getting anim event -- " + akSource + " " + asEventName)
    if (asEventName == "SetRace")
        TransformIfNecessary(akSource as Actor)
    endif
EndEvent

Function TransformIfNecessary(Actor Target)
	if (Target == None)
; 		Debug.Trace("WEREWOLF: Trying to transform something that's not an actor; bailing out.", 2)
		return
	endif

	UnRegisterForAnimationEvent(Target, "SetRace")

	Actor PlayerRef = Game.GetPlayer()

	Race currRace = Target.GetRace()
	if (currRace != Zelatarace  )
; 	Debug.Trace("VAMPIRE: VISUAL: Setting race " + Zelatarace   + " on " + Target)

	if (Target != Game.GetPlayer())
; 			Debug.Trace("WEREWOLF: VISUAL: Target is not player, doing the transition here.")
			Target.SetRace(Zelatarace) ;TEEN WOLF
			target.placeatme(FXVampChangeExplosion)
		if target == PlayerRef
			DLC1VampireChangeStagger.Cast(Target, Target)
		endif
		else
		
        endif
		
    endif
EndFunction

 


SPELL Property DLC1VampireChangeStagger  Auto  

and one from monster to human

Scriptname Prom_ZelataChangeBack extends activemagiceffect  

VisualEffect property FeedBloodVFX auto
Idle Property IdleVampireTransformation auto
Sound Property NPCVampireTransformation auto
Sound Property NPCVampireTransformationB2D auto
Sound Property NPCVampireTransformationB3D auto
Explosion Property FXVampChangeExplosion auto
Race Property Zelatarace  Auto  
Race Property human  Auto  
SPELL Property DLC1VampireChangeStagger  Auto  



Event OnEffectStart(Actor Target, Actor Caster)
    Debug.Trace("VAMPIRE: Starting change anim...")


    if (Target.GetActorBase().GetRace() != human  )
		; Add the tranformation wolf skin Armor effect 
		; Target.equipitem(VampireSkinFXArmor,False,True)		
        RegisterForAnimationEvent(Target, "SetRace")
        Target.PlayIdle(IdleVampireTransformation)
      TransformbackIfNecessary(Target)
    endif


EndEvent


Event OnAnimationEvent(ObjectReference akSource, string asEventName)
    Debug.Trace("VAMPIRE: Getting anim event -- " + akSource + " " + asEventName)
    if (asEventName == "SetRace")
        TransformbackIfNecessary(akSource as Actor)
    endif
EndEvent



Function TransformbackIfNecessary(Actor Target)
	if (Target == None)
; 		Debug.Trace("WEREWOLF: Trying to transform something that's not an actor; bailing out.", 2)
		return
	endif

	UnRegisterForAnimationEvent(Target, "SetRace")

	Actor PlayerRef = Game.GetPlayer()

	Race currRace = Target.GetRace()
	if (currRace != Human)
	if (Target != Game.GetPlayer())
			Target.SetRace(Human) ;TEEN WOLF
			target.placeatme(FXVampChangeExplosion)
		if target == PlayerRef
			DLC1VampireChangeStagger.Cast(Target, Target)
		endif
		else
		
        endif
		
    endif
EndFunction





Link to comment
Share on other sites

Not sure you can change any NPC race this way. Look at DLC1SeranaCureQuestScript.psc script for example, it's explicitly commented by devs :

[snip]
AliasToClear.Clear()
; serana.SetRace(DLC1NordRace) ; whoops, can't do this on NPCs
SetEyes()
[snip]

 

The race change they operate (for both Serana and other vampire thralls making if you follow the Volkihar questline) is not a true race change. It's just a poor eyes texture swapping. I also heard somewhere that werewolf transformation is hardcoded in the exe. Other specialists may confirm, but I guess you cannot achieve what you want (at least in this way). Why not literally changing the NPC ? Something like what the Wabbajack does ?

Link to comment
Share on other sites

Actually my scripts work fine, the only issues I am having are those listed above , must be something in the order of scripting I am not getting ...

Also is not just a texture change but a whole set race change, I Change the npc to another race and then shoudl get back to human when the conditions apply.

Link to comment
Share on other sites

Bit why it transforms to human and soon after back again to monster?

 

OnHit may fire with some delay, maybe right after transforming back. To avoid this, add a check to the OnHit event like so:

 

If IsDead == false

   Transform()

endIf

 

You probably also need to add an OnLoad event to Human state, to make sure that actors have the correct race. If an actor unloads for whatever reason while still in combat, the script reloads in auto state = Human, so the state is right but the race may still be wrong. Forget this.

 

EDIT: If an actor unloads while in wolf state, the player is obviously not around (he wouldn't unload otherwise), so he's almost certainly not in combat with the player either. In hat case, he should probably transform back. Can't do that when unloaded though, so I added a tracking bool to do it on next load.

 

While you're at t, throw everything out that is related to update registrations. There is no OnUpdate event anywhere on that script, and thus no need to register/unregister for updates either.

Link to comment
Share on other sites

there is already an onload

 

... but in empty state. And it doesn't do anything that is needed for this script to run.

Link to comment
Share on other sites

Try this one:

Scriptname Prom_WolfWitchTransformation extends Actor  

Actor Property PlayerRef Auto
Quest Property PROM_Wolfwitchgreet Auto 
Spell Property WolfWitchChange Auto
Spell Property WolfWitchChangeback Auto


bool bTransformBackOnLoad = false


Auto State Human
	Event OnHit(ObjectReference akAggressor, Form akSource, Projectile akProjectile, bool abPowerAttack, bool abSneakAttack, bool abBashAttack, bool abHitBlocked)
		if !IsDead()
			Transform()
		endIf
	EndEvent
EndState


State Wolf

	Event OnLoad()
		if bTransformBackOnLoad
			bTransformBackOnLoad = false
			TransformBack()
		endIf
	EndEvent

	Event OnEnterBleedout()
  		Debug.Trace("We entered bleedout ...")
		TransformBack()
		SetAv("aggression", 0) 
	EndEvent 

	Event OnDeath(Actor akKiller)
  		Debug.Trace("We are dead ...")
		TransformBack()
		;SetAv("aggression", 0) 
	EndEvent 

	Event OnUnload()
		Debug.Trace("Unloading while in 'wolf' state ...")
		bTransformBackOnLoad = true
	EndEvent

EndState


Function Transform()
	GoToState("Wolf")
	StopCombat()
	StopCombatAlarm()
	WolfWitchChange.Cast(self)
	; SetAv("aggression", 3)
	; SetAv("confidence", 4)
	StartCombat(PlayerRef)
EndFunction


Function TransformBack()
	GoToState("human")
	StopCombatAlarm()
	WolfWitchChangeback.Cast(self)
	StopCombat()
EndFunction 

I can't guarantee that it will work fine though. Just modified what came to my mind as requiring a modification.

Link to comment
Share on other sites

Now what happens is that when the npc transfroms to the creature, it sudden retransforms back into human and its entering a loop of transform and retransform .

Link to comment
Share on other sites

Aha.

 

Please modify the OnUnload event as follows and test it again (just add a semicolon to the 'bTransformBackOnLoad: = true' line to comment it out for the time being):

Event OnUnload()
   Debug.Trace("Unloading while in 'wolf' state ...")
   ;bTransformBackOnLoad = true
EndEvent

I'm getting an idea what happens here but it requires some testing.

Link to comment
Share on other sites

No loop this time but she reverts back to Monster .

 

 

Here is another change I did to the scripts , this time works but , The problem is that beeing in the autostate humanfinal it doesn't transform back to monster if attacked again !

Scriptname Prom_Wolfwitchtransformation extends Actor  
Quest Property PROM_Wolfwitchgreet Auto 
SPELL Property WolfWitchChange  Auto
SPELL Property WolfWitchChangeback  Auto
Faction Property Hyborianhutfaction  Auto  
Actor Property wolf  Auto  



Function Transform()
	; do nothing by default
 EndFunction

Function Transformback()
			; do nothing by default
EndFunction

 
Auto State human
	Function Transform()
		GoToState("Demivampire")
		StopCombat()
		StopCombatAlarm()
		WolfWitchChange.Cast(self)
		SetAv("aggression", 3)
		SetAv("confidence", 4)
		StartCombat(Game.GetPlayer())
	 EndFunction	 



	Event OnHit(ObjectReference akAggressor, Form akSource, Projectile akProjectile, bool abPowerAttack, bool abSneakAttack, bool abBashAttack, bool abHitBlocked)
		if akAggressor == game.getPlayer()		
			wolf.SetAv("aggression", 3) 

			if PROM_Wolfwitchgreet.GetStage()<20
				Transform()
				PROM_Wolfwitchgreet.SetStage(20)
			elseif (PROM_Wolfwitchgreet.GetStage()<35) && (PROM_Wolfwitchgreet.GetStage()>=20)
				PROM_Wolfwitchgreet.SetStage(22)
			elseif PROM_Wolfwitchgreet.GetStage()==35
				PROM_Wolfwitchgreet.SetStage(45)
			elseif PROM_Wolfwitchgreet.GetStage()==40
				PROM_Wolfwitchgreet.SetStage(45)


			
			endIf
		endIf
	EndEvent
 
EndState

State Demivampire

Function Transformback()
			GoToState("humanfinal")
			StopCombatAlarm()
			WolfWitchChangeback.Cast(self)
			StopCombat()
EndFunction	
 
Event OnEnterBleedout()
			Transformback()
  			;Debug.Trace("We entered bleedout...")
			SetAv("aggression", 0) 
Debug.SendAnimationEvent(self, "BleedOutStart")
			Utility.Wait(5.0)
Debug.SendAnimationEvent(self, "BleedOutStop")
	endEvent 

Event OnDeath(Actor akKiller)
  		;Debug.Trace("We entered bleedout...")		
			Transformback()
		; SetAv("aggression", 0) 
			Game.GetPlayer().AddToFaction(Hyborianhutfaction)			
			wolf.RemoveFromFaction(Hyborianhutfaction)			
			wolf.SetAv("aggression", 3) 


	


	endEvent 

	; Event OnCombatStateChanged(Actor akTarget, int aeCombatState)
  			; if (aeCombatState == 0)
			; 	if (PROM_Wolfwitchgreet.GetStage()<=35)
				; 		Transformback()
				; 		SetAv("aggression", 0) 
			; 	endIf
  		; 	endIf


	; endEvent 


 

EndState

State humanfinal
		Event OnBeginState()
		UnregisterForUpdate() ; being overly cautious
		EndEvent
 EndState


Event OnLoad()
	RegisterForSingleUpdate(1)
EndEvent


Link to comment
Share on other sites

also I wanted that when she enters bleedout she asks mercy and asks the player to spare her , but not sure how to , I tried to force the bleedout but she doesnt go into that animation loop .

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...