コード例 #1
0
ファイル: Cyclops.cs プロジェクト: willchris2/Nitrox
        public void ToggleEngineState(NitroxId id, bool isStarting, bool isOn, bool silent = false)
        {
            GameObject cyclops = NitroxIdentifier.RequireObjectFrom(id);
            CyclopsEngineChangeState engineState = cyclops.RequireComponentInChildren <CyclopsEngineChangeState>();
            CyclopsMotorMode         motorMode   = cyclops.RequireComponentInChildren <CyclopsMotorMode>();

            if (isOn == engineState.motorMode.engineOn)
            {
                if ((isStarting != (bool)engineState.ReflectionGet("startEngine")) != isOn)
                {
                    if (Player.main.currentSub != engineState.subRoot || silent)
                    {
                        engineState.ReflectionSet("startEngine", !isOn);
                        engineState.ReflectionSet("invalidButton", true);
                        engineState.Invoke("ResetInvalidButton", 2.5f);
                        engineState.subRoot.BroadcastMessage("InvokeChangeEngineState", !isOn, SendMessageOptions.RequireReceiver);
                    }
                    else
                    {
                        engineState.ReflectionSet("invalidButton", false);
                        using (packetSender.Suppress <CyclopsToggleInternalLighting>())
                        {
                            engineState.OnClick();
                        }
                    }
                }
            }
        }
コード例 #2
0
        public override void Process(ModuleRemoved packet)
        {
            GameObject           owner       = NitroxIdentifier.RequireObjectFrom(packet.OwnerId);
            GameObject           item        = NitroxIdentifier.RequireObjectFrom(packet.ItemId);
            Pickupable           pickupable  = item.RequireComponent <Pickupable>();
            Optional <Equipment> opEquipment = EquipmentHelper.GetBasedOnOwnersType(owner);

            if (opEquipment.IsPresent())
            {
                Equipment equipment = opEquipment.Get();

                Dictionary <string, InventoryItem> itemsBySlot = (Dictionary <string, InventoryItem>)equipment.ReflectionGet("equipment");
                InventoryItem inventoryItem = itemsBySlot[packet.Slot];
                itemsBySlot[packet.Slot] = null;

                equipment.ReflectionCall("UpdateCount", false, false, new object[] { pickupable.GetTechType(), false });
                Equipment.SendEquipmentEvent(pickupable, UNEQUIP_EVENT_TYPE_ID, owner, packet.Slot);
                equipment.ReflectionCall("NotifyUnequip", false, false, new object[] { packet.Slot, inventoryItem });
            }
            else
            {
                Log.Error("Could not find equipment type for " + owner.name);
            }

            UnityEngine.Object.Destroy(item);
        }
コード例 #3
0
ファイル: Cyclops.cs プロジェクト: willchris2/Nitrox
        public void ChangeSilentRunning(NitroxId id, bool isOn)
        {
            GameObject cyclops = NitroxIdentifier.RequireObjectFrom(id);
            CyclopsSilentRunningAbilityButton ability = cyclops.RequireComponentInChildren <CyclopsSilentRunningAbilityButton>();

            using (packetSender.Suppress <CyclopsChangeSilentRunning>())
            {
                if ((bool)ability.ReflectionGet("active") != isOn)
                {
                    Log.Debug("Set silent running to " + isOn + " for " + id);
                    ability.ReflectionSet("active", isOn);
                    if (isOn)
                    {
                        ability.image.sprite = ability.activeSprite;
                        ability.subRoot.BroadcastMessage("RigForSilentRunning");
                        ability.InvokeRepeating("SilentRunningIteration", 0f, ability.silentRunningIteration);
                    }
                    else
                    {
                        ability.image.sprite = ability.inactiveSprite;
                        ability.subRoot.BroadcastMessage("SecureFromSilentRunning");
                        ability.CancelInvoke("SilentRunningIteration");
                    }
                }
            }
        }
コード例 #4
0
ファイル: Cyclops.cs プロジェクト: willchris2/Nitrox
        public void ChangeSonarMode(NitroxId id, bool isOn)
        {
            GameObject         cyclops = NitroxIdentifier.RequireObjectFrom(id);
            CyclopsSonarButton sonar   = cyclops.GetComponentInChildren <CyclopsSonarButton>();

            if (sonar != null)
            {
                using (packetSender.Suppress <CyclopsChangeSonarMode>())
                {
                    // At this moment the code is "non functional" as for some reason changing the sprite will never happen
                    // Also setting sonar as active will never work

                    MethodInfo sonarSetActiveInfo = sonar.GetType().GetMethod("set_sonarActive", BindingFlags.NonPublic | BindingFlags.Instance);
                    if (sonarSetActiveInfo != null)
                    {
                        sonarSetActiveInfo.Invoke(sonar, new object[] { isOn });
                    }
                    if (isOn)
                    {
                        sonar.image.sprite = sonar.activeSprite;
                    }
                    else
                    {
                        sonar.image.sprite = sonar.inactiveSprite;
                    }
                }
            }
        }
