Jump to content

Code to get an object based on distance


SMB92

Recommended Posts

Hi folks,

 

I'm wondering what the best way to get an object based on a distant check, dynamically in game. Namely we want to get a marker, that either has a keyword or is defined in a formlist. All the markers are the same.

 

Basically I want to my script to pick out a loaded marker that is n units away from the player at least, set that as a the object to run my script on, I have every other part covered for now. I've tried a few things but no luck with this.

 

I've had enough of playing with code for the weekend so reaching out for ideas on this one. Cheers.

Link to comment
Share on other sites

  • Replies 40
  • Created
  • Last Reply

Top Posters In This Topic

Top Posters In This Topic

What about these functions?

FindClosestReferenceOfAnyTypeInList

FindClosestReferenceOfAnyTypeInListFromRef

FindClosestReferenceOfType

FindRandomReferenceOfAnyTypeInList

FindRandomReferenceOfAnyTypeInListFromRef

FindRandomReferenceOfType

FindRandomReferenceOfTypeFromRef

FindAllReferencesWithKeyword

Link to comment
Share on other sites

Nice list.

 

How can I use the FindRandom options to look for an object between say 2000 and 4000 units away from the player? At least without having to check that after I have the object and potentially having to keep grabbing one until my distance spec returns true?

Link to comment
Share on other sites

I think I've confused myself lol. Instead of looking for how to set min/max value, i should offset the search and define the radius. I'll have a play with that.
Link to comment
Share on other sites

Yes sorry, you just can check them in the wiki, it tells how to use them and provides examples. This would be too much info to copypaste.

You could also use a quest with an alias for the marker and conditions "Getdistance" to the player, HasKeyword, IsInlist etc. It`s just hard to say what is more effective in your case without more details.

Edited by kitcat81
Link to comment
Share on other sites

Yes sorry, you just can check them in the wiki, it tells how to use them and provides examples. This would be too much info to copypaste. Â

You could also use a quest with an alias for the marker and conditions "Getdistance" to the player, HasKeyword, IsInlist etc. It`s just hard to say what is more effective in your case without more details.

Thats about where I'm at, not sure which method is the most effective and economical.

 

I'll outline the plan a bit better:

 

Every so many seconds (this value can be defined by the user) as the player walks around the world I want the script to grab an object randomly some distance away from the player, namely a spawnpoint, which is an xmarker. I've placed my same base marker all over the map. When it gets this xmarker it runs code to make a spawn. I am going to use states to organize the code, so in the "find" state we get the marker aka spawnpoint, then we go to "spawn" state to run my code on the object, if it got one. Then we go back to "timer" state which then goes back to "find" etc.

 

Theres a few more things that go on in the code based on some variables but this is essentially all i need that get/find function to do, and do so reliably + economically ;)

Link to comment
Share on other sites

So these markers were placed by you. Then maybe you can go another way and add a script to the marker (if the marker is an activator it should not be a problem..and you can turn it into an activator if needed) :

Event OnLoad()
RegisterForDistanceLessThanEvent(Game.GetPlayer(), Self as ObjectReference,  2000.0)
EndEvent 

Event OnDistanceLessThan(ObjectReference akObj1, ObjectReference akObj2, float afDistance)
;Your cool stuff here, spawn enemies etc
EndEvent

Event OnUnload()
UnregisterForAllEvents()
EndEvent

I think it would be more economically than to run the script every 5 seconds.

Another way would be to add trigger boxes in different places. Though I have no idea how to do that :smile:

 

 

PS Just though if the marker is invisible..I`m not sure it get`s load events, have not tried that. But you can use a visible activator object as a trigger. And if you decide to use a quest maybe you can use OnLocationChange events . So each time the player changes location the quest will pick up the closest marker.

Edited by kitcat81
Link to comment
Share on other sites

I can either use a quest or an object in a persistent cell that loads at game start to receive the event, however I am preferring a quest so I can set stages to run other codes depending on the status of the mod (think uninstall stage etc). I believe the quest is also preferable for reliability in saving the state of the code, rather than forcing an OnLoad event everytime.

 

Problem with adding scripts to markers is, 1. They are persistent in the save game and 2. Multiple instances of scripts firing close by modify each others values. Example for the latter, if I have a timer in the "generic" script each time one fires it resets the timer on all of them. I'm not sure this is suppose to happen but thats what I saw with that. It would be a tremendous amount of work to make individual points, which could amount to the thousands.

 

Regarding the marker being invisible and load events, they seem to present even when not persistent, which would be required they not be persistent, or we could end up with spawns outside of loaded areas occasionally.

 

The code you posted above is really good for "ambush" type spawns, because their markers are few and far between. So you've have indeed answered a question I haven't even asked myself yet :D

Link to comment
Share on other sites

Just crossed my mind too, I suppose I have to get the players position for these coordinates

 

ObjectReference randomRef = Game.FindRandomReferenceOfType(Ref, 0.0, 0.0, 0.0, 5.0)

 

EDIT: The above way would be if I couldn't do the following on something similar:

 

Unless I can do this (Put a ">" sign in front of afRadius value or something similar):

 

ObjectReference SPP = Game.FindRandomReferenceOfTypeFromRef(ASC_SPP_Base, Game.GetPlayer(), >5.0)

Link to comment
Share on other sites

You can try OnCellAttach. It will ensure that nothing spawns for as long as the player isn't in the cell. OnLoad can fire before you enter.

Markers are statics, and the find functions may not pick up your markers for this reason, especially if they are not in an ObjectReference property. As you are concerned about persistence, it means they aren't in properties. So you can try this instead:

Form kMarker = Game.GetFormFromFile(0x00000034, "Fallout4.ESM") ; XmarkerHeadings, or use the formID 0x0000003B for xmarkers if using those)
ObjectReference kRandMarker = .Game.FindRandomReferenceOfTypeFromRef(kMarker, Game.GetPlayer(), 4096.0) ; radius is length of a cell.

This will ensure that it ONLY searches for XmarkerHeadings and not pick up other markers, and beth uses ton of markers have you've seen. Do not make arCenter the marker though, in case you want to do that. The find functions will always return arCenter if its the same type as arBaseObject.

I know that doesn't help much with the initial problem. I like to use dummy markers specifically for this and then do things to the real object I want to use through a script on the dummy marker.

Edited by TheDungeonDweller
Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.

×
×
  • Create New...