private void TrySpark() { //Has to be broken and have power to spark if (mState != LightMountState.Broken || powerState == PowerStates.Off) { return; } //25% chance to do effect and not already doing an effect if (DMMath.Prob(75) || currentSparkEffect != null) { return; } var worldPos = registerTile.WorldPositionServer; var result = Spawn.ServerPrefab(CommonPrefabs.Instance.SparkEffect, worldPos, gameObject.transform.parent); if (result.Successful) { currentSparkEffect = result.GameObject; //Try start fire if possible var reactionManager = MatrixManager.AtPoint(worldPos, true).ReactionManager; reactionManager.ExposeHotspotWorldPosition(worldPos.To2Int()); SoundManager.PlayNetworkedAtPos(SingletonSOSounds.Instance.Sparks, worldPos, sourceObj: gameObject); } }
/// <summary> /// Play footsteps at given position. It will handle all the logic to determine /// the proper sound to use. /// </summary> /// <param name="worldPos">Where in the world is this sound coming from. Also used to get the type of tile</param> /// <param name="stepType">What kind of step does the creature walking have</param> /// <param name="performer">The creature making the sound</param> public static void FootstepAtPosition(Vector3 worldPos, StepType stepType, FloorSounds Override = null) { MatrixInfo matrix = MatrixManager.AtPoint(worldPos.RoundToInt(), false); if (matrix == null) { return; } var locPos = matrix.ObjectParent.transform.InverseTransformPoint(worldPos).RoundToInt(); var tile = matrix.MetaTileMap.GetTile(locPos) as BasicTile; if (tile != null) { FloorSounds FloorTileSounds = tile.floorTileSounds; List <AddressableAudioSource> AddressableAudioSource = null; if (Override != null && tile.CanSoundOverride == false) { FloorTileSounds = Override; } switch (stepType) { case StepType.None: return; case StepType.Barefoot: AddressableAudioSource = FloorTileSounds?.Barefoot; if (FloorTileSounds == null || AddressableAudioSource.Count > 0) { AddressableAudioSource = Instant.DefaultFloorSound.Barefoot; } break; case StepType.Shoes: AddressableAudioSource = FloorTileSounds?.Shoes; if (FloorTileSounds == null || AddressableAudioSource.Count > 0) { AddressableAudioSource = Instant.DefaultFloorSound.Shoes; } break; case StepType.Claw: AddressableAudioSource = FloorTileSounds?.Claw; if (FloorTileSounds == null || AddressableAudioSource.Count > 0) { AddressableAudioSource = Instant.DefaultFloorSound.Claw; } break; } if (AddressableAudioSource == null) { return; } AudioSourceParameters audioSourceParameters = new AudioSourceParameters(pitch: Random.Range(0.7f, 1.2f)); SoundManager.PlayNetworkedAtPos(AddressableAudioSource.PickRandom(), worldPos, audioSourceParameters, polyphonic: true); } }
/// <summary> /// Try spark at world pos /// </summary> /// <returns>Null if the spark failed, else the new spark object.</returns> public static GameObject TrySpark(Vector3 worldPos, float chanceToSpark = 75, bool expose = true) { //Clamp just in case chanceToSpark = Mathf.Clamp(chanceToSpark, 1, 100); //E.g will have 25% chance to not spark when chanceToSpark = 75 if (DMMath.Prob(100 - chanceToSpark)) { return(null); } var result = Spawn.ServerPrefab(CommonPrefabs.Instance.SparkEffect, worldPos); if (result.Successful) { if (expose) { //Try start fire if possible var reactionManager = MatrixManager.AtPoint(worldPos.RoundToInt(), true).ReactionManager; reactionManager.ExposeHotspotWorldPosition(worldPos.To2Int(), 1000); } SoundManager.PlayNetworkedAtPos(SingletonSOSounds.Instance.Sparks, worldPos); return(result.GameObject); } return(null); }
public static void ProcessTile(Vector3 Location) { Location.z = 0f; Vector3Int worldPosInt = Location.To2Int().To3Int(); Matrix matrix = MatrixManager.AtPoint(worldPosInt, true).Matrix; Location = matrix.transform.InverseTransformPoint(Location); Vector3Int tilePosition = Vector3Int.FloorToInt(Location); var registerTiles = matrix.Get <RegisterTile>(tilePosition, false); List <GameObject> _Objects = registerTiles.Select(x => x.gameObject).ToList(); //include interactable tiles var interactableTiles = matrix.GetComponentInParent <InteractableTiles>(); if (interactableTiles != null) { _Objects.Add(interactableTiles.gameObject); } List <Transform> transforms = new List <Transform>(); foreach (var Object in _Objects) { transforms.Add(Object.transform); } ProcessListOnTileTransform(transforms); }
private void AttackTile(Vector3Int worldPos, Vector2 dir) { var matrix = MatrixManager.AtPoint(worldPos, true); matrix.MetaTileMap.ApplyDamage(MatrixManager.WorldToLocalInt(worldPos, matrix), hitDamage * 2, worldPos); ServerDoLerpAnimation(dir); }
public void VentContents() { var metaDataLayer = MatrixManager.AtPoint(Vector3Int.RoundToInt(transform.position), true).MetaDataLayer; Vector3Int localPosition = transform.localPosition.RoundToInt(); MetaDataNode node = metaDataLayer.Get(localPosition, false); float deltaPressure = Mathf.Min(GasMix.Pressure, ReleasePressure) - node.GasMix.Pressure; if (deltaPressure > 0) { float ratio = deltaPressure * Time.deltaTime; GasMix.TransferGas(node.GasMix, GasMix, ratio); metaDataLayer.UpdateSystemsAt(localPosition, SystemType.AtmosSystem); Volume = GasMix.Volume; Temperature = GasMix.Temperature; foreach (var gas in GasMix.GasesArray) { StoredGasMix.GasData.SetMoles(gas.GasSO, gas.Moles); } } }
public void SpillContent(Tuple <ReagentMix, GasMix> ToSpill) { if (pipeNode == null && MonoPipe == null) { return; } Vector3Int ZeroedLocation = Vector3Int.zero; if (pipeNode != null) { ZeroedLocation = pipeNode.NodeLocation; } else { ZeroedLocation = MonoPipe.MatrixPos; } ZeroedLocation.z = 0; var tileWorldPosition = MatrixManager.LocalToWorld(ZeroedLocation, matrix).RoundToInt(); MatrixManager.ReagentReact(ToSpill.Item1, tileWorldPosition); MetaDataLayer metaDataLayer = MatrixManager.AtPoint(tileWorldPosition, true).MetaDataLayer; if (pipeNode != null) { pipeNode.IsOn.GasMix += ToSpill.Item2; } else { matrix.GetMetaDataNode(ZeroedLocation).GasMix += ToSpill.Item2; } metaDataLayer.UpdateSystemsAt(ZeroedLocation); }
public void ServerPerformInteraction(PositionalHandApply interaction) { if (interaction.TargetObject != null) { if (interaction.TargetObject.TryGetComponent(out GasContainer container)) { Chat.AddExamineMsgFromServer(interaction.Performer, GetGasMixInfo(container.GasMix)); return; } if (interaction.TargetObject.TryGetComponent(out MonoPipe monoPipe)) { Chat.AddExamineMsgFromServer(interaction.Performer, GetGasMixInfo(monoPipe.pipeData.mixAndVolume.GetGasMix())); return; } } Vector3 worldPosition = interaction.WorldPositionTarget; var matrix = MatrixManager.AtPoint(worldPosition.CutToInt(), true); var localPosition = MatrixManager.WorldToLocal(worldPosition, matrix).CutToInt(); var metaDataNode = matrix.MetaDataLayer.Get(localPosition, false); if (metaDataNode.PipeData.Count > 0) { var gasMix = metaDataNode.PipeData[0].pipeData.GetMixAndVolume.GetGasMix(); Chat.AddExamineMsgFromServer(interaction.Performer, GetGasMixInfo(gasMix)); } }
private void RemoveAllShields() { foreach (var generator in connectedGenerator.ToArray()) { for (int i = 1; i <= detectionRange; i++) { var pos = registerTile.WorldPositionServer + GetCoordFromDirection(generator.Key) * i; if (pos == generator.Value.Item1.gameObject.WorldPosServer()) { break; } var matrix = MatrixManager.AtPoint(pos, true); var layerTile = matrix.TileChangeManager.MetaTileMap .GetTile(MatrixManager.WorldToLocalInt(pos, matrix), LayerType.Windows); if (layerTile == null) { continue; } if (layerTile.name == horizontal.name || layerTile.name == vertical.name) { matrix.TileChangeManager.RemoveTile(MatrixManager.WorldToLocalInt(pos, matrix), LayerType.Windows); } } } connectedGenerator.Clear(); }
private void CheckRelease() { if (Opened) { MetaDataLayer metaDataLayer = MatrixManager.AtPoint(Vector3Int.RoundToInt(transform.position)).MetaDataLayer; Vector3Int position = transform.localPosition.RoundToInt(); MetaDataNode node = metaDataLayer.Get(position, false); float deltaPressure = Mathf.Min(GasMix.Pressure, ReleasePressure) - node.GasMix.Pressure; if (deltaPressure > 0) { float ratio = deltaPressure / GasMix.Pressure * Time.deltaTime; node.GasMix += GasMix * ratio; GasMix *= (1 - ratio); metaDataLayer.UpdateSystemsAt(position); Volume = GasMix.Volume; Temperature = GasMix.Temperature; foreach (Gas gas in Gas.All) { Gases[gas] = GasMix.Gases[gas]; } } } }
/// <summary> /// Returns GameObjects eligible to be displayed in the Item List Tab /// </summary> /// <param name="position">Position where to look for items</param> public static List <GameObject> GetItemsAtPosition(Vector3 position) { var matrix = MatrixManager.AtPoint(Vector3Int.RoundToInt(position), CustomNetworkManager.Instance._isServer).Matrix; if (!matrix) { return(new List <GameObject>()); } position = matrix.transform.InverseTransformPoint(position); Vector3Int tilePosition = Vector3Int.FloorToInt(position); var registerTiles = matrix.Get <RegisterTile>(tilePosition, false); var result = registerTiles.Select(x => x.gameObject).ToList(); //include interactable tiles var interactableTiles = matrix.GetComponentInParent <InteractableTiles>(); if (interactableTiles != null) { result.Add(interactableTiles.gameObject); } return(result); }
private PlayerState NextState(PlayerState state, PlayerAction action, out bool matrixChanged, bool isReplay = false) { var newState = state; newState.MoveNumber++; newState.Position = playerMove.GetNextPosition(Vector3Int.RoundToInt(state.Position), action, isReplay, MatrixManager.Get(newState.MatrixId).Matrix); var proposedWorldPos = newState.WorldPosition; MatrixInfo matrixAtPoint = MatrixManager.AtPoint(Vector3Int.RoundToInt(proposedWorldPos)); bool matrixChangeDetected = !Equals(matrixAtPoint, MatrixInfo.Invalid) && matrixAtPoint.Id != state.MatrixId; //Switching matrix while keeping world pos newState.MatrixId = matrixAtPoint.Id; newState.WorldPosition = proposedWorldPos; // Debug.Log( $"NextState: src={state} proposedPos={newState.WorldPosition}\n" + // $"mAtPoint={matrixAtPoint.Id} change={matrixChangeDetected} newState={newState}" ); if (!matrixChangeDetected) { matrixChanged = false; return(newState); } matrixChanged = true; return(newState); }
private IEnumerator WaitForLoad() { yield return(new WaitForEndOfFrame()); if (serverStateCache.Position != Vector3.zero && !isLocalPlayer) { playerState = serverStateCache; transform.localPosition = Vector3Int.RoundToInt(playerState.Position); } else { //tries to be smart, but no guarantees. correct state is received later (during CustomNetworkManager initial sync) anyway Vector3Int worldPos = Vector3Int.RoundToInt((Vector2)transform.position); //cutting off Z-axis & rounding MatrixInfo matrixAtPoint = MatrixManager.AtPoint(worldPos); PlayerState state = new PlayerState { MoveNumber = 0, MatrixId = matrixAtPoint.Id, WorldPosition = worldPos }; // Debug.Log( $"{gameObject.name}: InitClientState for {worldPos} found matrix {matrixAtPoint} resulting in\n{state}" ); playerState = state; predictedState = state; } yield return(new WaitForSeconds(2f)); PullReset(PullObjectID); }
public void BloodSplat(Vector3 worldPos, BloodSplatSize splatSize) { GameObject chosenTile = null; switch (splatSize) { case BloodSplatSize.small: chosenTile = smallBloodTile; break; case BloodSplatSize.medium: chosenTile = mediumBloodTile; break; case BloodSplatSize.large: chosenTile = largeBloodTile; break; } if (chosenTile != null) { PoolManager.PoolNetworkInstantiate(chosenTile, worldPos, MatrixManager.AtPoint(Vector3Int.RoundToInt(worldPos), true).Objects); } }
/// <summary> /// Override this for custom target actions /// </summary> protected virtual void PerformTargetAction(Vector3Int checkPos) { if (registerObj == null || registerObj.Matrix == null) { return; } switch (target) { case Target.food: TryEatTarget(checkPos); break; case Target.dirtyFloor: var matrixInfo = MatrixManager.AtPoint(checkPos, true); var worldPos = MatrixManager.LocalToWorldInt(checkPos, matrixInfo); matrixInfo.MetaDataLayer.Clean(worldPos, checkPos, false); break; case Target.missingFloor: interactableTiles.TileChangeManager.UpdateTile(checkPos, TileType.Floor, "Floor"); break; case Target.injuredPeople: break; case Target.players: var people = registerObj.Matrix.GetFirst <PlayerScript>(checkPos, true); if (people != null) { gameObject.GetComponent <MobAI>().ExplorePeople(people); } break; } }
private void OnConnectedDestroy(DestructionInfo info) { foreach (var generator in connectedGenerator.ToArray()) { if (generator.Value.Item1 == info.Destroyed.gameObject) { for (int i = 1; i <= detectionRange; i++) { var pos = registerTile.WorldPositionServer + GetCoordFromDirection(generator.Key) * i; if (pos == info.Destroyed.gameObject.WorldPosServer()) { break; } var matrix = MatrixManager.AtPoint(pos, true); matrix.TileChangeManager.RemoveTile(MatrixManager.WorldToLocalInt(pos, matrix), LayerType.Windows); } connectedGenerator.Remove(generator.Key); info.Destroyed.OnWillDestroyServer.RemoveListener(OnConnectedDestroy); break; } } }
public override void DrawGizmo(MetaDataLayer source, Vector3Int position) { if (Application.isPlaying == false) { MetaDataNode node = source.Get(position, false); if (node.Exists) { if (node.IsSpace || node.Neighbors.Any(n => n != null && n.IsSpace)) { GizmoUtils.DrawCube(position, Color.red); } } } else { var INWorld = MatrixManager.LocalToWorld(position, source.Matrix.MatrixInfo); if (MatrixManager.AtPoint(INWorld.RoundToInt(), true).Matrix == source.Matrix) { MetaDataNode node = source.Get(position, false); if (node.Exists) { if (node.IsSpace || node.Neighbors.Any(n => n != null && n.IsSpace)) { GizmoUtils.DrawCube(position, Color.red); } } } } }
public static void DoReport() { if (!CustomNetworkManager.IsServer) { return; } foreach (ConnectedPlayer player in PlayerList.Instance.InGamePlayers) { var ps = player.Script; if (ps.IsDeadOrGhost) { continue; } if (ps.PlayerSync.IsMovingServer) { var plantPos = ps.WorldPos + ps.CurrentDirection.Vector; Spawn.ServerPrefab("Banana peel", plantPos, cancelIfImpassable: true); } foreach (var pos in ps.WorldPos.BoundsAround().allPositionsWithin) { var matrixInfo = MatrixManager.AtPoint(pos, true); var localPos = MatrixManager.WorldToLocalInt(pos, matrixInfo); matrixInfo.MetaDataLayer.Clean(pos, localPos, true); } } SoundManager.PlayNetworked(SingletonSOSounds.Instance.ClownHonk, Random.Range(0.2f, 0.5f), true, true); }
public void SetPosition(Vector3 worldPos, bool notify = true, bool keepRotation = false) { Poke(); Vector2 pos = worldPos; //Cut z-axis serverState.MatrixId = MatrixManager.AtPoint(Vector3Int.RoundToInt(worldPos)).Id; // serverState.Speed = speed; serverState.WorldPosition = pos; if (!keepRotation) { serverState.SpinRotation = 0; } if (notify) { NotifyPlayers(); } //Don't lerp (instantly change pos) if active state was changed if (serverState.Speed > 0) { var preservedLerpPos = serverLerpState.WorldPosition; serverLerpState.MatrixId = serverState.MatrixId; serverLerpState.WorldPosition = preservedLerpPos; } else { serverLerpState = serverState; } }
public void ServerPerformInteraction(HandActivate interaction) { string toShow = ""; var metaDataLayer = MatrixManager.AtPoint(interaction.PerformerPlayerScript.registerTile.WorldPositionServer, true).MetaDataLayer; if (metaDataLayer != null) { var node = metaDataLayer.Get(interaction.Performer.transform.localPosition.RoundToInt()); if (node != null) { toShow = $"Pressure : {node.GasMix.Pressure:0.###} kPa \n" + $"Temperature : {node.GasMix.Temperature:0.###} K {node.GasMix.Temperature - Atmospherics.Reactions.KOffsetC:0.###} C)" + " \n" //You want Fahrenheit? HAHAHAHA + $"Total Moles of gas : {node.GasMix.Moles:0.###} \n"; foreach (var gas in Gas.All) { var ratio = node.GasMix.GasRatio(gas); if (ratio != 0) { toShow += $"{gas.Name} : {ratio * 100:0.###} %\n"; } } } } Chat.AddExamineMsgFromServer(interaction.Performer, toShow); }
void DeconstructPipe() { DisposalPipe pipe = deconstructInteraction.BasicTile as DisposalPipe; // Despawn pipe tile var matrix = MatrixManager.AtPoint(deconstructInteraction.WorldPositionTarget.NormalizeTo3Int(), true).Matrix; matrix.RemoveUnderFloorTile(deconstructInteraction.TargetCellPos, pipe); // Spawn pipe GameObject if (deconstructInteraction.BasicTile.SpawnOnDeconstruct == null) { return; } var spawn = Spawn.ServerPrefab(deconstructInteraction.BasicTile.SpawnOnDeconstruct, deconstructInteraction.WorldPositionTarget); if (!spawn.Successful) { return; } if (!spawn.GameObject.TryGetComponent(out Directional directional)) { return; } directional.FaceDirection(Orientation.FromEnum(pipe.DisposalPipeObjectOrientation)); if (!spawn.GameObject.TryGetComponent(out ObjectBehaviour behaviour)) { return; } behaviour.ServerSetPushable(false); }
// Normal footsteps public static void FootstepAtPosition(Vector3 worldPos, Pickupable feetSlot, GameObject performer) { MatrixInfo matrix = MatrixManager.AtPoint(worldPos.NormalizeToInt(), false); var locPos = matrix.ObjectParent.transform.InverseTransformPoint(worldPos).RoundToInt(); var tile = matrix.MetaTileMap.GetTile(locPos) as BasicTile; if (tile != null) { if (Step) { if (feetSlot == null) { //TODO when we have creatures with claws, check here to make proper claw sound BarefootAtPosition(worldPos, tile, performer); } else if (Validations.HasItemTrait(feetSlot.gameObject, CommonTraits.Instance.Squeaky)) { ClownStepAtPos(worldPos, tile, performer); } else { PlayNetworkedAtPos( Instance.FootSteps[tile.WalkingSoundCategory][ RANDOM.Next(Instance.FootSteps[tile.WalkingSoundCategory].Count)], worldPos, (float)Instance.GetRandomNumber(0.7d, 1.2d), Global: false, polyphonic: true, sourceObj: performer); } } Step = !Step; } }
public void VentContents() { var metaDataLayer = MatrixManager.AtPoint(Vector3Int.RoundToInt(transform.position), true).MetaDataLayer; Vector3Int localPosition = transform.localPosition.RoundToInt(); MetaDataNode node = metaDataLayer.Get(localPosition, false); float deltaPressure = Mathf.Min(GasMix.Pressure, ReleasePressure) - node.GasMix.Pressure; if (deltaPressure > 0) { float ratio = deltaPressure / GasMix.Pressure * Time.deltaTime; node.GasMix += GasMix * ratio; GasMix *= (1 - ratio); metaDataLayer.UpdateSystemsAt(localPosition, SystemType.AtmosSystem); Volume = GasMix.Volume; Temperature = GasMix.Temperature; foreach (Gas gas in Gas.All) { Gases[gas] = GasMix.Gases[gas]; } } }
private static GameObject CreateMob(GameObject spawnSpot, GameObject mobPrefab) { var registerTile = spawnSpot.GetComponent <RegisterTile>(); Transform parentTransform; uint parentNetId; Vector3Int spawnPosition; if (registerTile) //spawnSpot is someone's corpse { var objectLayer = registerTile.layer; parentNetId = objectLayer.GetComponentInParent <NetworkIdentity>().netId; parentTransform = objectLayer.transform; spawnPosition = spawnSpot.GetComponent <ObjectBehaviour>().AssumedWorldPositionServer().RoundToInt(); } else //spawnSpot is a Spawnpoint object { spawnPosition = spawnSpot.transform.position.CutToInt(); var matrixInfo = MatrixManager.AtPoint(spawnPosition, true); parentNetId = matrixInfo.NetID; parentTransform = matrixInfo.Objects; } GameObject newMob = Object.Instantiate(mobPrefab, spawnPosition, Quaternion.identity, parentTransform); var playerScript = newMob.GetComponent <PlayerScript>(); playerScript.registerTile.ParentNetId = parentNetId; return(newMob); }
public bool Push(Vector2Int direction) { if (direction == Vector2Int.zero) { return(false); } Vector3Int origin = Vector3Int.RoundToInt((Vector2)serverState.WorldPosition); Vector3Int pushGoal = origin + Vector3Int.RoundToInt((Vector2)direction); if (!MatrixManager.IsPassableAt(origin, pushGoal)) { return(false); } Logger.Log($"Server push to {pushGoal}", Category.PushPull); ClearQueueServer(); MatrixInfo newMatrix = MatrixManager.AtPoint(pushGoal); //Note the client queue reset var newState = new PlayerState { MoveNumber = 0, Impulse = direction, MatrixId = newMatrix.Id, WorldPosition = pushGoal, ImportantFlightUpdate = true, ResetClientQueue = true }; serverLastDirection = direction; serverState = newState; SyncMatrix(); NotifyPlayers(); return(true); }
public void SetPosition(Vector3 worldPos, bool notify = true, bool keepRotation = false /*, float speed = 4f, bool _isPushing = false*/) { // Only allow one movement at a time if it is currently being pushed // if(isPushing || predictivePushing){ // if(predictivePushing && _isPushing){ // This is if the server player is pushing because the predictive flag //will be set early we still need to notify the players so call it here: // UpdateServerTransformState(pos, notify, speed); //And then set the isPushing flag: // isPushing = true; // } // return; // } Vector2 pos = worldPos; //Cut z-axis serverState.MatrixId = MatrixManager.AtPoint(Vector3Int.RoundToInt(worldPos)).Id; // serverState.Speed = speed; serverState.WorldPosition = pos; if (!keepRotation) { serverState.Rotation = 0; } if (notify) { NotifyPlayers(); } //Set it to being pushed if it is a push net action // if(_isPushing){ //This is synced via syncvar with all players // isPushing = true; // } }
void ExtinguishTile(Vector3Int worldPos) { var matrix = MatrixManager.AtPoint(worldPos, true); var localPosInt = MatrixManager.WorldToLocalInt(worldPos, matrix); matrix.MetaDataLayer.ReagentReact(reagentContainer.Contents, worldPos, localPosInt); }
protected override void ActOnTile(Vector3Int worldPos, Vector3 dir) { var matrix = MatrixManager.AtPoint(worldPos, true); matrix.MetaTileMap.ApplyDamage(MatrixManager.WorldToLocalInt(worldPos, matrix), hitDamage * 2, worldPos); ServerDoLerpAnimation(dir); }
private void InternalRemoveGenerator(GameObject generatorToRemove, Direction direction) { for (int i = 1; i <= detectionRange; i++) { var pos = registerTile.WorldPositionServer + GetCoordFromDirection(direction) * i; if (pos == generatorToRemove.WorldPosServer()) { break; } var matrix = MatrixManager.AtPoint(pos, true); var layerTile = matrix.TileChangeManager.MetaTileMap .GetTile(MatrixManager.WorldToLocalInt(pos, matrix), LayerType.Walls); if (layerTile == null) { continue; } if (layerTile.name == horizontal.name || layerTile.name == vertical.name) { matrix.TileChangeManager.MetaTileMap.RemoveTileWithlayer(MatrixManager.WorldToLocalInt(pos, matrix), LayerType.Walls); } } }
private void DeconstructPipe(TileApply interaction) { DisposalPipe pipe = interaction.BasicTile as DisposalPipe; // Despawn pipe tile var matrix = MatrixManager.AtPoint(interaction.WorldPositionTarget.NormalizeTo3Int(), true).Matrix; matrix.TileChangeManager.RemoveTile(interaction.TargetCellPos, LayerType.Underfloor); // Spawn pipe GameObject if (interaction.BasicTile.SpawnOnDeconstruct == null) { return; } var spawn = Spawn.ServerPrefab(interaction.BasicTile.SpawnOnDeconstruct, interaction.WorldPositionTarget); if (spawn.Successful == false) { return; } if (spawn.GameObject.TryGetComponent <Directional>(out var directional)) { directional.FaceDirection(Orientation.FromEnum(pipe.DisposalPipeObjectOrientation)); } if (spawn.GameObject.TryGetComponent <ObjectBehaviour>(out var behaviour)) { behaviour.ServerSetPushable(false); } }