Пример #1
0
        public void ServerPerformInteraction(HandApply interaction)
        {
            if (MachineParts == null)
            {
                return;
            }

            //unscrew
            ToolUtils.ServerUseToolWithActionMessages(interaction, secondsToScrewdrive,
                                                      "You start to deconstruct the machine...",
                                                      $"{interaction.Performer.ExpensiveName()} starts to deconstruct the machine...",
                                                      "You deconstruct the machine.",
                                                      $"{interaction.Performer.ExpensiveName()} deconstructs the machine.",
                                                      () =>
            {
                //drop all our contents
                ItemStorage itemStorage = null;

                // rare cases were gameObject is destroyed for some reason and then the method is called
                if (gameObject != null)
                {
                    itemStorage = GetComponent <ItemStorage>();
                }

                if (itemStorage != null)
                {
                    itemStorage.ServerDropAll();
                }

                var frame = Spawn.ServerPrefab(framePrefab, SpawnDestination.At(gameObject)).GameObject;

                frame.GetComponent <MachineFrame>().ServerInitFromComputer(this);

                Despawn.ServerSingle(gameObject);
            });
        }
Пример #2
0
        public void WhenDestroyed(DestructionInfo info)
        {
            //drop all our contents
            ItemStorage itemStorage = null;

            // rare cases were gameObject is destroyed for some reason and then the method is called
            if (gameObject == null)
            {
                return;
            }

            itemStorage = GetComponent <ItemStorage>();

            if (itemStorage != null)
            {
                itemStorage.ServerDropAll();
            }
            var frame = Spawn.ServerPrefab(framePrefab, SpawnDestination.At(gameObject)).GameObject;

            frame.GetComponent <ComputerFrame>().ServerInitFromComputer(this);
            _ = Despawn.ServerSingle(gameObject);

            integrity.OnWillDestroyServer.RemoveListener(WhenDestroyed);
        }
Пример #3
0
        /// <summary>
        /// Stage 1, Add cable to continue or welder to destroy frame.
        /// </summary>
        /// <param name="interaction"></param>
        private void InitialStateInteraction(HandApply interaction)
        {
            if (Validations.HasUsedItemTrait(interaction, CommonTraits.Instance.Cable) &&
                Validations.HasUsedAtLeast(interaction, 5))
            {
                //add 5 cables
                ToolUtils.ServerUseToolWithActionMessages(interaction, 2f,
                                                          "You start adding cables to the frame...",
                                                          $"{interaction.Performer.ExpensiveName()} starts adding cables to the frame...",
                                                          "You add cables to the frame.",
                                                          $"{interaction.Performer.ExpensiveName()} adds cables to the frame.",
                                                          () =>
                {
                    Inventory.ServerConsume(interaction.HandSlot, 5);
                    stateful.ServerChangeState(cablesAddedState);

                    //sprite change
                    spriteRender.sprite = boxCable;
                    ServerChangeSprite(SpriteStates.BoxCable);
                });
            }
            else if (Validations.HasUsedActiveWelder(interaction))
            {
                //deconsruct
                ToolUtils.ServerUseToolWithActionMessages(interaction, 2f,
                                                          "You start deconstructing the frame...",
                                                          $"{interaction.Performer.ExpensiveName()} starts deconstructing the frame...",
                                                          "You deconstruct the frame.",
                                                          $"{interaction.Performer.ExpensiveName()} deconstructs the frame.",
                                                          () =>
                {
                    Spawn.ServerPrefab(CommonPrefabs.Instance.Metal, SpawnDestination.At(gameObject), 5);
                    Despawn.ServerSingle(gameObject);
                });
            }
        }
Пример #4
0
        public void WhenDestroyed(DestructionInfo info)
        {
            //drop all our contents
            ItemStorage itemStorage = null;

            // rare cases were gameObject is destroyed for some reason and then the method is called
            if (gameObject == null)
            {
                return;
            }

            itemStorage = GetComponent <ItemStorage>();

            if (itemStorage != null)
            {
                itemStorage.ServerDropAll();
            }

            SpawnResult frameSpawn =
                Spawn.ServerPrefab(CommonPrefabs.Instance.MachineFrame, SpawnDestination.At(gameObject));

            if (!frameSpawn.Successful)
            {
                Logger.LogError($"Failed to spawn frame! Is {this} missing references in the inspector?",
                                Category.Construction);
                return;
            }

            GameObject frame = frameSpawn.GameObject;

            frame.GetComponent <MachineFrame>().ServerInitFromComputer(this);

            _ = Despawn.ServerSingle(gameObject);

            integrity.OnWillDestroyServer.RemoveListener(WhenDestroyed);
        }
Пример #5
0
    /// <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.Server);
            return;
        }
        //determine where to spawn the ghost
        var body = forMind.GetCurrentMob();

        if (body == null)
        {
            Logger.LogError("Body was null for ServerSpawnGhost", Category.Server);
            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.ItemSpawn,
                                  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 = 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 = UnityEngine.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));
    }
Пример #6
0
    /// <summary>
    /// Spawns a new player character and transfers the connection's control into the new body.
    /// If existingMind is null, creates the new mind and assigns it to the new body.
    ///
    /// Fires server and client side player spawn hooks.
    /// </summary>
    /// <param name="connection">connection to give control to the new player character</param>
    /// <param name="occupation">occupation of the new player character</param>
    /// <param name="characterSettings">settings of the new player character</param>
    /// <param name="existingMind">existing mind to transfer to the new player, if null new mind will be created
    /// and assigned to the new player character</param>
    /// <param name="spawnPos">world position to spawn at</param>
    /// <param name="spawnItems">If spawning a player, should the player spawn without the defined initial equipment for their occupation?</param>
    /// <param name="willDestroyOldBody">if true, indicates the old body is going to be destroyed rather than pooled,
    /// thus we shouldn't send any network message which reference's the old body's ID since it won't exist.</param>
    ///
    /// <returns>the spawned object</returns>
    private static GameObject ServerSpawnInternal(NetworkConnection connection, Occupation occupation, CharacterSettings characterSettings,
                                                  Mind existingMind, Vector3Int?spawnPos = null, bool spawnItems = true, bool willDestroyOldBody = false)
    {
        //determine where to spawn them
        if (spawnPos == null)
        {
            Transform spawnTransform;
            //Spawn normal location for special jobs or if less than 2 minutes passed
            if (GameManager.Instance.stationTime < ARRIVALS_SPAWN_TIME || occupation.LateSpawnIsArrivals == false)
            {
                spawnTransform = GetSpawnForJob(occupation.JobType);
            }
            else
            {
                spawnTransform = GetSpawnForLateJoin(occupation.JobType);
                //Fallback to assistant spawn location if none found for late join
                if (spawnTransform == null && occupation.JobType != JobType.NULL)
                {
                    spawnTransform = GetSpawnForJob(JobType.ASSISTANT);
                }
            }

            if (spawnTransform == null)
            {
                Logger.LogErrorFormat(
                    "Unable to determine spawn position for connection {0} occupation {1}. Cannot spawn player.",
                    Category.ItemSpawn,
                    connection.address, occupation.DisplayName);
                return(null);
            }

            spawnPos = spawnTransform.transform.position.CutToInt();
        }

        //create the player object
        var newPlayer       = ServerCreatePlayer(spawnPos.GetValueOrDefault());
        var newPlayerScript = newPlayer.GetComponent <PlayerScript>();

        //get the old body if they have one.
        var oldBody = existingMind?.GetCurrentMob();

        //transfer control to the player object
        ServerTransferPlayer(connection, newPlayer, oldBody, EVENT.PlayerSpawned, characterSettings, willDestroyOldBody);


        if (existingMind == null)
        {
            //create the mind of the player
            Mind.Create(newPlayer, occupation);
        }
        else
        {
            //transfer the mind to the new body
            existingMind.SetNewBody(newPlayerScript);
        }


        var ps = newPlayer.GetComponent <PlayerScript>();
        var connectedPlayer = PlayerList.Instance.Get(connection);

        connectedPlayer.Name = ps.playerName;
        connectedPlayer.Job  = ps.mind.occupation.JobType;
        UpdateConnectedPlayersMessage.Send();

        //fire all hooks
        var info = SpawnInfo.Player(occupation, characterSettings, CustomNetworkManager.Instance.humanPlayerPrefab,
                                    SpawnDestination.At(spawnPos), spawnItems: spawnItems);

        Spawn._ServerFireClientServerSpawnHooks(SpawnResult.Single(info, newPlayer));

        return(newPlayer);
    }
