Jump to content

Function to detect if Player is in a playerOwned Settlement?


Recommended Posts

Hey guys,

 

Does anybody knows of a simple way to detect if the player is currently inside the boundaries of a settlement that he owns?

 

I've been looking at the lengthy scripts of the related quests and it doesn't seem like there's any Faction or Formlist to which an owned settlement would be added, nor a keyword that'd be added to the settlements' cells or locations (apparently you can't add keywords nor ownership to exterior cells?)...

 

So far, it seems that my only resort could be to use lengthy arrays and custom functions to filter my arrays with ActorValues...

 

Would there be an obvious function I might have overlooked?

 

Many thanks in advance!

Link to comment
Share on other sites

Are you able to get the workshop reference when you want to determine whether the player's currently within a player owned settlement? If not, I'd check if the current location has the PlayerOwnedWorkshop ActorValue. If you are, you're able to call WorkshopRef.OwnedByPlayer. The former won't work in non-settlements such as Home Plate. The latter is the only way I've found to achieve that, but requires the workshop reference.

 

I wouldn't rely upon getting the workshop reference from the player's location, as that doesn't work in all areas of all workshops.

 

If you're looking for match conditions, you can also try LocationHasPlayerOwnedWorkshop.

Edited by KernalsEgg
Link to comment
Share on other sites

Thanks KernalsEgg, please don't bother launching your FO4 CK, I should be able to find my way, I hadn't thought of looking into the radiant quests, just the parent ones so far.

 

I guess I was hoping I had missed some obvious way (like you'd check your actual location against RefLocType or EncounterZone in Skyrim for instance) but apparently not.

 

Just for clarification "WorkshopRef" refers to the actual WorkshopBench (which is in fact a container) - not the location or cell, right? So that'd mean I'd have to FindClosestRefOfType(...) first to find that workbench if there's one, rather than use PlayerRef.GetLocation(), right?

 

The match condition could be interesting too as the script I'm using is attached to a MagicEffect - so that could indeed simplify a lot of things.

 

Thanks a lot! :)

Link to comment
Share on other sites

It's just the workshop reference, which is that of the settlements workbench. Just off the top of my head, the Sanctuary workshop reference is 250FE for example. There are a number of ways in which you can get the reference, such as through certain workshop related events. For example, opening and closing workshop mode gives you the workshop reference of the current settlement (in the form of akSender).

 

You can also check whether the location has a WorkshopRef type, but there are a couple odd scenarios when it's considered to be false. For example, when you have an outstanding quest for settlement NPCs (gotta kill those super mutants), or when the settlement's under attack.

 

Getting the workshop from the player's location is generally a bad idea. It works fine most of the time, but there's at least one settlement where there's a significant area within the workshop bounds that doesn't return a workshop.

 

Could you give me some more context? You can also get the workshop reference through linked references. For example, any workshop object is linked to the workshop reference through the WorkshopItemKeyword. Note, some pre-existing workshop objects such as Tatos on Abernathy farm don't have this keyword, but the UFO4P fixes this. You just need to use GetLinkedRef on that object with that keyword to get the workshop reference.

 

Basically, it can be unreliable to get the workshop reference if you're just hustling ass around your settlement, but it's easy if you have something to play with.

 

I've read that you can use the OnTriggerEnter() and OnTriggerLeave() Events to notify you when you enter/leave a workshops bounds. I didn't know enough back when I looked into it, so I didn't get too far, but that's something that you can look into as well if that interests you. I'll probably get around to it one of these days.

Edited by KernalsEgg
Link to comment
Share on other sites

Hey Homaii. I think I saw that vanilla scripts use this way to get the workshop for assigning settlers and it also worked for me even in DLC area.

WorkshopParentScript Property WorkshopParent Auto Const
  workshopscript WorkshopRef = WorkshopParent.GetWorkshopFromLocation(PlayerRef.GetCurrentLocation())

I`m not sure though if it only returns the workshop that is owned by player or any workshop...But there must be a way to chek the ownership . I`m sure I have seen it in some of vanilla scripts.

Link to comment
Share on other sites

All that function does is attempt to find the workshop from the player's current location (using the WorkshopParent WorkshopLocations array). That's what I was talking about above. Bethesda use that approach themselves, but surprise surprise, it doesn't work in some areas of some settlements. I don't recommend using this method, as it's not always reliable.

 

Edit: Specifically, this is the function you're referencing, for those interested.

 

 

 

WorkshopScript function GetWorkshopFromLocation(Location workshopLocation)
	int index = WorkshopLocations.Find(workshopLocation)
	if index < 0
		wsTrace(" ERROR - GetWorkshopFromLocation: workshop location " + workshopLocation + " not found in WorkshopLocations array", 2)
		return NONE
	else
		return Workshops[index] as WorkshopScript
	endif
endFunction 

 

 

Edited by KernalsEgg
Link to comment
Share on other sites

I did not notice prolems, but I have not used it that much and it was not critical for me. Maybe it`s related to script lags. Big scripts like WorkshopParent can sometimes cause some sort of lags. You can notice it when you assign settlers , sometimes it can take up to 5-8 seconds for it to work depending on the settemenrt size and number of settlers etc. I have also noticed that some settlements can be in 2 different locations in the same time. The bigger part is in one location and some small part near the border can be in another location. Maybe it`srelated to this then.

Link to comment
Share on other sites

Just off the top of my head, try it out in Somerville Place. There are several locations throughout the settlement that have issues. There shouldn't be any script lag involved in finding an entry in a ~37 entry array. I used this implementation in a mod of mine a while ago and remember getting a few complaints about this. This is one of the smaller settlements. Considering I don't experience any script lag in the larger settlements, there shouldn't be an issue. I could be wrong, though. Either way, it doesn't work for anyone I've contacted about this.

 

I had taken a picture of a couple locations, but I'm apparently unable to link to image sharing sites in this section of the forum (at least, using the image hosting sites that I tried). Brilliant.

Link to comment
Share on other sites

Wow, you're fast replying , thanks!.. Just went out to run some errand and I get a lot more answers already!.. :smile:

 

Actually, what I'm trying to do is indeed a condition check for a spell, checking:

 

A. whether the player is inside the boundaries of a settlement he owns,

B. whether or not this specific location's settlement has settlers.

 

The tricky thing is I'd want it to work for custom or modded settlements if I can.

 

Running a condition check on my spell would do the trick if that works.

 

Edit: maybe running the condition check through the WorkshopItemKeyword would work too because that spell can only be casted to the player if he is in SitState.

Link to comment
Share on other sites

Getting it to work with modded settlements shouldn't be an issue, so long as they've properly implemented their settlement into the vanilla system. Looks like you'll have to rely upon location. You can either pull the workshop reference from the WorkshopParent WorkshopLocations array using the player's current location (and then use WorkshopRef.OwnedByPlayer), use the LocationHasPlayerOwnedWorkshop match conditions, or check whether the location has the PlayerOwnedWorkshop ActorValue. There's probably a couple other ways that I'm just forgetting, but they'd all achieve approximately the same thing.

 

Edit: If you're sitting on an object that's a part of the workshop, you can probably use the WorkshopItemKeyword approach, as the OnSit() Event allows you to get the reference that you're sitting on.

Edited by KernalsEgg
Link to comment
Share on other sites

  • Recently Browsing   0 members

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