Jump to content

scripting made easy.... HA


Recommended Posts

ok so i have been bashing my head against the computer for a while now trying to figure out how to script, watching tutorials till my eyes bled and reading on wikis and yuckies and wookies but none seem to be clicking as to what im trying to do.

 

i have 10 bad guys and 10 good guys, i created LeveledCharacters Badguys and Goodguys and then placed 10 guys into each. then created 2 "actors" that are using the LvlCharacters as templates (cant seem to figure out how else to place them into the world).

 

added this script to the two "template" Actors and it partially works. they spawn one after another and the bodies disappear when they die and respawn YAY! BUT i was trying to get it to happen at certain times of the day, well that wasnt working. so would it be better to place markers and have them spawn at certain times of the day OR to add triggers that when the player enters the npc's will spawn?

 

i am thinking to just add triggers all over the place so when the player enters 5 from each LeveledCharacters (i created two factions and made them enemies) will spawn and they will automatically start fighting then when the player walks out of the trigger box they will all despawn.

 

so i will remove the time script from here but i dont know how to add into it to spawn at least 5 npc's.

Scriptname mbrespawn extends ObjectReference  


ActorBase Property ActorBaseProperty Auto
Int Property SecondsForRespawn Auto    

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}


Event OnDeath(Actor akKiller)
    Utility.wait(SecondsForRespawn)
    Self.PlaceActorAtMe(ActorBaseProperty)
    self.disable()
    self.delete()
    Self.DeleteWhenAble()
endevent

again, i know nothing on scripting and am trying to learn but english is the only language i know :sad:

Link to comment
Share on other sites

The problem is that you have no skill in papyrus scripting. Script below is thought to use for your triggerbox solution. Maybe its helpful. It does not despawn enemies as soon as player has left the triggerbox.

 

psychLvlActorTriggerScript

 

Scriptname psychLvlActorTriggerScript extends ObjectReference
; https://forums.nexusmods.com/index.php?/topic/10015408-scripting-made-easy-ha/

  GlobalVariable PROPERTY GameHour auto         ; use auto-fill here
 
  Float PROPERTY fStartSpawnTime =  6.0 auto    ; from 6AM
  Float PROPERTY fEndSpawnTime   = 11.0 auto    ; to  11AM

; make sure you fill next property by manuell selection
  ActorBase PROPERTY NPCBase auto        ; first way, enemies you want to spawn as baseobject
 ;Actor     PROPERTY NPC auto            ; second way, enemy as actor

  Bool bSpawning   ; [default=False], missing on original post

  Actor[] a        ; an array to hold Refs for spawned NPCs, filled at runtime


; -- EVENTs --

EVENT OnReset()
    Debug.Trace(" OnReset() - has been called for " +self)   ; the triggerbox got reset
ENDEVENT

EVENT OnInit()
    Debug.Trace(" OnInit() - has been called for " +self)    ; "self" is the triggerbox where this script is attached
ENDEVENT


EVENT OnTriggerEnter(ObjectReference triggerRef)
;===================
IF (triggerRef == Game.GetPlayer() as ObjectReference)
ELSE
    RETURN    ; - STOP -    player was not here!
ENDIF
;---------------------
    myF_Action(TRUE)    ; spawn enemies
ENDEVENT

EVENT OnTriggerLeave(ObjectReference triggerRef)
    ; let this empty
ENDEVENT


EVENT OnCellDetach()  ; player has left the cell of this triggerbox
;=================
IF ( bSpawning )
    bSpawning = False
    myF_Action(False)    ; remove enemies
ENDIF
ENDEVENT

EVENT OnUnLoad()  ; triggerbox gets unloaded for whatever reason
;=============
IF ( bSpawning )
    bSpawning = False
    myF_Action(False)    ; remove enemies
ENDIF
ENDEVENT


; -- FUNCTIONs -- 3

;---------------------------------
FUNCTION myF_Action(Bool bTrigger)
;---------------------------------
IF ( bTrigger )                      ; OnTriggerEnter()
    float f = GameHour.GetValue()

    IF (f < fStartSpawnTime) || (f > fEndSpawnTime)
        RETURN    ; - STOP -    out of time
    ENDIF
;   ------------------------
    bSpawning = TRUE
    myF_Spawn()
ELSE                                 ; OnCellDettach(), OnUnLoad()
    myF_CleanOut()
ENDIF
ENDFUNCTION


;-------------------
FUNCTION myF_Spawn()
;-------------------
; https://www.creationkit.com/index.php?title=PlaceActorAtMe_-_ObjectReference

    actor player = Game.GetPlayer()
    a = new Actor[5]    ; *** init array for five actors