Пример #7
0
        public void ServerPerformInteraction(HandApply interaction)
        {
            if (Validations.HasUsedItemTrait(interaction, CommonTraits.Instance.Screwdriver))
            {
                if (coverOpen)
                {
                    coverOpen = false;
                    if (activated)
                    {
                        stateSync = FireAlarmState.TopLightSpriteAlert;
                    }
                    else
                    {
                        stateSync = FireAlarmState.TopLightSpriteNormal;
                    }
                }
                else
                {
                    coverOpen = true;
                    if (hasCables)
                    {
                        stateSync = FireAlarmState.OpenCabledSprite;
                    }
                    else
                    {
                        stateSync = FireAlarmState.OpenEmptySprite;
                    }
                }
                ToolUtils.ServerPlayToolSound(interaction);
                return;
            }
            if (coverOpen)
            {
                if (hasCables && Validations.HasUsedItemTrait(interaction, CommonTraits.Instance.Wirecutter))
                {
                    //cut out cables
                    Chat.AddActionMsgToChat(interaction, $"You remove the cables.",
                                            $"{interaction.Performer.ExpensiveName()} removes the cables.");
                    ToolUtils.ServerPlayToolSound(interaction);
                    Spawn.ServerPrefab(CommonPrefabs.Instance.SingleCableCoil, SpawnDestination.At(gameObject), 5);
                    stateSync = FireAlarmState.OpenEmptySprite;
                    hasCables = false;
                    activated = false;
                    return;
                }

                if (!hasCables && Validations.HasUsedItemTrait(interaction, CommonTraits.Instance.Cable) &&
                    Validations.HasUsedAtLeast(interaction, 5))
                {
                    //add 5 cables
                    ToolUtils.ServerUseToolWithActionMessages(interaction, 2f,
                                                              "You start adding cables to the frame...",
                                                              $"{interaction.Performer.ExpensiveName()} starts adding cables to the frame...",
                                                              "You add cables to the frame.",
                                                              $"{interaction.Performer.ExpensiveName()} adds cables to the frame.",
                                                              () =>
                    {
                        Inventory.ServerConsume(interaction.HandSlot, 5);
                        hasCables = true;
                        stateSync = FireAlarmState.OpenCabledSprite;
                    });
                }
            }
            else
            {
                InternalToggleState();
            }
        }
Пример #8
0
 public void ServerPerformInteraction(HandApply interaction)
 {
     if (CurrentState == initialState)
     {
         if (objectBehaviour.IsPushable)
         {
             if (Validations.HasUsedItemTrait(interaction, CommonTraits.Instance.Wrench))
             {
                 if (!ServerValidations.IsAnchorBlocked(interaction))
                 {
                     //wrench in place
                     ToolUtils.ServerUseToolWithActionMessages(interaction, 2f,
                                                               "You start wrenching the frame into place...",
                                                               $"{interaction.Performer.ExpensiveName()} starts wrenching the frame into place...",
                                                               "You wrench the frame into place.",
                                                               $"{interaction.Performer.ExpensiveName()} wrenches the frame into place.",
                                                               () => objectBehaviour.ServerSetAnchored(true, interaction.Performer));
                 }
             }
             else if (Validations.HasUsedActiveWelder(interaction))
             {
                 //deconsruct
                 ToolUtils.ServerUseToolWithActionMessages(interaction, 2f,
                                                           "You start deconstructing the frame...",
                                                           $"{interaction.Performer.ExpensiveName()} starts deconstructing the frame...",
                                                           "You deconstruct the frame.",
                                                           $"{interaction.Performer.ExpensiveName()} deconstructs the frame.",
                                                           () =>
                 {
                     Spawn.ServerPrefab(CommonPrefabs.Instance.Metal, SpawnDestination.At(gameObject), 5);
                     _ = Despawn.ServerSingle(gameObject);
                 });
             }
         }
         else
         {
             //already wrenched in place
             if (Validations.HasUsedItemTrait(interaction, CommonTraits.Instance.Wrench))
             {
                 //unwrench
                 ToolUtils.ServerUseToolWithActionMessages(interaction, 2f,
                                                           "You start to unfasten the frame...",
                                                           $"{interaction.Performer.ExpensiveName()} starts to unfasten the frame...",
                                                           "You unfasten the frame.",
                                                           $"{interaction.Performer.ExpensiveName()} unfastens the frame.",
                                                           () => objectBehaviour.ServerSetAnchored(false, interaction.Performer));
             }
             else if (Validations.HasUsedComponent <ComputerCircuitboard>(interaction) && circuitBoardSlot.IsEmpty)
             {
                 //stick in the circuit board
                 Chat.AddActionMsgToChat(interaction, $"You place the {interaction.UsedObject.ExpensiveName()} inside the frame.",
                                         $"{interaction.Performer.ExpensiveName()} places the {interaction.UsedObject.ExpensiveName()} inside the frame.");
                 Inventory.ServerTransfer(interaction.HandSlot, circuitBoardSlot);
             }
             else if (Validations.HasUsedItemTrait(interaction, CommonTraits.Instance.Screwdriver) && circuitBoardSlot.IsOccupied)
             {
                 //screw in the circuit board
                 Chat.AddActionMsgToChat(interaction, $"You screw {circuitBoardSlot.ItemObject.ExpensiveName()} into place.",
                                         $"{interaction.Performer.ExpensiveName()} screws {circuitBoardSlot.ItemObject.ExpensiveName()} into place.");
                 ToolUtils.ServerPlayToolSound(interaction);
                 stateful.ServerChangeState(circuitScrewedState);
             }
             else if (Validations.HasUsedItemTrait(interaction, CommonTraits.Instance.Crowbar) &&
                      circuitBoardSlot.IsOccupied)
             {
                 //wrench out the circuit board
                 Chat.AddActionMsgToChat(interaction, $"You remove the {circuitBoardSlot.ItemObject.ExpensiveName()} from the frame.",
                                         $"{interaction.Performer.ExpensiveName()} removes the {circuitBoardSlot.ItemObject.ExpensiveName()} from the frame.");
                 ToolUtils.ServerPlayToolSound(interaction);
                 Inventory.ServerDrop(circuitBoardSlot);
             }
         }
     }
     else if (CurrentState == circuitScrewedState)
     {
         if (Validations.HasUsedItemTrait(interaction, CommonTraits.Instance.Screwdriver))
         {
             //unscrew circuit board
             Chat.AddActionMsgToChat(interaction, $"You unfasten the circuit board.",
                                     $"{interaction.Performer.ExpensiveName()} unfastens the circuit board.");
             ToolUtils.ServerPlayToolSound(interaction);
             stateful.ServerChangeState(initialState);
         }
         else if (Validations.HasUsedItemTrait(interaction, CommonTraits.Instance.Cable) &&
                  Validations.HasUsedAtLeast(interaction, 5))
         {
             //add 5 cables
             ToolUtils.ServerUseToolWithActionMessages(interaction, 2f,
                                                       "You start adding cables to the frame...",
                                                       $"{interaction.Performer.ExpensiveName()} starts adding cables to the frame...",
                                                       "You add cables to the frame.",
                                                       $"{interaction.Performer.ExpensiveName()} adds cables to the frame.",
                                                       () =>
             {
                 Inventory.ServerConsume(interaction.HandSlot, 5);
                 stateful.ServerChangeState(cablesAddedState);
             });
         }
     }
     else if (CurrentState == cablesAddedState)
     {
         if (Validations.HasUsedItemTrait(interaction, CommonTraits.Instance.Wirecutter))
         {
             //cut out cables
             Chat.AddActionMsgToChat(interaction, $"You remove the cables.",
                                     $"{interaction.Performer.ExpensiveName()} removes the cables.");
             ToolUtils.ServerPlayToolSound(interaction);
             Spawn.ServerPrefab(CommonPrefabs.Instance.SingleCableCoil, SpawnDestination.At(gameObject), 5);
             stateful.ServerChangeState(circuitScrewedState);
         }
         else if (Validations.HasUsedItemTrait(interaction, CommonTraits.Instance.GlassSheet) &&
                  Validations.HasUsedAtLeast(interaction, 2))
         {
             //add glass
             ToolUtils.ServerUseToolWithActionMessages(interaction, 2f,
                                                       "You start to put in the glass panel...",
                                                       $"{interaction.Performer.ExpensiveName()} starts to put in the glass panel...",
                                                       "You put in the glass panel.",
                                                       $"{interaction.Performer.ExpensiveName()} puts in the glass panel.",
                                                       () =>
             {
                 Inventory.ServerConsume(interaction.HandSlot, 2);
                 stateful.ServerChangeState(glassAddedState);
             });
         }
     }
     else if (CurrentState == glassAddedState)
     {
         if (Validations.HasUsedItemTrait(interaction, CommonTraits.Instance.Screwdriver))
         {
             //screw in monitor, completing construction
             Chat.AddActionMsgToChat(interaction, $"You connect the monitor.",
                                     $"{interaction.Performer.ExpensiveName()} connects the monitor.");
             ToolUtils.ServerPlayToolSound(interaction);
             var circuitBoard = circuitBoardSlot.ItemObject?.GetComponent <ComputerCircuitboard>();
             if (circuitBoard == null)
             {
                 Logger.LogWarningFormat("Cannot complete computer, circuit board not in frame {0}. Probably a coding error.",
                                         Category.Construction, name);
                 return;
             }
             Spawn.ServerPrefab(circuitBoard.ComputerToSpawn, SpawnDestination.At(gameObject));
             _ = Despawn.ServerSingle(gameObject);
         }
         else if (Validations.HasUsedItemTrait(interaction, CommonTraits.Instance.Crowbar))
         {
             //remove glass
             Chat.AddActionMsgToChat(interaction, $"You remove the glass panel.",
                                     $"{interaction.Performer.ExpensiveName()} removes the glass panel.");
             ToolUtils.ServerPlayToolSound(interaction);
             Spawn.ServerPrefab(CommonPrefabs.Instance.GlassSheet, SpawnDestination.At(gameObject), 2);
             stateful.ServerChangeState(cablesAddedState);
         }
     }
 }
