Jump to content

[LE] Throttling OnHit scripts


lesi123

Recommended Posts

If a state doesn't have a particular function defined then a default version of the function is used. It's either the one defined at the default state level (outside of any state declarations) or something inherited from the script that's being extended. Explicitly declaring an empty event in the state will always work. Simply leaving it undeclared may work, but only in certain cases. That's why seeing the entire script matters.

Link to comment
Share on other sites

  • Replies 67
  • Created
  • Last Reply

Top Posters In This Topic

Here's my script that I have been testing:

Scriptname BTDCREATUREtoPLAYERDmg extends ReferenceAlias
{Script that handles Creature to Player bleed damage}

;---------------------------------------------------------------------------------------------------------------------------------------
; The HitChance conditions in the function blocks control the hit chances to apply the bleed damage spells to targets. To increase the chances of applying a bleed, use a lower number. To reduce the chances of applying a bleed, use a higher number.
;---------------------------------------------------------------------------------------------------------------------------------------

Actor Property PlayerRef Auto

Race Property WolfRace Auto
Race Property SlaughterfishRace Auto
Race Property SabreCatRace Auto
Race Property SabreCatSnowyRace Auto
Race Property BearBlackRace Auto
Race Property BearBrownRace Auto
Race Property BearSnowRace Auto
Race Property IceWraithRace Auto
Race Property WerewolfBeastRace Auto
Race Property SprigganRace Auto
Race Property SprigganMatronRace Auto
Race Property TrollRace Auto
Race Property TrollFrostRace Auto
Race Property DwarvenSphereRace Auto
Race Property DwarvenCenturionRace Auto
Race Property DLC1DeathHoundRace Auto
Race Property DLC1SabreCatGlowRace Auto
Race Property SprigganEarthMotherRace Auto
Race Property DLC1GargoyleRace Auto
Race Property DLC1GargoyleVariantBossRace Auto
Race Property DLC1GargoyleVariantGreenRace Auto
Race Property DLC2SprigganBurntRace Auto
Race Property DLC2WerebearBeastRace Auto
Race Property DLC1LD_ForgemasterRace Auto
Race Property DLC2DwarvenBallistaRace Auto
Race Property DLC2dunKarstaagIceWraithRace Auto
Race Property DragonRace Auto

Spell Property BTDSpellCREATURESmalltoPLAYERBleedDmg Auto
Spell Property BTDSpellCREATUREMediumtoPLAYERBleedDmg Auto
Spell Property BTDSpellCREATURELargetoPLAYERBleedDmg Auto
Spell Property BTDSpellCREATUREXLargetoPLAYERBleedDmg Auto

Keyword Property ActorTypeAnimal Auto
Keyword Property ActorTypeCreature Auto
Keyword Property ActorTypeDwarven Auto

Actor Aggressor
Race AggressorRace

Int HitChance

; Dragons and hagravens had to be excluded since their breaths and spells would apply bleeds to the player.
;------------------------------------------------------------------------------------------------------------------------
; HIT REGISTERED ON PLAYER
;------------------------------------------------------------------------------------------------------------------------
Auto State Ready 

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

		GoToState("Busy") ; Don't run this function again until it's finished
		Aggressor = akAggressor as Actor

		if (akAggressor != None) && (akSource as Weapon) && (abHitBlocked != true) && (Aggressor.GetRace() != DragonRace) && !(akSource as Spell)
			if (Aggressor.HasKeyword(ActorTypeAnimal))
				PlayerHitByAnimal(Aggressor)
			elseif (Aggressor.HasKeyword(ActorTypeCreature))
				PlayerHitByCreature(Aggressor)
			elseif (Aggressor.HasKeyword(ActorTypeDwarven))
				PlayerHitByDwarven(Aggressor)
			endif
		endif
		
		GoToState("Ready") ; The function has finished, so it can be called again
		
	EndEvent

EndState

State Busy

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

EndState

