예제 #1
0
        public void RemoveItemToProduce(MyFixedPoint amount, MyBlueprintToProduce blueprintInProduction, long senderEntityId)
        {
            SerializableDefinitionId blueprintId = blueprintInProduction.Blueprint.Id;

            int itemId = m_itemsToProduce.IndexOf(blueprintInProduction);

            if (m_itemsToProduce.IsValidIndex(itemId))
            {
                MyMultiplayer.RaiseEvent(this, x => x.RemoveItemToProduce_Request, amount, blueprintId, senderEntityId, itemId);
            }
        }
예제 #2
0
 void SendCloseEditor()
 {
     if (Sync.IsServer)
     {
         m_consoleOpen = false;
     }
     else
     {
         MyMultiplayer.RaiseEvent(this, x => x.CloseEditor);
     }
 }
예제 #3
0
        private void OnAddQueueItemRequest(int idx, SerializableDefinitionId defId, MyFixedPoint ammount)
        {
            var blueprint = MyDefinitionManager.Static.GetBlueprintDefinition(defId);

            Debug.Assert(blueprint != null, "Blueprint not present in the dictionary.");
            if (blueprint != null)
            {
                this.InsertQueueItem(idx, blueprint, ammount);
                MyMultiplayer.RaiseEvent(this, x => x.OnAddQueueItemSuccess, idx, defId, ammount);
            }
        }
예제 #4
0
        void OnChangeOpenRequest(bool isOpen, bool editable, ulong user, bool isPublic)
        {
            if (Sync.IsServer && IsOpen && isOpen)
            {
                return;
            }

            OnChangeOpen(isOpen, editable, user, isPublic);

            MyMultiplayer.RaiseEvent(this, x => x.OnChangeOpenSuccess, isOpen, editable, user, isPublic);
        }
예제 #5
0
 public void RecreateRotor(long?builderId = null)
 {
     if (builderId.HasValue)
     {
         MyMultiplayer.RaiseEvent(this, x => x.DoRecreateRotor, builderId.Value);
     }
     else
     {
         MyMultiplayer.RaiseEvent(this, x => x.DoRecreateRotor, MySession.Static.LocalPlayerId);
     }
 }
예제 #6
0
        private void RaiseEvent_NewItemSelected(int index)
        {
            m_currentItem       = index;
            m_currentItemStatus = 0.0f;

            if (Sync.IsServer)
            {
                MyMultiplayer.RaiseEvent(this, x => x.NewItemSelected_Event, index);
            }

            RaiseEvent_ProductionChanged();
        }
예제 #7
0
        public void Build(MySlimBlock cubeBlock, long owner, long builder, bool requestInstant = true)
        {
            Quaternion quat        = Quaternion.Identity;
            var        orientation = cubeBlock.Orientation;

            Quaternion projQuat = Quaternion.Identity;

            Orientation.GetQuaternion(out projQuat);
            orientation.GetQuaternion(out quat);
            quat = Quaternion.Multiply(ProjectionRotationQuaternion, quat);
            quat = Quaternion.Multiply(projQuat, quat);

            var projectorGrid = CubeGrid;
            var projectedGrid = cubeBlock.CubeGrid;

            Vector3I cubeMin = cubeBlock.FatBlock != null ? cubeBlock.FatBlock.Min : cubeBlock.Position;
            Vector3I cubeMax = cubeBlock.FatBlock != null ? cubeBlock.FatBlock.Max : cubeBlock.Position;

            Vector3I min = projectorGrid.WorldToGridInteger(projectedGrid.GridIntegerToWorld(cubeMin));
            Vector3I max = projectorGrid.WorldToGridInteger(projectedGrid.GridIntegerToWorld(cubeMax));
            Vector3I pos = projectorGrid.WorldToGridInteger(projectedGrid.GridIntegerToWorld(cubeBlock.Position));

            Vector3I projectedMin = new Vector3I(Math.Min(min.X, max.X), Math.Min(min.Y, max.Y), Math.Min(min.Z, max.Z));
            Vector3I projectedMax = new Vector3I(Math.Max(min.X, max.X), Math.Max(min.Y, max.Y), Math.Max(min.Z, max.Z));


            MyCubeGrid.MyBlockLocation location = new MyCubeGrid.MyBlockLocation(cubeBlock.BlockDefinition.Id, projectedMin, projectedMax, pos, quat, 0, owner);

            MyObjectBuilder_CubeBlock objectBuilder = null;

            //Find original grid builder
            foreach (var blockBuilder in m_originalGridBuilder.CubeBlocks)
            {
                if ((Vector3I)blockBuilder.Min == cubeMin && blockBuilder.GetId() == cubeBlock.BlockDefinition.Id)
                {
                    objectBuilder = (MyObjectBuilder_CubeBlock)blockBuilder.Clone();
                    objectBuilder.SetupForProjector();
                }
            }

            if (objectBuilder == null)
            {
                System.Diagnostics.Debug.Fail("Original object builder could not be found! (AlexFlorea)");
                objectBuilder     = cubeBlock.GetObjectBuilder();
                location.EntityId = MyEntityIdentifier.AllocateId();
            }

            objectBuilder.ConstructionInventory = null;
            bool buildInstant = requestInstant && MySession.Static.IsAdminModeEnabled(Sync.MyId);

            MyMultiplayer.RaiseEvent(projectorGrid, x => x.BuildBlockRequest, cubeBlock.ColorMaskHSV.PackHSVToUint(), location, objectBuilder, builder, buildInstant, owner);
            HideCube(cubeBlock);
        }