Пример #9
0
        /// <summary>
        /// Stage 5, complete construction, or remove board and return to stage 3.
        /// </summary>
        /// <param name="interaction"></param>
        private void PartsAddedStateInteraction(HandApply interaction)
        {
            //Complete construction, spawn new machine and send data over to it.
            if (Validations.HasUsedItemTrait(interaction, CommonTraits.Instance.Screwdriver))
            {
                var spawnedObject = Spawn.ServerPrefab(machineParts.machine, SpawnDestination.At(gameObject)).GameObject.GetComponent <Machine>();

                if (spawnedObject == null)
                {
                    Logger.LogWarning(machineParts.machine + " is missing the machine script!", Category.ItemSpawn);
                    return;
                }

                //Send circuit board data to the new machine
                spawnedObject.SetBasicPartsUsed(basicPartsUsed);
                spawnedObject.SetPartsInFrame(partsInFrame);
                spawnedObject.SetMachineParts(machineParts);

                //Despawn frame
                Despawn.ServerSingle(gameObject);
            }
            else if (Validations.HasUsedItemTrait(interaction, CommonTraits.Instance.Crowbar) && circuitBoardSlot.IsOccupied)
            {
                //wrench out the circuit board, when it has all the parts in.
                Chat.AddActionMsgToChat(interaction, $"You remove the {circuitBoardSlot.ItemObject.ExpensiveName()} from the frame.",
                                        $"{interaction.Performer.ExpensiveName()} removes the {circuitBoardSlot.ItemObject.ExpensiveName()} from the frame.");
                ToolUtils.ServerPlayToolSound(interaction);
                Inventory.ServerDrop(circuitBoardSlot);
                stateful.ServerChangeState(wrenchedState);

                //If frame in mapped; count == 0 and its the only time putBoardInManually will be false as putting in board makes it true
                if (partsInFrame.Count == 0 && !putBoardInManually)
                {
                    foreach (var part in machineParts.machineParts)
                    {
                        Spawn.ServerPrefab(part.basicItem, gameObject.WorldPosServer(), gameObject.transform.parent, count: part.amountOfThisPart);
                    }
                }
                else
                {
                    foreach (var item in partsInFrame)               //Moves the hidden objects back on to the gameobject.
                    {
                        if (item.Key == null)                        //Shouldnt ever happen, but just incase
                        {
                            continue;
                        }

                        var pos = gameObject.GetComponent <CustomNetTransform>().ServerPosition;

                        item.Key.GetComponent <CustomNetTransform>().AppearAtPositionServer(pos);
                    }
                }

                putBoardInManually = false;

                //Sprite change
                spriteRender.sprite = boxCable;
                ServerChangeSprite(SpriteStates.BoxCable);

                //Reset data
                partsInFrame.Clear();
                basicPartsUsed.Clear();
            }
        }
Пример #10
0
 /// <summary>
 /// Clone the item and syncs it over the network. This only works if toClone has a PoolPrefabTracker
 /// attached or its name matches a prefab name, otherwise we don't know what prefab to create.
 /// </summary>
 /// <param name="toClone">GameObject to clone. This only works if toClone has a PoolPrefabTracker
 /// attached or its name matches a prefab name, otherwise we don't know what prefab to create.. Intended to work for any object, but don't
 /// be surprised if it doesn't as there are LOTS of prefabs in the game which might need unique behavior for how they should spawn. If you are trying
 /// to clone something and it isn't properly setting itself up, check to make sure each component that needs to set something up has
 /// properly implemented IOnStageServer or IOnStageClient when IsCloned = true</param>
 /// <param name="worldPosition">world position to appear at. Defaults to HiddenPos (hidden / invisible)</param>
 /// <param name="localRotation">local rotation to spawn with, defaults to Quaternion.identity</param>
 /// <param name="parent">Parent to spawn under, defaults to no parent. Most things
 /// should always be spawned under the Objects transform in their matrix. Many objects (due to RegisterTile)
 /// usually take care of properly parenting themselves when spawned so in many cases you can leave it null.</param>
 /// <returns>the newly created GameObject</returns>
 public static SpawnResult ServerClone(GameObject toClone, Vector3?worldPosition = null, Transform parent = null,
                                       Quaternion?localRotation = null)
 {
     return(Server(
                SpawnInfo.Clone(toClone, SpawnDestination.At(worldPosition, parent, localRotation))));
 }
Пример #11
0
    public override IEnumerator Process()
    {
        var clientStorage = SentByPlayer.Script.ItemStorage;
        var usedSlot      = clientStorage.GetActiveHandSlot();

        if (usedSlot == null || usedSlot.ItemObject == null)
        {
            yield break;
        }

        var hasConstructionMenu = usedSlot.ItemObject.GetComponent <BuildingMaterial>();

        if (hasConstructionMenu == null)
        {
            yield break;
        }

        var entry = hasConstructionMenu.BuildList.Entries.ToArray()[EntryIndex];

        if (!entry.CanBuildWith(hasConstructionMenu))
        {
            yield break;
        }

        //check if the space to construct on is passable
        if (!MatrixManager.IsPassableAt((Vector3Int)SentByPlayer.GameObject.TileWorldPosition(), true, includingPlayers: false))
        {
            Chat.AddExamineMsg(SentByPlayer.GameObject, "It won't fit here.");
            yield break;
        }

        //if we are building something impassable, check if there is anything on the space other than the performer.
        var atPosition =
            MatrixManager.GetAt <RegisterTile>((Vector3Int)SentByPlayer.GameObject.TileWorldPosition(), true);

        if (entry.Prefab == null)
        {
            //requires immediate attention, show it regardless of log filter:
            Logger.Log($"Construction entry is missing prefab for {entry.Name}");
            yield break;
        }

        var registerTile = entry.Prefab.GetComponent <RegisterTile>();

        if (registerTile == null)
        {
            Logger.LogWarningFormat("Buildable prefab {0} has no registerTile, no idea if it's passable", Category.Construction, entry.Prefab);
        }
        var builtObjectIsImpassable = registerTile == null || !registerTile.IsPassable(true);

        foreach (var thingAtPosition in atPosition)
        {
            if (entry.OnePerTile)
            {
                //can only build one of this on a given tile
                if (entry.Prefab.Equals(Spawn.DeterminePrefab(thingAtPosition.gameObject)))
                {
                    Chat.AddExamineMsg(SentByPlayer.GameObject, $"There's already one here.");
                    yield break;
                }
            }

            if (builtObjectIsImpassable)
            {
                //if the object we are building is itself impassable, we should check if anything blocks construciton.
                //otherwise it's fine to add it to the pile on the tile
                if (ServerValidations.IsConstructionBlocked(SentByPlayer.GameObject, null,
                                                            SentByPlayer.GameObject.TileWorldPosition()))
                {
                    yield break;
                }
            }
        }

        //build and consume
        void ProgressComplete()
        {
            if (entry.ServerBuild(SpawnDestination.At(SentByPlayer.Script.registerTile), hasConstructionMenu))
            {
                Chat.AddActionMsgToChat(SentByPlayer.GameObject, $"You finish building the {entry.Name}.",
                                        $"{SentByPlayer.GameObject.ExpensiveName()} finishes building the {entry.Name}.");
            }
        }

        Chat.AddActionMsgToChat(SentByPlayer.GameObject, $"You begin building the {entry.Name}...",
                                $"{SentByPlayer.GameObject.ExpensiveName()} begins building the {entry.Name}...");
        ToolUtils.ServerUseTool(SentByPlayer.GameObject, usedSlot.ItemObject,
                                ActionTarget.Tile(SentByPlayer.Script.registerTile.WorldPositionServer), entry.BuildTime,
                                ProgressComplete);
    }
Пример #12
0
 private void DeconstructBelt()
 {
     Spawn.ServerPrefab(CommonPrefabs.Instance.Metal, SpawnDestination.At(gameObject), 5);
     Despawn.ServerSingle(gameObject);
 }
Пример #13
0
    private float AddDamage(float damage, AttackType attackType, MetaDataNode data,
                            BasicTile basicTile, Vector3 worldPosition)
    {
        if (basicTile.indestructible || damage < basicTile.damageDeflection)
        {
            return(0);
        }

        var damageTaken = basicTile.Armor.GetDamage(damage < basicTile.damageDeflection ? 0 : damage, attackType);

        data.AddTileDamage(Layer.LayerType, damageTaken);

        if (basicTile.SoundOnHit != null && !string.IsNullOrEmpty(basicTile.SoundOnHit.AssetAddress) && basicTile.SoundOnHit.AssetAddress != "null")
        {
            if (damage >= 1)
            {
                SoundManager.PlayNetworkedAtPos(basicTile.SoundOnHit, worldPosition);
            }
        }

        var totalDamageTaken = data.GetTileDamage(Layer.LayerType);

        if (totalDamageTaken >= basicTile.MaxHealth)
        {
            if (basicTile.SoundOnDestroy.Count > 0)
            {
                SoundManager.PlayNetworkedAtPos(basicTile.SoundOnDestroy.RandomElement(), worldPosition);
            }
            data.RemoveTileDamage(Layer.LayerType);
            tileChangeManager.RemoveTile(data.Position, Layer.LayerType);
            tileChangeManager.RemoveOverlaysOfType(data.Position, LayerType.Effects, TileChangeManager.OverlayType.Damage);

            if (Layer.LayerType == LayerType.Floors || Layer.LayerType == LayerType.Base)
            {
                tileChangeManager.RemoveOverlaysOfType(data.Position, LayerType.Floors, TileChangeManager.OverlayType.Cleanable);
            }

            if (Layer.LayerType == LayerType.Walls)
            {
                tileChangeManager.RemoveOverlaysOfType(data.Position, LayerType.Walls, TileChangeManager.OverlayType.Cleanable);
            }

            //Add new tile if needed
            //TODO change floors to using overlays, but generic overlay will need to be sprited
            if (basicTile.ToTileWhenDestroyed != null)
            {
                var damageLeft = totalDamageTaken - basicTile.MaxHealth;
                var tile       = basicTile.ToTileWhenDestroyed as BasicTile;

                var overFlowProtection = 0;

                while (damageLeft > 0 && tile != null)
                {
                    overFlowProtection++;

                    if (tile.MaxHealth <= damageLeft)
                    {
                        damageLeft -= tile.MaxHealth;
                        tile        = tile.ToTileWhenDestroyed as BasicTile;
                    }
                    else
                    {
                        //Atm we just set remaining damage to 0, instead of absorbing it for the new tile
                        damageLeft = 0;
                        tileChangeManager.UpdateTile(data.Position, tile);
                        break;
                    }

                    if (overFlowProtection > maxOverflowProtection)
                    {
                        Logger.LogError($"Overflow protection triggered on {basicTile.name}, ToTileWhenDestroyed is spawning tiles in a loop", Category.TileMaps);
                        break;
                    }
                }

                damageTaken = damageLeft;
            }

            if (basicTile.SpawnOnDestroy != null)
            {
                basicTile.SpawnOnDestroy.SpawnAt(SpawnDestination.At(worldPosition, metaTileMap.ObjectLayer.gameObject.transform));
            }

            basicTile.LootOnDespawn?.SpawnLoot(worldPosition);
        }
        else
        {
            if (basicTile.DamageOverlayList != null)
            {
                foreach (var overlayData in basicTile.DamageOverlayList.DamageOverlays)
                {
                    if (overlayData.damagePercentage <= totalDamageTaken / basicTile.MaxHealth)
                    {
                        tileChangeManager.AddOverlay(data.Position, overlayData.overlayTile);
                        break;
                    }
                }
            }

            //All the damage was absorbed, none left to return for next layer
            damageTaken = 0;
        }

        if (basicTile.MaxHealth < basicTile.MaxHealth - totalDamageTaken)
        {
            data.ResetDamage(Layer.LayerType);
        }

        if (damageTaken > totalDamageTaken)
        {
            Logger.LogError($"Applying damage to {basicTile.DisplayName} increased the damage to be dealt, when it should have decreased!", Category.Damage);
            return(totalDamageTaken);
        }

        //Return how much damage is left
        return(damageTaken);
    }