int i = 0
    WHILE (i < 5)
        int iLevel = Utility.RandomInt(0, 4)        ; level of spawned actors
        actor aRef = self.PlaceActorAtMe(NPCBase, iLevel, None)                                ; first way
;;;        actor aRef = self.PlaceActorAtMe(NPC.GetBaseObject() as ActorBase, iLevel, None)    ; second way
        IF ( aRef )
            a[i] = aRef                             ; store actorRef to array
            Utility.Wait(0.1)                       ; small waiting here

            IF player.IsDead()
                RETURN ; - STOP - player has been killed, abort this loop immediately
            ENDIF
;           ---------------------
            aRef.StartCombat(player)                ; make npc aggressive against player
        ENDIF
        i = i + 1
    ENDWHILE
ENDFUNCTION


;----------------------
FUNCTION myF_CleanOut()
;----------------------
    actor player = Game.GetPlayer()

int i = 0
    WHILE (i < 5)
        actor aRef = a[i]            ; a[0] .. a[4]
        IF ( aRef )                                    ; make sure the array entry is valid
            IF aRef.IsDead()
                ; npc is dead, no more in combat
            ELSE
                aRef.StopCombat(player)                ; make npc unaggressive against player
            ENDIF
            
            aRef.DisableNoWait()    ; (1) make npc invisible
;;            aRef.Disable(TRUE)
            aRef.Delete()           ; (2) mark spawned NPC for delete
            aRef = None
            a[i] = aRef             ; (3) remove actor persistent, clear the entry
        ENDIF
        i = i + 1
    ENDWHILE

    actor[] b
    a = b                ; *** destroy array finally
ENDFUNCTION

 

 

 

This is the wiki database for papyrus https://www.creationkit.com/index.php?title=Category:Papyrus

Edited by ReDragon2013
Link to comment
Share on other sites

I think you can still put the script directly on the actor base. Use OnDeath still and wait the appropriate hours until respawn:

 

 

 

ActorBase Property ActorBaseProperty Auto
Int Property SecondsForRespawn Auto    

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}

Event OnDeath(Actor akKiller)
    Float Hour = GameHour.GetValue() 
    If Hour > fStartSpawnTime && Hour <= fEndSpawnTime
        Respawn()
    Elseif Hour > fEndSpawnTime 
        ;if hour is past fEndSpawnTime, wait the amount of hours till midnight plus the fStartSpawnTime
        Float HoursToWait = (24 - Hour) + fStartSpawnTime
        RegisterforSingleUpdateGameTime(HoursToWait)
    Else 
        ;if hour is less than fStartSpawnTime, wait amount of hours till fStartSpawnTime
        Float HoursToWait = fStartSpawnTime - Hour
        RegisterforSingleUpdateGameTime(HoursToWait)
    Endif
    
endevent

Event OnUpdateGameTime()
    Respawn()
EndEvent

Function Respawn()
    Self.PlaceActorAtMe(ActorBaseProperty)
    self.disable()
    self.delete()
    Self.DeleteWhenAble()
Endfunction

 

 

Link to comment
Share on other sites

thanx for the replies.

 

I think you can still put the script directly on the actor base. Use OnDeath still and wait the appropriate hours until respawn:

 


 

 

that helped to get the time working, but if i were to place the NPC in multiple areas around Tamriel would this kind of script be a performance hit on the game?

 

The problem you have no skill in papyrus scripting. Next code is thought to use for your triggerbox solution. Maybe its helpful. It does not despawn enemies, in case player has left the the triggerbox.

 

psychLvlActorTriggerScript

 


 

 

 

This is the wiki database for papyrus https://www.creationkit.com/index.php?title=Category:Papyrus

thanx for the wiki tut, theres soooo much i am wanting/trying to learn just a bit hard as i read. im a hands on kinda kreepo when it comes to learning, just wish there were like "multiple choice" and "press this if you wanna do that" type things in scripting HAHAHA.

 

anywayz, thanx for the help :)

Link to comment
Share on other sites

i been trying to manipulate the "critterspawn.psc" script to work as it is what i really like. it will spawn multiple at certain times and then once its over they disapear. but figuring out what to change the values to like "iCurrentCritterCount" and "iMaxCritterCount" im assuming its not possible without just rewriting the whole script.

Link to comment
Share on other sites

I don't think using the script on the actor would cause too much of a performance hit. The script will only do something if the actor dies, then after it respawns, won't do anything until the new actor dies and so on. I use a similar script for my mod Solar Street Lamps for FO4 and didn't notice a performance hit, even when placing multiple lights in multiple locations. Editing and using the critter script might work better though, just needs some testing.

Link to comment
Share on other sites

If i were you i would follow the 'Master Controller' logic, meaning that everything will be handle by just one script and not have 20 scripts, it's a certainly more performance friendly way to do it, plus you can easily control everything.


