Jump to content

OnHit Event delay , unknown reason .


SugarSteak

Recommended Posts

Holle Guys , poor English hope you don't mind . :pinch:

 

Situation description :

For my a combat MOD http://www.nexusmods.com/skyrim/mods/58717 , I am making a new version .
When I am during the test, I found the OnHit Event script on NPC appeared about one or two seconds delay for no reason, but it will be run immediately without delay on the player.

 

The part of related delay code :

 

Event OnEffectStart(Actor akTarget, Actor akCaster)
PlayerRef = Game.GetPlayer()
HitTarget = akTarget
RegisterForSingleUpdate(1.0)
RegisterForAnimationEvent(HitTarget,"StaggerStart")
RegisterForAnimationEvent(HitTarget,"StaggerStop")
RegisterForAnimationEvent(HitTarget,"WeaponSwing")
RegisterForAnimationEvent(HitTarget,"AttackStop")
EndEvent
;These are the delay code
Event OnHit(ObjectReference akAggressor, Form akSource, Projectile akProjectile, bool abPowerAttack, bool abSneakAttack, bool abBashAttack, bool abHitBlocked)
If !(akSource as Spell || akSource as Explosion || akSource as Ingredient || akSource as Potion || akSource as Enchantment )
If HitTarget.IsDead()==false
Debug.SendAnimationEvent(HitTarget,"AttackStop")
Debug.SendAnimationEvent(HitTarget,"BlockStop")
Debug.SendAnimationEvent(HitTarget,"StaggerStart")
EndIf
EndIf
EndEvent

 

A part of log show:

 

[None]._CM_OnHitScript.OnEffectFinish() - "_CM_OnHitScript.psc" Line ?

[01/11/2015 - 02:17:01AM] Error: Unable to call RegisterForSingleUpdate - no native object bound to the script object, or object is of incorrect type
stack:
[None]._CM_OnHitScript.RegisterForSingleUpdate() - "<native>" Line ?
[None]._CM_OnHitScript.OnEffectStart() - "_CM_OnHitScript.psc" Line ?
[01/11/2015 - 02:17:01AM] Error: Unable to call RegisterForAnimationEvent - no native object bound to the script object, or object is of incorrect type
stack:
[None]._CM_OnHitScript.RegisterForAnimationEvent() - "<native>" Line ?
[None]._CM_OnHitScript.OnEffectStart() - "_CM_OnHitScript.psc" Line ?
[01/11/2015 - 02:17:01AM] warning: Assigning None to a non-object variable named "::temp7"
stack:
[None]._CM_OnHitScript.OnEffectStart() - "_CM_OnHitScript.psc" Line ?
[01/11/2015 - 02:17:01AM] Error: Unable to call RegisterForAnimationEvent - no native object bound to the script object, or object is of incorrect type

These error repeated a lots , don't know if these error is the reason for the delay, or perhaps it's just another sign of real causes of delay? Or they are not related ?

 

 

And, In the old version (1.42), there is a almost same script , but no this bug . :confused:

What's the problem >_<

 

 

PS: I can't upload my script , how to do it ?

Edited by SugarSteak
Link to comment
Share on other sites

 

 

PS: I can't upload my script , how to do it ?

Copy paste the script code rather than upload it.

 

Use the following, remove the hyphens before posting.

 

[-spoiler]

[-code]

*paste script code here*

[/code-]

[/spoiler-]

 

Should look like the following:

 

 

 

*paste script code here*

Edited by IsharaMeradin
Link to comment
Share on other sites

	@IsharaMeradin	 

Scriptname _CM_OnHitScript extends activemagiceffect  ; Not only hit event , include most functions

Actor HitTarget
Float TargetMass
Float ArmorWeight = 0.0
Armor EvaluateArmor 
Int i 
Bool StaggerStopped = false
Float LastAttack = 0.0
Float CurrentAttack
Int Wound = 0
Int Hurt = 0
Actor PlayerRef
Bool b
Bool WoundInformed = false
Int SleptTime
Int WaitedTime
Float StaggerTimeCopy
Float Pain = 0.0
Bool StartTimers = false
Bool ShouldNumb = true
Int BlockSkill
Int BlockValue
Int BaseBlockValue
Bool KillDeferred = false
Bool DesperationTriggered = false
Bool BeAttacked = false
Actor Aggressor
;NPC Dodge
Actor Attacker
Actor DodgeActor
Bool Dodged = false
KeyWord Property NPC Auto
;Consecutive Hits
Int Hits = 0