Пример #14
0
 public void ServerPerformInteraction(HandApply interaction)
 {
     if (stateSync == MountedMonitorState.OpenCabled || stateSync == MountedMonitorState.OpenEmpty)
     {
         if (!hasCables && Validations.HasUsedItemTrait(interaction, CommonTraits.Instance.Cable) &&
             Validations.HasUsedAtLeast(interaction, 5))
         {
             //add 5 cables
             ToolUtils.ServerUseToolWithActionMessages(interaction, 2f,
                                                       "You start adding cables to the frame...",
                                                       $"{interaction.Performer.ExpensiveName()} starts adding cables to the frame...",
                                                       "You add cables to the frame.",
                                                       $"{interaction.Performer.ExpensiveName()} adds cables to the frame.",
                                                       () =>
             {
                 Inventory.ServerConsume(interaction.HandSlot, 5);
                 hasCables = true;
                 stateSync = MountedMonitorState.OpenCabled;
             });
         }
         else if (Validations.HasUsedItemTrait(interaction, CommonTraits.Instance.GlassSheet) &&
                  Validations.HasUsedAtLeast(interaction, 2))
         {
             //add 2 glass
             ToolUtils.ServerUseToolWithActionMessages(interaction, 2f,
                                                       "You start to put in the glass panel...",
                                                       $"{interaction.Performer.ExpensiveName()} starts to put in the glass panel...",
                                                       "You put in the glass panel.",
                                                       $"{interaction.Performer.ExpensiveName()} puts in the glass panel.",
                                                       () =>
             {
                 Inventory.ServerConsume(interaction.HandSlot, 2);
                 stateSync = MountedMonitorState.NonScrewedPanel;
             });
         }
         else if (hasCables && Validations.HasUsedItemTrait(interaction, CommonTraits.Instance.Wirecutter))
         {
             //cut out cables
             Chat.AddActionMsgToChat(interaction, $"You remove the cables.",
                                     $"{interaction.Performer.ExpensiveName()} removes the cables.");
             ToolUtils.ServerPlayToolSound(interaction);
             Spawn.ServerPrefab(CommonPrefabs.Instance.SingleCableCoil, SpawnDestination.At(gameObject), 5);
             stateSync           = MountedMonitorState.OpenEmpty;
             hasCables           = false;
             currentTimerSeconds = 0;
             doorControllers.Clear();
             NewdoorControllers.Clear();
         }
     }
     else if (stateSync == MountedMonitorState.NonScrewedPanel)
     {
         if (Validations.HasUsedItemTrait(interaction, CommonTraits.Instance.Crowbar))
         {
             //remove glass
             Chat.AddActionMsgToChat(interaction, $"You remove the glass panel.",
                                     $"{interaction.Performer.ExpensiveName()} removes the glass panel.");
             ToolUtils.ServerPlayToolSound(interaction);
             Spawn.ServerPrefab(CommonPrefabs.Instance.GlassSheet, SpawnDestination.At(gameObject), 2);
             if (hasCables)
             {
                 stateSync = MountedMonitorState.OpenCabled;
             }
             else
             {
                 stateSync = MountedMonitorState.OpenEmpty;
             }
         }
         else if (Validations.HasUsedItemTrait(interaction, CommonTraits.Instance.Screwdriver))
         {
             //screw in monitor, completing construction
             Chat.AddActionMsgToChat(interaction, $"You connect the monitor.",
                                     $"{interaction.Performer.ExpensiveName()} connects the monitor.");
             ToolUtils.ServerPlayToolSound(interaction);
             if (hasCables)
             {
                 stateSync = MountedMonitorState.StatusText;
             }
         }
     }
     else
     {
         if (Validations.HasUsedItemTrait(interaction, CommonTraits.Instance.Screwdriver))
         {
             //disconnect the monitor
             Chat.AddActionMsgToChat(interaction, $"You disconnect the monitor.",
                                     $"{interaction.Performer.ExpensiveName()} disconnect the monitor.");
             ToolUtils.ServerPlayToolSound(interaction);
             stateSync = MountedMonitorState.NonScrewedPanel;
         }
         else if (stateSync == MountedMonitorState.Image)
         {
             ChangeChannelMessage(interaction);
             stateSync = MountedMonitorState.StatusText;
         }
         else if (stateSync == MountedMonitorState.StatusText)
         {
             if (channel == StatusDisplayChannel.DoorTimer)
             {
                 if (AccessRestrictions == null || AccessRestrictions.CheckAccess(interaction.Performer))
                 {
                     AddTime(60);
                 }
                 else
                 {
                     Chat.AddExamineMsg(interaction.Performer, $"Access Denied.");
                     // Play sound
                     SoundManager.PlayNetworkedAtPos(CommonSounds.Instance.AccessDenied,
                                                     gameObject.AssumedWorldPosServer(), sourceObj: gameObject);
                 }
             }
             else
             {
                 ChangeChannelMessage(interaction);
                 stateSync = MountedMonitorState.Image;
             }
         }
     }
 }