예제 #8
0
        public void SendAsRpcToServerAndSelf <TMsg>(ref TMsg msg, MyTransportMessageEnum messageType = MyTransportMessageEnum.Request)
            where TMsg : struct, IEntityMessage
        {
            // Send to self
            Sync.Layer.TransportLayer.SendMessage(ref msg, m_emptyRecipients, messageType, true);

            // When I'm not server, send also to server
            if (!Sync.IsServer)
            {
                var replicable = PrepareSend <TMsg>(ref msg, messageType);
                MyMultiplayer.RaiseEvent(replicable, x => x.RpcToServer_Implementation, (BitReaderWriter)m_sender);
            }
        }
예제 #9
0
 public void SendAsRpcToAllButOne <TMsg>(ref TMsg msg, ulong dontSentTo, MyTransportMessageEnum messageType = MyTransportMessageEnum.Request)
     where TMsg : struct, IEntityMessage
 {
     Debug.Assert(Sync.IsServer, "Must be server to send message to all");
     if (MyMultiplayer.Static != null)
     {
         var replicable = PrepareSend <TMsg>(ref msg, messageType);
         if (replicable != null)
         {
             MyMultiplayer.RaiseEvent(replicable, x => x.RpcToAllButOne_Implementation, (BitReaderWriter)m_sender, new EndpointId(dontSentTo));
         }
     }
 }
예제 #10
0
 public void UpdateHudParams(VRage.Game.Entity.MyEntity entity)
 {
     if (Sync.IsServer)
     {
         List <MyObjectBuilder_HudEntityParams> list = new List <MyObjectBuilder_HudEntityParams>();
         foreach (MyHudEntityParams @params in entity.GetHudParams(false))
         {
             list.Add(@params.GetObjectBuilder());
         }
         EndpointId targetEndpoint = new EndpointId();
         MyMultiplayer.RaiseEvent <MyDataBroadcaster, List <MyObjectBuilder_HudEntityParams> >(this, x => new Action <List <MyObjectBuilder_HudEntityParams> >(x.OnUpdateHudParams), list, targetEndpoint);
     }
 }
        protected void ClearQueueRequest()
        {
            for (int i = m_queue.Count - 1; i >= 0; i--)
            {
                if (!RemoveQueueItemTests(i))
                {
                    continue;
                }

                MyFixedPoint ammount = 1;
                MyMultiplayer.RaiseEvent(this, x => x.OnRemoveQueueItem, i, ammount, 0f);
            }
        }
 void OpenEditorRequest()
 {
     if (m_consoleOpen == false)
     {
         UserId        = MyEventContext.Current.Sender.Value;
         m_consoleOpen = true;
         MyMultiplayer.RaiseEvent(this, x => x.OpenEditorSucess, new EndpointId(UserId));
     }
     else
     {
         MyMultiplayer.RaiseEvent(this, x => x.OpenEditorFailure, new EndpointId(UserId));
     }
 }