コード例 #5
0
        public override void Process(DeconstructionBegin packet)
        {
            GameObject    deconstructing = NitroxIdentifier.RequireObjectFrom(packet.Id);
            Constructable constructable  = deconstructing.RequireComponent <Constructable>();

            constructable.SetState(false, false);
        }
コード例 #6
0
ファイル: StorageSlots.cs プロジェクト: willchris2/Nitrox
        public void RemoveItem(NitroxId ownerId, bool silent = false)
        {
            GameObject             owner   = NitroxIdentifier.RequireObjectFrom(ownerId);
            Optional <EnergyMixin> opMixin = Optional <EnergyMixin> .OfNullable(owner.GetComponent <EnergyMixin>());

            if (opMixin.IsPresent())
            {
                EnergyMixin mixin = opMixin.Get();
                StorageSlot slot  = (StorageSlot)mixin.ReflectionGet("batterySlot");

                // Suppress sound when silent is active
                // Will be used to suppress swap sound at the initialisation of the game
                bool allowedToPlaySounds = true;
                if (silent)
                {
                    allowedToPlaySounds = (bool)mixin.ReflectionGet("allowedToPlaySounds");
                    mixin.ReflectionSet("allowedToPlaySounds", !silent);
                }
                using (packetSender.Suppress <StorageSlotItemRemove>())
                {
                    slot.RemoveItem();
                }
                if (silent)
                {
                    mixin.ReflectionSet("allowedToPlaySounds", allowedToPlaySounds);
                }
            }
            else
            {
                Log.Error("Removing storage slot item: Could not find storage slot field on object " + owner.name);
            }
        }
コード例 #7
0
        public override void Process(CyclopsActivateHorn hornPacket)
        {
            GameObject         cyclops = NitroxIdentifier.RequireObjectFrom(hornPacket.Id);
            CyclopsHornControl horn    = cyclops.RequireComponentInChildren <CyclopsHornControl>();

            Utils.PlayEnvSound(horn.hornSound, horn.hornSound.gameObject.transform.position, 20f);
        }
コード例 #8
0
        // The next two functions could potentially reside outside of this specific serializer.
        // They only happen to be in here because dropped items use this code path.

        private void AssignToWaterPark(GameObject gameObject, NitroxId waterParkId)
        {
            Pickupable pickupable  = gameObject.RequireComponent <Pickupable>();
            GameObject waterParkGo = NitroxIdentifier.RequireObjectFrom(waterParkId);
            WaterPark  waterPark   = waterParkGo.RequireComponent <WaterPark>();

            waterPark.AddItem(pickupable);
        }
コード例 #9
0
        /// <summary>
        /// Finds and executes <see cref="Fire.Douse(float)"/>. If the fire is extinguished, it will pass a large float to trigger the private
        /// <see cref="Fire.Extinguish()"/> method.
        /// </summary>
        public override void Process(FireDoused packet)
        {
            GameObject fireGameObject = NitroxIdentifier.RequireObjectFrom(packet.Id);

            using (packetSender.Suppress <FireDoused>())
            {
                fireGameObject.RequireComponent <Fire>().Douse(packet.DouseAmount);
            }
        }
コード例 #10
0
        public override void Process(OpenableStateChanged packet)
        {
            GameObject gameObject = NitroxIdentifier.RequireObjectFrom(packet.Id);
            Openable   openable   = gameObject.RequireComponent <Openable>();

            using (packetSender.Suppress <OpenableStateChanged>())
            {
                openable.PlayOpenAnimation(packet.IsOpen, packet.Duration);
            }
        }
コード例 #11
0
ファイル: Cyclops.cs プロジェクト: willchris2/Nitrox
        public void ChangeEngineMode(NitroxId id, CyclopsMotorMode.CyclopsMotorModes mode)
        {
            GameObject       cyclops   = NitroxIdentifier.RequireObjectFrom(id);
            CyclopsMotorMode motorMode = cyclops.RequireComponentInChildren <CyclopsMotorMode>();

            if (motorMode.cyclopsMotorMode != mode)
            {
                motorMode.BroadcastMessage("SetCyclopsMotorMode", mode, SendMessageOptions.RequireReceiver);
            }
        }
