Jump to content

Help with a Script - Thanks!


Recommended Posts

So I followed a tutorial on the Creation kit wiki:

https://www.creationkit.com/index.php?title=Dynamically_Attaching_Scripts

 

and looked at an old skyrim mod (that used skse) and changed some things to get the script working except I can't figure out how to display NO decimal points (or just ONE decimal points) when the notifications appear. The script gives you a notification of the damage done (health,Magicka, Stamina) to a creature when you hit it. Here is my script:

Scriptname MonitorScript extends ActiveMagicEffect  
 
Actor MySelf
Float Health
Float Magicka
Float Stamina

Float Function Round(Float OldNum, Int Precision = 1)
endFunction

Event OnEffectStart(Actor akTarget, Actor akCaster)
	MySelf = akTarget
	Health = MySelf.GetActorValue("Health")
	Magicka = MySelf.GetActorValue("Magicka")
	Stamina = MySelf.GetActorValue("Stamina")
	RegisterForSingleUpdate(0.25)
	GoToState("alive")
EndEvent

State alive

		Float Function Round(Float OldNum, Int Precision = 1)
		Float TempNum = OldNum * Math.Pow(10, Precision)
		if (Math.Ceiling(TempNum) * 2 == Math.Ceiling(TempNum * 2))
			return Math.Ceiling(TempNum) / Math.Pow(10, Precision)
		else
			return Math.Floor(TempNum) / Math.Pow(10, Precision)
		endif
	endFunction
	
   Event OnBeginState()
		RegisterForSingleUpdate(0.25)
	EndEvent
	Event OnUpdate()
		Health = MySelf.GetActorValue("Health")
		Magicka = MySelf.GetActorValue("Magicka")
		Stamina = MySelf.GetActorValue("Stamina")
		RegisterForSingleUpdate(0.25)
	EndEvent
	
	Event OnEffectFinish(Actor akTarget, Actor akCaster)
	EndEvent
	
	Event OnDying(Actor akKiller)
	UnregisterForUpdate()
	GoToState("dead")
	EndEvent
 EndState
 
State dead
; Nothing needed here
EndState
 
	Event OnHit(ObjectReference akAggressor, Form akSource, Projectile akProjectile, bool abPowerAttack, bool abSneakAttack, bool abBashAttack, bool abHitBlocked)
		UnregisterForUpdate()
		if (akAggressor as Actor == Game.GetPlayer())
			Float HDamage = Health - MySelf.GetActorValue("Health")
			Float MDamage = Magicka - MySelf.GetActorValue("Magicka")
			Float SDamage = Stamina - MySelf.GetActorValue("Stamina")
			if (HDamage >= 1) || (MDamage >= 1) || (SDamage >= 1)
				String Notice = "Your "
				if (abHitBlocked)
					Notice += "blocked "
				endif
				bool Bullet = akProjectile as bool
				if (Bullet)
					Notice += "fired "
				endif
				if (abSneakAttack)
					Notice += "sneak "
				endif
				if (abPowerAttack)
					Notice += "power "
				endif
				if (abBashAttack)
					Notice += "bash "
				endif
				Notice += "attack did "
				if (HDamage >= 1)
					Notice += Round(HDamage) + "H "
				endif
				if (MDamage >= 1)
					Notice += Round(MDamage) + "M "
				endif
				if (SDamage >= 1)
					Notice += Round(SDamage) + "S "
				endif
				Debug.Notification(Notice)
			endif
		endif
		Health = MySelf.GetActorValue("Health")
		Magicka = MySelf.GetActorValue("Magicka")
		Stamina = MySelf.GetActorValue("Stamina")
		RegisterForSingleUpdate(0.25)
	EndEvent

But it always displays like Damage 6.000000, etc. I am COMPLETELY new to scripting so if you could let me know EXACTLY what to change in the above that would be great! If I have to display at least one decimal point that would be fine as well! Thanks! I found this post but am not sure how to apply it to this script:

 

http://www.gamesas.com/outputting-number-decimal-places-t290446.html

Link to comment
Share on other sites

Note that according the the game developers you should be using Show on a Message instead of calling Debug.Notification. The Message object has a formatting option for floating point numbers.

 

If you want to use Notification you have to convert the number into an appropriate string format yourself. It's the conversion from float to string that determines how many decimal places show and the Notification function will always choose to display six places when showing a float.

 

Use this as your Round function so it's returning a string instead of a float for use by Notification.

string Function Round(float number, int precision)
    string result = number as int
    number -= number as int
    if precision > 0
        result += "."
    endif
    while precision > 0
        number *= 10
        precision -= 1
        if precision == 0
            number += 0.5
        endif
        result += number as int
        number -= number as int
    endwhile
    return result
EndFunction
Link to comment
Share on other sites

Great Works! Anyway to get it to not show any decimal points at all, just whole numbers? Also, a BIG problem I did not notice earlier (but could have been there) is when my attack strikes it dispalys "your attack did HDamage" but if its a blocked attack it will say "Your blocked attack did HDamage" AND "Your attack did Hdamage" for the same attack. Basically doubling the notification for the same attack. If its a blocked attack or a sneak attack, etc. it should only say "your blocked attack did HDamage."

 

Thanks!