예제 #13
0
        // Override of parent class event dispatcher
        public override void RaiseItemEvent <T>(int logicalItem, ref MyDefinitionId modDef, T eventData, bool fromClient)
        {
            // Client must raise event to server always
            Debug.Assert(Sync.IsServer != fromClient);

            if (fromClient)
            {
                MyMultiplayer.RaiseEvent(this, x => x.HandleItemEventClient, logicalItem, (SerializableDefinitionId)modDef, (object)eventData);
            }
            else
            {
                MyMultiplayer.RaiseEvent(this, x => x.HandleItemEventServer, logicalItem, (SerializableDefinitionId)modDef, (object)eventData);
            }
        }
예제 #14
0
        static MySoundBlock()
        {
            var volumeSlider = new MyTerminalControlSlider <MySoundBlock>("VolumeSlider", MySpaceTexts.BlockPropertyTitle_SoundBlockVolume, MySpaceTexts.BlockPropertyDescription_SoundBlockVolume);

            volumeSlider.SetLimits(0, 1.0f);
            volumeSlider.DefaultValue = 1;
            volumeSlider.Getter       = (x) => x.Volume;
            volumeSlider.Setter       = (x, v) => x.Volume = v;
            volumeSlider.Writer       = (x, result) => result.AppendInt32((int)(x.Volume * 100.0)).Append(" %");
            volumeSlider.EnableActions();
            MyTerminalControlFactory.AddControl(volumeSlider);

            var rangeSlider = new MyTerminalControlSlider <MySoundBlock>("RangeSlider", MySpaceTexts.BlockPropertyTitle_SoundBlockRange, MySpaceTexts.BlockPropertyDescription_SoundBlockRange);

            rangeSlider.SetLimits(0, 500);
            rangeSlider.DefaultValue = 50;
            rangeSlider.Getter       = (x) => x.Range;
            rangeSlider.Setter       = (x, v) => x.Range = v;
            rangeSlider.Writer       = (x, result) => result.AppendInt32((int)x.Range).Append(" m");
            rangeSlider.EnableActions();
            MyTerminalControlFactory.AddControl(rangeSlider);

            m_playButton         = new MyTerminalControlButton <MySoundBlock>("PlaySound", MySpaceTexts.BlockPropertyTitle_SoundBlockPlay, MySpaceTexts.Blank, (x) => MyMultiplayer.RaiseEvent(x, y => y.PlaySound));
            m_playButton.Enabled = (x) => x.IsSoundSelected;
            m_playButton.EnableAction();
            MyTerminalControlFactory.AddControl(m_playButton);

            m_stopButton = new MyTerminalControlButton <MySoundBlock>("StopSound", MySpaceTexts.BlockPropertyTitle_SoundBlockStop, MySpaceTexts.Blank,
                                                                      (x) => { MyMultiplayer.RaiseEvent(x, y => y.StopSound); x.m_willStartSound = false; });
            m_stopButton.Enabled = (x) => x.IsSoundSelected;
            m_stopButton.EnableAction();
            MyTerminalControlFactory.AddControl(m_stopButton);

            m_loopableTimeSlider = new MyTerminalControlSlider <MySoundBlock>("LoopableSlider", MySpaceTexts.BlockPropertyTitle_SoundBlockLoopTime, MySpaceTexts.Blank);
            m_loopableTimeSlider.DefaultValue = 1f;
            m_loopableTimeSlider.Getter       = (x) => x.LoopPeriod;
            m_loopableTimeSlider.Setter       = (x, f) => x.LoopPeriod = f;
            m_loopableTimeSlider.Writer       = (x, result) => MyValueFormatter.AppendTimeInBestUnit(x.LoopPeriod, result);
            m_loopableTimeSlider.Enabled      = (x) => x.IsLoopable;
            m_loopableTimeSlider.Normalizer   = (x, f) => x.NormalizeLoopPeriod(f);
            m_loopableTimeSlider.Denormalizer = (x, f) => x.DenormalizeLoopPeriod(f);
            m_loopableTimeSlider.EnableActions();
            MyTerminalControlFactory.AddControl(m_loopableTimeSlider);

            var soundsList = new MyTerminalControlListbox <MySoundBlock>("SoundsList", MySpaceTexts.BlockPropertyTitle_SoundBlockSoundList, MySpaceTexts.Blank);

            soundsList.ListContent  = (x, list1, list2) => x.FillListContent(list1, list2);
            soundsList.ItemSelected = (x, y) => x.SelectSound(y, true);
            MyTerminalControlFactory.AddControl(soundsList);
        }
        protected override void OnOwnershipChanged()
        {
            base.OnOwnershipChanged();

            //In survival mode, the new owner needs to recompile the script to be able to run it
            if (MySession.Static.SurvivalMode)
            {
                OnProgramTermination(ScriptTerminationReason.OwnershipChange);
                if (Sync.IsServer)
                {
                    MyMultiplayer.RaiseEvent(this, x => x.WriteProgramResponse, MyTexts.GetString(MySpaceTexts.ProgrammableBlock_Exception_Ownershipchanged));
                }
            }
        }
