Jump to content

Recommended Posts

Now working on the critter scripts and there are a couple of questions already.

 

  • The script lets critters die when hit by a magic effect. Makes certainly sense for destruction spells, and it is understandable that they won't survive the magic turbulences associated with a conjuration, illusion or alteration attack, because they are tiny creatures. But what about a restoration spell ? If no one objects, I'll make them immune to "restoration attacks".

Share this post


Link to post
Share on other sites

Would that make them immune to Poison Rune?

Poison Rune is an adept level Restoration spell that creates a rune which will explode when enemies come near, causing them to take 3 damage per second for 30 seconds.

 

so yes XD

Share this post


Link to post
Share on other sites
Now working on the critter scripts and there are a couple of questions already.

  • The script lets critters die when hit by a magic effect. Makes certainly sense for destruction spells, and it is understandable that they won't survive the magic turbulences associated with a conjuration, illusion or alteration attack, because they are tiny creatures. But what about a restoration spell ? If no one objects, I'll make them immune to "restoration attacks".

 

Is this clearly and obviously a bug? If so yes, change it. If not then it seems to me that it would be a change "just for the sake of it" and is not, strictly speaking, suitable for inclusion in the USKP.

There's undoubtedly a million and one things which could be changed, the question is - should they?

Share this post


Link to post
Share on other sites

Poison Rune is an adept level Restoration spell that creates a rune which will explode when enemies come near, causing them to take 3 damage per second for 30 seconds.

 

so yes XD

 

