Jump to content

Placing a actor at the player.


Recommended Posts

I'm trying to place a actor near the player with a script but for some reason it doesn't spawn the NPC. And i have no clue whats wrong with the script.

ScriptName Quest extends Quest Conditional

Static Property XMarker Auto 
ActorBase Property EnemyNPC Auto

Function SpawnNPC() 
ObjectReference PlayerLocationMarker = Game.GetPlayer().PlaceAtMe(Xmarker) 
PlayerLocationMarker.PlaceActorAtMe(EnemyNPC)
Edited by Icrusher
Link to comment
Share on other sites

Do you need the xmarker for something specific? If you place an xmarker each time you want to spawn an actor, then you will have quite a lot of xmarkers in-game by the end of the day. Something like this should work:

ActorBase Property EnemyNPC Auto

Game.GetPlayer().PlaceAtMe(EnemyNPC)

According to the wiki: http://www.creationkit.com/index.php?title=PlaceAtMe_-_ObjectReference

 

Hopefully that helps a bit. :thumbsup:

 

Also, this page here might come in handy --> http://www.creationkit.com/index.php?title=Script_Objects

Link to comment
Share on other sites

I don't need the xmarker for something but i want to place multiple actors at the same time at the same location.

 

The idea of the script is placing a small group of npc's near the player.

 

After the script finishes i have.

 

PlayerLocationMarker.Disable()
PlayerLocationMarker.Delete()
For some reason it still doesn't seem to work.
Edited by Icrusher
Link to comment
Share on other sites

Ah, okay. That sounds odd. Have you checked your Papyrus log? Could it have something in it? For example, if one of your properties is not filled, then Papyrus cannot place anything anywhere.

 

Spawning multiple instances of the same actor would work by setting the spawn count higher. Multiple actors, one of each, could work with a FormList and a while loop to interate through it, for example. I think?

 

What does that one below produce? I cannot test myself at the moment, though.

ActorBase Property EnemyNPC Auto

Function SpawnTest()
    Debug.MessageBox("EnemyNPC property: " + EnemyNPC) ; <-- shows you the contents of the property
    Game.GetPlayer().PlaceAtMe(EnemyNPC, 2) ; <-- to place two of them
    Debug.MessageBox("Actors should be spawned just now")
EndFunction
Link to comment
Share on other sites

It says: EnemyNPC Property: none

 

Wait nvm for some reason whenever i actually call it EnemyNPC isntead of my orignal name: JNPC_VampireHunter_Melee_01

It works i think there is a issue with The _ or something.

 

Yeh i removed all _ and its seems to works strange....

Edited by Icrusher
Link to comment
Share on other sites

Great (sort of)! That means your property is empty. When the property is empty, the game cannot place an actor, since the actor property does not point at an actor. Solving the issue with the empty property should also solve the issue with your enemies not appearing. :thumbsup:

 

There is something funny going on with filling properties in the Creation Kit after the mod has been loaded in-game. For example quest scripts. If there is a property on a quest script, and the property is empty when the quest is loaded in-game, filling the property in the Creation Kit will not cause the property to get filled in-game unless starting a new game (in which case the property would be considered initially filled when first loaded). It looks like as if the game remembered (or, the player's savegame remembered) the contents of a property as they were when initially loaded in-game. Changing property contents with scripting commands works, though.

 

If the property is filled in the Creation Kit, but "none" in-game, have you tried renaming the property (to make it look like a new one to the game), filling it too, and then loading the game and trying? Just to test it?

 

Edit: Reworded that. Sorry. My communication skills are absolutely inexistent.

Edited by Contrathetix
Link to comment
Share on other sites

No problem, happy to help. Good luck with your project. :thumbsup:

 

If you need to place one of each actor in a list, you can do that with a FormList. You mentioned a group of actors, so I am dropping this here in case it will be useful for someone looking to place actors:

FormList Property EnemyList Auto

Function SpawnWholeList()
    Int i = EnemyList.GetSize()
    Actor PlayerRef = Game.GetPlayer()
    While ( i > 0 )
        i -= 1
        PlayerRef.PlaceAtMe(EnemyList.GetAt(i), 1) ; place one
    EndWhile
EndFunction

Edit: Oooopsie, I forgot about storing the refs for deletion. Since there is no SKSE for the Special Edition yet, a static size array is probably the only option. The script below is just an idea, I cannot test it at the moment, so it might not even compile, although I think it should work. If someone wants to use it, make sure it works okay before publishing anything that uses it. I have other things to do and booting up my desktop would just result in me sitting at it the whole night. :tongue:

ScriptName _SomePrefix_SpawnEffectScript Extends ActiveMagicEffect

; assuming this one can be attached to an effect, then this could be used for all spawning
; and the objects to spawn could be changed by swapping the FormList - also single-element lists work

FormList Property ObjectList Auto
ObjectReference[] RefArr

Event OnEffectStart(Actor akTarget, Actor akCaster)
    ; without SKSE, array sizes need to be literals written into the script,
    ; so picking something that is at least enough would be handy
    Debug.MessageBox("OnEffectStart, spawning stuff at " + akCaster + "...")
    Int i = ObjectList.GetSize()
    RefArr = New ObjectReference[16]
    If ( i > RefArr.Length )
        Debug.MessageBox("too many items in FormList, increase RefArr size, dispelling...")
        Dispel()
    Else
        While ( i > 0 )
            i -= 1
            RefArr[i] = akCaster.PlaceAtMe(ObjectList.GetAt(i))
        EndWhile
    EndIf
    Debug.MessageBox("OnEffectStart, spawn finished")
EndEvent

Event OnEffectFinish(Actor akTarget, Actor akCaster)
    Debug.MessageBox("OnEffectFinish, marking for delete...")
    Int i = RefArr.Length
    While ( i > 0 )
        i -= 1
        If ( RefArr[i] )
            RefArr[i].Disable()
            RefArr[i].Delete()
        EndIf
    EndWhile
    Debug.MessageBox("OnEffectFinish, marking finished")
EndEvent

Edit 2: Fixed up some formatting issues in the post. :blush: Anyone feel free to point out any issues or other suspicious-looking things.

Edited by Contrathetix
Link to comment
Share on other sites

Script Properties are baked into game saves. If you want to update one that has already been established, changing it in the CK will have no effect because it's already too late. You can do it in-game by running a suitable script, though, to change the property to a new value.

Edited by OldMansBeard
Link to comment
Share on other sites

Script Properties are baked into game saves. If you want to update one that has already been established, changing it in the CK will have no effect because it's already too late. You can do it in-game by running a suitable script, though, to change the property to a new value.

I prefer to have a fresh save, and just test a bunch on that one. It's easier than revisions via script

Link to comment
Share on other sites

  • Recently Browsing   0 members

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