Event OnEffectStart(Actor akTarget, Actor akCaster)

	PlayerRef = Game.GetPlayer()
	HitTarget = akTarget
	Attacker = akTarget 
	TargetMass = HitTarget.GetActorValue("mass")
	BlockSkill = HitTarget.GetActorValue("Block") as Int
	GotoState("InitBaseBlockValue")

		i = 61
		While i >= 30
			EvaluateArmor = HitTarget.GetWornForm(Armor.GetMaskForSlot(i)) as Armor
			If EvaluateArmor != None
				ArmorWeight += EvaluateArmor.GetWeight()
			EndIf
			i -= 1
		EndWhile
	RegisterForSingleUpdate(1.0)
	RegisterForAnimationEvent(HitTarget,"StaggerStart")
	RegisterForAnimationEvent(HitTarget,"StaggerStop")
	RegisterForAnimationEvent(HitTarget,"WeaponSwing")
	RegisterForAnimationEvent(HitTarget,"AttackStop")

	RegisterForAnimationEvent(Attacker,"WeaponSwing")

EndEvent

Event OnObjectUnequipped(Form akBaseObject, ObjectReference akReference)
		ArmorWeight = 0.0
		i = 61
		While i >= 30
			EvaluateArmor = HitTarget.GetWornForm(Armor.GetMaskForSlot(i)) as Armor
			If EvaluateArmor != None
				ArmorWeight += EvaluateArmor.GetWeight()
			EndIf
			i -= 1
		EndWhile
		If akBaseObject as Armor
			Armor UnEquippedShield = akBaseObject as Armor
			If UnEquippedShield.IsShield()  
				GotoState("InitBaseBlockValue")
			EndIf
		ElseIf akBaseObject as Weapon
			GotoState("InitBaseBlockValue")
		EndIf
EndEvent

Event OnObjectEquipped(Form akBaseObject, ObjectReference akReference)
	Utility.Wait(0.5)
		ArmorWeight = 0.0
		i = 61
		While i >= 30
			EvaluateArmor = HitTarget.GetWornForm(Armor.GetMaskForSlot(i)) as Armor
			If EvaluateArmor != None
				ArmorWeight += EvaluateArmor.GetWeight()
			EndIf
			i -= 1
		EndWhile
		If akBaseObject as Armor
			Armor EquippedShield = akBaseObject as Armor
			If EquippedShield.IsShield()  
				GotoState("InitBaseBlockValue")
			EndIf
		ElseIf akBaseObject as Weapon
			GotoState("InitBaseBlockValue")
		EndIf
EndEvent


Event OnAnimationEvent(ObjectReference akSource, string asEventName)
	If (akSource == HitTarget) && (asEventName == "WeaponSwing")
		HitTarget.SetAnimationVariableBool("IsBlocking",true)
	EndIf
	If (akSource == HitTarget) && (asEventName == "AttackStop")
		HitTarget.SetAnimationVariableBool("IsBlocking",false)
	EndIf
	If (akSource == Attacker) && (asEventName == "WeaponSwing") && (Dodged == false)
		Dodged = true
		DodgeActor = Attacker.GetCombatTarget()
		If (DodgeActor as Actor)
			If (DodgeActor != Game.GetPLayer()) && (DodgeActor.GetRace().HasKeyWord(NPC)) && (DodgeActor.GetActorValue("Stamina")>0) && (DodgeActor.GetAnimationVariablebool("IsStaggering") == false)
				Int DodgeType = Utility.RandomInt(0,3)
				If (DodgeType >= 1) && (DodgeType <= 3)
					DodgeActor.SetGhost(true)
					If (DodgeActor.GetAnimationVariablebool("IsStaggering") == true)
						Debug.SendAnimationEvent(DodgeActor,"StaggerStop")
					EndIf
					If (DodgeActor.GetAnimationVariablebool("IsAttacking") == true)
						Debug.SendAnimationEvent(DodgeActor, "AttackStop")
					EndIf
					If (DodgeActor.GetAnimationVariablebool("IsBlocking") == true)
						Debug.SendAnimationEvent(DodgeActor, "BlockStop")
					EndIf
					Debug.SendAnimationEvent(DodgeActor, "SprintStart")
					Debug.SendAnimationEvent(DodgeActor, "SprintStop")
					Debug.SendAnimationEvent(DodgeActor, "MoveStart")
					If (DodgeType == 1)
						Debug.SendAnimationEvent(DodgeActor, "DodgeBack")
					ElseIf (DodgeType == 2)
						Debug.SendAnimationEvent(DodgeActor, "DodgeLeft")
					ElseIf (DodgeType == 3)
						Debug.SendAnimationEvent(DodgeActor, "DodgeRight")
					EndIf
					Utility.Wait(0.4)
					DodgeActor.SetGhost(false)
				EndIf
			EndIf
		EndIf
		Utility.Wait(3)
		Dodged = false
	EndIf