;------------------------------------------------------------------------------------------------------------------------
; FUNCTION BLOCKS
;------------------------------------------------------------------------------------------------------------------------

; ---------- Player hit by an animal ----------
Function PlayerHitByAnimal(Actor Param1)

AggressorRace = Aggressor.GetRace()
HitChance = Utility.RandomInt()
	
		if ((AggressorRace == WolfRace) && (HitChance >= 70)) || ((AggressorRace == SlaughterfishRace) && (HitChance >= 30))
			BTDSpellCREATURESmalltoPLAYERBleedDmg.cast(PlayerRef,PlayerRef)
			
		elseif ((AggressorRace == SabreCatRace) && (HitChance >= 60)) || ((AggressorRace == SabreCatSnowyRace) && (HitChance >= 50)) || ((AggressorRace == BearBlackRace) && (HitChance >= 50)) || ((AggressorRace == BearBrownRace) && (HitChance >= 60)) || ((AggressorRace == BearSnowRace) && (HitChance >= 50)) || ((AggressorRace == DLC1SabreCatGlowRace) && (HitChance >= 50))
			BTDSpellCREATUREMediumtoPLAYERBleedDmg.cast(PlayerRef,PlayerRef)
			
		elseif ((AggressorRace == TrollRace) && (HitChance >= 60)) || ((AggressorRace == TrollFrostRace) && (HitChance >= 50))
			BTDSpellCREATURELargetoPLAYERBleedDmg.cast(PlayerRef,PlayerRef)
		endif
			
EndFunction

; ---------- Player hit by a creature ----------
Function PlayerHitByCreature(Actor Param1)

AggressorRace = Aggressor.GetRace()
HitChance = Utility.RandomInt()

		if ((AggressorRace == DLC1DeathHoundRace) && (HitChance >= 70))
			BTDSpellCREATURESmalltoPLAYERBleedDmg.cast(PlayerRef,PlayerRef)
			
		elseif ((AggressorRace == IceWraithRace) && (HitChance >= 50)) || ((AggressorRace == DLC2dunKarstaagIceWraithRace) && (HitChance >= 50))
			BTDSpellCREATUREMediumtoPLAYERBleedDmg.cast(PlayerRef,PlayerRef)
			
		elseif ((AggressorRace == WerewolfBeastRace) && (HitChance >= 50)) || ((AggressorRace == SprigganRace) && (HitChance >= 60)) || ((AggressorRace == SprigganMatronRace) && (HitChance >= 50)) || ((AggressorRace == SprigganEarthMotherRace) && (HitChance >= 40)) || ((AggressorRace == DLC1GargoyleRace) && (HitChance >= 50)) || ((AggressorRace == DLC1GargoyleVariantBossRace) && (HitChance >= 40)) || ((AggressorRace == DLC1GargoyleVariantGreenRace) && (HitChance >= 50)) || ((AggressorRace == DLC2SprigganBurntRace) && (HitChance >= 60)) || ((AggressorRace == DLC2WerebearBeastRace) && (HitChance >= 50))
			BTDSpellCREATURELargetoPLAYERBleedDmg.cast(PlayerRef,PlayerRef)

		endif
		
EndFunction

; ---------- Player hit by a dwarven automaton ----------
Function PlayerHitByDwarven(Actor Param1)

AggressorRace = Aggressor.GetRace()
HitChance = Utility.RandomInt()

		if ((AggressorRace == DwarvenSphereRace) && (HitChance >= 50))
			BTDSpellCREATURELargetoPLAYERBleedDmg.cast(PlayerRef,PlayerRef)
			
		elseif ((AggressorRace == DwarvenCenturionRace) && (HitChance >= 20)) || ((AggressorRace == DLC1LD_ForgemasterRace) || (AggressorRace == DLC2DwarvenBallistaRace) && (HitChance >= 10))
			BTDSpellCREATUREXLargetoPLAYERBleedDmg.cast(PlayerRef,PlayerRef)
		endif
		
EndFunction