コード例 #12
0
        public override void Process(VehicleNameChange namePacket)
        {
            GameObject   target       = NitroxIdentifier.RequireObjectFrom(namePacket.Id);
            SubNameInput subNameInput = target.RequireComponentInChildren <SubNameInput>();

            using (packetSender.Suppress <VehicleNameChange>())
            {
                subNameInput.OnNameChange(namePacket.Name);
            }
        }
コード例 #13
0
        public override void UpdateMetadata(NitroxId id, SignMetadata metadata)
        {
            GameObject     gameObject = NitroxIdentifier.RequireObjectFrom(id);
            uGUI_SignInput sign       = gameObject.GetComponentInChildren <uGUI_SignInput>();

            sign.text          = metadata.Text;
            sign.colorIndex    = metadata.ColorIndex;
            sign.elementsState = metadata.Elements;
            sign.scaleIndex    = metadata.ScaleIndex;
            sign.SetBackground(metadata.Background);
        }
コード例 #14
0
        public override void Process(PowerLevelChanged packet)
        {
            GameObject gameObject = NitroxIdentifier.RequireObjectFrom(packet.Id);

            if (packet.PowerType == PowerType.ENERGY_INTERFACE)
            {
                EnergyInterface energyInterface = gameObject.RequireComponent <EnergyInterface>();

                float amount = packet.Amount;
                float num    = 0f;
                if (GameModeUtils.RequiresPower())
                {
                    int num2 = 0;
                    if (packet.Amount > 0f)
                    {
                        float num3 = energyInterface.TotalCanConsume(out num2);
                        if (num3 > 0f)
                        {
                            float amount2 = amount / (float)num2;
                            for (int i = 0; i < energyInterface.sources.Length; i++)
                            {
                                EnergyMixin energyMixin = energyInterface.sources[i];
                                if (energyMixin != null && energyMixin.charge < energyMixin.capacity)
                                {
                                    num += energyMixin.ModifyCharge(amount2);
                                }
                            }
                        }
                    }
                    else
                    {
                        float num4 = energyInterface.TotalCanProvide(out num2);
                        if (num2 > 0)
                        {
                            amount = ((-amount <= num4) ? amount : (-num4));
                            for (int j = 0; j < energyInterface.sources.Length; j++)
                            {
                                EnergyMixin energyMixin2 = energyInterface.sources[j];
                                if (energyMixin2 != null && energyMixin2.charge > 0f)
                                {
                                    float num5 = energyMixin2.charge / num4;
                                    num += energyMixin2.ModifyCharge(amount * num5);
                                }
                            }
                        }
                    }
                }
            }
            else
            {
                Log.Error("Unsupported packet power type: " + packet.PowerType);
            }
        }
コード例 #15
0
        public override void Process(FabricatorBeginCrafting packet)
        {
            GameObject gameObject = NitroxIdentifier.RequireObjectFrom(packet.FabricatorId);
            Fabricator fabricator = gameObject.RequireComponentInChildren <Fabricator>(true);

            float buildDuration = packet.Duration + 0.2f; // small increase to prevent this player from swiping item from remote player

            FieldInfo    logic        = typeof(Crafter).GetField("_logic", BindingFlags.Instance | BindingFlags.NonPublic);
            CrafterLogic crafterLogic = (CrafterLogic)logic.GetValue(fabricator);

            crafterLogic.Craft(packet.TechType.Enum(), buildDuration);
        }
コード例 #16
0
ファイル: Cyclops.cs プロジェクト: willchris2/Nitrox
        public void StartFireSuppression(NitroxId id)
        {
            GameObject cyclops = NitroxIdentifier.RequireObjectFrom(id);
            CyclopsFireSuppressionSystemButton fireSuppButton = cyclops.RequireComponentInChildren <CyclopsFireSuppressionSystemButton>();

            using (packetSender.Suppress <CyclopsFireSuppression>())
            {
                // Infos from SubFire.StartSystem
                fireSuppButton.subFire.StartCoroutine(StartFireSuppressionSystem(fireSuppButton.subFire));
                fireSuppButton.StartCooldown();
            }
        }