Пример #15
0
        public void ServerPerformInteraction(HandApply interaction)
        {
            //Anchor or disassemble
            if (CurrentState == initialState)
            {
                if (Validations.HasUsedItemTrait(interaction, CommonTraits.Instance.Wrench))
                {
                    if (ServerValidations.IsAnchorBlocked(interaction) == false)
                    {
                        //wrench in place
                        ToolUtils.ServerUseToolWithActionMessages(interaction, 2f,
                                                                  "You start wrenching the Ai core frame into place...",
                                                                  $"{interaction.Performer.ExpensiveName()} starts wrenching the Ai core frame into place...",
                                                                  "You wrench the Ai core frame into place.",
                                                                  $"{interaction.Performer.ExpensiveName()} wrenches the Ai core frame into place.",
                                                                  () =>
                        {
                            objectBehaviour.ServerSetAnchored(true, interaction.Performer);

                            stateful.ServerChangeState(anchoredState);
                        });

                        return;
                    }

                    Chat.AddExamineMsgFromServer(interaction.Performer, "Unable to anchor Ai core frame here");
                }
                else if (Validations.HasUsedActiveWelder(interaction))
                {
                    //Deconstruct
                    ToolUtils.ServerUseToolWithActionMessages(interaction, 2f,
                                                              "You start deconstructing the Ai core frame...",
                                                              $"{interaction.Performer.ExpensiveName()} starts deconstructing the Ai core frame...",
                                                              "You deconstruct the Ai core frame.",
                                                              $"{interaction.Performer.ExpensiveName()} deconstructs the Ai core frame.",
                                                              () =>
                    {
                        Spawn.ServerPrefab(CommonPrefabs.Instance.Plasteel, SpawnDestination.At(gameObject), 5);
                        _ = Despawn.ServerSingle(gameObject);
                    });
                }

                return;
            }

            //Adding Circuit board or unanchor
            if (CurrentState == anchoredState)
            {
                if (Validations.HasUsedItemTrait(interaction, aiCoreCircuitBoardTrait))
                {
                    //Add Circuit board
                    ToolUtils.ServerUseToolWithActionMessages(interaction, 2f,
                                                              "You start adding the circuit board to the Ai core frame...",
                                                              $"{interaction.Performer.ExpensiveName()} starts adding a circuit board to the Ai core frame...",
                                                              "You add a circuit board to the Ai core frame.",
                                                              $"{interaction.Performer.ExpensiveName()} adds a circuit board to the Ai core frame.",
                                                              () =>
                    {
                        Inventory.ServerConsume(interaction.HandSlot, 1);
                        stateful.ServerChangeState(circuitAddedState);
                        spriteHandler.ChangeSprite(1);
                    });
                }
                else if (Validations.HasUsedItemTrait(interaction, CommonTraits.Instance.Wrench))
                {
                    //Unanchor
                    ToolUtils.ServerUseToolWithActionMessages(interaction, 2f,
                                                              "You start unwrenching the Ai core frame from the floor...",
                                                              $"{interaction.Performer.ExpensiveName()} starts unwrenching the Ai core frame from the floor...",
                                                              "You unwrench the Ai core frame from the floor.",
                                                              $"{interaction.Performer.ExpensiveName()} unwrenches the Ai core frame from the floor.",
                                                              () =>
                    {
                        objectBehaviour.ServerSetAnchored(false, interaction.Performer);
                        stateful.ServerChangeState(initialState);
                    });
                }

                return;
            }

            //Screwdriver or remove Circuit board
            if (CurrentState == circuitAddedState)
            {
                if (Validations.HasUsedItemTrait(interaction, CommonTraits.Instance.Screwdriver))
                {
                    //Screwdriver
                    ToolUtils.ServerUseToolWithActionMessages(interaction, 2f,
                                                              "You start screwing in the circuit board...",
                                                              $"{interaction.Performer.ExpensiveName()} starts screwing in the circuit board...",
                                                              "You screw in the circuit board.",
                                                              $"{interaction.Performer.ExpensiveName()} screws in the circuit board.",
                                                              () =>
                    {
                        stateful.ServerChangeState(screwState);
                        spriteHandler.ChangeSprite(2);
                    });
                }
                else if (interaction.HandObject == null)
                {
                    //Remove Circuit board
                    Chat.AddActionMsgToChat(interaction, "You remove the circuit board from the frame",
                                            $"{interaction.Performer.ExpensiveName()} removes the circuit board from the frame");

                    Spawn.ServerPrefab(aiCoreCircuitBoardPrefab, SpawnDestination.At(gameObject));
                    stateful.ServerChangeState(anchoredState);
                    spriteHandler.ChangeSprite(0);
                }

                return;
            }

            //Add wire or unscrew
            if (CurrentState == screwState)
            {
                if (Validations.HasUsedItemTrait(interaction, CommonTraits.Instance.Cable))
                {
                    //Add wire
                    ToolUtils.ServerUseToolWithActionMessages(interaction, 2f,
                                                              "You start adding wire to the Ai core frame...",
                                                              $"{interaction.Performer.ExpensiveName()} starts adding wire to the Ai core frame...",
                                                              "You add wire to the Ai core frame.",
                                                              $"{interaction.Performer.ExpensiveName()} adds wire to the Ai core frame.",
                                                              () =>
                    {
                        Inventory.ServerConsume(interaction.HandSlot, 1);
                        stateful.ServerChangeState(wireAddedState);
                        spriteHandler.ChangeSprite(3);
                    });
                }
                else if (Validations.HasUsedItemTrait(interaction, CommonTraits.Instance.Screwdriver))
                {
                    //Remove unscrew
                    ToolUtils.ServerUseToolWithActionMessages(interaction, 2f,
                                                              "You start unscrewing in the circuit board...",
                                                              $"{interaction.Performer.ExpensiveName()} starts unscrewing in the circuit board...",
                                                              "You remove unscrew the circuit board.",
                                                              $"{interaction.Performer.ExpensiveName()} unscrews the circuit board.",
                                                              () =>
                    {
                        stateful.ServerChangeState(circuitAddedState);
                        spriteHandler.ChangeSprite(1);
                    });
                }

                return;
            }

            //Add brain, or skip brain and add reinforced glass or remove wire
            if (CurrentState == wireAddedState)
            {
                //TODO add brain adding interaction
                // if (Validations.HasUsedItemTrait(interaction, CommonTraits.Instance.brain))
                // {
                //  //Add brain
                //  Chat.AddActionMsgToChat(interaction, $"You place the {interaction.UsedObject.ExpensiveName()} inside the turret frame.",
                //      $"{interaction.Performer.ExpensiveName()} places the {interaction.UsedObject.ExpensiveName()} inside the turret frame.");
                //  _ = Despawn.ServerSingle(interaction.UsedObject);
                //  stateful.ServerChangeState(brainAddedState);

                //	spriteHandler.ChangeSprite(4);
                // }
                /*else */ if (Validations.HasUsedItemTrait(interaction, CommonTraits.Instance.ReinforcedGlassSheet))
                {
                    //Skip adding brain and add reinforced glass straight away instead
                    if (Validations.HasUsedAtLeast(interaction, 2) == false)
                    {
                        Chat.AddExamineMsgFromServer(interaction.Performer, "You need to use 2 reinforced glass sheets");
                        return;
                    }

                    ToolUtils.ServerUseToolWithActionMessages(interaction, 2f,
                                                              "You start adding the reinforced glass to the front of the Ai core...",
                                                              $"{interaction.Performer.ExpensiveName()} starts add reinforced glass to the front of the Ai core...",
                                                              "You add reinforced glass to the front of the Ai core.",
                                                              $"{interaction.Performer.ExpensiveName()} adds reinforced glass to the front of the Ai core.",
                                                              () =>
                    {
                        Inventory.ServerConsume(interaction.HandSlot, 2);
                        stateful.ServerChangeState(glassState);
                        spriteHandler.ChangeSprite(5);
                    });
                }
                else if (Validations.HasUsedItemTrait(interaction, CommonTraits.Instance.Wirecutter))
                {
                    //Remove wire
                    ToolUtils.ServerUseToolWithActionMessages(interaction, 2f,
                                                              "You start cutting out the wire...",
                                                              $"{interaction.Performer.ExpensiveName()} starts cutting out the wire...",
                                                              "You cut out the wire.",
                                                              $"{interaction.Performer.ExpensiveName()} cuts out the wire.",
                                                              () =>
                    {
                        Spawn.ServerPrefab(CommonPrefabs.Instance.SingleCableCoil, SpawnDestination.At(gameObject), 1);
                        stateful.ServerChangeState(screwState);
                        spriteHandler.ChangeSprite(2);
                    });
                }

                return;
            }

            //Add reinforced glass or remove brain
            if (CurrentState == brainAddedState)
            {
                if (Validations.HasUsedItemTrait(interaction, CommonTraits.Instance.ReinforcedGlassSheet))
                {
                    //Add reinforced glass
                    if (Validations.HasUsedAtLeast(interaction, 2) == false)
                    {
                        Chat.AddExamineMsgFromServer(interaction.Performer, "You need to use 2 reinforced glass sheets");
                        return;
                    }

                    ToolUtils.ServerUseToolWithActionMessages(interaction, 2f,
                                                              "You start adding the reinforced glass to the front of the Ai core...",
                                                              $"{interaction.Performer.ExpensiveName()} starts add reinforced glass to the front of the Ai core...",
                                                              "You add reinforced glass to the front of the Ai core.",
                                                              $"{interaction.Performer.ExpensiveName()} adds reinforced glass to the front of the Ai core.",
                                                              () =>
                    {
                        Inventory.ServerConsume(interaction.HandSlot, 2);
                        stateful.ServerChangeState(glassState);
                        spriteHandler.ChangeSprite(5);
                    });
                }
                else if (Validations.HasUsedItemTrait(interaction, CommonTraits.Instance.Crowbar))
                {
                    //Remove brain
                    ToolUtils.ServerUseToolWithActionMessages(interaction, 2f,
                                                              "You start removing the MMI/Positron Brain from the Ai core...",
                                                              $"{interaction.Performer.ExpensiveName()} starts removing the MMI/Positron Brain from the Ai core...",
                                                              "You remove the MMI/Positron Brain from the Ai core.",
                                                              $"{interaction.Performer.ExpensiveName()} removes the MMI/Positron Brain from the Ai core.",
                                                              () =>
                    {
                        //TODO remove brain logic
                        stateful.ServerChangeState(wireAddedState);
                        spriteHandler.ChangeSprite(3);
                    });
                }

                return;
            }

            //Screw to finish or remove glass
            if (CurrentState == glassState)
            {
                if (Validations.HasUsedItemTrait(interaction, CommonTraits.Instance.Screwdriver))
                {
                    //Finish
                    ToolUtils.ServerUseToolWithActionMessages(interaction, 2f,
                                                              "You start screwing in the glass to the frame...",
                                                              $"{interaction.Performer.ExpensiveName()} starts screwing in the glass to the frame...",
                                                              "You screw in the glass to the frame.",
                                                              $"{interaction.Performer.ExpensiveName()} screws in the glass to the frame.",
                                                              () =>
                    {
                        var newCore = Spawn.ServerPrefab(aiCorePrefab, SpawnDestination.At(gameObject), 1);

                        if (newCore.Successful)
                        {
                            //TODO set up ai core when we have brain
                            newCore.GameObject.GetComponent <AiVessel>().SetLinkedPlayer(null);
                        }

                        _ = Despawn.ServerSingle(gameObject);
                    });
                }
                else if (Validations.HasUsedItemTrait(interaction, CommonTraits.Instance.Crowbar))
                {
                    //Crowbar out glass
                    ToolUtils.ServerUseToolWithActionMessages(interaction, 2f,
                                                              "You start removing the reinforced glass from the Ai core frame...",
                                                              $"{interaction.Performer.ExpensiveName()} starts removing removing the reinforced glass from the Ai core frame...",
                                                              "You remove the reinforced glass from the Ai core frame.",
                                                              $"{interaction.Performer.ExpensiveName()} removes the reinforced glass from the Ai core frame.",
                                                              () =>
                    {
                        //TODO check for brain
                        // if ()
                        // {
                        //  stateful.ServerChangeState(brainAddedState);
                        //	spriteHandler.ChangeSprite(4);
                        //  return;
                        // }

                        Spawn.ServerPrefab(CommonPrefabs.Instance.ReinforcedGlassSheet, SpawnDestination.At(gameObject), 2);
                        stateful.ServerChangeState(wireAddedState);
                        spriteHandler.ChangeSprite(3);
                    });
                }
            }
        }
