Jump to content

Spawning random NPC from leveled list


MasterMuhaha

Recommended Posts

guys, an other problem. i need an npc to be disabled at 24 o'clock and to be enabled and COMPLETELY RESET at 6 o´clock.

 

the purpose of all this is that i have a randomized-character-npc which should generate/output an npc from the leveled list it is based on. but it appears to be, that once an npc from the leveled list has been generated, it stays there. what i mean is, i want to have an other npc from the leveled list to spawn after an enable-disable-sequence, but there is always the same npc from the list spawning.

 

i thought, that it might work, if i simply do not ENABLE the leveled-list-npc at 6 o´clock, but make it spawn an other one of its kind with a placeatme-command and delete the original with markfordelete. now, since i have problems with programming in papyrus, i ask for your help. :)

Link to comment
Share on other sites

I think to do this is better a PlaceActorAtMe()? Setting an ActorBase property for that and filling with your leveled list will do the thing imho (not sure).

 

Problem is the disable. I don't know how to disable a script created reference.

 

EDIT: just found this http://www.creationkit.com/Reset_-_ObjectReference. Reading it i can't understand if it resets the ActorBase too, respawning a new actor. Try it.

Edited by gasti89
Link to comment
Share on other sites

"(Reset) Resets this object reference to its original location, resets its inventory, resurrects it if it's an actor, and in general tries to get it back to its original state. May optionally move it to the location of the specified reference instead."

 

- so it won't spawn a new actor.

 

Each reference has its own individual characteristics. What you need to do is spawn a new random reference from the leveled list, and delete the old reference. All the leveled list does is randomly choose an npc from the list. The list would have several versions of the same npc with different level/stats.

 

The previous scripts that we gave you simply enabled/disabled the SAME actor reference AFTER it was spawned by the leveled list.

 

What you want is a custom spawner, similar to the critter spawner, that spawns x npcs from a leveled list at a particular time, and deletes it/them at a particular time. The critter spawner script works very much like this but picks the critters from a formlist. Actually, I just had a lightbulb moment, you could have several different npcs already placed in the same location, all disabled, then using the previous scripts we gave you, just have the script randomly choose one of the npcs to enable each time :woot: The npcs could either be given each a property, or you could set up a formlist with each npc reference in it (like the critter spawner uses). Would that suit your purposes?

Edited by steve40
Link to comment
Share on other sites

uhm i thought of something different. as i can only operate with the old scripting language, i would really appreciate if you could "translate" the following script in the papyrus language:

 

this is a script applied to the leveled npc with the id "TestNPC":

 

;--------------------------------------------------------------------------------------------------------------------

scn myscript

 

float time

ref me

int doonce

 

begin gamemode

 

set time to getcurrenttime

set me to getself

 

if time >= 22 && time < 6

me.disable

else

if doonce != 1

me.placeatme TestNPC 1

me.markfordelete

set doonce to 1

endif

endif

 

end

;--------------------------------------------------------------------------------------------------------------------

 

man, i miss the old scripting language. everything was so simple then :(

Edited by MasterMuhaha
Link to comment
Share on other sites

I believe that there are problems with actually attaching scripts to leveled characters (ie leveled list of characters). If you do manage to do it somehow (whether through magic effects or whatever else), then yes it is quite possible.

 

By the way, the script you posted wouldn't work even in Oblivion. First of all, the condition of time being greater than 22 and at the same time less than 6 will never happen. The actors will never disable themselves, and only the 'else' part of the script will run.

 

You'd end up with actors that kept trying to deleting themselves and spawning new actors from their leveled list. And these new actors will proceed to do the same thing, since presumably they have the same script on them. An infinite loop.

Link to comment
Share on other sites

the condition of time being greater than 22 and at the same time less than 6 will never happen
I meant "||" (or) of course, not "&&" (and). Thank you :)

 

You'd end up with actors that kept trying to deleting themselves and spawning new actors from their leveled list. And these new actors will proceed to do the same thing, since presumably they have the same script on them. An infinite loop.
Ah, don't worry. I thought about this. This is why I added the "doonce" variable. And why do you think the "disable" function won't work with actors calling it on themselves? It always did, as far as I can recall.

 

So, to get back to my actual request: could someone try to "translate" this script from the old scripting language in Papyrus? Here is it again (corrected version) :

 

scn myscript

float time
ref me
int doonce

begin gamemode

set time to getcurrenttime
set me to getself

if time >= 22 || time < 6
me.disable
else
if doonce != 1
me.placeatme TestNPC 1
set doonce to 1
me.markfordelete
endif
endif

end

Link to comment
Share on other sites

I haven't tested this script yet, but this is along the lines of what you want.

 

