MasterMuhaha Posted June 18, 2012 Share Posted June 18, 2012 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 More sharing options...
MasterMuhaha Posted June 18, 2012 Author Share Posted June 18, 2012 please guys, i need help Link to comment Share on other sites More sharing options...
gasti89 Posted June 18, 2012 Share Posted June 18, 2012 (edited) 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 June 18, 2012 by gasti89 Link to comment Share on other sites More sharing options...
steve40 Posted June 19, 2012 Share Posted June 19, 2012 (edited) "(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 June 19, 2012 by steve40 Link to comment Share on other sites More sharing options...
MasterMuhaha Posted June 19, 2012 Author Share Posted June 19, 2012 (edited) 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 timeref meint doonce begin gamemode set time to getcurrenttimeset me to getself if time >= 22 && time < 6 me.disableelse if doonce != 1 me.placeatme TestNPC 1 me.markfordelete set doonce to 1 endifendif end;-------------------------------------------------------------------------------------------------------------------- man, i miss the old scripting language. everything was so simple then :( Edited June 19, 2012 by MasterMuhaha Link to comment Share on other sites More sharing options...
MasterMuhaha Posted June 19, 2012 Author Share Posted June 19, 2012 is it even possible? i mean common, if the OLD scripting language can do this, why not papyrus? Link to comment Share on other sites More sharing options...
MasterMuhaha Posted June 19, 2012 Author Share Posted June 19, 2012 is it even possible? i mean common, if the OLD scripting language can do this, why not papyrus? Link to comment Share on other sites More sharing options...
fg109 Posted June 19, 2012 Share Posted June 19, 2012 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 More sharing options...
MasterMuhaha Posted June 20, 2012 Author Share Posted June 20, 2012 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 More sharing options...
steve40 Posted June 20, 2012 Share Posted June 20, 2012 (edited) 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 June 20, 2012 by steve40 Link to comment Share on other sites More sharing options...
Recommended Posts