I did two tests just now with a Sun Dragon from DD. Both tests were timed for 1min 30sec as soon as I spawned the dragon. My character was at the entrance to the cave leading from Helgen (save with no mods) and the only other NPC nearby was Rolof.

 

The first test was with the script above as is. The log was 242kb.

 

Image of the Papyrus Log Viewer: http://i.imgur.com/CsM7NdI.png

 

 

The second test was with the OnHit Event in the Busy state marked out with ;. The log was 598kb.

 

Image of the papyrus Log Viewer: http://i.imgur.com/XEzLEmy.png

Link to comment
Share on other sites

Here's my script that I have been testing:

 

 

Would you please simply take 5 minutes to test the script I wrote? I think if you want that script to function well you need to shut down the event until all of the functions have been completed.

 

I do not think the event being defined in the State has anything to do with this.

 

Now that I can see the script you will have to do the first part like this.

 

 

 

Auto State Ready

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

        GoToState("Busy") ; Don't run this function again until it's finished
        Aggressor = akAggressor as Actor

        if (akAggressor != None) && (akSource as Weapon) && (abHitBlocked != true) && (Aggressor.GetRace() != DragonRace) && !(akSource as Spell)
            if (Aggressor.HasKeyword(ActorTypeAnimal))
                PlayerHitByAnimal(Aggressor)
            elseif (Aggressor.HasKeyword(ActorTypeCreature))
                PlayerHitByCreature(Aggressor)
            elseif (Aggressor.HasKeyword(ActorTypeDwarven))
                PlayerHitByDwarven(Aggressor)
            Else
                 GoToState("Ready")
            EndIf
         Else           
            GoToState("Ready")
         Endif
    EndEvent

EndState

 

 

 

I believe all of the events in the base scripts are empty, so leaving the event undefined should always work.

 

Have you ever seen an event defined in a empty state before?

Edited by Masterofnet
Link to comment
Share on other sites

 

 

Would you please simply take 5 minutes to test the script I wrote? I think if you want that script to function well you need to shut down the event until all of the functions have been completed.

 

I do not think the event being defined in the State has anything to do with this.

 

 

Whoops, I didn't see the other changes in the script. My bad!

 

Just did the same test as the others with all of your changes and had no errors in the log (24kb file). I also spawned in some wolves to double check the hits were registering from races that could give the player bleeds; so far so good! I will continue testing and hope that this was the last scripting hurdle.

 

Thank you very much for all of your help guys!

Link to comment
Share on other sites

 

Just did the same test as the others with all of your changes and had no errors in the log (24kb file). I also spawned in some wolves to double check the hits were registering from races that could give the player bleeds; so far so good! I will continue testing and hope that this was the last scripting hurdle.

 

Thank you very much for all of your help guys!

 

 

Great! It is always fun to help someone who is willing to do some testing. If you wanted to put an empty function in the Busy State maybe you could find one that would be less likely to get called.

 

BTW I have never seen that done or heard of doing it before this thread. Where did you get the idea to put the OnHit event in the Empty "Busy" State?

Edited by Masterofnet
Link to comment
Share on other sites

 

Great! It is always fun to help someone who is willing to do some testing. If you wanted to put an empty function in the Busy State maybe you could find one that would be less likely to get called.

 

BTW I have never seen that done or heard of doing it before this thread. Where did you get the idea to put the OnHit event in the Empty "Busy" State?

 

ScriptName LongFunctionScript extends ObjectReference

Function LongFunction()
    GoToState("Busy") ; Don't run this function again until it's finished

    ; Do something that takes a long time

    GoToState("Waiting") ; The function has finished, so it can be called again
EndFunction

State Busy
    Function LongFunction()
        ; Do nothing
    EndFunction
EndState

On the Cipscis site's example above, I simply replaced LongFunction with OnHit. I thought maybe it was serving an important purpose being there. :|

Link to comment
Share on other sites

Well, I spoke too soon. I fought the dragon for longer this time (a little over 5 minutes) and ended up with stack dumps again, log at 3,285kb.

 