コード例 #17
0
        public override void Process(CyclopsActivateHorn hornPacket)
        {
            GameObject         cyclops = NitroxIdentifier.RequireObjectFrom(hornPacket.Id);
            CyclopsHornControl horn    = cyclops.RequireComponentInChildren <CyclopsHornControl>();

            EventInstance eventInstance = (EventInstance)fieldInfo.GetValue(horn.hornSound);

            eventInstance.setProperty(EVENT_PROPERTY.MAXIMUM_DISTANCE, 150f);
            fieldInfo.SetValue(horn.hornSound, eventInstance);

            horn.OnHandClick(null);
        }
コード例 #18
0
ファイル: Cyclops.cs プロジェクト: willchris2/Nitrox
        public void SonarPing(NitroxId id)
        {
            GameObject         cyclops = NitroxIdentifier.RequireObjectFrom(id);
            CyclopsSonarButton sonar   = cyclops.GetComponentInChildren <CyclopsSonarButton>();

            if (sonar != null)
            {
                using (packetSender.Suppress <CyclopsSonarPing>())
                {
                    sonar.ReflectionCall("SonarPing");
                }
            }
        }
コード例 #19
0
        public override void Process(CyclopsDamagePointRepaired packet)
        {
            GameObject gameObject = NitroxIdentifier.RequireObjectFrom(packet.Id);
            SubRoot    cyclops    = GameObjectHelper.RequireComponent <SubRoot>(gameObject);

            using (packetSender.Suppress <CyclopsDamage>())
            {
                using (packetSender.Suppress <CyclopsDamagePointRepaired>())
                {
                    cyclops.damageManager.damagePoints[packet.DamagePointIndex].liveMixin.AddHealth(packet.RepairAmount);
                }
            }
        }
コード例 #20
0
        public override void Process(VehicleOnPilotModeChanged packet)
        {
            GameObject vehicleGo = NitroxIdentifier.RequireObjectFrom(packet.VehicleId);
            Vehicle    vehicle   = vehicleGo.RequireComponent <Vehicle>();

            // If the vehicle is docked, then we will manually set the piloting mode
            // once the animations complete.  This prevents weird behaviour such as the
            // player existing the vehicle while it is about to dock (the event fires
            // before the animation completes on the remote player.)
            if (!vehicle.docked)
            {
                vehicles.SetOnPilotMode(packet.VehicleId, packet.PlayerId, packet.IsPiloting);
            }
        }
コード例 #21
0
ファイル: Cyclops.cs プロジェクト: willchris2/Nitrox
        public void LaunchDecoy(NitroxId id)
        {
            GameObject          cyclops      = NitroxIdentifier.RequireObjectFrom(id);
            CyclopsDecoyManager decoyManager = cyclops.RequireComponent <CyclopsDecoyManager>();

            using (packetSender.Suppress <CyclopsChangeSilentRunning>())
            {
                decoyManager.Invoke("LaunchWithDelay", 3f);
                decoyManager.decoyLaunchButton.UpdateText();
                decoyManager.subRoot.voiceNotificationManager.PlayVoiceNotification(decoyManager.subRoot.decoyNotification, false, true);
                decoyManager.subRoot.BroadcastMessage("UpdateTotalDecoys", decoyManager.decoyCount, SendMessageOptions.DontRequireReceiver);
                CyclopsDecoyLaunchButton decoyLaunchButton = cyclops.RequireComponent <CyclopsDecoyLaunchButton>();
                decoyLaunchButton.StartCooldown();
            }
        }
コード例 #22
0
        public override void Process(VehicleDocking packet)
        {
            GameObject vehicleGo           = NitroxIdentifier.RequireObjectFrom(packet.VehicleId);
            GameObject vehicleDockingBayGo = NitroxIdentifier.RequireObjectFrom(packet.DockId);

            Vehicle           vehicle           = vehicleGo.RequireComponent <Vehicle>();
            VehicleDockingBay vehicleDockingBay = vehicleDockingBayGo.RequireComponentInChildren <VehicleDockingBay>();

            using (packetSender.Suppress <VehicleDocking>())
            {
                vehicleDockingBay.SetVehicleDocked(vehicle);
            }

            vehicle.StartCoroutine(DisablePilotingAfterAnimation(packet.VehicleId, packet.PlayerId));
        }
コード例 #23
0
        public override void Process(FabricatorItemPickup packet)
        {
            GameObject   gameObject   = NitroxIdentifier.RequireObjectFrom(packet.FabricatorId);
            CrafterLogic crafterLogic = gameObject.RequireComponentInChildren <CrafterLogic>(true);

            if (crafterLogic.numCrafted > 0)
            {
                crafterLogic.numCrafted--;

                if (crafterLogic.numCrafted == 0)
                {
                    crafterLogic.Reset();
                }
            }
        }