This is a spawner script. Place an activator/trigger reference into the game where you want the npc to spawn (do not place the leveled list reference directly in the game).

Attach this script to the activator. Don't assign any triggers, we just want the activator to be an invisible placeholder for the script (like a critter spawner object).

Assign your leveled list to the TestNPC property.

Oh, it would be a good idea to uncomment the debug statements in the script while you are testing it.

(If it won't compile, I'll test it when I get home. I'm not sure if I got the casts right for the leveled list and spawned actor, will this test later)

 

 

Scriptname TimedSpawnControl extends ObjectReference  
{Script to spawn an Actor from a leveled list between two different hours of the day.
THIS IS A SPAWNER SCRIPT. PLACE THIS SCRIPT ON AN INVISIBLE ACTIVATOR(SPAWNER OBJECT) WHERE YOU WANT THE NPC TO SPAWN.
The actor will be spawned, or disabled and deleted at the specified time.
This script can also cope with a disable time that is earlier than the enable time.
There's an option to either spawn a new actor (DeleteMe=TRUE) or to enable/disable an existing one (DeleteMe=FALSE) without further spawning. }
;***************************************************

GlobalVariable Property GameHour  auto
{You need to autofill this property from the CK}

float Property EnableTime = 6.0 auto
{Enable me at about 6am by default}

float Property DisableTime = 24.0 auto
{Disable me at about midnight by default}

bool Property DeleteMe = TRUE auto
{Delete me after disabling me}

ActorBase Property TestNPC auto
{This should point to your leveled list}

Actor myActor = NONE

float interval ; The time interval for the next update

;***************************************************

Event OnInit()
{A bit of idiot proofing...}

       ; make sure sensible values have been set
       If EnableTime < 0.0 || EnableTime > 24.0
               EnableTime = 6.0 ; failsafe default
       EndIf

       ; make sure sensible values have been set
       If DisableTime < 0.0 || DisableTime > 24.0
               DisableTime = 24.0 ; failsafe default
       EndIf

EndEvent

;***************************************************

Event OnLoad()
{start the good stuff...}

       CheckTime() ; check the time and spawn/disable me as required

EndEvent

;***************************************************

Event OnUpdateGameTime()
{Continue checking at set intervals}

       CheckTime() ; check the time and spawn/disable me at calculated intervals

EndEvent

;***************************************************
;***************************************************







;***************************************************
;** FUNCTIONS
;***************************************************

Function CheckTime()
{Decide whether to spawn the actor or disable and delete it}

;       Debug.MessageBox("[TimedSpawnControl] CheckTime was called.")

       If IsActiveTime()
	If !myActor
		myActor = PlaceActorAtMe(TestNPC) ; spawn an Actor from the leveled list
	Else
		myActor.Enable()
	EndIf
       Else
	If DeleteMe
                myActor.Disable()
		myActor.DeleteWhenAble() ; if Actor is persistant, must do it this way
		myActor = NONE	; important to do
	Else	
		myActor.Disable()
	EndIf
       EndIf

       GetInterval() ; calculate the next time interval to check
       RegisterForSingleUpdateGameTime(interval)

EndFunction

;***************************************************

bool Function IsActiveTime()
{Returns TRUE if current time is within the active time range}

       bool bTimeRange = false
float fGHour = GameHour.GetValue()

       If (DisableTime >= EnableTime)
               bTimeRange = (fGHour >= EnableTime) && (fGHour < DisableTime)
       Else
               bTimeRange = (fGHour >= EnableTime) || (fGHour < DisableTime)
       EndIf

;       Debug.MessageBox("[TimedSpawnControl] IsActiveTime returned: " + bTimeRange)

       Return bTimeRange

EndFunction

;***************************************************

Function GetInterval()
{Calculate the time interval for the next update call}

       float int1
       float int2
float fGHour = GameHour.GetValue()

       If EnableTime >= fGHour
               Int1 = EnableTime - fGHour
       Else
               Int1 = EnableTime - fGHour +24
       EndIf
               
       If DisableTime >= fGHour
               Int2 = DisableTime - fGHour
       Else
               Int2 = DisableTime - fGHour +24
       EndIf

       If Int1 <= Int2 ; choose the smallest time interval
               interval = Int1
       Else
               interval = int2
       EndIf

       If Interval < 0.167
               interval = 0.167 ; set the minimum update interval to about 10 game minutes
       EndIf

;       Debug.MessageBox("[TimedSpawnControl] The next update will be in " + interval + " hours.")

EndFunction

;***************************************************

 

 

EDIT: Script compiles OK.

Edited by steve40
Link to comment
Share on other sites

  • Recently Browsing   0 members

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