Пример #16
0
    /// <summary>
    /// FOR DEV / TESTING ONLY! Simulates destroying and recreating an item by putting it in the pool and taking it back
    /// out again. If item is not pooled, simply destroys and recreates it as if calling Despawn and then Spawn
    /// Can use this to validate that the object correctly re-initializes itself after spawning -
    /// no state should be left over from its previous incarnation.
    /// </summary>
    /// <returns>the re-created object</returns>
    public static GameObject ServerPoolTestRespawn(GameObject target)
    {
        var poolPrefabTracker = target.GetComponent <PoolPrefabTracker>();

        if (poolPrefabTracker == null)
        {
            //destroy / create using normal approach with no pooling
            Logger.LogWarningFormat("Object {0} has no pool prefab tracker, thus cannot be pooled. It will be destroyed / created" +
                                    " without going through the pool.", Category.ItemSpawn, target.name);

            //determine prefab
            var position = target.TileWorldPosition();
            var prefab   = DeterminePrefab(target);
            if (prefab == null)
            {
                Logger.LogErrorFormat("Object {0} at {1} cannot be respawned because it has no PoolPrefabTracker and its name" +
                                      " does not match a prefab name, so we cannot" +
                                      " determine the prefab to instantiate. Please fix this object so that it" +
                                      " has an attached PoolPrefabTracker or so its name matches the prefab it was created from.", Category.ItemSpawn, target.name, position);
                return(null);
            }

            Despawn.ServerSingle(target);
            return(ServerPrefab(prefab, position.To3Int()).GameObject);
        }
        else
        {
            //destroy / create with pooling
            //save previous position
            var destination = SpawnDestination.At(target);
            var worldPos    = target.TileWorldPosition();
            var transform   = target.GetComponent <IPushable>();
            var prevParent  = target.transform.parent;

            //this simulates going into the pool
            Despawn._ServerFireDespawnHooks(DespawnResult.Single(DespawnInfo.Single(target)));

            if (transform != null)
            {
                transform.VisibleState = false;
            }

            //this simulates coming back out of the pool
            target.SetActive(true);

            target.transform.parent   = prevParent;
            target.transform.position = worldPos.To3Int();

            var cnt = target.GetComponent <CustomNetTransform>();
            if (cnt)
            {
                cnt.ReInitServerState();
                cnt.NotifyPlayers();                 //Sending out clientState for already spawned items
            }
            var       prefab    = DeterminePrefab(target);
            SpawnInfo spawnInfo = SpawnInfo.Spawnable(
                SpawnablePrefab.For(prefab),
                destination);


            _ServerFireClientServerSpawnHooks(SpawnResult.Single(spawnInfo, target));
            return(target);
        }
    }