예제 #16
0
        private void FixOwnerAndAuthorShip(MyCubeGrid myCubeGrid, string playername)
        {
            HashSet <long>        authors = new HashSet <long>();
            HashSet <MySlimBlock> blocks  = new HashSet <MySlimBlock>(myCubeGrid.GetBlocks());
            var      player = utils.GetPlayerByNameOrId(playername);
            MyPlayer id     = MySession.Static.Players.TryGetPlayerBySteamId(player.SteamUserId);


            foreach (MySlimBlock block in blocks)
            {
                if (block == null || block.CubeGrid == null || block.IsDestroyed)
                {
                    continue;
                }

                MyCubeBlock cubeBlock = block.FatBlock;
                if (cubeBlock != null && cubeBlock.OwnerId != player.Identity.IdentityId)
                {
                    myCubeGrid.ChangeOwnerRequest(myCubeGrid, cubeBlock, 0, MyOwnershipShareModeEnum.Faction);

                    if (player.IdentityId != 0)
                    {
                        myCubeGrid.ChangeOwnerRequest(myCubeGrid, cubeBlock, player.IdentityId, MyOwnershipShareModeEnum.Faction);
                    }
                }
                if (block.BuiltBy == 0)
                {
                    /*
                     * Hack: TransferBlocksBuiltByID only transfers authorship if it has an author.
                     * Transfer Authorship Client just sets the author so we need to take care of limits ourselves.
                     */
                    block.TransferAuthorshipClient(player.IdentityId);
                    block.AddAuthorship();
                }
                authors.Add(block.BuiltBy);

                IMyCharacter character = player.Character;

                if (cubeBlock is Sandbox.ModAPI.IMyCockpit cockpit && cockpit.CanControlShip)
                {
                    cockpit.AttachPilot(character);
                }
            }

            foreach (long author in authors)
            {
                MyMultiplayer.RaiseEvent(myCubeGrid, x => new Action <long, long>(x.TransferBlocksBuiltByID), author, player.IdentityId, new EndpointId());
            }
        }
 /// <summary>
 /// Grid has been converted to dynamic, all small to large connections must be removed.
 /// </summary>
 internal void GridConvertedToDynamic(MyCubeGrid grid)
 {
     if (grid.GridSizeEnum == MyCubeSize.Small)
     {
         RemoveSmallGridConnections(grid);
         if (Sync.IsServer)
         {
             MyMultiplayer.RaiseEvent(grid, x => x.RequestConvertToDynamic);
         }
     }
     else
     {
         RemoveLargeGridConnections(grid);
     }
 }
예제 #18
0
        protected void OnTrigger()
        {
            if (!IsWorking)
            {
                return;
            }

            StopCountdown();
            if (Sync.IsServer)
            {
                NeedsUpdate |= MyEntityUpdateEnum.BEFORE_NEXT_FRAME;
            }
            else
            {
                MyMultiplayer.RaiseEvent(this, x => x.Trigger);
            }
        }