Critters are not capable of activating runes (they aren't actors).

Share this post


Link to post
Share on other sites
Is this clearly and obviously a bug?

 

It is debatable. That's why I asked for opinions.

 

There's undoubtedly a million and one things which could be changed, the question is - should they?

 

Yes, if they clearly don't make any sense as they are.

Yes also, if the code unnecessarily costs performance and memory or if it clearly doesn't do what it was intended for.

 

Critter movement recurs to a number of geometric +/- trigonometric problems, of which not a single one has been appropriately implemented. Most of the time, variables are adapted to preset conditions by trial and error and in certain conditions, some functions never return a valid result even by chance. The critter script, for example, has a function that is supposed to let a critter fly around a spawner, but it lets the critter travel to one of the eight corners of the imaginary bounding box instead and effectively keeps it there until it gets eventually deleted. There's another example in the CritterBird script (the problem here should also be more obvious than in the last example):

FUNCTION groundHop()	
	trace(self + " beginning groundHop()")
	; Set up variables to solve for right triangle ABC
	; c is the hypotenuse - think of it as the path along which the bird hops
	; the a and c values are going to be added to current XY to determine goal XY
	float aA = getAngleZ()		;      B
 	float aB			;    /  |
 	float aC = 90			;  c/   |b	; we know angle C is 90 because it's a right triangle
 	float a				; A/____|C
 	float b				;     a	
	float c = randomFloat(fMinHop, fMaxHop)

 	; use an int to track the quadrant into which we're hopping (global)
	; I:(+,+)   II:(-,+)   III:(-,-)   IV:(+,-)

	int quadrant
 	if (aA > 0 && aA <= 90) || aA > 360			
		quadrant = 1
 	elseif aA > 90 && aA <= 180
		quadrant = 4
 	elseif aA > 180 && aA <= 270
		quadrant = 3
 	elseif aA > 270 && aA <= 360
		quadrant = 2
 	endif

	a = c*(cos(aB))
 	b = c*(cos(aA))

	float newX
 	float newY

	if quadrant == 1
 		newX = (self.x + a)
		newY = (self.y + b)
 	elseif quadrant == 2
		newX = (self.x - a)
 		newY = (self.y + b)
	elseif quadrant == 3
 		newX = (self.x - a)
		newY = (self.y - b)
 	elseif quadrant == 4
		newX = (self.x + a)
		newY = (self.y - b)
	endif
	; now use a spline to "hop" there quicky.
	SplineTranslateTo(newX, newY, self.z, 0, 0, self.getAngleZ(), 300, fSpeed)
	trace(self + "performing a short hop to: " + newX + ", " + newY + ".")
	; test, but a little pause between each seems proper.
	wait(randomFloat(0.1, 2.0))
endFUNCTION

It's no surprise that the scripts continue to spam "none" errors when the time between 3D checks is bloated by superfluous operations. This code does the same:

Function GroundHop()

	Float AngleZ = Self.GetAngleZ()
	Float HopDistance = RandomFloat (fMinHop, fMaxHop)

	Float NewX = Self.X + HopDistance * Cos (AngleZ)
	Float NewY = Self.Y + HopDistance * Sin (AngleZ)
	
	SplineTranslateTo (NewX, NewY, Self.Z, 0, 0, AngleZ, 300, fSpeed)

	Wait (RandomFloat (0.1, 2.0))

EndFunction

In other words, correcting inconsistencies like magic damage issues on the fly will take a ridiculously unimportant fraction of the time that has to be spent on the scripts anyway. When that's accomplished, I would feel extremely unhappy to modify them again for whatever reason. Therefore, I would like to get some consensus on all potential issues until I'm done.

Share this post


Link to post
Share on other sites

Point taken, I'm merely cautioning about "mission creep" - too many worthwhile projects have fallen by the wayside because of it ;)

i think hes looking at it from the angle hes redoing the whole bloody thing anyway you might as well optimize as you go

Share this post


Link to post
Share on other sites

In his Flora Respawn Fix, BlueDanieru also changed critters, added a switch from wait to an updategametime. I've looked at it an thought it wasn't done in a very backwardly compatible manner. But I'll include it here for you to gander:

Scriptname FXfakeCritterScript extends ObjectReference  
{Make fake critters shootable}

container Property myContainer Auto
Flora Property myFlora Auto
ingredient Property myIngredient Auto
potion Property myFood Auto
string Property myLocationOffset Auto
string Property myFakeForceExplosionOffset Auto
Explosion Property myExplosion Auto
Explosion Property myFakeForceExplosion Auto
objectReference myContainerRef
objectReference myIngredientRef
objectReference myExplosionRef
objectReference myFakeForceExplosionRef
objectReference myFloraRef
int Property numberOfIngredientsOnCatch Auto
int property hoursBeforeReset = 72 auto

Event OnActivate(ObjectReference akActionRef)
    self.disable()
    if myFood
        game.getplayer().additem(myFood, numberOfIngredientsOnCatch)
    endif
    if  myIngredient
        game.getplayer().additem(myIngredient, numberOfIngredientsOnCatch)
    endif
    RegisterForSingleUpdateGameTime(hoursBeforeReset)
EndEvent

Event OnHit(ObjectReference akAggressor, Form akSource, Projectile akProjectile, bool abPowerAttack, bool abSneakAttack, bool abBashAttack, bool abHitBlocked)
  if akAggressor == game.getplayer()
    if myContainer
      myContainerRef = self.placeAtMe(myContainer, 1, false, true)
      utility.wait(0.01)
      myContainerRef.enable(false)
      myContainerRef.MoveToNode(self, myLocationOffset)    
    endIf
    if myFlora
      myFloraRef = self.placeAtMe(myFlora, 1, false, true)
      utility.wait(0.01)
      myFloraRef.enable(false)
      myFloraRef.MoveToNode(self, myLocationOffset)    
    endIf
    utility.wait(0.1)
    self.disable()
    RegisterForSingleUpdateGameTime(hoursBeforeReset)
  endIf
EndEvent

Event OnUpdateGameTime()
  enable()
  if myContainerRef
    myContainerRef.disable()
    utility.wait(0.1)
    myContainerRef.delete()
  endif
  if myFloraRef
    myFloraRef.disable()
    utility.wait(0.1)
    myFloraRef.delete()
  endif
  if myIngredientRef
    myIngredientRef.disable()
  endif
endEvent

Share this post


Link to post
Share on other sites

 

In his Flora Respawn Fix, BlueDanieru also changed critters, added a switch from wait to an updategametime. I've looked at it an thought it wasn't done in a very backwardly compatible manner. But I'll include it here for you to gander:

....

I thought I read that this fix for the flora wasn't able to used in the USKP, due to some compatibility issues with the game engine or something like that. Sorry, maybe I'm missing something, but did someone finally find a way to integrate a fix for the flora respawn issue into the USKP without it causing other bugs?

Share this post


Link to post
Share on other sites

The flora fix is unsuitable for the USKP because he had to change all the animated flora objects into static tree objects to get the respawning to work. Or something like that. Not a solution we could accept.

Share this post


Link to post
Share on other sites

Thinking about it, this is another project that can be easily developed beyond a simple fix. I could add a few bugs to Skyrim's wildlife ... :innocent:

 

Thinking about this again, the pleasure of presenting such a mod alone would pay for the efforts of its development (after all, I would have to conceive new 3D models and textures in addition to the script). Imagine the short description on the Nexus:

  • "Bugs" will add immersion to your game ...
  • "Bugs" is intended as a modder's resource. Feel free to use them in your own mods ...
  • "Bugs" comes as a false-flagged master file (this one will probably take a while to setlle)

Share this post


Link to post
Share on other sites

I thought I read that this fix for the flora wasn't able to used in the USKP, due to some compatibility issues with the game engine or something like that. Sorry, maybe I'm missing something, but did someone finally find a way to integrate a fix for the flora respawn issue into the USKP without it causing other bugs?

Perhaps I wasn't clear. This is not about the flora respawn. This thread is about critters. He included a critter change from using OnCellAttach() to OnUpdate(). I was hoping to discuss whether that change was a good idea that should be adopted here.

 

The flora fix is unsuitable for the USKP because he had to change all the animated flora objects into static tree objects to get the respawning to work. Or something like that. Not a solution we could accept.

I concur -- although you have the details backward, he changed all the "TreeFlora" objects to new "FloraTreeFlora" objects. He had to do that in his design, because "TreeFlora" objects don't allow scripts. Regular "Flora" objects can have scripts.

 

My biggest objection is that meant it was incompatible with every plugin that moved a "TreeFlora" -- including USKP and Touring Carriages. It also means he needs a compatibility patch for every new interior, and every DLC, etc. He promises that on the Skyrim.Nexus, but never delivered.

 

I suggested a different approach, with a quest task monitoring the player adding to inventory, so that no new objects would be needed. Maybe I'll try to code that up, and see whether it works....

Share this post


Link to post
Share on other sites

Perhaps I wasn't clear. This is not about the flora respawn. This thread is about critters. He included a critter change from using OnCellAttach() to OnUpdate(). I was hoping to discuss whether that change was a good idea that should be adopted here.

Sorry about that. I guess I misunderstood what was being discussed.

Share this post


Link to post
Share on other sites

He had to do that in his design, because "TreeFlora" objects don't allow scripts. Regular "Flora" objects can have scripts.

Actually I'm interested if it is a CK limitation or game doesn't support scripts there.

Midas Magic had VMAD attached to explosions which is impossible to do in CK. I don't know if it worked at all, but there is a possibility.

I can create a special version of TES5Edit which will allow to add VMAD to flora if someone is willing to test it in game.

Share this post


Link to post
Share on other sites

Actually I'm interested if it is a CK limitation or game doesn't support scripts there.

Midas Magic had VMAD attached to explosions which is impossible to do in CK. I don't know if it worked at all, but there is a possibility.

I can create a special version of TES5Edit which will allow to add VMAD to flora if someone is willing to test it in game.

Sure, I'm interested!

Share this post


Link to post
Share on other sites

Very slowly, the nastier bugs come to surface.

 

Have a look at the critter kickoff, which is handled from an OnUpdate event in a state the Critter script is only in immediately after spawning (3D checks are needed so often that I have made it a new "CheckFor3D" function on the Critter script):

State KickOffOnStart

	Event OnUpdate()

		GotoState("")

		DummyMarker = PlaceAtMe (LandingMarkerForm)
		LandingMarker = PlaceAtMe (LandingMarkerForm)

		CheckFor3D (LandingMarker)
		CheckFor3D (DummyMarker)

		OnStart()
		Enable()

	EndEvent

EndState

Note the Enable() command after OnStart() returns. The latter is a custom event which contains critter-specific code and is handled therefore by each critter species script individually. For dragon flies, it looks as follows:

Event OnStart()

	SetScale (RandomFloat (fMinScale, fMaxScale))

	PlayAnimation (PathStartGraphEvent)

	If (PlayerRef.GetDistance (Self) > fMaxPlayerDistance)
		DisableAndDelete()
	Else

		WarpToRandomPoint()
		Enable()

		If CheckFor3D (Self As ObjectReference)
			SetMotionType (Motion_Keyframed, False)
			RegisterForSingleUpdate (0.0)
		Else
			DisableAndDelete (False)
		EndIf

	EndIf

EndEvent

This event has its own Enable() command and checks subsequently whether the critter does actually load. If not, it gets deleted. When the event is done, the script returns to the OnUpdate event on the Critter main script, and this will try to enable it again (see above). Very funny, when the critter is already deleted.

 

By the way, does anyone have an idea what sense it makes to play an animation when the critter is not yet enabled (second line in the OnStart() event) ?

Share this post


Link to post
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

Support us on Patreon!

×