EndEvent



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

	If !(akSource as Spell || akSource as Explosion || akSource as Ingredient || akSource as Potion || akSource as Enchantment )

		Hits += 1

		Aggressor = akAggressor as Actor
		Float AggressorMass = Aggressor.GetActorValue("mass")
		Float StaggerTime = 0.0
		Float WeaponWeight = 0.0
		Weapon TheWeapon = akSource as Weapon
		Float WeaponSkill 


		
;/		If TheWeapon != None
			Int TheWeaponType = TheWeapon.GetWeaponType()
			If TheWeapontype == 1 || TheWeaponType == 2 || TheWeaponType == 3 || TheWeaponType == 4
				WeaponSkill = Aggressor.GetActorValue("OneHanded")
			ElseIf TheWeapontype == 5 || TheWeaponType == 6
				WeaponSkill = Aggressor.GetActorValue("TwoHanded")
			EndIf
		EndIf

		If abPowerAttack == true 
			If (Aggressor.GetEquippedWeapon(true) == None) && (Aggressor.GetEquippedWeapon() == None) 
				StaggerTime = 1.5 + AggressorMass*0.5 - TargetMass*0.5 - ArmorWeight*0.01
				If abHitBlocked == true
					BlockValue -= (20*AggressorMass) as Int
				EndIf
			Else 
				WeaponWeight = TheWeapon.GetWeight()
				StaggerTime = 0.5 + WeaponWeight*0.15 - ArmorWeight*0.01 - TargetMass*0.25
				If abHitBlocked == true
					BlockValue -= (3*TheWeapon.GetWeight()/(1.5 - 0.01*WeaponSkill)) as Int 
				EndIf
			EndIf

		Else 
			
				If (Aggressor.GetEquippedWeapon(true) == None) && (Aggressor.GetEquippedWeapon() == None) 
					StaggerTime = AggressorMass*0.4 - TargetMass*0.1 - ArmorWeight*0.004
					If abHitBlocked == true
						BlockValue -= (5*AggressorMass) as Int 
					EndIf
				Else
					WeaponWeight = TheWeapon.GetWeight()
					StaggerTime = 0.25 + WeaponWeight*0.04 - ArmorWeight*0.006 - TargetMass*0.25 				
					If abHitBlocked == true
						BlockValue -= (TheWeapon.GetWeight()/(1.5 - 0.01*WeaponSkill)) as Int 
					EndIf
				EndIf		
		EndIf
		


		If abHitBlocked == true
			If BlockValue < 0
				BlockValue = 0
			EndIf
			StaggerTime *= (1- BlockValue/BaseBlockValue)
			If (abBashAttack == true) && (HitTarget.GetAnimationVariablebool("IsAttacking") == true)
				Debug.SendAnimationEvent(HitTarget,"RecoilLargeStart")
				StaggerTime = 0
			ElseIf (HitTarget.GetAnimationVariablebool("IsBashing") == true) && (Aggressor.GetAnimationVariablebool("IsBashing") == false)
				Debug.SendAnimationEvent(Aggressor,"RecoilLargeStart")
				StaggerTime = 0
			ElseIf StaggerTime < 0.5
				StaggerTime = 0
				If (HitTarget.GetAnimationVariablebool("IsAttacking") == true) && (abBashAttack == false)
					Debug.SendAnimationEvent(Aggressor,"RecoilLargeStart")
;					Utility.Wait(0.5)
;					Aggressor.SetAnimationVariableFloat("StaggerMagnitude",0.2)
;					Debug.SendAnimationEvent(Aggressor,"StaggerStart")	
				EndIf
			EndIf
		EndIf

		If (abBashAttack == true) && (HitTarget.GetAnimationVariablebool("IsAttacking") == true)
			Debug.SendAnimationEvent(HitTarget,"RecoilLargeStart")
;			Utility.Wait(0.5)
;			StaggerTime = 0.5
		ElseIf (HitTarget.GetAnimationVariablebool("IsBashing") == true) && (Aggressor.GetAnimationVariablebool("IsBashing") == false)
			Debug.SendAnimationEvent(Aggressor,"RecoilLargeStart")
			StaggerTime = 0