예제 #19
0
 /// <summary>
 /// Sends always to server (even server to self).
 /// </summary>
 public void SendAsRpcToServer <TMsg>(ref TMsg msg, MyTransportMessageEnum messageType = MyTransportMessageEnum.Request)
     where TMsg : struct, IEntityMessage
 {
     if (Sync.IsServer)
     {
         // Sending to self
         Sync.Layer.TransportLayer.SendMessage(ref msg, m_emptyRecipients, messageType, true);
     }
     else
     {
         var replicable = PrepareSend <TMsg>(ref msg, messageType);
         if (replicable != null)
         {
             MyMultiplayer.RaiseEvent(replicable, x => x.RpcToServer_Implementation, (BitReaderWriter)m_sender);
         }
     }
 }
        void assignCombobox_ItemSelected(MyCubeGrid grid, MyPlayer.PlayerId playerId)
        {
            ulong steamId  = playerId.SteamId;
            var   identity = MySession.Static.Players.TryGetPlayerIdentity(playerId);

            if (identity == null)
            {
                Debug.Fail("Transfering grid to nonexistent player.");
                return;
            }
            if (grid.IsTransferBlocksBuiltByIDPossible(MySession.Static.LocalPlayerId, identity.IdentityId))
            {
                var messageBox = MyGuiSandbox.CreateMessageBox(
                    styleEnum: Graphics.GUI.MyMessageBoxStyleEnum.Info,
                    buttonType: MyMessageBoxButtonsType.YES_NO,
                    messageText: new StringBuilder().AppendFormat(MyTexts.GetString(MyCommonTexts.MessageBoxTextConfirmTransferGrid), new object[] { grid.DisplayName, identity.DisplayName }),
                    messageCaption: MyTexts.Get(MyCommonTexts.MessageBoxCaptionPleaseConfirm),
                    canHideOthers: false,
                    callback: (result) =>
                {
                    if (result == MyGuiScreenMessageBox.ResultEnum.YES)
                    {
                        if (MySession.Static.Players.GetOnlinePlayers().Contains(MySession.Static.Players.GetPlayerById(playerId)))
                        {
                            MyMultiplayer.RaiseEvent(grid, x => x.SendTransferRequestMessage, MySession.Static.LocalPlayerId, identity.IdentityId, steamId);
                        }
                        else
                        {
                            ShowPlayerNotOnlineMessage(identity);
                        }
                    }
                });
                MyGuiSandbox.AddScreen(messageBox);
            }
            else
            {
                var messageBox = MyGuiSandbox.CreateMessageBox(
                    buttonType: MyMessageBoxButtonsType.OK,
                    messageText: new StringBuilder().AppendFormat(MyCommonTexts.MessageBoxTextNotEnoughFreeBlocksForTransfer, identity.DisplayName),
                    messageCaption: MyTexts.Get(MyCommonTexts.MessageBoxCaptionError),
                    canHideOthers: false
                    );
                MyGuiSandbox.AddScreen(messageBox);
            }
        }
예제 #21
0
        public void ClientUpdate()
        {
            const int ClientUpdateSleepFrames = 6;

            // Don't sync more often then once per 6 frames (~100 ms)
            if (m_dirtyProperties.Bits != 0 && MyMultiplayer.Static.FrameCounter - m_lastUpdateFrame >= ClientUpdateSleepFrames)
            {
                foreach (var property in m_properties)
                {
                    if (m_dirtyProperties[property.Id])
                    {
                        MyMultiplayer.RaiseEvent(this, x => x.TerminalValueChanged_Implementation, (byte)property.Id, (BitReaderWriter)property);
                    }
                }
                m_dirtyProperties.Reset(false);
                m_lastUpdateFrame = MyMultiplayer.Static.FrameCounter;
            }
        }
예제 #22
0
        void SetCountdown(bool countdownState)
        {
            bool success = false;

            if (countdownState)
            {
                success = StartCountdown();
            }
            else
            {
                success = StopCountdown();
            }

            if (success)
            {
                MyMultiplayer.RaiseEvent(this, x => x.SetCountdownClient, countdownState);
            }
        }
 public void Run(string argument)
 {
     if (this.IsWorking == false || this.IsFunctional == false)
     {
         return;
     }
     if (Sync.IsServer)
     {
         string response = this.ExecuteCode(argument);
         if (this.DetailedInfo.ToString() != response)
         {
             MyMultiplayer.RaiseEvent(this, x => x.WriteProgramResponse, response);
         }
     }
     else
     {
         this.SyncObject.SendRunProgramRequest(argument);
     }
 }
 void SendOpenEditorRequest()
 {
     if (Sync.IsServer)
     {
         if (m_consoleOpen == false)
         {
             m_consoleOpen = true;
             OpenEditor();
         }
         else
         {
             ShowEditorAllReadyOpen();
         }
     }
     else
     {
         MyMultiplayer.RaiseEvent(this, x => x.OpenEditorRequest);
     }
 }
        void deleteOwnedBlocksButton_ButtonClicked(MyGuiControlButton obj)
        {
            var grid       = m_infoGrids[obj.Index];
            var messageBox = MyGuiSandbox.CreateMessageBox(
                buttonType: MyMessageBoxButtonsType.YES_NO,
                messageText: new StringBuilder().AppendFormat(MyCommonTexts.MessageBoxTextConfirmDeleteGrid, grid.DisplayName),
                messageCaption: MyTexts.Get(MyCommonTexts.MessageBoxCaptionPleaseConfirm),
                canHideOthers: false,
                callback: (result) =>
            {
                if (result == MyGuiScreenMessageBox.ResultEnum.YES)
                {
                    if (grid != null)
                    {
                        MyMultiplayer.RaiseEvent(grid, x => x.RemoveBlocksBuiltByID, MySession.Static.LocalPlayerId);
                    }
                }
            });

            MyGuiSandbox.AddScreen(messageBox);
        }