The script below is what I'm using. It takes longer to start dumping stacks but it seems to still have trouble keeping up.

 

 

 

Scriptname BTDCREATUREtoPLAYERDmg extends ReferenceAlias
{Script that handles Creature to Player bleed damage}

;---------------------------------------------------------------------------------------------------------------------------------------
; The HitChance conditions in the function blocks control the hit chances to apply the bleed damage spells to targets. To increase the chances of applying a bleed, use a lower number. To reduce the chances of applying a bleed, use a higher number.
;---------------------------------------------------------------------------------------------------------------------------------------

Actor Property PlayerRef Auto

Race Property WolfRace Auto
Race Property SlaughterfishRace Auto
Race Property SabreCatRace Auto
Race Property SabreCatSnowyRace Auto
Race Property BearBlackRace Auto
Race Property BearBrownRace Auto
Race Property BearSnowRace Auto
Race Property IceWraithRace Auto
Race Property WerewolfBeastRace Auto
Race Property SprigganRace Auto
Race Property SprigganMatronRace Auto
Race Property TrollRace Auto
Race Property TrollFrostRace Auto
Race Property DwarvenSphereRace Auto
Race Property DwarvenCenturionRace Auto
Race Property DLC1DeathHoundRace Auto
Race Property DLC1SabreCatGlowRace Auto
Race Property SprigganEarthMotherRace Auto
Race Property DLC1GargoyleRace Auto
Race Property DLC1GargoyleVariantBossRace Auto
Race Property DLC1GargoyleVariantGreenRace Auto
Race Property DLC2SprigganBurntRace Auto
Race Property DLC2WerebearBeastRace Auto
Race Property DLC1LD_ForgemasterRace Auto
Race Property DLC2DwarvenBallistaRace Auto
Race Property DLC2dunKarstaagIceWraithRace Auto
Race Property DragonRace Auto

Spell Property BTDSpellCREATURESmalltoPLAYERBleedDmg Auto
Spell Property BTDSpellCREATUREMediumtoPLAYERBleedDmg Auto
Spell Property BTDSpellCREATURELargetoPLAYERBleedDmg Auto
Spell Property BTDSpellCREATUREXLargetoPLAYERBleedDmg Auto

Keyword Property ActorTypeAnimal Auto
Keyword Property ActorTypeCreature Auto
Keyword Property ActorTypeDwarven Auto

Actor Aggressor
Race AggressorRace

Int HitChance

; Dragons and hagravens had to be excluded since their breaths and spells would apply bleeds to the player
;------------------------------------------------------------------------------------------------------------------------
; HIT REGISTERED ON PLAYER
;------------------------------------------------------------------------------------------------------------------------
Auto State Ready 

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

		GoToState("Busy") ; Don't run this OnHit Event again until it's finished
		Aggressor = akAggressor as Actor

		if (akAggressor != None) && (akSource as Weapon) && (abHitBlocked != true) && (Aggressor.GetRace() != DragonRace) && !(akSource as Spell)
			if (Aggressor.HasKeyword(ActorTypeAnimal))
				PlayerHitByAnimal(Aggressor)
			elseif (Aggressor.HasKeyword(ActorTypeCreature))
				PlayerHitByCreature(Aggressor)
			elseif (Aggressor.HasKeyword(ActorTypeDwarven))
				PlayerHitByDwarven(Aggressor)
			else 
				GoToState("Ready") ; The OnHit Event has finished, so it can be called again
			endif
		else
			GoToState("Ready") ; The OnHit Event has finished, so it can be called again
		endif
						
	EndEvent

EndState


State Busy
	; Nothing
EndState

;------------------------------------------------------------------------------------------------------------------------
; FUNCTION BLOCKS
;------------------------------------------------------------------------------------------------------------------------

; ---------- Player hit by an animal ----------
Function PlayerHitByAnimal(Actor Param1)