This logic requires to add to each actor one simple script with just 1 line that will fire "OnDeath()" and will execute/access the "Master Controller's Script Function" and from there the "Master Controller Script" will do/handle the rest according always with what you want to do.


* Too many "Wait()" functions running in the same session can and will cause a performance hit even if you have the strongest PC in the world, it's better to remove entairly the "Wait()" function an add a "RegisterForSingleUpdate()" that it will be handle by the "Master Controller" and not fireing 20 "Wait()" functions.


This requires a good knowledge of scripting/papyrus, but in this forum there are quite a few scripters that can help you with that like the ones that answer you before me.


Have a nice week.

Edited by maxarturo
Link to comment
Share on other sites

So if you want to do the Spawner route, you can maybe do something like this. Attach this script to a custom marker and have it extend object reference. Place the marker where you want your actors to spawn. It checks every 24 game hours if its actors are dead, and if they are, respawns them.

 

GlobalVariable Property GameHour Auto

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}

Actorbase Property ActorBaseProperty Auto 
Actor[] Property MyActors Auto Hidden


Event OnInit() 
    MyActors = New Actor[10] ;initalize actor array with a size of 10
    Int Index = 10 
    While Index > 0 ;place 10 actors at self and store them in the MyActors array
        Index -= 1 ;subtract 1 from index 
        MyActors[Index] = Self.PlaceActorAtMe(ActorBaseProperty)
    Endwhile 
    
    Float Hour = GameHour.GetValue() 
    If Hour >= fStartSpawnTime && Hour < fEndSpawnTime
        RegisterforSingleUpdateGameTime(24) ;update in 24 hours
    Elseif Hour > fEndSpawnTime 
        ;if hour is past fEndSpawnTime, wait the amount of hours till midnight plus the fStartSpawnTime
        Float HoursToWait = (24 - Hour) + fStartSpawnTime
        RegisterforSingleUpdateGameTime(HoursToWait)
    Else 
        ;if hour is less than fStartSpawnTime, wait amount of hours till fStartSpawnTime
        Float HoursToWait = fStartSpawnTime - Hour
        RegisterforSingleUpdateGameTime(HoursToWait)
    Endif
EndEvent


Event OnUpdateGameTime()
    Float Hour = GameHour.GetValue() 
    If Hour >= fStartSpawnTime && Hour < fEndSpawnTime
        Int Index = 10 
        While Index > 0 ;check if any of the actors are dead. If they are, respawn them.
            Index -= 1 ;subtract 1 from index 
            If MyActors[Index].IsDead() && Game.GetPlayer().HasLOS(MyActors[Index]) == False ;If actor in array is dead and player can't see the actor. 
                MyActors[Index].Disable()
                MyActors[Index].Delete()
                MyActors[Index] = Self.PlaceActorAtMe(ActorBaseProperty)
            Endif
        Endwhile 
        RegisterforSingleUpdateGameTime(24) ;update in 24 hours
    Elseif Hour > fEndSpawnTime 
        ;if hour is past fEndSpawnTime, wait the amount of hours till midnight plus the fStartSpawnTime
        Float HoursToWait = (24 - Hour) + fStartSpawnTime
        RegisterforSingleUpdateGameTime(HoursToWait)
    Else 
        ;if hour is less than fStartSpawnTime, wait amount of hours till fStartSpawnTime
        Float HoursToWait = fStartSpawnTime - Hour
        RegisterforSingleUpdateGameTime(HoursToWait)
    Endif
EndEvent
Link to comment
Share on other sites

  • 4 weeks later...

 

So if you want to do the Spawner route, you can maybe do something like this. Attach this script to a custom marker and have it extend object reference. Place the marker where you want your actors to spawn. It checks every 24 game hours if its actors are dead, and if they are, respawns them.

 

Dylbill can i message you? im having problems with that script you posted. they are not respawning.

 

i took a break from this mod to work on other things and am back to it again so im back into retard scripting mode again lol.

 

but i created 20 npc's 10 good and 10 bad. placed the bad into a "leveledCharater" and the good into another one, then created agood and bad actor that uses those as template.

 

i really wanted say like 5 of each to spawn when the player enters a trigger box and then they despawn when the player leaves but i cant even get a trigger box to work properly lol. my CK wont create one i have to create a "multiboundmarker".

 

so my other idea was to have them spawn only for a couple hours then despawn, but during the time if the die they respawn another npc from the formlist i created with their names in it. so they wont be duplicates.

 

and once i get that working i will place these boxes all over the lands so their battles can be seen not in just one spot.

Link to comment
Share on other sites

  • Recently Browsing   0 members

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