コード例 #24
0
ファイル: Constructor.cs プロジェクト: willchris2/Nitrox
        public void BeginCrafting(GameObject constructor, TechType techType, float duration)
        {
            NitroxId constructorId = NitroxIdentifier.GetId(constructor);

            Log.Debug("Building item from constructor with id: " + constructorId);

            Optional <object> opConstructedObject = TransientLocalObjectManager.Get(TransientObjectType.CONSTRUCTOR_INPUT_CRAFTED_GAMEOBJECT);

            if (opConstructedObject.IsPresent())
            {
                GameObject constructedObject = (GameObject)opConstructedObject.Get();

                List <InteractiveChildObjectIdentifier> childIdentifiers = VehicleChildObjectIdentifierHelper.ExtractInteractiveChildren(constructedObject);
                Vehicle   vehicle             = constructedObject.GetComponent <Vehicle>();
                NitroxId  constructedObjectId = NitroxIdentifier.GetId(constructedObject);
                Vector3[] HSB       = new Vector3[5];
                Vector3[] Colours   = new Vector3[5];
                Vector4   tmpColour = Color.white;
                string    name      = "";

                if (!vehicle)
                { // Cylcops
                    GameObject   target        = NitroxIdentifier.RequireObjectFrom(constructedObjectId);
                    SubNameInput subNameInput  = target.RequireComponentInChildren <SubNameInput>();
                    SubName      subNameTarget = (SubName)subNameInput.ReflectionGet("target");

                    Colours = subNameTarget.GetColors();
                    HSB     = subNameTarget.GetColors();
                    name    = subNameTarget.GetName();
                }
                else if (vehicle)
                { // Seamoth & Prawn Suit
                    name    = (string)vehicle.ReflectionCall("GetName", true);
                    HSB     = vehicle.subName.GetColors();
                    Colours = vehicle.subName.GetColors();
                }
                ConstructorBeginCrafting beginCrafting = new ConstructorBeginCrafting(constructorId, constructedObjectId, techType.Model(), duration, childIdentifiers, constructedObject.transform.position, constructedObject.transform.rotation,
                                                                                      name, HSB, Colours);
                vehicles.AddVehicle(VehicleModelFactory.BuildFrom(beginCrafting));
                packetSender.Send(beginCrafting);

                SpawnDefaultBatteries(constructedObject, childIdentifiers);
            }
            else
            {
                Log.Error("Could not send packet because there wasn't a corresponding constructed object!");
            }
        }
コード例 #25
0
        public override void Process(VehicleColorChange colorPacket)
        {
            GameObject   target        = NitroxIdentifier.RequireObjectFrom(colorPacket.Id);
            SubNameInput subNameInput  = target.RequireComponentInChildren <SubNameInput>();
            SubName      subNameTarget = (SubName)subNameInput.ReflectionGet("target");

            using (packetSender.Suppress <VehicleColorChange>())
            {
                // Switch to the currently selected tab:
                subNameInput.SetSelected(colorPacket.Index);

                // OnColorChange calls these two methods, in order to update the vehicle color and the color+text on the ingame panel, respectively:
                subNameTarget.SetColor(colorPacket.Index, colorPacket.HSB, colorPacket.Color);
                subNameInput.ReflectionCall("SetColor", args: new object[] { colorPacket.Index, colorPacket.Color });
            }
        }
コード例 #26
0
ファイル: Cyclops.cs プロジェクト: willchris2/Nitrox
        public void SetFloodLighting(NitroxId id, bool isOn)
        {
            GameObject           cyclops  = NitroxIdentifier.RequireObjectFrom(id);
            CyclopsLightingPanel lighting = cyclops.RequireComponentInChildren <CyclopsLightingPanel>();

            if (lighting.floodlightsOn != isOn)
            {
                using (packetSender.Suppress <CyclopsToggleFloodLights>())
                {
                    lighting.floodlightsOn = !lighting.floodlightsOn;
                    lighting.ReflectionCall("SetExternalLighting", false, false, new object[] { lighting.floodlightsOn });
                    FMODAsset asset = (!lighting.floodlightsOn) ? lighting.vn_floodlightsOff : lighting.vn_floodlightsOn;
                    FMODUWE.PlayOneShot(asset, lighting.transform.position, 1f);
                    lighting.ReflectionCall("UpdateLightingButtons");
                }
            }
        }
