//searches chunks and loads location data into the locationData list //only searches for locations added using the SetMapData function public IEnumerator LocationsForChunks(string chunkName, int chunkID, Queue <WorldMapLocation> locationData, List <MapMarker> activeMapMarkers) { //Debug.Log ("WorldMap: LocationsForChunks"); List <MobileReference> locationList = null; if (!mRevealableToShow.TryGetValue(chunkName, out locationList)) { //Debug.Log ("WorldMap: We have no locations for this chunk from SetMapData, returning immediately"); yield break; } Vector3 chunkPosition; //add markers for (int i = 0; i < activeMapMarkers.Count; i++) { if (activeMapMarkers [i].ChunkID == chunkID) { chunkPosition = activeMapMarkers [i].ChunkPosition; WorldMapLocation wml = new WorldMapLocation( null, 1, "Marker", string.Empty, string.Empty, true, false, "MapIconMapMarker", Color.white, MapIconStyle.Medium, MapLabelStyle.None, Vector3.zero, chunkPosition, false, false, LocationTypesToDisplay); locationData.Enqueue(wml); } } MobileReference currentLocation = null; for (int i = 0; i < locationList.Count; i++) { if (!LoadData) { //Debug.Log ("WorldMap: Load data is false, returning"); yield break; } currentLocation = locationList [i]; StackItem stackItem = null; if (WIGroups.LoadStackItem(currentLocation, out stackItem)) { chunkPosition = stackItem.ChunkPosition; //Debug.Log ("WorldMap: found stack item " + stackItem.DisplayName); //next we need to get the location state from the stack item LocationState ls = null; RevealableState rs = null; VisitableState vs = null; bool isNewLocation = false; bool isMarked = false; if (NewLocations.Count > 0) { for (int j = NewLocations.LastIndex(); j >= 0; j--) { if (NewLocations [j] == currentLocation) { NewLocations.RemoveAt(j); isNewLocation = true; break; } } } //Debug.Log ("current location " + currentLocation.FullPath + " is marked? " + isMarked.ToString ( )); isMarked = MarkedLocations.Contains(currentLocation); if (stackItem.GetStateData <RevealableState> (out rs)) { stackItem.GetStateData <LocationState> (out ls); stackItem.GetStateData <VisitableState> (out vs); //now convert it into a world map location WorldMapLocation wml = null; if (rs.CustomMapSettings || ls == null) { //non-custom settings come from the location //so we can only use custom settings if ls is not null //Debug.Log ("Custom settings for revealable with " + rs.IconName + " icon name"); wml = new WorldMapLocation( currentLocation, stackItem.Props.Local.ActiveRadius, ls != null ? ls.Name.CommonName : string.Empty, ls != null ? ls.Name.ProperName : string.Empty, ls != null ? ls.Name.NickName : string.Empty, vs != null ? vs.HasBeenVisited : true, rs.MarkedForTriangulation, rs.IconName, rs.IconColor, rs.IconStyle, rs.LabelStyle, rs.IconOffset, chunkPosition, isNewLocation, isMarked, LocationTypesToDisplay); locationData.Enqueue(wml); } else { string iconName = "Outpost"; MapIconStyle iconStyle = MapIconStyle.None; MapLabelStyle labelStyle = MapLabelStyle.None; Color32 iconColor = Color.gray; Vector3 iconOffset = Vector3.zero; GetIconProperties(stackItem, ls, rs, vs, ref iconName, ref iconStyle, ref labelStyle, ref iconColor, ref iconOffset); wml = new WorldMapLocation( currentLocation, stackItem.Props.Local.ActiveRadius, ls != null ? ls.Name.CommonName : string.Empty, ls != null ? ls.Name.ProperName : string.Empty, ls != null ? ls.Name.NickName : string.Empty, vs != null ? vs.HasBeenVisited : true, rs.MarkedForTriangulation, iconName, iconColor, iconStyle, labelStyle, iconOffset, chunkPosition, isNewLocation, isMarked, LocationTypesToDisplay); locationData.Enqueue(wml); } } else { //Debug.Log ("Didn't get revealable state data in " + currentLocation.FileName); } } else { //Debug.Log ("Didin't get stack item for location " + currentLocation.FullPath); } //clear the stack item, we don't need it any more if (stackItem != null) { stackItem.Clear(); } yield return(null); } locationList.Clear(); yield break; }
//this function is meant to be used with the HouseOfHealing skill //i've only been able to get this process to work a few times //the idea is to super-load the last visited HOH //then load its interior and put the player in one of its beds //great in theory but in practice something always f***s up protected IEnumerator SpawnInClosestStructureOverTime(Vector3 despawnPosition, List <MobileReference> structureReferences, Action <Bed> OnFinishAction) { if (mSpawningPlayer) { //whoops yield break; } mSpawningPlayer = true; CurrentStartupPosition = null; float closestDistanceSoFar = Mathf.Infinity; StackItem closestStructureStateSoFar = null; StackItem currentStructureState = null; MobileReference currentStructureReference = null; MobileReference closestStructureReferenceSoFar = null; Vector3 closestStructurePositionSoFar = despawnPosition; WorldChunk currentChunk = null; //find out which structure is the closest for (int i = 0; i < structureReferences.Count; i++) { currentStructureReference = structureReferences [i]; //Debug.Log ("SPAWNMANAGER: Checking structure reference " + currentStructureReference.FullPath.ToString ()); if (WIGroups.LoadStackItem(currentStructureReference, out currentStructureState)) { if (currentStructureState.Is <Structure> ()) { //get the chunk for this item if (GameWorld.Get.ChunkByID(currentStructureReference.ChunkID, out currentChunk)) { Vector3 structureWorldPosition = WorldChunk.ChunkPositionToWorldPosition(currentChunk.ChunkBounds, currentStructureState.ChunkPosition); structureWorldPosition += currentChunk.ChunkOffset; float currentDistance = Vector3.Distance(despawnPosition, structureWorldPosition); if (currentDistance < closestDistanceSoFar) { closestDistanceSoFar = currentDistance; closestStructureStateSoFar = currentStructureState; closestStructureReferenceSoFar = currentStructureReference; closestStructurePositionSoFar = structureWorldPosition; } } } } } if (closestStructureStateSoFar == null) { yield break; } //move the player to the position of the new item //this will help us to super-load the structure Player.Local.Position = closestStructurePositionSoFar; //reset the current loading structure mSpawnStructureWorldItem = null; Structure spawnStructure = null; Bed loadedBed = null; //super-load the item //yield return null; //WorldItems.Get.SuspendActiveStateChecking = true; StartCoroutine(WIGroups.SuperLoadChildItem(closestStructureReferenceSoFar.GroupPath, closestStructureReferenceSoFar.FileName, SpawnStructureLoaded, 0f)); WIGroup lastGroupLoaded = null; while (mSpawnStructureWorldItem == null) { yield return(null); } //WorldItems.Get.SuspendActiveStateChecking = false; //okay next we have to load the structure interior mSpawnStructureWorldItem.ActiveStateLocked = false; mSpawnStructureWorldItem.ActiveState = WIActiveState.Active; mSpawnStructureWorldItem.ActiveStateLocked = true; yield return(null); //now that the player is where they're supposed to be we can resume active state checking //but keep the structure itself locked //Player.Local.Position = mSpawnStructureWorldItem.Position; //ColoredDebug.Log ("Sending player to spawn structure position " + mSpawnStructureWorldItem.Position.ToString (), "Yellow"); spawnStructure = mSpawnStructureWorldItem.Get <Structure> (); spawnStructure.LoadPriority = StructureLoadPriority.SpawnPoint; if (spawnStructure.Is(StructureLoadState.ExteriorUnloaded)) { yield return(StartCoroutine(spawnStructure.CreateStructureGroups(StructureLoadState.ExteriorLoaded))); Structures.AddExteriorToLoad(spawnStructure); while (spawnStructure.Is(StructureLoadState.ExteriorLoading | StructureLoadState.ExteriorWaitingToLoad)) { yield return(null); } } if (spawnStructure.Is(StructureLoadState.ExteriorLoaded)) { Structures.AddInteriorToLoad(spawnStructure); while (spawnStructure.Is(StructureLoadState.InteriorWaitingToLoad | StructureLoadState.InteriorLoading)) { yield return(null); } spawnStructure.RefreshColliders(true); spawnStructure.RefreshRenderers(true); //finally we search for a bed } spawnStructure.StructureGroup.Load(); while (!spawnStructure.StructureGroup.Is(WIGroupLoadState.Loaded)) { yield return(null); } yield return(null); //wait a tick to let the group catch up //wait a tick to let the group catch up yield return(null); List <WorldItem> bedWorldItems = new List <WorldItem> (); while (bedWorldItems.Count == 0) { yield return(StartCoroutine(WIGroups.GetAllChildrenByType(spawnStructure.StructureGroup.Props.PathName, new List <string> () { "Bed" }, bedWorldItems, spawnStructure.worlditem.Position, Mathf.Infinity, 1))); //can't use WaitForSeconds because timescale will be zero double waitUntil = WorldClock.RealTime + 0.1f; while (WorldClock.RealTime < waitUntil) { yield return(null); } } WorldItem bedWorldItem = bedWorldItems [0]; while (!bedWorldItem.Is(WILoadState.Initialized)) { yield return(null); } loadedBed = bedWorldItem.Get <Bed> (); //Player.Local.Position = loadedBed.BedsidePosition; mSpawningPlayer = false; mSpawnStructureWorldItem.ActiveStateLocked = false; OnFinishAction(loadedBed); Player.Local.Surroundings.StructureEnter(spawnStructure); yield break; }