protected IEnumerator SendPlayerToActionNode(int chunkID, string actionNodeName, float delay) { if (!GUILoading.IsLoading) { yield return(GUILoading.LoadStart(GUILoading.Mode.FullScreenBlack)); } Player.Local.Despawn(); //start off by setting the primary chunk GameWorld.Get.SetPrimaryChunk(chunkID); //action nodes won't exist unless it's primary while (GameWorld.Get.PrimaryChunk.CurrentMode != ChunkMode.Primary) //wait for the chunk to load before we send it there //Debug.Log("Waiting for primary chunk to load"); { yield return(null); } ActionNodeState nodeState = null; if (GameWorld.Get.PrimaryChunk.GetNode(actionNodeName, false, out nodeState)) { //send player to location string locationPath = WIGroup.AllButLastInPath(nodeState.ParentGroupPath); string locationName = WIGroup.LastInPath(nodeState.ParentGroupPath); STransform spawnPosition = nodeState.Transform; if (nodeState.IsLoaded) { spawnPosition = new STransform(nodeState.actionNode.transform, false); } yield return(StartCoroutine(SendPlayerToLocation(chunkID, locationPath, locationName, spawnPosition, GameWorld.Get.PrimaryChunk.ChunkOffset, delay))); } if (GUILoading.IsLoading) { yield return(GUILoading.LoadStart(GUILoading.Mode.FullScreenBlack)); } yield break; }
public void SpawnGuards( ) { //get the spawn guard nodes GuardSpawnNodes.Clear(); WorldChunk chunk = worlditem.Group.GetParentChunk(); ActionNodeState nodeState = null; for (int i = 0; i < State.GuardSpawnNodeNames.Count; i++) { if (chunk.GetNode(State.GuardSpawnNodeNames [i], false, out nodeState)) { GuardSpawnNodes.Add(nodeState.actionNode); } } if (chunk.GetNode(State.AlbertSpawnNodeName, false, out nodeState)) { AlbertSpawnNode = nodeState.actionNode; } for (int i = 0; i < GuardSpawnNodes.Count; i++) { Character newGuard = null; if (Characters.SpawnCharacter(GuardSpawnNodes [i], State.GuardTemplateName, State.GuardFlags, worlditem.Group, out newGuard)) { //something something, tell them to follow SpawnedGuards.Add(newGuard); } } Characters.GetOrSpawnCharacter(AlbertSpawnNode, "Albert", worlditem.Group, out SpawnedAlbert); mHasSpawnedGuards = true; enabled = true; }
public void ActivateGhost() { if (mActivating | mDeactivating) { return; } Activated = true; if (mSpeakingCharacter == null || mSpeakingCharacter.IsDestroyed) { if (mCharacterSpawnPoint == null) { WorldChunk c = worlditem.Group.GetParentChunk(); ActionNodeState actionNodeState = null; string nodeName = worlditem.FileName + "GhostNode"; if (!c.GetOrCreateNode(worlditem.Group, worlditem.tr, worlditem.FileName + "GhostNode", out actionNodeState)) { Debug.LogError("Couldn't create spawn node " + nodeName + " in ghost to create character"); return; } actionNodeState.actionNode.transform.position = worlditem.tr.position; actionNodeState.CustomConversation = State.CharacterConversation; if (!Characters.GetOrSpawnCharacter(actionNodeState.actionNode, State.CharacterName, worlditem.Group, out mSpeakingCharacter)) { Debug.LogError("Couldn't spawn character " + State.CharacterName + " in ghost"); } else { mSpeakingCharacter.worlditem.ActiveState = WIActiveState.Visible; mSpeakingCharacter.worlditem.ActiveStateLocked = true; Debug.Log("Setting character's conversation name to " + State.CharacterConversation); //we don't need motile for this character Motile m = null; if (mSpeakingCharacter.worlditem.Is <Motile> (out m)) { m.Finish(); } mSpeakingCharacter.Ghost = true; mSpeakingCharacter.Body.OnSpawn(mSpeakingCharacter); } } } if (mSpeakingCharacter != null) { Talkative t = mSpeakingCharacter.worlditem.Get <Talkative> (); t.State.ConversationName = State.CharacterConversation; t.State.DefaultToDTS = false; //don't show the body until we're sure it has its materials mSpeakingCharacter.Body.SetVisible(false); mSpeakingCharacter.Body.IgnoreCollisions(true); mSpeakingCharacter.Body.LockVisible = true; mActivating = true; StartCoroutine(ActivateOverTime()); enabled = true; } }
protected bool TryToSpawnCharacter(CharacterSpawnRequest spawnRequest) { if (spawnRequest.RequireOnFoot && !Player.Local.IsOnFoot) { //can't spawn character, player isn't on foot return false; } //get a point in the world behind the player mTerrainHit.feetPosition = Vector3.MoveTowards(Player.Local.Position, Player.Local.Position - Player.Local.ForwardVector, spawnRequest.MinimumDistanceFromPlayer); GameWorld.Get.TerrainHeightAtInGamePosition(ref mTerrainHit); if (mTerrainHit.hitWater) { //can't spawn character, hit water return false; } if (spawnRequest.SpawnNode == null) { //can't spawn character, spawn node was being created ActionNodeState spawnNodeState = null; GameWorld.Get.PrimaryChunk.GetOrCreateNode(WIGroups.Get.World, WIGroups.Get.World.transform, spawnRequest.ActionNodeName, out spawnNodeState); spawnRequest.SpawnNode = spawnNodeState.actionNode; } if (spawnRequest.SpawnNode == null) { //can't spawn character, spawn node was null return false; } else { spawnRequest.SpawnNode.transform.position = mTerrainHit.feetPosition; spawnRequest.SpawnNode.State.UseGenericTemplate = spawnRequest.UseGenericTemplate; spawnRequest.SpawnNode.State.CustomSpeech = spawnRequest.CustomSpeech; spawnRequest.SpawnNode.State.CustomConversation = spawnRequest.CustomConversation; } Character spawnCharacter = null; if (Characters.GetOrSpawnCharacter(spawnRequest.SpawnNode, spawnRequest.CharacterName, WIGroups.Get.World, out spawnCharacter)) { if (!string.IsNullOrEmpty(spawnRequest.DTSOnSpawn)) { spawnCharacter.LookAtPlayer(); spawnCharacter.worlditem.Get <Talkative>().SayDTS(spawnRequest.DTSOnSpawn); } return true; } else { Debug.Log("Couldn't spawn character for some reason"); } return false; }
public SpawnPoint(ActionNodeState actionNodeState) { nodeState = actionNodeState; }
public IEnumerable <SpawnPoint> GetSpawnPoints(SpawnerStateSetting setting, Location location, WIGroup spawnGroup, PlayerBase player, System.Random random) { //figure out how many we need setting.NumAttempts = 0; setting.NumFailedAttempts = 0; int numExistingObjects = spawnGroup.NumChildItemsByCategory(setting.CategoryName, setting.MaxSpawnedObjects); //TODO make sure this works int numObjectsToSpawn = random.Next(setting.MinSpawnedObjects, setting.MaxSpawnedObjects) - numExistingObjects; if (numObjectsToSpawn <= 0) { //we don't need any more right now #if UNITY_EDITOR Debug.Log("Skipping spawning in " + name + " because num objects to spawn is <= 0"); #endif yield break; } bool succeededThisAttempt = false; switch (setting.Type) { case SpawnerType.Characters: //when we're spawning characters, we need action nodes WorldChunk chunk = spawnGroup.GetParentChunk(); List <ActionNodeState> nodeStates = null; if (chunk.GetNodesForLocation(location.worlditem.StaticReference.FullPath, out nodeStates)) { for (int i = 0; i < nodeStates.Count; i++) { mNextSpawnPoint.nodeState = nodeStates [i]; yield return(mNextSpawnPoint); } } else { nodeStates = new List <ActionNodeState> (); Debug.Log("Didn't find spawn points at location, so we're going to create some"); //if we can't find any nodes for this location //that means we've never spawned here before //we need to create some nodes for (int i = 0; i < numObjectsToSpawn; i++) { //are we totally done? if (setting.NumFailedAttempts >= setting.MaxFailedAttempts) { yield break; } //if not, try to get another spawn point if (spawnGroup.Props.Interior) { succeededThisAttempt = GetInteriorSpawnPoint(ref mNextSpawnPoint, setting, location, spawnGroup); } else if (spawnGroup.Props.TerrainType == LocationTerrainType.AboveGround) { succeededThisAttempt = GetAboveGroundSpawnPoint(ref mNextSpawnPoint, setting, location, spawnGroup); } else { succeededThisAttempt = GetBelowGroundSpawnPoint(ref mNextSpawnPoint, setting, location, spawnGroup); } //did we do it? if (succeededThisAttempt) { //hooray we created a new action node setting.NumAttempts++; //turn this spawn point into an action node ActionNodeState nodeState = new ActionNodeState(); nodeState.Name = location.worlditem.FileName + "-Spawn-" + nodeStates.Count.ToString(); nodeState.Type = ActionNodeType.Generic; nodeState.Users = ActionNodeUsers.AnyOccupant; nodeState.Transform.CopyFrom(mNextSpawnPoint.Transform); mNextSpawnPoint.nodeState = nodeState; ActionNode node = chunk.SpawnActionNode(spawnGroup, nodeState, location.worlditem.tr); yield return(mNextSpawnPoint); } else { //boo, we failed setting.NumFailedAttempts++; } } } nodeStates.Clear(); nodeStates = null; break; default: //when we're spawning other things, we just need spawn points //ok, try to spawn this stuff for (int i = 0; i < numObjectsToSpawn; i++) { //are we totally done? if (setting.NumFailedAttempts >= setting.MaxFailedAttempts) { yield break; } //if not, try to get another spawn point if (spawnGroup.Props.Interior) { succeededThisAttempt = GetInteriorSpawnPoint(ref mNextSpawnPoint, setting, location, spawnGroup); } else if (spawnGroup.Props.TerrainType == LocationTerrainType.AboveGround) { succeededThisAttempt = GetAboveGroundSpawnPoint(ref mNextSpawnPoint, setting, location, spawnGroup); } else { succeededThisAttempt = GetBelowGroundSpawnPoint(ref mNextSpawnPoint, setting, location, spawnGroup); } //did we do it? if (succeededThisAttempt) { //hooray, we got another spawn point setting.NumAttempts++; yield return(mNextSpawnPoint); } else { //boo, we failed setting.NumFailedAttempts++; yield return(SpawnPoint.Empty); } } break; } yield break; }
public IEnumerator SpawnCharactersOverTime() { if (Globals.MissionDevelopmentMode) { //we don't care about random characters in mission dev mode HasSpawnedCharacters = true; mSpawningCharacters = false; yield break; } List <ActionNodeState> actionNodeStates = null; while (!GameManager.Is(FGameState.InGame) || (mSpawningCharacters && (location.LocationGroup == null || !location.LocationGroup.Is(WIGroupLoadState.Loaded)))) { yield return(null); } //set owner once it's available location.LocationGroup.Owner = worlditem; bool hasSpawnedMinorStructures = false; while (mSpawningCharacters && !hasSpawnedMinorStructures) { hasSpawnedMinorStructures = true; for (int i = 0; i < State.MinorStructures.Count; i++) { if (State.MinorStructures [i].LoadState != StructureLoadState.ExteriorLoaded) { hasSpawnedMinorStructures = false; break; } } double waitUntil = WorldClock.RealTime + 0.25f + UnityEngine.Random.value; while (WorldClock.RealTime < waitUntil) { yield return(null); } } if (!mSpawningCharacters) { yield break; } yield return(null); if (gTransformHelper == null) { gTransformHelper = new GameObject("City Transform Helper").transform; } gTransformHelper.position = worlditem.tr.position; gTransformHelper.rotation = worlditem.tr.rotation; gTransformHelper.localScale = worlditem.tr.lossyScale; //transform the movement node positions MovementNode mn = MovementNode.Empty; for (int i = 0; i < State.MovementNodes.Count; i++) { mn = State.MovementNodes [i]; mn.Position = MovementNode.GetPosition(gTransformHelper, mn); State.MovementNodes [i] = mn; } yield return(null); //TODO move this functionality into the Spawner script if (worlditem.Group.GetParentChunk().GetNodesForLocation(location.LocationGroup.Props.PathName, out actionNodeStates)) { Character spawnedCharacter = null; for (int i = 0; i < actionNodeStates.Count; i++) { if (!mSpawningCharacters) { //whoops, time to stop yield break; } spawnedCharacter = null; ActionNodeState actionNodeState = actionNodeStates [i]; if (actionNodeState.IsLoaded && actionNodeState.UseAsSpawnPoint && !actionNodeState.HasOccupant) { if (string.IsNullOrEmpty(actionNodeState.OccupantName)) { Characters.SpawnRandomCharacter( actionNodeState.actionNode, State.RandomResidentTemplateNames, State.ResidentFlags, location.LocationGroup, out spawnedCharacter); } else { Characters.SpawnRandomCharacter( actionNodeState.actionNode, actionNodeState.OccupantName, State.ResidentFlags, location.LocationGroup, out spawnedCharacter); } if (spawnedCharacter != null) { //let the character know it can use the city for movement nodes if it wants them DailyRoutine dailyRoutine = null; if (spawnedCharacter.worlditem.Is <DailyRoutine> (out dailyRoutine)) { dailyRoutine.ParentSite = this; } SpawnedCharacters.Add(spawnedCharacter); } } double waitUntil = WorldClock.RealTime + 0.5f + UnityEngine.Random.value; while (WorldClock.RealTime < waitUntil) { yield return(null); } } } HasSpawnedCharacters = true; //do we need to update our characters? if (SpawnedCharacters.Count > 0) { enabled = true; } mSpawningCharacters = false; yield break; }
public void FindNextTarget() { State.CurrentTarget++; if (State.CurrentTarget >= State.Targets.Count) { if (State.UseCharacterRoom) { State.CurrentTarget = -1; } else { State.CurrentTarget = 0; } } //if we use the character room (-1) then cycle that //otherwise go for the other targets if (State.CurrentTarget > 0) { ObexTransmitterTarget target = State.Targets [State.CurrentTarget]; } else { //send the camera to the character room TargetCamera.transform.position = CharacterRoomCameraTarget.position; TargetCamera.transform.rotation = CharacterRoomCameraTarget.rotation; //spawn the character if (mSpeakingCharacter == null || mSpeakingCharacter.IsDestroyed) { if (mCharacterSpawnPoint == null) { WorldChunk c = worlditem.Group.GetParentChunk(); ActionNodeState actionNodeState = null; string nodeName = worlditem.FileName + "TransmitterNode"; if (!c.GetOrCreateNode(worlditem.Group, worlditem.tr, worlditem.FileName + "TransmitterNode", out actionNodeState)) { Debug.LogError("Couldn't create spawn node " + nodeName + " in transmitter to create character"); return; } actionNodeState.actionNode.transform.position = CharacterRoomCharacterTarget.position; actionNodeState.CustomConversation = State.CharacterConversation; if (!Characters.GetOrSpawnCharacter(actionNodeState.actionNode, State.CharacterName, worlditem.Group, out mSpeakingCharacter)) { Debug.LogError("Couldn't spawn character " + State.CharacterName + " in transmitter"); } else { mSpeakingCharacter.worlditem.ActiveState = WIActiveState.Visible; mSpeakingCharacter.worlditem.ActiveStateLocked = true; Debug.Log("Setting character's conversation name to " + State.CharacterConversation); //we don't need motile for this character Motile m = null; if (mSpeakingCharacter.worlditem.Is <Motile> (out m)) { m.Finish(); } mSpeakingCharacter.Body.OnSpawn(mSpeakingCharacter); } } } //initiate conversation with the character if it exists //TODO make character look in direction of intermediary if (mSpeakingCharacter != null) { Talkative t = mSpeakingCharacter.worlditem.Get <Talkative> (); t.State.ConversationName = State.CharacterConversation; t.State.DefaultToDTS = false; mSpeakingCharacter.Body.SetVisible(true); mSpeakingCharacter.Body.IgnoreCollisions(true); mSpeakingCharacter.Body.LockVisible = true; t.SpeakThroughIntermediary(this); } } }