コード例 #27
0
ファイル: Cyclops.cs プロジェクト: willchris2/Nitrox
        public void SetInternalLighting(NitroxId id, bool isOn)
        {
            GameObject           cyclops  = NitroxIdentifier.RequireObjectFrom(id);
            CyclopsLightingPanel lighting = cyclops.RequireComponentInChildren <CyclopsLightingPanel>();

            if (lighting.lightingOn != isOn)
            {
                using (packetSender.Suppress <CyclopsToggleInternalLighting>())
                {
                    lighting.lightingOn = !lighting.lightingOn;
                    lighting.cyclopsRoot.ForceLightingState(lighting.lightingOn);
                    FMODAsset asset = (!lighting.lightingOn) ? lighting.vn_lightsOff : lighting.vn_lightsOn;
                    FMODUWE.PlayOneShot(asset, lighting.transform.position, 1f);
                    lighting.ReflectionCall("UpdateLightingButtons");
                }
            }
        }
コード例 #28
0
        public override void Process(SubRootChanged packet)
        {
            Optional <RemotePlayer> remotePlayer = remotePlayerManager.Find(packet.PlayerId);

            if (remotePlayer.IsPresent())
            {
                SubRoot subRoot = null;

                if (packet.SubRootId.IsPresent())
                {
                    GameObject sub = NitroxIdentifier.RequireObjectFrom(packet.SubRootId.Get());
                    subRoot = sub.GetComponent <SubRoot>();
                }

                remotePlayer.Get().SetSubRoot(subRoot);
            }
        }
コード例 #29
0
        public override void Process(NitroxModel.Packets.ToggleLights packet)
        {
            GameObject   gameObject   = NitroxIdentifier.RequireObjectFrom(packet.Id);
            ToggleLights toggleLights = gameObject.GetComponent <ToggleLights>();

            if (toggleLights == null)
            {
                toggleLights = gameObject.RequireComponentInChildren <ToggleLights>();
            }

            if (packet.IsOn != toggleLights.GetLightsActive())
            {
                using (packetSender.Suppress <NitroxModel.Packets.ToggleLights>())
                {
                    toggleLights.SetLightsActive(packet.IsOn);
                }
            }
        }
コード例 #30
0
        public override void Process(SeamothModulesAction packet)
        {
            using (packetSender.Suppress <SeamothModulesAction>())
                using (packetSender.Suppress <ItemContainerRemove>())
                {
                    GameObject _gameObject = NitroxIdentifier.RequireObjectFrom(packet.Id);
                    SeaMoth    seamoth     = _gameObject.GetComponent <SeaMoth>();
                    if (seamoth != null)
                    {
                        TechType techType = packet.TechType.Enum();

                        if (techType == TechType.SeamothElectricalDefense)
                        {
                            float[]           chargearray = (float[])seamoth.ReflectionGet("quickSlotCharge");
                            float             charge      = chargearray[packet.SlotID];
                            float             slotCharge  = seamoth.GetSlotCharge(packet.SlotID);
                            GameObject        gameObject  = global::Utils.SpawnZeroedAt(seamoth.seamothElectricalDefensePrefab, seamoth.transform, false);
                            ElectricalDefense component   = gameObject.GetComponent <ElectricalDefense>();
                            component.charge       = charge;
                            component.chargeScalar = slotCharge;
                        }

                        if (techType == TechType.SeamothTorpedoModule)
                        {
                            Transform      muzzle        = (packet.SlotID != seamoth.GetSlotIndex("SeamothModule1") && packet.SlotID != seamoth.GetSlotIndex("SeamothModule3")) ? seamoth.torpedoTubeRight : seamoth.torpedoTubeLeft;
                            ItemsContainer storageInSlot = seamoth.GetStorageInSlot(packet.SlotID, TechType.SeamothTorpedoModule);
                            TorpedoType    torpedoType   = null;

                            for (int i = 0; i < seamoth.torpedoTypes.Length; i++)
                            {
                                if (storageInSlot.Contains(seamoth.torpedoTypes[i].techType))
                                {
                                    torpedoType = seamoth.torpedoTypes[i];
                                    break;
                                }
                            }

                            //Original Function use Player Camera need parse owner camera values
                            TorpedoShot(storageInSlot, torpedoType, muzzle, packet.Forward, packet.Rotation);
                        }
                    }
                }
        }