AggressorRace = Aggressor.GetRace()
HitChance = Utility.RandomInt()
	
	if ((AggressorRace == WolfRace) && (HitChance >= 70)) || ((AggressorRace == SlaughterfishRace) && (HitChance >= 30))
		BTDSpellCREATURESmalltoPLAYERBleedDmg.cast(PlayerRef,PlayerRef)
		
	elseif ((AggressorRace == SabreCatRace) && (HitChance >= 60)) || ((AggressorRace == SabreCatSnowyRace) && (HitChance >= 50)) || ((AggressorRace == BearBlackRace) && (HitChance >= 50)) || ((AggressorRace == BearBrownRace) && (HitChance >= 60)) || ((AggressorRace == BearSnowRace) && (HitChance >= 50)) || ((AggressorRace == DLC1SabreCatGlowRace) && (HitChance >= 50))
		BTDSpellCREATUREMediumtoPLAYERBleedDmg.cast(PlayerRef,PlayerRef)
		
	elseif ((AggressorRace == TrollRace) && (HitChance >= 60)) || ((AggressorRace == TrollFrostRace) && (HitChance >= 50))
		BTDSpellCREATURELargetoPLAYERBleedDmg.cast(PlayerRef,PlayerRef)
	endif
	
	GoToState("Ready") ; The OnHit Event has finished, so it can be called again
			
EndFunction

; ---------- Player hit by a creature ----------
Function PlayerHitByCreature(Actor Param1)

AggressorRace = Aggressor.GetRace()
HitChance = Utility.RandomInt()

	if ((AggressorRace == DLC1DeathHoundRace) && (HitChance >= 70))
		BTDSpellCREATURESmalltoPLAYERBleedDmg.cast(PlayerRef,PlayerRef)
		
	elseif ((AggressorRace == IceWraithRace) && (HitChance >= 50)) || ((AggressorRace == DLC2dunKarstaagIceWraithRace) && (HitChance >= 50))
		BTDSpellCREATUREMediumtoPLAYERBleedDmg.cast(PlayerRef,PlayerRef)
		
	elseif ((AggressorRace == WerewolfBeastRace) && (HitChance >= 50)) || ((AggressorRace == SprigganRace) && (HitChance >= 60)) || ((AggressorRace == SprigganMatronRace) && (HitChance >= 50)) || ((AggressorRace == SprigganEarthMotherRace) && (HitChance >= 40)) || ((AggressorRace == DLC1GargoyleRace) && (HitChance >= 50)) || ((AggressorRace == DLC1GargoyleVariantBossRace) && (HitChance >= 40)) || ((AggressorRace == DLC1GargoyleVariantGreenRace) && (HitChance >= 50)) || ((AggressorRace == DLC2SprigganBurntRace) && (HitChance >= 60)) || ((AggressorRace == DLC2WerebearBeastRace) && (HitChance >= 50))
		BTDSpellCREATURELargetoPLAYERBleedDmg.cast(PlayerRef,PlayerRef)
	endif
	
	GoToState("Ready") ; The OnHit Event has finished, so it can be called again
		
EndFunction

; ---------- Player hit by a dwarven automaton ----------
Function PlayerHitByDwarven(Actor Param1)

AggressorRace = Aggressor.GetRace()
HitChance = Utility.RandomInt()

	if ((AggressorRace == DwarvenSphereRace) && (HitChance >= 50))
		BTDSpellCREATURELargetoPLAYERBleedDmg.cast(PlayerRef,PlayerRef)
		
	elseif ((AggressorRace == DwarvenCenturionRace) && (HitChance >= 20)) || ((AggressorRace == DLC1LD_ForgemasterRace) || (AggressorRace == DLC2DwarvenBallistaRace) && (HitChance >= 10))
		BTDSpellCREATUREXLargetoPLAYERBleedDmg.cast(PlayerRef,PlayerRef)
	endif
	
	GoToState("Ready") ; The OnHit Event has finished, so it can be called again
		
EndFunction 

 

 

Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.

×
×
  • Create New...