WIGWAM Posted August 26, 2018 Share Posted August 26, 2018 I'm trying to spawn an NPC at a random offset from the player each time the NPC spawn. The relevant parts of the script are: ScriptName zzDCScript Extends Quest int zzSpawntimer = 1 ActorBase Property Critter1Base auto Actor Property PlayerRef auto ObjectReference property TargetMarker auto ;An XMarker placed in the commonwealth. Float Random Function Random() Random = Utility.RandomFloat(250,500) EndFunction Event OnInit() StartTimer(15, zzSpawntimer) TargetMarker.SetPosition((PlayerRef.GetPositionX() + Random), (PlayerRef.GetPositionY() + Random),(PlayerRef.GetPositionZ())) ; move the xmarker to player with random x and y offsets. ObjectReference newCritter1 = TargetMarker.PlaceActorAtMe(Critter1Base) ;Spawn NPC EndEvent ;some other code after this... The problem I have with this is:1. The NPCs only spawn when the player is in the commonwealth (excluding diamond city and goodneighbour) i.e. where the original marker is placed. 2. The NPCs spawn on top of the player. Are there any changes I can make to this so the NPCs will spawn no matter where the player is and have the NPC spawn with an offset? Thanks, WIGWAM. Link to comment Share on other sites More sharing options...
ElPolloAzul Posted August 26, 2018 Share Posted August 26, 2018 I'm trying to spawn an NPC at a random offset from the player each time the NPC spawn. The relevant parts of the script are: ScriptName zzDCScript Extends Quest int zzSpawntimer = 1 ActorBase Property Critter1Base auto Actor Property PlayerRef auto ObjectReference property TargetMarker auto ;An XMarker placed in the commonwealth. Float Random Function Random() Random = Utility.RandomFloat(250,500) EndFunction Event OnInit() StartTimer(15, zzSpawntimer) TargetMarker.SetPosition((PlayerRef.GetPositionX() + Random), (PlayerRef.GetPositionY() + Random),(PlayerRef.GetPositionZ())) ; move the xmarker to player with random x and y offsets. ObjectReference newCritter1 = TargetMarker.PlaceActorAtMe(Critter1Base) ;Spawn NPC EndEvent ;some other code after this... The problem I have with this is:1. The NPCs only spawn when the player is in the commonwealth (excluding diamond city and goodneighbour) i.e. where the original marker is placed. 2. The NPCs spawn on top of the player. Are there any changes I can make to this so the NPCs will spawn no matter where the player is and have the NPC spawn with an offset? Thanks, WIGWAM. 1.) For one thing, you are positioning the spawning marker with SetPosition(), which changes the coordinates of an ObjectReference. Each worldspace (and interior) has its own coordinate plane. You might want to use MoveTo to relocate the marker to the Player (this takes into account also the cell & worldspace of the target reference). If there's just a coordinate change, you are likely plopping down your actors close to the middle of the Commonwealth map when you are in, for instance, interiors. 2.) Random seems to refer to a variable you declared (Float Random), but did not intuitively define. You do assign a value in the body of a function also called Random(), but is this function called per random deviate you want (x and y) to generate? Also, if you wanted to immediately get the return value of the function and add it to the result of a GetPosition call, you would want to declare your function as such (float Function Random() and explicitly return the value of Utility.RandomFloat(250,500)). Link to comment Share on other sites More sharing options...
WIGWAM Posted August 26, 2018 Author Share Posted August 26, 2018 Thanks, I think I have sorted, I haven't tested it out but I'm not getting any compilation errors. Changed the relevant line to this: ; ; float Function Random() Return Utility.RandomFloat(250,500) EndFunction ; ; ; TargetMarker.MoveTo(PlayerRef,(PlayerRef.GetPositionX() + Random()), (PlayerRef.GetPositionY() + Random()), (PlayerRef.GetPositionZ())) ; ; ; Link to comment Share on other sites More sharing options...
SKKmods Posted August 26, 2018 Share Posted August 26, 2018 X and Y run positive and negative so to totally randomise all quadrants you may want to add a random bit flip: If (Utility.RandomInt(0,1) == 0) Return Utility.RandomFloat(250.0,500.0) Else Return Utility.RandomFloat(-250.0,-500.0) EndifIf you would like your actors to face the player after spawning for instant engagement: Float fHeading = ThisActorREF.GetHeadingAngle(pPlayerREF) ThisActorREF.SetAngle( ThisActorREF.GetAngleX(), ThisActorREF.GetAngleY(), (ThisActorREF.GetAngleZ() + fHeading) ) ThisActorREF.Enable(abFadein = True)If you don't want the player to see the actor slew, as soon as you PlaceActorAtMe then .Disable(abfadout = False) move 'em around and then enable. Link to comment Share on other sites More sharing options...
WIGWAM Posted August 27, 2018 Author Share Posted August 27, 2018 Thanks both of you. I have tested this but now the NPCs have started spawning off the top left corner of the map, I had to put a quest marker on it the find out where they are. The location of the marker doesn't seem to change when I fast travel or change cell. Could it be a problem with the reference I'm using - should I use the ObjectReference for the player or the actor reference? Link to comment Share on other sites More sharing options...
SKKmods Posted August 27, 2018 Share Posted August 27, 2018 Yes totally must be the ObjectReference, to help with casting the naming conventions are usually: ObjectReference Property pPlayerREF auto const mandatoryActor Property pPlayerACTOR auto const mandatory Can define one or either to save casting as: (pPlayerREF as Actor).ActorScriptFunction()(pPlayerActor as ObjectReference).ORScriptFunction() If I am calling both a lot in a script I set 'em both as properties for a tiny performance bonus on calls. Really doesn't matter, just makes *me* happy :) Link to comment Share on other sites More sharing options...
markyrocks Posted August 27, 2018 Share Posted August 27, 2018 (edited) Edit, ok nm it looks like the script is being called by a quest. What is the relevant part of the quest script that calls this script? I'd like to see that. Edited August 27, 2018 by markyrocks Link to comment Share on other sites More sharing options...
ElPolloAzul Posted August 27, 2018 Share Posted August 27, 2018 TargetMarker.MoveTo(PlayerRef,(PlayerRef.GetPositionX() + Random()), (PlayerRef.GetPositionY() + Random()), (PlayerRef.GetPositionZ()))Thanks both of you. I have tested this but now the NPCs have started spawning off the top left corner of the map, I had to put a quest marker on it the find out where they are. The location of the marker doesn't seem to change when I fast travel or change cell. Could it be a problem with the reference I'm using - should I use the ObjectReference for the player or the actor reference? If you are using just MoveTo (as opposed to doing MoveTo to do a relocation to the player's cell and position and then a SetPosition based on the new absolute coordinates you compute), I think those offsets should be then relative-to-the-target (not incorporating player position) rather than absolute. There's an example of these semantics on the Creation Kit wiki for Skyrim (but amusingly not the Fallout 4 page?): Actor PlayerRef = Game.GetPlayer() Portal.MoveTo(PlayerRef, 120.0 * Math.Sin(PlayerRef.GetAngleZ()), 120.0 * Math.Cos(PlayerRef.GetAngleZ()), PlayerRef.GetHeight() - 35.0) Link to comment Share on other sites More sharing options...
markyrocks Posted August 27, 2018 Share Posted August 27, 2018 (edited) Function MoveTo(ObjectReference akTarget, float afXOffset = 0.0, float afYOffset = 0.0, float afZOffset = 0.0, bool abMatchRotation = true) native Based on this you are getting the x and y coordinates and taking those values and adding random() to those values and using them as the offset. Hence if the player is at x=100, y=100. Your using x=100 + random as the offset. Obviously in that scenario it might be close but if it was x=600 y=1000.... some times its easier to figure out what is going on if you define the variables outside of the function call. I realize it's not as tidy but sometimes unexpected stuff can happen bc its overly complicated. I think that's right. I've been hesitant to reply with any advice bc I been getting alot of stuff wrong lately. But I'm pretty sure that what I'm saying is correct Basically I'm saying the offset is relative to the player position as if the player was at 0,0 relative to himself but you're taking the x and y relative to his position in the world or cell (not sure ) then adding random and using those combined values as the offset. I could be completely off base in assuming this isn't what you're trying to do. I'm assuming that you want the creature to spawn in the general vicinity of the player. But based on what is happening now the creature is going to spawn in a random spot on the map that may or may not be close to the player. Also I'd advise you to use debug.notification to spit out values of these variables and even let you know where in your script you are. Bc again there could be unexpected behavior that youd never know how or why it's happening without the notifications. Save you alot of pain and frustration Edited August 27, 2018 by markyrocks Link to comment Share on other sites More sharing options...
WIGWAM Posted August 28, 2018 Author Share Posted August 28, 2018 Thanks. Finally got this working by doing a MoveTo then a SetPosition command on the marker. Link to comment Share on other sites More sharing options...
Recommended Posts