Need help identifying issue with critterspawn script

Post » Tue Jun 19, 2012 9:21 am

I lack the appropriate skills at this time to fully understand what is going on in the critterspawn script.

However, I know that it does not work in interior cells most of the time UNLESS you coc into the cell from the load screen. Worldspaces seem to work just fine. I looked at the critterspawn in the Winterhold Arch Mage and can find nothing different. That cell seems to function properly.

Can anyone with the necessary scripting skills please take a look at the script and see if you can identify the problem?

Spoiler
scriptName CritterSpawn extends ObjectReferenceimport Critterimport Utility;----------------------------------------------; Properties to be set for this Critter spawn;----------------------------------------------; The type of critter (base object) to createFormList property CritterTypes auto{ The base object to create references of to spawn critters}; The distance from this spawner that Moths are allowed to befloat property fLeashLength = 500.0 auto{ The distance that moths are allowed to be from this spawner}float property fLeashHeight = 50.0 auto{ The distance that dragonflies are allowed to be from above spawner}float property fLeashDepth = 50.0 auto{ The distance that fish are allowed to be from below spawner}float property fMaxPlayerDistance = 2000.0 auto{ The distance from the player before the Spawner stops spawning critters}int property iMaxCritterCount = 10 auto{ The maximum number of critters this spawner can generate}float property fFastSpawnInterval = 0.1 auto{ When spawning critters, the interval between spawns}float property fSlowSpawnInterval = 5.0 auto{ When spawning critters, the interval between spawns}GlobalVariable property GameHour auto{ Make this point to the GameHour global }float property fStartSpawnTime = 6.0 auto{ The Time after which this spawner can be active}float property fEndSpawnTime = 11.0 auto{ The Time before which this spawner can be active}float property fLeashOverride auto{Optional: Manually set roaming radius for critters spawned}bool property bSpawnInPrecipitation auto{Should this critter spawn in rain/snow?  DEFAULT: FALSE};----------------------------------------------; Constants (shouldn't need to modify these);----------------------------------------------float fCheckPlayerDistanceTime = 2.0;----------------------------------------------; Variables to keep track of spawned critters;----------------------------------------------int property iCurrentCritterCount = 0 auto hiddenbool bLoopingbool bPrintDebug = FALSE   ; should usually be set to false.int recursions; Do initial stuff when my 3D has loaded up.EVENT OnLoad(); The Spawner will register for update and periodically check whether the player is close or not; - JOEL REFACTOR - Going to use onLoad() & onUnload() instead of states?; GotoState("WaitingForPlayer"); - JOEL REFACTOR - also no longer need to update; RegisterForSingleUpdate(fCheckPlayerDistanceTime)if bPrintDebug == TRUE;   debug.trace("spawner " + self + " loaded.")  recursions = 0endif; set our control bool to start the loopbLooping = TRUEwhile bLooping == TRUE  if bPrintDebug == TRUE   recursions += 1;	debug.trace("spawner " + self +  " while loop #" + recursions)  endif  if shouldSpawn() == FALSE   ; wait a bit, then see if the player is close again.   ; Removing this to eliminate some TPLOG spam; ;	debug.TraceConditional("player not yet near spawner " + self, bPrintDebug)   utility.wait(fCheckPlayerDistanceTime)  else; ;	debug.TraceConditional("spawner " + self + " ready to spawn!!!", bPrintDebug)   ; player must be nearby - spawn our initial critters   ; don't follow up as we no longer wish to re-generate new critters until the player leaves entirely   spawnInitialCritterBatch()   bLooping = FALSE  endifendWhileendEVENTEVENT onUnload(); when our 3D unloads, stop looping until loaded again.bLooping = FALSE; ;  debug.TraceConditional("spawner " + self + " unloading due to onUnload() EVENT.", bPrintDebug)endEVENTEVENT onCellDetach()bLooping = FALSE; ;  debug.TraceConditional("spawner " + self + " unloading due to onCellDetach() EVENT.", bPrintDebug)endEVENTFunction SpawnInitialCritterBatch(); How many do we need to spawn?int icrittersToSpawn = iMaxCritterCount - iCurrentCritterCount; Create that many crittersint i = 0;while (i < icrittersToSpawn)  ; Create one critter at a time  SpawnCritter()  ; Wait a bit before the next spawn  ;Wait(fFastSpawnInterval)  ; Next  i = i + 1endWhileendFunction; Called by critters when they dieEvent OnCritterDied(); Decrement current critter count, next time OnUpdate; gets called, we'll spawn a new oneif iCurrentCritterCount > 0  iCurrentCritterCount = iCurrentCritterCount - 1elseif iCurrentCritterCount == 0  ; don't do anything if already @ zeroelse  ; iCurrentCritterCount must be in the negatives.  Something is up, but for now increment towards zero  iCurrentCritterCount = iCurrentCritterCount + 1endifendEvent; Spawns one Critterbool Function SpawnCritter()if (iCurrentCritterCount < iMaxCritterCount) && (iCurrentCritterCount >= 0)  ; Go ahead with the actual spawn  SpawnCritterAtRef(self)  ; Increment count  iCurrentCritterCount = iCurrentCritterCount + 1  return trueelseif iCurrentCritterCount < 0;   debug.trace("("+self+") has invalid iCurrentCritterCount of "+iCurrentCritterCount+", abort!")  ; turn off loop  bLooping = FALSEelse;   debug.trace("("+self+") SpawnCritter() failed because iCurrentCritterCount is "+iCurrentCritterCount);   ;debug.trace("("+self+") iMaxCritterCount: "+iMaxCritterCount)endifendFunction; Spawns one Critter at a specific locationFunction SpawnCritterAtRef(ObjectReference arSpawnRef); Pick a random critter typeActivator critterType = CritterTypes.GetAt(RandomInt(0, CritterTypes.GetSize() - 1)) as Activator; Create the critter and cast it to the critter base classObjectReference critterRef = arSpawnRef.PlaceAtMe(critterType, 1, false, true)Critter thecritter = critterRef as Critter; Set initial variables on the critter; ;  Debug.TraceConditional("Spawner " + self + " is creating Critter " + thecritter, bPrintDebug);thecritter.SetInitialSpawnerProperties(fLeashLength, fLeashHeight, fLeashDepth, fMaxPlayerDistance + fLeashLength, self)endFunction; Utility method that returns the player's distancefloat Function GetPlayerDistance()return Game.GetPlayer().GetDistance(self)endFunction; Utility method that tells the spawner whether it should spawn crittersbool Function ShouldSpawn();DREW - Added an extra safety measure for if the object is stuck in the spawn check loop while the 3d is not loaded; NOTE - is3dLoaded dumps an error when the 3d is not loaded, but the function still returns false which should;  set bLooping to false and jump out of the bLooping While, at which point no additional errors will be thrownif self.is3dLoaded()  if !(GetPlayerDistance() <= fMaxPlayerDistance)   return false  endIf  ; Otherwise, base value on time of day (no handling of wrap around though...)  return IsActiveTime()else  ;if the 3d is not loaded jump out of the looped state. Just an extra safety measure.;   ;debug.Trace(self + ": should be setting bLooping to False")  bLooping = FALSE  return falseendifendFunctionbool Function IsActiveTime()bool binTimeRange = falseif (fEndSpawnTime >= fStartSpawnTime)  binTimeRange = (GameHour.GetValue() >= fStartSpawnTime) && (GameHour.GetValue() < fEndSpawnTime)else  binTimeRange = (GameHour.GetValue() >= fStartSpawnTime) || (GameHour.GetValue() < fEndSpawnTime)endIfreturn binTimeRange && ((Weather.GetCurrentWeather() == none) || \		 (Weather.GetCurrentWeather().GetClassification() < 2) || \		 (bSpawnInPrecipitation == TRUE))endFunction

Would be most appreciated.
User avatar
Nicola
 
Posts: 3365
Joined: Wed Jul 19, 2006 7:57 am

Post » Tue Jun 19, 2012 1:10 pm

I have already read that script through and through prior to seeing this, and I even have mine working correctly within my mod... I have done nothing special to get it working. I have also seen the bug report stating your claim. However, mine is in an interior cell as well, yet no failures.

The trick to the critter spawn, is that the cell needs to be unloaded and loaded again to get more critters.
User avatar
Rachel Tyson
 
Posts: 3434
Joined: Sat Oct 07, 2006 4:42 pm

Post » Tue Jun 19, 2012 4:05 pm

Who knows man. I can recreate this consistently in indoor cells.

In order to avoid save bugs, I will coc into an adjacent cell then enter the interior cell with the critter spawns. The spawns work fine. I can walk around any adjacent interior cell and come back and the critter spawn works.

However, upon moving into the connecting exterior worldspace of Tamriel and re-entering the adjacent cell, and then going into the interior cell with the critter spawn, they no longer function.

Whatever though, I've spent too much time trying to figure this out. If they work for people they work, if not, oh well.

Thank you for your input.
User avatar
Nicola
 
Posts: 3365
Joined: Wed Jul 19, 2006 7:57 am

Post » Wed Jun 20, 2012 1:02 am

Well... one thing you could do is manually make the critter spawn respawn using http://www.creationkit.com/Reset_-_ObjectReference in some other script called by some sort of activator, or even a trigger.
User avatar
Marie Maillos
 
Posts: 3403
Joined: Wed Mar 21, 2007 4:39 pm

Post » Tue Jun 19, 2012 3:02 pm

It's not by any chance related to the NavMesh bug in some form?
User avatar
yermom
 
Posts: 3323
Joined: Mon Oct 15, 2007 12:56 pm

Post » Tue Jun 19, 2012 9:53 am

It's not by any chance related to the NavMesh bug in some form?

Dont know what you mean by that...
User avatar
Scott
 
Posts: 3385
Joined: Fri Nov 30, 2007 2:59 am

Post » Tue Jun 19, 2012 6:22 pm

Adding a trigger and referencing every critter spawn in the interior sounds like a lot more work than I want to put in to some butterflies..haha. Perhaps it's just my game that is doing it. Once I release the location I'll get some feedback from the community.

Thank you for the suggestion though.
User avatar
SaVino GοΜ
 
Posts: 3360
Joined: Mon Sep 17, 2007 8:00 pm

Post » Tue Jun 19, 2012 9:26 pm

Good lord. How may of those critter markers do you have?
User avatar
Mrs Pooh
 
Posts: 3340
Joined: Wed Oct 24, 2007 7:30 pm

Post » Tue Jun 19, 2012 10:05 pm

Just thought I'd update this.

Severed Skullz - A lot of critters...tons actually.

and....Daemonjax found and corrected the issue in the script for me. It will be in the next release of Deus Mons for anyone interested in taking a peak at what he did.
User avatar
JUan Martinez
 
Posts: 3552
Joined: Tue Oct 16, 2007 7:12 am

Post » Tue Jun 19, 2012 6:15 pm

i just started critterizing my interior and encountered this "bug"


turns out it is not a bug at all, this is intentional. moths are scripted to kill themselves at night, and then torchbugs take over.

so if you do not have torchbugs in your form list, there will be no bugs when you return at night.


from the vanilla moth script
; When the moths go to sleep, they get deletedState KillForTheNightEvent OnCritterGoalReached()  ; We've reached the nest, die;   debug.trace ("Killing for the night: "+self)  DisableAndDelete()endEventendState



i suggest trying it out, and see if the bugs only disappear at night.

if it is the case i suggest you delete your script (if it is modifying the vanilla critter script), because it will probably break all critters in skyrim, as well as all mods that use critters



if this still somehow breaks regardless of the time of day, i still suggest removing the script and applying a new one so that it does not override vanilla one, because the vanilla script is not broken.
User avatar
Nana Samboy
 
Posts: 3424
Joined: Thu Sep 14, 2006 4:29 pm


Return to V - Skyrim