Link to comment
Share on other sites

Just use a precision value of 0 and it should display whole numbers.

 

Special attacks generate multiple hit events. If the special attack (block/sneak/etc) occurs first you might be able to work around the problem by temporarily disabling hit events. That will also improve overall performance but it means only the first attack of a group will get a notification.

 

You should also avoid using Game.GetPlayer() for an OnHit event it's very inefficient.

 

Try this an see how it works. It might not work the way you want and I haven't tested it. If it basically works but always generates the plain attack message there might be a way to fix it.

Scriptname MonitorScript extends ActiveMagicEffect  
 
Actor PlayerRef
Actor MySelf
Float Health
Float Magicka
Float Stamina

string Function Round(float number, int Precision = 1)
	string result = number as int
	number -= number as int
	if precision > 0
		result += "."
	endif
	while precision > 0
		number *= 10
		precision -= 1
		if precision == 0
			number += 0.5
		endif
		result += number as int
		number -= number as int
	endwhile
	return result
EndFunction

Event OnEffectStart(Actor akTarget, Actor akCaster)
	PlayerRef = Game.GetPlayer()
	MySelf = akTarget
	Health = MySelf.GetActorValue("Health")
	Magicka = MySelf.GetActorValue("Magicka")
	Stamina = MySelf.GetActorValue("Stamina")
	RegisterForSingleUpdate(0.25)
EndEvent

Event OnDying(Actor akKiller)
	UnregisterForUpdate()
EndEvent

Event OnUpdate()
	Health = MySelf.GetActorValue("Health")
	Magicka = MySelf.GetActorValue("Magicka")
	Stamina = MySelf.GetActorValue("Stamina")
	RegisterForSingleUpdate(0.25)
EndEvent
 
State busy
	Event OnHit(ObjectReference akAggressor, Form akSource, Projectile akProjectile, bool abPowerAttack, bool abSneakAttack, bool abBashAttack, bool abHitBlocked)
	EndEvent
EndState

Event OnHit(ObjectReference akAggressor, Form akSource, Projectile akProjectile, bool abPowerAttack, bool abSneakAttack, bool abBashAttack, bool abHitBlocked)
	GoToState("busy")
	if (akAggressor as Actor == PlayerRef)
		Float HDamage = Health - MySelf.GetActorValue("Health")
		Float MDamage = Magicka - MySelf.GetActorValue("Magicka")
		Float SDamage = Stamina - MySelf.GetActorValue("Stamina")
		if (HDamage >= 1) || (MDamage >= 1) || (SDamage >= 1)
			String Notice = "Your "
			if (abHitBlocked)
				Notice += "blocked "
			endif
			bool Bullet = akProjectile as bool
			if (Bullet)
				Notice += "fired "
			endif
			if (abSneakAttack)
				Notice += "sneak "
			endif
			if (abPowerAttack)
				Notice += "power "
			endif
			if (abBashAttack)
				Notice += "bash "
			endif
			Notice += "attack did "
			if (HDamage >= 1)
				Notice += Round(HDamage, 0) + "H "
			endif
			if (MDamage >= 1)
				Notice += Round(MDamage, 0) + "M "
			endif
			if (SDamage >= 1)
				Notice += Round(SDamage, 0) + "S "
			endif
			Debug.Notification(Notice)
		endif
	endif
	Utility.Wait(0.1)
	Health = MySelf.GetActorValue("Health")
	Magicka = MySelf.GetActorValue("Magicka")
	Stamina = MySelf.GetActorValue("Stamina")
	GoToState("")
EndEvent
Link to comment
Share on other sites

That one did not work. The notifications hardly ever appear on any strikes. I fought a mob and the notification would only rarely appear. When it did it only said your attack did xdamage. But it was extremely difficult to get it to appear. Maybe once every 30 or 40 hits and only on some creatures it seemed like. Like the npcs I could hardly ever get it to appear, but one summoned a creature and it appeared a little more often :/

Link to comment
Share on other sites

in original code try just casting the float number to an Integer for the notification...

 Notice += (Round(HDamage) as Int) + "H "

Or .....

Wouldn't you not have to round by simply casting as Integer... ?

Int HDamage = Health - (MySelf.GetActorValue("Health") as Int)

If you know you don't want decimals then just use Integer.

 

I think, maybe, I'm not super scripter either.

Link to comment
Share on other sites

  • 3 years later...

Thanks for this snippet, it just saved me a bunch of anguish in outputting some nice-looking floats.

 

 

Note that according the the game developers you should be using Show on a Message instead of calling Debug.Notification. The Message object has a formatting option for floating point numbers.

 

If you want to use Notification you have to convert the number into an appropriate string format yourself. It's the conversion from float to string that determines how many decimal places show and the Notification function will always choose to display six places when showing a float.

 

Use this as your Round function so it's returning a string instead of a float for use by Notification.

string Function Round(float number, int precision)
    string result = number as int
    number -= number as int
    if precision > 0
        result += "."
    endif
    while precision > 0
        number *= 10
        precision -= 1
        if precision == 0
            number += 0.5
        endif
        result += number as int
        number -= number as int
    endwhile
    return result
EndFunction
Link to comment
Share on other sites

  • Recently Browsing   0 members

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