;			Utility.Wait(0.5)
;			Aggressor.SetAnimationVariableFloat("StaggerMagnitude",0.2)
;			Debug.SendAnimationEvent(Aggressor,"StaggerStart")			
		EndIf



		If (Pain > Utility.RandomInt(0,20))
			If (StaggerTime >= 1.1)
				StaggerTime -= 1
			ElseIf (StaggerTime > 0.1)
				StaggerTime = 0.1
			EndIf
		Else
			StaggerTime += 0.1*Pain
		EndIf


		
		If (Pain <= 0)
			Pain = 1
		Else
			Pain *= 2
		EndIf
		If (StaggerTime > 0.1)
			Pain += StaggerTime
		EndIf
/;


		Stagger(3)  ; !!!! This is the main code I want ,and it delay .but I don't know is this function delay or OnHit Event delay ?

		ConsecutiveHits()

	EndIf
EndEvent


Event OnUpdate() 
	If BlockSkill != HitTarget.GetActorValue("Block")
		GotoState("InitBaseBlockValue")
	EndIf
	If BlockValue < BaseBlockValue
		If (BlockValue/BaseBlockValue) < 0.2
			BlockValue += (0.05*BaseBlockValue) as Int
		Else
			BlockValue += (0.1*BaseBlockValue) as Int
		EndIf
	EndIf
	If BlockValue > BaseBlockValue
		BlockValue = BaseBlockValue as Int
	EndIf
	If (BlockValue/BaseBlockValue) > 0.6
		If !HitTarget.HasSpell(BlockFortifySpell)
			HitTarget.AddSpell(BlockFortifySpell,false)
		EndIf
		If HitTarget.HasSpell(BlockWeakenSpell)
			HitTarget.RemoveSpell(BlockWeakenSpell)
		EndIf
	ElseIf (BlockValue/BaseBlockValue) < 0.2
		If !HitTarget.HasSpell(BlockWeakenSpell)
			HitTarget.AddSpell(BlockWeakenSpell,false)
		EndIf
		If HitTarget.HasSpell(BlockFortifySpell)
			HitTarget.RemoveSpell(BlockFortifySpell)
		EndIf
	EndIf
	
	RegisterForSingleUpdate(1.0)
EndEvent

Function Stagger(Float afStaggerTime = 0.0)

		If HitTarget.IsDead()==false
			If afStaggerTime >= 0.1
				If HitTarget.GetAnimationVariablebool("IsStaggering") == true
					Debug.SendAnimationEvent(HitTarget,"StaggerStop")
					StaggerStopped = true
				EndIf
				HitTarget.SetAnimationVariableFloat("StaggerMagnitude",afStaggerTime*0.4)
				Debug.SendAnimationEvent(HitTarget,"AttackStop")
				Debug.SendAnimationEvent(HitTarget,"BlockStop")
				Debug.SendAnimationEvent(HitTarget,"StaggerStart")
				Utility.Wait(afStaggerTime)
				If StaggerStopped == false
					Debug.SendAnimationEvent(HitTarget,"StaggerStop")
				Else
					StaggerStopped = false
				EndIf
			EndIf	
		EndIf
		
EndFunction

Function ConsecutiveHits()
	Utility.Wait(2)
	Hits -= 1
	If (Hits == 0)
		Pain = 0.0
	EndIf
EndFunction

;/
State Numb
	Event OnBeginState()
		Utility.Wait(3.0)
		Pain = 0
	EndEvent
EndState
/;

State InitBaseBlockValue
	Event OnBeginState()
		Int BBA_Coefficient
		BlockSkill = HitTarget.GetActorValue("Block") as Int
		If HitTarget.GetEquippedShield() == None
			If HitTarget.GetEquippedWeapon() != None
				BBA_Coefficient = HitTarget.GetEquippedWeapon().GetWeight() as Int
				BaseBlockValue = (0.8*BlockSkill + BBA_Coefficient/(1.5 - 0.01*BlockSkill)) as Int
			EndIf
		Else
			BBA_Coefficient = HitTarget.GetEquippedShield().GetArmorRating() as Int
			BaseBlockValue = (3*BBA_Coefficient/(1.4 - 0.01*BlockSkill)) as Int
		EndIf
;		If PlayerRef == HitTarget
;			Debug.Notification("Block Value: "+BlockValue+"/"+BaseBlockValue)
;		EndIf
		If BaseBlockValue == 0
			BaseBlockValue = 1
		EndIf
	EndEvent
EndState