예제 #26
0
        public void RecreateTop(long?builderId = null)
        {
            if (this.m_topBlock != null || this.m_welded == true)
            {
                long builder = builderId.HasValue ? builderId.Value : MySession.Static.LocalPlayerId;
                if (builder == MySession.Static.LocalPlayerId)
                {
                    MyHud.Notifications.Add(MyNotificationSingletons.HeadAlreadyExists);
                }
                return;
            }

            if (builderId.HasValue)
            {
                MyMultiplayer.RaiseEvent(this, x => x.DoRecreateTop, builderId.Value);
            }
            else
            {
                MyMultiplayer.RaiseEvent(this, x => x.DoRecreateTop, MySession.Static.LocalPlayerId);
            }
        }
예제 #27
0
 private static void VoxelOperationElipsoid_Implementation(long entityId, Vector3 radius, MatrixD Transformation, byte material, OperationType Type)
 {
     m_ellipsoidShape.Transformation = Transformation;
     m_ellipsoidShape.Radius         = radius;
     if (CanPlaceInArea(Type, m_ellipsoidShape))
     {
         MyEntity entity;
         MyEntities.TryGetEntityById(entityId, out entity);
         MyVoxelBase voxel = entity as MyVoxelBase;
         if (voxel != null)
         {
             voxel.BeforeContentChanged = true;
             MyMultiplayer.RaiseEvent(voxel.RootVoxel, x => x.PerformVoxelOperationElipsoid_Implementation, radius, Transformation, material, Type);
             var amountChanged = voxel.UpdateVoxelShape(Type, m_ellipsoidShape, material);
             if (Type == OperationType.Cut || Type == OperationType.Fill)
             {
                 MySession.Static.VoxelHandVolumeChanged += amountChanged;
             }
         }
     }
 }
        protected void RecreateTop(long?builderId = null, bool smallToLarge = false)  //If smallToLarge is set will add small Top Part Grid to Large CubeGrid. Used in MotorStator
        {
            if (m_isAttached)
            {
                long builder = builderId.HasValue ? builderId.Value : MySession.Static.LocalPlayerId;
                if (builder == MySession.Static.LocalPlayerId)
                {
                    MyHud.Notifications.Add(MyNotificationSingletons.HeadAlreadyExists);
                }
                return;
            }

            if (builderId.HasValue)
            {
                MyMultiplayer.RaiseEvent(this, x => x.DoRecreateTop, builderId.Value, smallToLarge);
            }
            else
            {
                MyMultiplayer.RaiseEvent(this, x => x.DoRecreateTop, MySession.Static.LocalPlayerId, smallToLarge);
            }
        }
예제 #29
0
        protected override void OnStartWorking()
        {
            base.OnStartWorking();

            for (int i = 0; i < EMITTERS_NUMBER; i++)
            {
                var sound = m_soundEmitters[i].Sound;
                if (sound != null)
                {
                    sound.Resume();
                }
            }

            if (m_willStartSound && CubeGrid.Physics != null)
            {
                // postponed sound start - here we should know if this.IsWorking == true
                // otherwise sound request is cancelled inside SendPlaySoundRequest call
                MyMultiplayer.RaiseEvent(this, x => x.PlaySound);
                m_willStartSound = false;
            }
        }
        private void RecreateTop(long?builderId = null)
        {
            if (m_isAttached)
            {
                long builder = builderId.HasValue ? builderId.Value : MySession.Static.LocalPlayerId;
                if (builder == MySession.Static.LocalPlayerId)
                {
                    MyHud.Notifications.Add(MyNotificationSingletons.HeadAlreadyExists);
                }
                return;
            }

            if (builderId.HasValue)
            {
                MyMultiplayer.RaiseEvent(this, x => x.DoRecreateTop, builderId.Value);
            }
            else
            {
                MyMultiplayer.RaiseEvent(this, x => x.DoRecreateTop, MySession.Static.LocalPlayerId);
            }
        }