/// <summary> /// Spawns a ghost for the indicated mind's body and transfers the connection's control to it. /// </summary> /// <param name="conn"></param> /// <param name="oldBody"></param> /// <param name="characterSettings"></param> /// <param name="occupation"></param> /// <returns></returns> public static void ServerSpawnGhost(Mind forMind) { //determine where to spawn the ghost var body = forMind.GetCurrentMob(); var settings = body.GetComponent <PlayerScript>().characterSettings; var connection = body.GetComponent <NetworkIdentity>().connectionToClient; var registerTile = body.GetComponent <RegisterTile>(); if (registerTile == null) { Logger.LogErrorFormat("Cannot spawn ghost for body {0} because it has no registerTile", Category.ItemSpawn, body.name); return; } Vector3Int spawnPosition = body.GetComponent <ObjectBehaviour>().AssumedWorldPositionServer().RoundToInt(); if (spawnPosition == TransformState.HiddenPos) { //spawn ghost at occupation location if we can't determine where their body is Transform spawnTransform = GetSpawnForJob(forMind.occupation.JobType); if (spawnTransform == null) { Logger.LogErrorFormat("Unable to determine spawn position for occupation {1}. Cannot spawn ghost.", Category.ItemSpawn, forMind.occupation.DisplayName); return; } spawnPosition = spawnTransform.transform.position.CutToInt(); } var matrixInfo = MatrixManager.AtPoint(spawnPosition, true); var parentNetId = matrixInfo.NetID; var parentTransform = matrixInfo.Objects; //using parentTransform.rotation rather than Quaternion.identity because objects should always //be upright w.r.t. localRotation, NOT world rotation var ghost = Object.Instantiate(CustomNetworkManager.Instance.ghostPrefab, spawnPosition, parentTransform.rotation, parentTransform); ghost.GetComponent <PlayerScript>().registerTile.ServerSetNetworkedMatrixNetID(parentNetId); forMind.Ghosting(ghost); ServerTransferPlayer(connection, ghost, body, EVENT.GhostSpawned, settings); //fire all hooks var info = SpawnInfo.Ghost(forMind.occupation, settings, CustomNetworkManager.Instance.ghostPrefab, SpawnDestination.At(spawnPosition, parentTransform)); Spawn._ServerFireClientServerSpawnHooks(SpawnResult.Single(info, ghost)); }
/// <summary> /// Spawns a ghost for the indicated mind's body and transfers the connection's control to it. /// </summary> /// <param name="conn"></param> /// <param name="oldBody"></param> /// <param name="characterSettings"></param> /// <param name="occupation"></param> /// <returns></returns> public static void ServerSpawnGhost(Mind forMind) { if (forMind == null) { Logger.LogError("Mind was null for ServerSpawnGhost", Category.Ghosts); return; } //determine where to spawn the ghost var body = forMind.GetCurrentMob(); if (body == null) { Logger.LogError("Body was null for ServerSpawnGhost", Category.Ghosts); return; } var settings = body.GetComponent <PlayerScript>().characterSettings; var connection = body.GetComponent <NetworkIdentity>().connectionToClient; var registerTile = body.GetComponent <RegisterTile>(); if (registerTile == null) { Logger.LogErrorFormat("Cannot spawn ghost for body {0} because it has no registerTile", Category.Ghosts, body.name); return; } Vector3Int spawnPosition = TransformState.HiddenPos; var objBeh = body.GetComponent <ObjectBehaviour>(); if (objBeh != null) { spawnPosition = objBeh.AssumedWorldPositionServer(); } if (spawnPosition == TransformState.HiddenPos) { //spawn ghost at occupation location if we can't determine where their body is Transform spawnTransform = SpawnPoint.GetRandomPointForJob(forMind.occupation.JobType, true); if (spawnTransform == null) { Logger.LogErrorFormat("Unable to determine spawn position for occupation {1}. Cannot spawn ghost.", Category.Ghosts, forMind.occupation.DisplayName); return; } spawnPosition = spawnTransform.transform.position.CutToInt(); } var matrixInfo = MatrixManager.AtPoint(spawnPosition, true); var parentTransform = matrixInfo.Objects; //using parentTransform.rotation rather than Quaternion.identity because objects should always //be upright w.r.t. localRotation, NOT world rotation var ghost = UnityEngine.Object.Instantiate(CustomNetworkManager.Instance.ghostPrefab, spawnPosition, parentTransform.rotation, parentTransform); forMind.Ghosting(ghost); ServerTransferPlayer(connection, ghost, body, Event.GhostSpawned, settings); //fire all hooks var info = SpawnInfo.Ghost(forMind.occupation, settings, CustomNetworkManager.Instance.ghostPrefab, SpawnDestination.At(spawnPosition, parentTransform)); Spawn._ServerFireClientServerSpawnHooks(SpawnResult.Single(info, ghost)); if (PlayerList.Instance.IsAdmin(forMind.ghost.connectedPlayer)) { var adminItemStorage = AdminManager.Instance.GetItemSlotStorage(forMind.ghost.connectedPlayer); adminItemStorage.ServerAddObserverPlayer(ghost); ghost.GetComponent <GhostSprites>().SetAdminGhost(); } }