;/
State Dodge
	Event OnBeginState()
		Int DodgeType = Utility.RandomInt(0,3)
		If (DodgeType >= 1) && (DodgeType <= 3)
		DodgeActor.SetGhost(true)
		If (DodgeActor.GetAnimationVariablebool("IsStaggering") == true)
			Debug.SendAnimationEvent(DodgeActor,"StaggerStop")
		EndIf
		If (DodgeActor.GetAnimationVariablebool("IsAttacking") == true)
			Debug.SendAnimationEvent(DodgeActor, "AttackStop")
		EndIf
		If (DodgeActor.GetAnimationVariablebool("IsBlocking") == true)
			Debug.SendAnimationEvent(DodgeActor, "BlockStop")
		EndIf
		Debug.SendAnimationEvent(DodgeActor, "SprintStart")
		Debug.SendAnimationEvent(DodgeActor, "SprintStop")
		Debug.SendAnimationEvent(DodgeActor, "MoveStart")
		If (DodgeType == 1)
			Debug.SendAnimationEvent(DodgeActor, "DodgeBack")
		ElseIf (DodgeType == 2)
			Debug.SendAnimationEvent(DodgeActor, "DodgeLeft")
		ElseIf (DodgeType == 3)
			Debug.SendAnimationEvent(DodgeActor, "DodgeRight")
		EndIf
		Utility.Wait(0.4)
		DodgeActor.SetGhost(false)
		EndIf
	EndEvent
EndState
/;


Event OnEffectFinish(Actor akTarget, Actor akCaster)
	If akTarget.HasSpell(BlockWeakenSpell)
		akTarget.RemoveSpell(BlockWeakenSpell)
	EndIf
	If akTarget.HasSpell(BlockFortifySpell)
		akTarget.RemoveSpell(BlockFortifySpell)
	EndIf
;	DodgeActor.SetGhost(false)
EndEvent


Spell Property BlockFortifySpell Auto
Spell Property BlockWeakenSpell Auto

 

 

Link to comment
Share on other sites

Event OnEffectStart(Actor akTarget, Actor akCaster)

PlayerRef = Game.GetPlayer()
HitTarget = akTarget
Attacker = akTarget
TargetMass = HitTarget.GetActorValue("mass")
BlockSkill = HitTarget.GetActorValue("Block") as Int
GotoState("InitBaseBlockValue")

 

I'm a little confused as to why your HitTarget and the Attacker are both defined as the akTarget. If they are both the same actor, why do you need to define both? Should Attacker=akCaster? I'm pretty new at this; that's why I'm asking.

Link to comment
Share on other sites

wouldn't you want it as

akTarget.RegisterForAnimationEvent(HitTarget,"StaggerStart")
akTarget.RegisterForAnimationEvent(HitTarget,"StaggerStop")
akTarget.RegisterForAnimationEvent(HitTarget,"WeaponSwing")
akTarget.RegisterForAnimationEvent(HitTarget,"AttackStop")
As that is the person you want to have the animation happen to?
I also am somewhat unfamiliar with animation events so I also could be full of crap
Link to comment
Share on other sites

 

wouldn't you want it as

akTarget.RegisterForAnimationEvent(HitTarget,"StaggerStart")
akTarget.RegisterForAnimationEvent(HitTarget,"StaggerStop")
akTarget.RegisterForAnimationEvent(HitTarget,"WeaponSwing")
akTarget.RegisterForAnimationEvent(HitTarget,"AttackStop")
As that is the person you want to have the animation happen to?
I also am somewhat unfamiliar with animation events so I also could be full of crap

 

 

look here

http://www.creationkit.com/RegisterForAnimationEvent_-_Form

Link to comment
Share on other sites

Lucky, I fix the delay.
It's not the OnHit script caused, Just my a mistake in apply the OnHit script to NPCs .

 

Scriptname _CM_ApplySpellScript extends activemagiceffect  

SPELL Property OnHitAbility  Auto  

Event OnEffectStart(Actor akTarget, Actor akCaster)
	akTarget.AddSpell(OnHitAbility,false)
EndEvent

Event OnEffectFinish(Actor akTarget, Actor akCaster)
	akTarget.RemoveSpell(OnHitAbility)  ;So fool, why I had want it to remove ?
EndEvent

 

 

 

 

 

:laugh: Thanks for guys' help

Link to comment
Share on other sites

Event OnEffectStart(Actor akTarget, Actor akCaster)

 

PlayerRef = Game.GetPlayer()

HitTarget = akTarget

Attacker = akTarget

TargetMass = HitTarget.GetActorValue("mass")

BlockSkill = HitTarget.GetActorValue("Block") as Int

GotoState("InitBaseBlockValue")

 

I'm a little confused as to why your HitTarget and the Attacker are both defined as the akTarget. If they are both the same actor, why do you need to define both? Should Attacker=akCaster? I'm pretty new at this; that's why I'm asking.

Because this script is not only for HIt Event ,but also for dodge 、block etc, in order to I avoid confuse them, I call them different name .

Link to comment
Share on other sites

  • Recently Browsing   0 members

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