Пример #17
0
        public void ServerPerformInteraction(HandApply interaction)
        {
            //Anchor or disassemble
            if (CurrentState == initialState)
            {
                if (Validations.HasUsedItemTrait(interaction, CommonTraits.Instance.Wrench))
                {
                    if (!ServerValidations.IsAnchorBlocked(interaction))
                    {
                        //wrench in place
                        ToolUtils.ServerUseToolWithActionMessages(interaction, 2f,
                                                                  "You start wrenching the turret frame into place...",
                                                                  $"{interaction.Performer.ExpensiveName()} starts wrenching the turret frame into place...",
                                                                  "You wrench the turret frame into place.",
                                                                  $"{interaction.Performer.ExpensiveName()} wrenches the turret frame into place.",
                                                                  () =>
                        {
                            objectBehaviour.ServerSetAnchored(true, interaction.Performer);

                            stateful.ServerChangeState(anchoredState);
                        });

                        return;
                    }

                    Chat.AddExamineMsgFromServer(interaction.Performer, "Unable to anchor turret frame here");
                }
                else if (Validations.HasUsedItemTrait(interaction, CommonTraits.Instance.Crowbar))
                {
                    //deconstruct
                    ToolUtils.ServerUseToolWithActionMessages(interaction, 2f,
                                                              "You start deconstructing the turret frame...",
                                                              $"{interaction.Performer.ExpensiveName()} starts deconstructing the turret frame...",
                                                              "You deconstruct the turret frame.",
                                                              $"{interaction.Performer.ExpensiveName()} deconstructs the turret frame.",
                                                              () =>
                    {
                        Spawn.ServerPrefab(CommonPrefabs.Instance.Metal, SpawnDestination.At(gameObject), 5);
                        _ = Despawn.ServerSingle(gameObject);
                    });
                }

                return;
            }

            //Adding metal or unanchor
            if (CurrentState == anchoredState)
            {
                if (Validations.HasUsedItemTrait(interaction, CommonTraits.Instance.MetalSheet))
                {
                    //Add metal
                    ToolUtils.ServerUseToolWithActionMessages(interaction, 2f,
                                                              "You start adding a metal cover to the turret frame...",
                                                              $"{interaction.Performer.ExpensiveName()} starts adding a metal cover to the turret frame...",
                                                              "You add a metal cover to the turret frame.",
                                                              $"{interaction.Performer.ExpensiveName()} adds a metal cover to the turret frame.",
                                                              () =>
                    {
                        Inventory.ServerConsume(interaction.HandSlot, 1);
                        stateful.ServerChangeState(metalAddedState);
                    });
                }
                else if (Validations.HasUsedItemTrait(interaction, CommonTraits.Instance.Wrench))
                {
                    //Unanchor
                    ToolUtils.ServerUseToolWithActionMessages(interaction, 2f,
                                                              "You start unwrenching the turret frame from the floor...",
                                                              $"{interaction.Performer.ExpensiveName()} starts unwrenching the turret frame from the floor...",
                                                              "You unwrench the turret frame from the floor.",
                                                              $"{interaction.Performer.ExpensiveName()} unwrenches the turret frame from the floor.",
                                                              () =>
                    {
                        objectBehaviour.ServerSetAnchored(false, interaction.Performer);

                        stateful.ServerChangeState(initialState);
                    });
                }

                return;
            }

            //Wrench or remove metal
            if (CurrentState == metalAddedState)
            {
                if (Validations.HasUsedItemTrait(interaction, CommonTraits.Instance.Wrench))
                {
                    //Wrench
                    ToolUtils.ServerUseToolWithActionMessages(interaction, 2f,
                                                              "You start wrenching the bolts on the turret frame...",
                                                              $"{interaction.Performer.ExpensiveName()} starts wrenching the bolts on the turret frame...",
                                                              "You wrench the bolts on the turret frame.",
                                                              $"{interaction.Performer.ExpensiveName()} wrenches the bolts on the turret frame.",
                                                              () =>
                    {
                        stateful.ServerChangeState(wrenchState);
                    });
                }
                else if (Validations.HasUsedActiveWelder(interaction))
                {
                    //Remove metal
                    ToolUtils.ServerUseToolWithActionMessages(interaction, 2f,
                                                              "You start removing the metal cover from the turret frame...",
                                                              $"{interaction.Performer.ExpensiveName()} starts removing the metal cover from the turret frame...",
                                                              "You remove the metal cover from the turret frame.",
                                                              $"{interaction.Performer.ExpensiveName()} removes the metal cover from the turret frame.",
                                                              () =>
                    {
                        Spawn.ServerPrefab(CommonPrefabs.Instance.Metal, SpawnDestination.At(gameObject), 1);
                        stateful.ServerChangeState(anchoredState);
                    });
                }

                return;
            }

            //Add gun or unwrench
            if (CurrentState == wrenchState)
            {
                if (Validations.HasUsedItemTrait(interaction, gunTrait))
                {
                    //Add energy gun
                    Chat.AddActionMsgToChat(interaction, $"You place the {interaction.UsedObject.ExpensiveName()} inside the turret frame.",
                                            $"{interaction.Performer.ExpensiveName()} places the {interaction.UsedObject.ExpensiveName()} inside the turret frame.");
                    Inventory.ServerTransfer(interaction.HandSlot, gunSlot);
                    stateful.ServerChangeState(gunAddedState);
                }
                else if (Validations.HasUsedItemTrait(interaction, CommonTraits.Instance.Wrench))
                {
                    //Remove unwrench bolts
                    ToolUtils.ServerUseToolWithActionMessages(interaction, 2f,
                                                              "You start removing the bolts from the turret frame...",
                                                              $"{interaction.Performer.ExpensiveName()} starts removing the bolts from the turret frame...",
                                                              "You remove the bolts from the turret frame.",
                                                              $"{interaction.Performer.ExpensiveName()} removes the bolts from the turret frame.",
                                                              () =>
                    {
                        stateful.ServerChangeState(metalAddedState);
                    });
                }

                return;
            }

            //Add prox or remove gun
            if (CurrentState == gunAddedState)
            {
                if (Validations.HasUsedItemTrait(interaction, CommonTraits.Instance.ProximitySensor))
                {
                    //Add proximity sensor
                    Chat.AddActionMsgToChat(interaction, $"You place the {interaction.UsedObject.ExpensiveName()} inside the turret frame.",
                                            $"{interaction.Performer.ExpensiveName()} places the {interaction.UsedObject.ExpensiveName()} inside the turret frame.");
                    _ = Despawn.ServerSingle(interaction.UsedObject);
                    stateful.ServerChangeState(proxAddedState);
                }
                else if (interaction.HandObject == null)
                {
                    //Remove gun
                    Chat.AddActionMsgToChat(interaction, $"You remove the {gunSlot.ItemObject.ExpensiveName()} from the frame.",
                                            $"{interaction.Performer.ExpensiveName()} removes the {gunSlot.ItemObject.ExpensiveName()} from the frame.");
                    Inventory.ServerDrop(gunSlot);

                    stateful.ServerChangeState(wrenchState);
                }

                return;
            }

            //Screw or remove prox
            if (CurrentState == proxAddedState)
            {
                if (Validations.HasUsedItemTrait(interaction, CommonTraits.Instance.Screwdriver))
                {
                    //Screw
                    ToolUtils.ServerUseToolWithActionMessages(interaction, 2f,
                                                              "You start closing the internal hatch of the turret frame...",
                                                              $"{interaction.Performer.ExpensiveName()} starts closing the internal hatch of the turret frame...",
                                                              "You close the internal hatch of the turret frame.",
                                                              $"{interaction.Performer.ExpensiveName()} closes the internal hatch of the turret frame.",
                                                              () =>
                    {
                        stateful.ServerChangeState(screwState);
                    });
                }
                else if (interaction.HandObject == null)
                {
                    //Remove prox
                    Chat.AddActionMsgToChat(interaction, $"You remove the {gunSlot.ItemObject.ExpensiveName()} from the frame.",
                                            $"{interaction.Performer.ExpensiveName()} removes the {gunSlot.ItemObject.ExpensiveName()} from the frame.");
                    Spawn.ServerPrefab(proximityPrefab, objectBehaviour.registerTile.WorldPosition, transform.parent);

                    stateful.ServerChangeState(gunAddedState);
                }

                return;
            }

            //Add metal or unscrew
            if (CurrentState == screwState)
            {
                if (Validations.HasUsedItemTrait(interaction, CommonTraits.Instance.MetalSheet))
                {
                    //Add metal
                    ToolUtils.ServerUseToolWithActionMessages(interaction, 2f,
                                                              "You start adding a metal cover to the turret frame...",
                                                              $"{interaction.Performer.ExpensiveName()} starts adding a metal cover to the turret frame...",
                                                              "You add a metal cover to the turret frame.",
                                                              $"{interaction.Performer.ExpensiveName()} adds a metal cover to the turret frame.",
                                                              () =>
                    {
                        Inventory.ServerConsume(interaction.HandSlot, 1);
                        stateful.ServerChangeState(secondMetalAddedState);
                    });
                }
                else if (Validations.HasUsedItemTrait(interaction, CommonTraits.Instance.Screwdriver))
                {
                    //Unscrew
                    ToolUtils.ServerUseToolWithActionMessages(interaction, 2f,
                                                              "You start removing the bolts from the turret frame...",
                                                              $"{interaction.Performer.ExpensiveName()} starts removing the bolts from the turret frame...",
                                                              "You remove the bolts from the turret frame.",
                                                              $"{interaction.Performer.ExpensiveName()} removes the bolts from the turret frame.",
                                                              () =>
                    {
                        stateful.ServerChangeState(proxAddedState);
                    });
                }

                return;
            }

            //Finish construction, or remove metal
            if (CurrentState == secondMetalAddedState)
            {
                if (Validations.HasUsedActiveWelder(interaction))
                {
                    //Weld to finish turret
                    ToolUtils.ServerUseToolWithActionMessages(interaction, 2f,
                                                              "You start welding the outer metal cover to the turret frame...",
                                                              $"{interaction.Performer.ExpensiveName()} starts welding the outer metal cover to the turret frame...",
                                                              "You weld the outer metal cover to the turret frame.",
                                                              $"{interaction.Performer.ExpensiveName()} welds the outer metal cover to the turret frame.",
                                                              () =>
                    {
                        var spawnedTurret = Spawn.ServerPrefab(turretPrefab, objectBehaviour.registerTile.WorldPosition, transform.parent);

                        if (spawnedTurret.Successful && spawnedTurret.GameObject.TryGetComponent <Turret>(out var turret))
                        {
                            turret.SetUpTurret(gunSlot.Item.GetComponent <Gun>(), gunSlot);
                        }

                        _ = Despawn.ServerSingle(gameObject);
                    });
Пример #18
0
    private float AddDamage(float Energy, AttackType attackType, MetaDataNode data,
                            BasicTile basicTile, Vector3 worldPosition)
    {
        float energyAbsorbed = 0;

        if (basicTile.indestructible || Energy < basicTile.damageDeflection)
        {
            if (attackType == AttackType.Bomb && basicTile.ExplosionImpassable == false)
            {
                return(Energy * 0.375f);
            }
            else
            {
                if (attackType == AttackType.Bomb)
                {
                    return(energyAbsorbed * 0.85f);
                }
                else
                {
                    return(energyAbsorbed);
                }
            }
        }

        var damageTaken = basicTile.Armor.GetDamage(Energy, attackType);

        data.AddTileDamage(Layer.LayerType, damageTaken);

        if (basicTile.SoundOnHit != null && !string.IsNullOrEmpty(basicTile.SoundOnHit.AssetAddress) && basicTile.SoundOnHit.AssetAddress != "null")
        {
            if (damageTaken >= 1)
            {
                SoundManager.PlayNetworkedAtPos(basicTile.SoundOnHit, worldPosition);
            }
        }

        var totalDamageTaken = data.GetTileDamage(Layer.LayerType);

        if (totalDamageTaken >= basicTile.MaxHealth)
        {
            float excessEnergy = basicTile.Armor.GetForce(totalDamageTaken - basicTile.MaxHealth, attackType);
            if (basicTile.SoundOnDestroy.Count > 0)
            {
                SoundManager.PlayNetworkedAtPos(basicTile.SoundOnDestroy.RandomElement(), worldPosition);
            }
            data.RemoveTileDamage(Layer.LayerType);
            tileChangeManager.RemoveTile(data.Position, Layer.LayerType);
            tileChangeManager.RemoveOverlaysOfType(data.Position, LayerType.Effects, OverlayType.Damage);

            if (Layer.LayerType == LayerType.Floors || Layer.LayerType == LayerType.Base)
            {
                tileChangeManager.RemoveOverlaysOfType(data.Position, LayerType.Floors, OverlayType.Cleanable);
            }

            if (Layer.LayerType == LayerType.Walls)
            {
                tileChangeManager.RemoveOverlaysOfType(data.Position, LayerType.Walls, OverlayType.Cleanable);
                tileChangeManager.RemoveOverlaysOfType(data.Position, LayerType.Effects, OverlayType.Mining);
            }

            //Add new tile if needed
            //TODO change floors to using overlays, but generic overlay will need to be sprited
            //TODO Use Armour values
            //TODO have tiles present but one z down
            if (basicTile.ToTileWhenDestroyed != null)
            {
                var tile = basicTile.ToTileWhenDestroyed as BasicTile;

                var overFlowProtection = 0;

                while (excessEnergy > 0 && tile != null)
                {
                    overFlowProtection++;

                    if (tile.MaxHealth <= excessEnergy)
                    {
                        excessEnergy -= tile.MaxHealth;
                        tile          = tile.ToTileWhenDestroyed as BasicTile;
                    }
                    else
                    {
                        //Atm we just set remaining damage to 0, instead of absorbing it for the new tile
                        excessEnergy = 0;
                        tileChangeManager.UpdateTile(data.Position, tile);
                        break;
                    }

                    if (overFlowProtection > maxOverflowProtection)
                    {
                        Logger.LogError($"Overflow protection triggered on {basicTile.name}, ToTileWhenDestroyed is spawning tiles in a loop", Category.TileMaps);
                        break;
                    }
                }

                energyAbsorbed = Energy - excessEnergy;
            }

            if (basicTile.SpawnOnDestroy != null)
            {
                basicTile.SpawnOnDestroy.SpawnAt(SpawnDestination.At(worldPosition, metaTileMap.ObjectLayer.gameObject.transform));
            }

            basicTile.LootOnDespawn?.SpawnLoot(worldPosition);
        }
        else
        {
            if (basicTile.DamageOverlayList != null)
            {
                foreach (var overlayData in basicTile.DamageOverlayList.DamageOverlays)
                {
                    if (overlayData.damagePercentage <= totalDamageTaken / basicTile.MaxHealth)
                    {
                        tileChangeManager.AddOverlay(data.Position, overlayData.overlayTile);
                        break;
                    }
                }
            }

            //All the damage was absorbed, none left to return for next layer
            energyAbsorbed = Energy;
        }

        if (basicTile.MaxHealth < basicTile.MaxHealth - totalDamageTaken)
        {
            data.ResetDamage(Layer.LayerType);
        }

        if (attackType == AttackType.Bomb && basicTile.ExplosionImpassable == false)
        {
            return(energyAbsorbed * 0.375f);
        }
        else
        {
            if (attackType == AttackType.Bomb)
            {
                return(energyAbsorbed * 0.85f);
            }
            else
            {
                return(energyAbsorbed);
            }
        }
    }
Пример #19
0
        public void ServerPerformInteraction(HandApply interaction)
        {
            if (Validations.HasUsedItemTrait(interaction, CommonTraits.Instance.Screwdriver))
            {
                if (coverOpen)
                {
                    coverOpen = false;
                    if (activated)
                    {
                        stateSync = FireAlarmState.TopLightSpriteAlert;
                    }
                    else
                    {
                        stateSync = FireAlarmState.TopLightSpriteNormal;
                    }
                }
                else
                {
                    coverOpen = true;
                    if (hasCables)
                    {
                        stateSync = FireAlarmState.OpenCabledSprite;
                    }
                    else
                    {
                        stateSync = FireAlarmState.OpenEmptySprite;
                    }
                }
                ToolUtils.ServerPlayToolSound(interaction);
                return;
            }
            if (coverOpen)
            {
                if (hasCables && Validations.HasUsedItemTrait(interaction, CommonTraits.Instance.Wirecutter))
                {
                    //cut out cables
                    Chat.AddActionMsgToChat(interaction, $"You remove the cables.",
                                            $"{interaction.Performer.ExpensiveName()} removes the cables.");
                    ToolUtils.ServerPlayToolSound(interaction);
                    Spawn.ServerPrefab(CommonPrefabs.Instance.SingleCableCoil, SpawnDestination.At(gameObject), 5);
                    stateSync = FireAlarmState.OpenEmptySprite;
                    hasCables = false;
                    activated = false;
                    return;
                }

                if (!hasCables && Validations.HasUsedItemTrait(interaction, CommonTraits.Instance.Cable) &&
                    Validations.HasUsedAtLeast(interaction, 5))
                {
                    //add 5 cables
                    ToolUtils.ServerUseToolWithActionMessages(interaction, 2f,
                                                              "You start adding cables to the frame...",
                                                              $"{interaction.Performer.ExpensiveName()} starts adding cables to the frame...",
                                                              "You add cables to the frame.",
                                                              $"{interaction.Performer.ExpensiveName()} adds cables to the frame.",
                                                              () =>
                    {
                        Inventory.ServerConsume(interaction.HandSlot, 5);
                        hasCables = true;
                        stateSync = FireAlarmState.OpenCabledSprite;
                    });
                }
            }
            else
            {
                if (activated && !isInCooldown)
                {
                    activated = false;
                    stateSync = FireAlarmState.TopLightSpriteNormal;
                    StartCoroutine(SwitchCoolDown());
                    foreach (var firelock in FireLockList)
                    {
                        if (firelock == null)
                        {
                            continue;
                        }
                        var controller = firelock.Controller;
                        if (controller == null)
                        {
                            continue;
                        }

                        controller.TryOpen();
                    }
                }
                else
                {
                    SendCloseAlerts();
                }
            }
        }
Пример #20
0
    public void ServerPerformInteraction(HandApply interaction)
    {
        if (stateSync == MountedMonitorState.OpenCabled || stateSync == MountedMonitorState.OpenEmpty)
        {
            if (!hasCables && Validations.HasUsedItemTrait(interaction, CommonTraits.Instance.Cable) &&
                Validations.HasUsedAtLeast(interaction, 5))
            {
                //add 5 cables
                ToolUtils.ServerUseToolWithActionMessages(interaction, 2f,
                                                          "You start adding cables to the frame...",
                                                          $"{interaction.Performer.ExpensiveName()} starts adding cables to the frame...",
                                                          "You add cables to the frame.",
                                                          $"{interaction.Performer.ExpensiveName()} adds cables to the frame.",
                                                          () =>
                {
                    Inventory.ServerConsume(interaction.HandSlot, 5);
                    hasCables = true;
                    stateSync = MountedMonitorState.OpenCabled;
                });
            }
            else if (Validations.HasUsedItemTrait(interaction, CommonTraits.Instance.GlassSheet) &&
                     Validations.HasUsedAtLeast(interaction, 2))
            {
                //add 2 glass
                ToolUtils.ServerUseToolWithActionMessages(interaction, 2f,
                                                          "You start to put in the glass panel...",
                                                          $"{interaction.Performer.ExpensiveName()} starts to put in the glass panel...",
                                                          "You put in the glass panel.",
                                                          $"{interaction.Performer.ExpensiveName()} puts in the glass panel.",
                                                          () =>
                {
                    Inventory.ServerConsume(interaction.HandSlot, 2);
                    stateSync = MountedMonitorState.NonScrewedPanel;
                });
            }
            else if (hasCables && Validations.HasUsedItemTrait(interaction, CommonTraits.Instance.Wirecutter))
            {
                //cut out cables
                Chat.AddActionMsgToChat(interaction, $"You remove the cables.",
                                        $"{interaction.Performer.ExpensiveName()} removes the cables.");
                ToolUtils.ServerPlayToolSound(interaction);
                Spawn.ServerPrefab(CommonPrefabs.Instance.SingleCableCoil, SpawnDestination.At(gameObject), 5);
                stateSync           = MountedMonitorState.OpenEmpty;
                hasCables           = false;
                currentTimerSeconds = 0;
                doorControllers.Clear();
            }
        }
        else if (stateSync == MountedMonitorState.NonScrewedPanel)
        {
            if (Validations.HasUsedItemTrait(interaction, CommonTraits.Instance.Crowbar))
            {
                //remove glass
                Chat.AddActionMsgToChat(interaction, $"You remove the glass panel.",
                                        $"{interaction.Performer.ExpensiveName()} removes the glass panel.");
                ToolUtils.ServerPlayToolSound(interaction);
                Spawn.ServerPrefab(CommonPrefabs.Instance.GlassSheet, SpawnDestination.At(gameObject), 2);
                if (hasCables)
                {
                    stateSync = MountedMonitorState.OpenCabled;
                }
                else
                {
                    stateSync = MountedMonitorState.OpenEmpty;
                }
            }
            else if (Validations.HasUsedItemTrait(interaction, CommonTraits.Instance.Screwdriver))
            {
                //screw in monitor, completing construction
                Chat.AddActionMsgToChat(interaction, $"You connect the monitor.",
                                        $"{interaction.Performer.ExpensiveName()} connects the monitor.");
                ToolUtils.ServerPlayToolSound(interaction);
                if (hasCables)
                {
                    stateSync = MountedMonitorState.StatusText;
                }
            }
        }
        else
        {
            if (Validations.HasUsedItemTrait(interaction, CommonTraits.Instance.Screwdriver))
            {
                //disconnect the monitor
                Chat.AddActionMsgToChat(interaction, $"You disconnect the monitor.",
                                        $"{interaction.Performer.ExpensiveName()} disconnect the monitor.");
                ToolUtils.ServerPlayToolSound(interaction);
                stateSync = MountedMonitorState.NonScrewedPanel;
            }
            else if (stateSync == MountedMonitorState.Image)
            {
                ChangeChannelMessage(interaction);
                stateSync = MountedMonitorState.StatusText;
            }
            else if (stateSync == MountedMonitorState.StatusText)
            {
                if (channel == StatusDisplayChannel.DoorTimer)
                {
                    currentTimerSeconds += 60;
                    if (currentTimerSeconds > 600)
                    {
                        currentTimerSeconds = 1;
                    }

                    if (!countingDown)
                    {
                        StartCoroutine(TickTimer());
                    }
                    else
                    {
                        OnTextBroadcastReceived(StatusDisplayChannel.DoorTimer);
                    }
                }
                else
                {
                    ChangeChannelMessage(interaction);
                    stateSync = MountedMonitorState.Image;
                }
            }
        }
    }
Пример #21
0
 private void ReinforceGirder(HandApply interaction)
 {
     interaction.HandObject.GetComponent <Stackable>().ServerConsume(1);
     Spawn.ServerPrefab(reinforcedGirder, SpawnDestination.At(gameObject));
     Despawn.ServerSingle(gameObject);
 }
Пример #22
0
    public void ServerPerformInteraction(HandApply interaction)
    {
        if (Validations.HasUsedItemTrait(interaction, CommonTraits.Instance.Crowbar))
        {
            //deconsruct
            ToolUtils.ServerUseToolWithActionMessages(interaction, 2f,
                                                      "You start deconstructing the conveyor belt...",
                                                      $"{interaction.Performer.ExpensiveName()} starts deconstructing the conveyor belt...",
                                                      "You deconstruct the conveyor belt.",
                                                      $"{interaction.Performer.ExpensiveName()} deconstructs the conveyor belt.",
                                                      () =>
            {
                Spawn.ServerPrefab(CommonPrefabs.Instance.Metal, SpawnDestination.At(gameObject), 5);
                Despawn.ServerSingle(gameObject);
            });
        }
        else if (Validations.HasUsedItemTrait(interaction, CommonTraits.Instance.Wrench))        //change direction
        {
            int count = (int)CurrentDirection + 1;

            if (count > 7)
            {
                count = 0;
            }

            ToolUtils.ServerUseToolWithActionMessages(interaction, 1f,
                                                      "You start redirecting the conveyor belt...",
                                                      $"{interaction.Performer.ExpensiveName()} starts redirecting the conveyor belt...",
                                                      "You redirect the conveyor belt.",
                                                      $"{interaction.Performer.ExpensiveName()} redirects the conveyor belt.",
                                                      () =>
            {
                CurrentDirection = (ConveyorDirection)count;

                UpdateDirection(CurrentDirection);

                spriteHandler.ChangeSpriteVariant(count);
            });
        }
        else if (Validations.HasUsedItemTrait(interaction, CommonTraits.Instance.Screwdriver))
        {
            ToolUtils.ServerUseToolWithActionMessages(interaction, 1f,
                                                      "You start inverting the conveyor belt...",
                                                      $"{interaction.Performer.ExpensiveName()} starts inverting the conveyor belt...",
                                                      "You invert the conveyor belt.",
                                                      $"{interaction.Performer.ExpensiveName()} invert the conveyor belt.",
                                                      () =>
            {
                switch (SyncInverted)
                {
                case true:
                    SyncInverted = false;
                    break;

                case false:
                    SyncInverted = true;
                    break;
                }
            });
        }
    }