コード例 #1
0
 public override void OnRemovedFromScene(object source)
 {
     base.OnRemovedFromScene(source);
     m_topBlockToReattach = m_topBlock;
     Detach(true);
     CubeGrid.OnPhysicsChanged -= cubeGrid_OnPhysicsChanged;
 }
コード例 #2
0
 protected override void Closing()
 {
     CubeGrid.OnPhysicsChanged -= cubeGrid_OnPhysicsChanged;
     Detach();
     m_topBlockToReattach = null;
     base.Closing();
 }
コード例 #3
0
        bool CanAttach(MyAttachableTopBlockBase top)
        {
            bool closed = MarkedForClose || Closed || CubeGrid.MarkedForClose || CubeGrid.Closed;

            if (closed)
            {
                return(false);
            }

            bool topClosed = top.MarkedForClose || top.Closed || top.CubeGrid.MarkedForClose || top.CubeGrid.Closed;

            if (topClosed)
            {
                return(false);
            }

            bool notInWorld = CubeGrid.Physics == null ||
                              CubeGrid.Physics.RigidBody == null || CubeGrid.Physics.RigidBody.InWorld == false;

            if (notInWorld)
            {
                return(false);
            }

            bool topNotInWorld = top.CubeGrid.Physics == null || top.CubeGrid.Physics.RigidBody == null ||
                                 CubeGrid.Physics.RigidBody.InWorld == false;

            if (topNotInWorld)
            {
                return(false);
            }

            return(true);
        }
コード例 #4
0
        protected override bool Attach(MyAttachableTopBlockBase topBlock, bool updateGroup = true)
        {
            Debug.Assert(topBlock != null, "Top block cannot be null!");

            MyPistonTop pistonTop = topBlock as MyPistonTop;

            if (pistonTop != null && base.Attach(topBlock, updateGroup))
            {
                Debug.Assert(m_constraint == null, "Contraint already attached, call detach first!");
                Debug.Assert(m_connectionState.Value.TopBlockId.HasValue && (m_connectionState.Value.TopBlockId.Value == 0 || m_connectionState.Value.TopBlockId.Value == topBlock.EntityId), "m_topBlockId must be set prior calling Attach!");

                UpdateAnimation();

                CreateConstraint(topBlock);

                if (updateGroup)
                {
                    m_conveyorEndpoint.Attach(pistonTop.ConveyorEndpoint as MyAttachableConveyorEndpoint);
                }

                UpdateText();
                return(true);
            }
            return(false);
        }
コード例 #5
0
        private void FindTopServer(MyEntityUpdateEnum updateFlags)
        {
            MyAttachableTopBlockBase top = null;

            if (m_topBlockToReattach != null)
            {
                top = m_topBlockToReattach;
            }
            else
            {
                top = FindMatchingTop();
            }

            if (top != null)
            {
                if (CanDetach())
                {
                    Detach();
                }

                if (TryAttach(top))
                {
                    m_topBlockToReattach = null;
                }
                else
                {
                    updateFlags |= MyEntityUpdateEnum.EACH_10TH_FRAME;
                }
            }
            else
            {
                updateFlags |= MyEntityUpdateEnum.EACH_10TH_FRAME;
            }
        }
コード例 #6
0
        private void TryForceWeldServer()
        {
            if (m_topBlockToReattach != null && m_forceWeld)
            {
                m_topBlock           = m_topBlockToReattach;
                m_topGrid            = m_topBlock.CubeGrid;
                m_topBlockToReattach = null;
            }

            if (m_topBlock == null && (m_connectionState.Value.TopBlockId.HasValue))
            {
                TryGetTop();
                NeedsUpdate |= MyEntityUpdateEnum.BEFORE_NEXT_FRAME;
                return;
            }

            if (m_topBlock != null)
            {
                if (m_forceWeld || m_speedWeld)
                {
                    if (m_welded == false)
                    {
                        WeldGroup(false);
                        UpdateText();
                    }
                }
                else if (m_welded)
                {
                    UnweldGroup();
                    m_forceApply = true;
                    TryAttach();
                    UpdateText();
                }
            }
        }
コード例 #7
0
        private void CreateTopPart(out MyAttachableTopBlockBase topBlock, long builtBy, MyCubeBlockDefinitionGroup topGroup, bool smallToLarge)
        {
            Debug.Assert(Sync.IsServer, "Server only method.");
            if (topGroup == null)
            {
                topBlock = null;
                return;
            }

            var gridSize = CubeGrid.GridSizeEnum;

            if (smallToLarge && gridSize == MyCubeSize.Large)   //If we have pressed the Attach Small Rotor Head button on large grid take the small grid definition from pair
            {
                gridSize = MyCubeSize.Small;
            }
            var matrix = GetTopGridMatrix();

            var definition = topGroup[gridSize];

            Debug.Assert(definition != null);

            var block = MyCubeGrid.CreateBlockObjectBuilder(definition, Vector3I.Zero, MyBlockOrientation.Identity, MyEntityIdentifier.AllocateId(), OwnerId, fullyBuilt: MySession.Static.CreativeMode);

            matrix.Translation = Vector3D.Transform(-definition.Center * CubeGrid.GridSize, matrix);

            var gridBuilder = MyObjectBuilderSerializer.CreateNewObject <MyObjectBuilder_CubeGrid>();

            gridBuilder.GridSizeEnum           = gridSize;
            gridBuilder.IsStatic               = false;
            gridBuilder.PositionAndOrientation = new MyPositionAndOrientation(matrix);
            gridBuilder.CubeBlocks.Add(block);

            var grid = MyEntityFactory.CreateEntity <MyCubeGrid>(gridBuilder);

            grid.Init(gridBuilder);

            topBlock = (MyAttachableTopBlockBase)grid.GetCubeBlock(Vector3I.Zero).FatBlock;

            if (!CanPlaceTop(topBlock, builtBy))
            {
                topBlock = null;
                grid.Close();
                return;
            }
            grid.PositionComp.SetPosition(grid.WorldMatrix.Translation - (Vector3D.Transform(topBlock.DummyPosLoc, grid.WorldMatrix) - grid.WorldMatrix.Translation));

            MyEntities.Add(grid);
            if (MyFakes.ENABLE_SENT_GROUP_AT_ONCE)
            {
                MyMultiplayer.ReplicateImmediatelly(MyExternalReplicable.FindByObject(grid), MyExternalReplicable.FindByObject(CubeGrid));
            }

            MatrixD masterToSlave = topBlock.CubeGrid.WorldMatrix * MatrixD.Invert(WorldMatrix);

            m_connectionState.Value = new State()
            {
                TopBlockId = topBlock.EntityId, MasterToSlave = masterToSlave
            };
        }
コード例 #8
0
        protected override bool Attach(MyAttachableTopBlockBase topBlock, bool updateGroup = true)
        {
            Debug.Assert(topBlock != null, "Top block cannot be null!");

            if (CubeGrid == topBlock.CubeGrid)
            {
                return(false);
            }

            MyPistonTop pistonTop = topBlock as MyPistonTop;

            if (pistonTop != null && base.Attach(topBlock, updateGroup))
            {
                Debug.Assert(m_constraint == null, "Contraint already attached, call detach first!");
                Debug.Assert(m_connectionState.Value.TopBlockId.HasValue && (m_connectionState.Value.TopBlockId.Value == 0 || m_connectionState.Value.TopBlockId.Value == topBlock.EntityId), "m_topBlockId must be set prior calling Attach!");

                UpdateAnimation();

                var matAD = MatrixD.CreateWorld(Vector3D.Transform(Vector3D.Transform(m_constraintBasePos, Subpart3.WorldMatrix), CubeGrid.PositionComp.WorldMatrixNormalizedInv), PositionComp.LocalMatrix.Forward, PositionComp.LocalMatrix.Up);
                var matBD = MatrixD.CreateWorld(m_topBlock.Position * m_topBlock.CubeGrid.GridSize, m_topBlock.PositionComp.LocalMatrix.Forward, m_topBlock.PositionComp.LocalMatrix.Up);
                var matA  = (Matrix)matAD;
                var matB  = (Matrix)matBD;
                m_fixedData = new HkFixedConstraintData();
                m_fixedData.SetInertiaStabilizationFactor(10);
                m_fixedData.SetSolvingMethod(HkSolvingMethod.MethodStabilized);
                m_fixedData.SetInBodySpace(matA, matB, CubeGrid.Physics, m_topGrid.Physics);

                //Dont dispose the fixed data or we wont have access to them

                m_constraint             = new HkConstraint(CubeGrid.Physics.RigidBody, topBlock.CubeGrid.Physics.RigidBody, m_fixedData);
                m_constraint.WantRuntime = true;

                CubeGrid.Physics.AddConstraint(m_constraint);
                if (!m_constraint.InWorld)
                {
                    Debug.Fail("Constraint was not added to world");
                    CubeGrid.Physics.RemoveConstraint(m_constraint);
                    m_constraint.Dispose();
                    m_constraint = null;
                    m_fixedData  = null;
                    return(false);
                }
                m_constraint.Enabled = true;

                m_topBlock = topBlock;
                m_topGrid  = topBlock.CubeGrid;
                topBlock.Attach(this);
                m_isAttached = true;

                if (updateGroup)
                {
                    m_conveyorEndpoint.Attach(pistonTop.ConveyorEndpoint as MyAttachableConveyorEndpoint);
                }

                UpdateText();
                return(true);
            }
            return(false);
        }
コード例 #9
0
        public void Reattach(bool force = false)
        {
            if (m_isWelding || m_welded || m_topBlock == null || m_topBlock.Closed)
            {
                return;
            }

            var  top      = m_topBlock;
            bool detached = Detach(force);

            if (Sync.IsServer)
            {
                m_connectionState.Value = new State()
                {
                    TopBlockId = 0, MasterToSlave = null
                };
            }

            if (CanAttach(top))
            {
                m_topBlock = top;
                m_topGrid  = top.CubeGrid;

                bool attached = Attach(top, force);

                if (attached && Sync.IsServer)
                {
                    MatrixD masterToSlave = top.CubeGrid.WorldMatrix * MatrixD.Invert(WorldMatrix);
                    m_connectionState.Value = new State()
                    {
                        TopBlockId = top.EntityId, MasterToSlave = masterToSlave, Force = force
                    };
                }

                //Debug.Assert(detached && attached);
                if (!top.MarkedForClose && top.CubeGrid.Physics != null)
                {
                    top.CubeGrid.Physics.ForceActivate();
                }
            }
            else
            {
                if (MyCubeGridGroups.Static.GetGroups(GridLinkTypeEnum.Physical).LinkExists(EntityId, CubeGrid, top.CubeGrid))
                {
                    OnConstraintRemoved(GridLinkTypeEnum.Physical, top.CubeGrid);
                }

                if (MyCubeGridGroups.Static.GetGroups(GridLinkTypeEnum.Logical).LinkExists(EntityId, CubeGrid, top.CubeGrid))
                {
                    OnConstraintRemoved(GridLinkTypeEnum.Logical, top.CubeGrid);
                }

                if (Sync.IsServer && top != null)
                {
                    top.Attach(this);
                }
            }
        }
コード例 #10
0
        private void CreateTopGrid(out MyCubeGrid topGrid, out MyAttachableTopBlockBase topBlock, long builtBy, MyCubeBlockDefinitionGroup topGroup)
        {
            if (topGroup == null)
            {
                topGrid  = null;
                topBlock = null;
                return;
            }

            var gridSize = CubeGrid.GridSizeEnum;

            float size   = MyDefinitionManager.Static.GetCubeSize(gridSize);
            var   matrix = GetTopGridMatrix();

            var definition = topGroup[gridSize];

            Debug.Assert(definition != null);

            var block = MyCubeGrid.CreateBlockObjectBuilder(definition, Vector3I.Zero, MyBlockOrientation.Identity, MyEntityIdentifier.AllocateId(), OwnerId, fullyBuilt: MySession.Static.CreativeMode);

            var gridBuilder = MyObjectBuilderSerializer.CreateNewObject <MyObjectBuilder_CubeGrid>();

            gridBuilder.GridSizeEnum           = gridSize;
            gridBuilder.IsStatic               = false;
            gridBuilder.PositionAndOrientation = new MyPositionAndOrientation(matrix);
            gridBuilder.CubeBlocks.Add(block);

            var grid = MyEntityFactory.CreateEntity <MyCubeGrid>(gridBuilder);

            grid.Init(gridBuilder);

            topGrid  = grid;
            topBlock = (MyAttachableTopBlockBase)topGrid.GetCubeBlock(Vector3I.Zero).FatBlock;

            if (!CanPlaceTop(topBlock, builtBy))
            {
                topGrid  = null;
                topBlock = null;
                grid.Close();
                return;
            }
            //topGrid.SetPosition(topGrid.WorldMatrix.Translation - (topBlock.WorldMatrix.Translation/*Vector3.Transform(topBlock.DummyPosLoc, topGrid.WorldMatrix) - topGrid.WorldMatrix.Translation*/));

            MyEntities.Add(grid);
            if (MyFakes.ENABLE_SENT_GROUP_AT_ONCE)
            {
                MyMultiplayer.ReplicateImmediatelly(MyExternalReplicable.FindByObject(grid), MyExternalReplicable.FindByObject(CubeGrid));
            }

            MatrixD masterToSlave = topBlock.CubeGrid.WorldMatrix * MatrixD.Invert(WorldMatrix);

            m_connectionState.Value = new State()
            {
                TopBlockId = topBlock.EntityId, MasterToSlave = masterToSlave
            };
        }
コード例 #11
0
        private void FindAndAttachTopServer()
        {
            Debug.Assert(Sync.IsServer, "Server only method");
            MyAttachableTopBlockBase top = FindMatchingTop();

            if (top != null)
            {
                TryAttach(top);
            }
        }
コード例 #12
0
        //Only overriden, not called from elsewhere
        protected virtual bool Attach(MyAttachableTopBlockBase topBlock, bool updateGroup = true)
        {
            Debug.Assert(TopBlock == null, "Inconsistency");
            Debug.Assert(!m_welded, "Inconsistency");
            if (topBlock.CubeGrid.Physics == null)
            {
                return(false);
            }

            if (CubeGrid.Physics == null || !CubeGrid.Physics.Enabled)
            {
                return(false);
            }

            m_topBlock = topBlock;
            m_topGrid  = TopBlock.CubeGrid;
            TopBlock.Attach(this);

            if (updateGroup)
            {
                CubeGrid.OnPhysicsChanged += cubeGrid_OnPhysicsChanged;

                TopGrid.OnGridSplit      += CubeGrid_OnGridSplit;
                TopGrid.OnPhysicsChanged += cubeGrid_OnPhysicsChanged;
                TopBlock.OnClosing       += TopBlock_OnClosing;

                OnConstraintAdded(GridLinkTypeEnum.Physical, TopGrid);
                OnConstraintAdded(GridLinkTypeEnum.Logical, TopGrid);

                RaiseAttachedEntityChanged(); //top is already set we can call here
            }

            if (Sync.IsServer)
            {
                MatrixD masterToSlave = TopBlock.CubeGrid.WorldMatrix * MatrixD.Invert(WorldMatrix);
                m_connectionState.Value = new State()
                {
                    TopBlockId = TopBlock.EntityId, MasterToSlave = masterToSlave, Welded = m_welded
                };
            }
            else if (m_connectionState.Value.MasterToSlave.HasValue)
            {
                TopBlock.CubeGrid.WorldMatrix = MatrixD.Multiply(m_connectionState.Value.MasterToSlave.Value, this.WorldMatrix);
            }

            m_isAttached = true; //Welding only allowed when attached

            if (m_forceWeld)
            {
                WeldGroup(true);
            }
            CheckVelocities();

            return(true);
        }
コード例 #13
0
        public void ReattachTop(MyAttachableTopBlockBase top)
        {
            if (m_topBlock != null || m_welded)
            {
                Detach();
            }

            m_topBlockToReattach = top;
            // Rotor not found by EntityId or not in scene, try again in 10 frames
            NeedsUpdate |= MyEntityUpdateEnum.BEFORE_NEXT_FRAME;
        }
コード例 #14
0
 protected virtual bool CreateConstraint(MyAttachableTopBlockBase top)
 {
     if (CanAttach(top))
     {
         return(!m_welded && CubeGrid.Physics.RigidBody != top.CubeGrid.Physics.RigidBody);
     }
     else
     {
         return(false);
     }
 }
コード例 #15
0
        protected override bool CanPlaceTop(MyAttachableTopBlockBase topBlock, long builtBy)
        {
            // Compute the rough actual position for the head, this improves the detection if it can be placed
            float    topDistance = (Subpart3.Model.BoundingBoxSize.Y);
            Vector3D topPosition = this.Subpart3.WorldMatrix.Translation + this.WorldMatrix.Up * topDistance;
            float    topRadius   = topBlock.ModelCollision.HavokCollisionShapes[0].ConvexRadius * 0.9f;

            // First test if we intersect any blocks of our own grid
            BoundingSphereD sphere = topBlock.Model.BoundingSphere;

            sphere.Center = topPosition;
            sphere.Radius = topRadius;
            CubeGrid.GetBlocksInsideSphere(ref sphere, m_tmpSet);

            // If we intersect more than 1 block (because top sometimes intersects piston), don't add top
            if (m_tmpSet.Count > 1)
            {
                m_tmpSet.Clear();
                if (builtBy == MySession.Static.LocalPlayerId)
                {
                    MyHud.Notifications.Add(MyNotificationSingletons.HeadNotPlaced);
                }
                return(false);
            }

            m_tmpSet.Clear();

            // Next test if we intersect any physics objects
            HkSphereShape spShape = new HkSphereShape(topRadius);
            Quaternion    q       = Quaternion.Identity;

            MyPhysics.GetPenetrationsShape(topBlock.ModelCollision.HavokCollisionShapes[0], ref topPosition, ref q, m_penetrations, MyPhysics.CollisionLayers.DefaultCollisionLayer);

            // If we have any collisions with anything other than our own grid, don't add the head
            // We already checked for inner-grid collisions in the previous case
            for (int i = 0; i < m_penetrations.Count; i++)
            {
                MyCubeGrid grid = m_penetrations[i].GetCollisionEntity().GetTopMostParent() as MyCubeGrid;
                if (grid == null || grid != CubeGrid)
                {
                    m_penetrations.Clear();
                    if (builtBy == MySession.Static.LocalPlayerId)
                    {
                        MyHud.Notifications.Add(MyNotificationSingletons.HeadNotPlaced);
                    }
                    return(false);
                }
            }

            m_penetrations.Clear();

            return(true);
        }
コード例 #16
0
        private MyAttachableTopBlockBase FindMatchingTop()
        {
            Debug.Assert(CubeGrid != null, "\"Impossible\"");
            Debug.Assert(m_penetrations != null, "\"Impossible\"");
            Debug.Assert(CubeGrid.Physics != null, "\"Impossible\"");

            Quaternion orientation;
            Vector3D   pos;
            Vector3    halfExtents;

            ComputeTopQueryBox(out pos, out halfExtents, out orientation);
            try
            {
                MyPhysics.GetPenetrationsBox(ref halfExtents, ref pos, ref orientation, m_penetrations, MyPhysics.CollisionLayers.DefaultCollisionLayer);
                foreach (var obj in m_penetrations)
                {
                    var entity = obj.GetCollisionEntity();
                    if (entity == null || entity == CubeGrid)
                    {
                        continue;
                    }

                    MyAttachableTopBlockBase top = FindTopInGrid(entity, pos);

                    if (top != null)
                    {
                        return(top);
                    }

                    MyPhysicsBody body = entity.Physics as MyPhysicsBody;
                    if (body != null)
                    {
                        foreach (var child in body.WeldInfo.Children)
                        {
                            top = FindTopInGrid(child.Entity, pos);
                            if (top != null)
                            {
                                return(top);
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
            }
            finally
            {
                m_penetrations.Clear();
            }
            return(null);
        }
コード例 #17
0
        public override void OnUnregisteredFromGridSystems()
        {
            base.OnUnregisteredFromGridSystems();

            if (Sync.IsServer)
            {
                if (m_topBlock != null)
                {
                    m_topBlockToReattach = m_topBlock;
                    Detach(true);
                }
                CubeGrid.OnGridSplit -= CubeGrid_OnGridSplit;
            }
        }
コード例 #18
0
        protected virtual bool Attach(MyAttachableTopBlockBase topBlock, bool updateGroup = true)
        {
            if (topBlock.CubeGrid.Physics == null)
            {
                return(false);
            }

            if (CubeGrid.Physics != null && CubeGrid.Physics.Enabled)
            {
                m_topBlock = topBlock;
                m_topGrid  = m_topBlock.CubeGrid;

                if (updateGroup)
                {
                    OnConstraintAdded(GridLinkTypeEnum.Physical, m_topGrid);
                    OnConstraintAdded(GridLinkTypeEnum.Logical, m_topGrid);
                    m_topGrid.OnPhysicsChanged += cubeGrid_OnPhysicsChanged;
                }

                if (CubeGrid.Physics.RigidBody == m_topGrid.Physics.RigidBody)
                {
                    if (m_welded)
                    {
                        m_isAttached = true;
                        return(true);
                    }
                    else
                    {
                        m_topAndBottomSamePhysicsBody.Value = true;
                        m_isAttached = false;
                        return(false);
                    }
                }
                else
                {
                    m_topAndBottomSamePhysicsBody.Value = false;
                }


                if (m_connectionState.Value.MasterToSlave.HasValue)
                {
                    m_topBlock.CubeGrid.WorldMatrix = MatrixD.Multiply(m_connectionState.Value.MasterToSlave.Value, this.WorldMatrix);
                }

                return(true);
            }
            return(m_welded);
        }
コード例 #19
0
        public virtual bool Detach(bool updateGroup = true)
        {
            var tmptopGrid = m_topBlock == null ? null: m_topBlock.CubeGrid;

            if (m_connectionState.Value.Welded || m_welded)
            {
                UnweldGroup();
            }
            else
            {
                if (updateGroup && tmptopGrid != null && (m_connectionState.Value.Welded == false || m_isWelding == false))
                {
                    OnConstraintRemoved(GridLinkTypeEnum.Physical, tmptopGrid);
                    OnConstraintRemoved(GridLinkTypeEnum.Logical, tmptopGrid);
                }
            }

            //Debug.Assert(m_topGrid != null);

            DisposeConstraint();

            if (m_topBlock != null)
            {
                m_topBlock.Detach(m_connectionState.Value.Welded || m_isWelding);

                if (updateGroup)
                {
                    tmptopGrid.OnPhysicsChanged -= cubeGrid_OnPhysicsChanged;
                    if (Sync.IsServer)
                    {
                        m_connectionState.Value = new State()
                        {
                            TopBlockId = 0, Welded = false
                        };
                    }
                }
            }


            m_topGrid    = null;
            m_topBlock   = null;
            m_isAttached = false;

            UpdateText();
            return(true);
        }
コード例 #20
0
        protected override bool Attach(MyAttachableTopBlockBase rotor, bool updateGroup = true)
        {
            if (rotor is MyMotorRotor)
            {
                var ret = base.Attach(rotor, updateGroup);

                if (ret)
                {
                    if (m_topBlock is MyMotorAdvancedRotor)
                    {
                        m_conveyorEndpoint.Attach((m_topBlock as MyMotorAdvancedRotor).ConveyorEndpoint as MyAttachableConveyorEndpoint);
                    }
                }

                return ret;
            }
            return false;
        }
コード例 #21
0
        private bool TryAttach(MyAttachableTopBlockBase top)
        {
            bool attached = false;

            if (CanAttach(top))
            {
                attached = Attach(top);
                if ((attached || m_topAndBottomSamePhysicsBody) && Sync.IsServer)
                {
                    MatrixD masterToSlave = top.CubeGrid.WorldMatrix * MatrixD.Invert(WorldMatrix);
                    m_connectionState.Value = new State()
                    {
                        TopBlockId = top.EntityId, MasterToSlave = masterToSlave, Welded = m_welded
                    };
                }
            }
            return(attached);
        }
コード例 #22
0
        private void WeldGroup(bool force)
        {
            var        topBlock = m_topBlock;
            MyCubeGrid topGrid  = m_topBlock.CubeGrid;

            m_isWelding = true;

            if (m_isAttached)
            {
                Detach(false);
            }

            MyWeldingGroups.Static.CreateLink(EntityId, CubeGrid, topGrid);

            if (MyCubeGridGroups.Static.GetGroups(GridLinkTypeEnum.Physical).LinkExists(EntityId, CubeGrid, topGrid) == false)
            {
                OnConstraintAdded(GridLinkTypeEnum.Physical, topGrid);
            }

            if (MyCubeGridGroups.Static.GetGroups(GridLinkTypeEnum.Logical).LinkExists(EntityId, CubeGrid, topGrid) == false)
            {
                OnConstraintAdded(GridLinkTypeEnum.Logical, topGrid);
            }

            if (Sync.IsServer)
            {
                MatrixD masterToSlave = topBlock.CubeGrid.WorldMatrix * MatrixD.Invert(WorldMatrix);
                m_connectionState.Value = new State()
                {
                    TopBlockId = topBlock.EntityId, MasterToSlave = masterToSlave, Welded = true, Force = force
                };
            }

            topBlock.Attach(this);
            topBlock.CubeGrid.OnPhysicsChanged += cubeGrid_OnPhysicsChanged;

            m_welded   = true;
            m_topGrid  = topGrid;
            m_topBlock = topBlock;

            m_isWelding = false;
            RaisePropertiesChanged();
        }
コード例 #23
0
        //Only overriden, not called from elsewhere
        protected virtual void Detach(bool updateGroups = true)
        {
            Debug.Assert(m_isAttached && TopBlock != null, "Inconsistency! critical!");
            if (m_welded)
            {
                UnweldGroup();
            }

            if (updateGroups)
            {
                m_needReattach = false; //i.e. block could be destroyed after the flag was rised

                BreakLinks(TopGrid, TopBlock);

                if (Sync.IsServer)
                {
                    m_connectionState.Value = new State()
                    {
                        TopBlockId = null, Welded = false
                    };
                }
            }

            DisposeConstraint();

            if (TopBlock != null)
            {
                TopBlock.Detach(false);
            }


            m_topGrid    = null;
            m_topBlock   = null;
            m_isAttached = false;

            UpdateText();

            if (updateGroups)
            {
                RaiseAttachedEntityChanged();
            }
        }
コード例 #24
0
        /// <summary>
        /// Breaks links and unregisters all events
        /// </summary>
        private void BreakLinks(MyCubeGrid topGrid, MyAttachableTopBlockBase topBlock)
        {
            OnConstraintRemoved(GridLinkTypeEnum.Physical, topGrid);
            OnConstraintRemoved(GridLinkTypeEnum.Logical, topGrid);

            if (CubeGrid != null)
            {
                CubeGrid.OnPhysicsChanged -= cubeGrid_OnPhysicsChanged;
            }

            if (topGrid != null)
            {
                topGrid.OnGridSplit      -= CubeGrid_OnGridSplit;
                topGrid.OnPhysicsChanged -= cubeGrid_OnPhysicsChanged;
            }

            if (topBlock != null)
            {
                topBlock.OnClosing -= TopBlock_OnClosing;
            }
        }
コード例 #25
0
        private void WeldGroup()
        {
            var topGrid  = m_topGrid;
            var topBlock = m_topBlock;

            m_isWelding = true;

            m_weldedTopBlockId = m_topBlock.EntityId;

            Detach(false);
            MyWeldingGroups.Static.CreateLink(EntityId, CubeGrid, topGrid);

            if (MyCubeGridGroups.Static.GetGroups(GridLinkTypeEnum.Physical).LinkExists(EntityId, CubeGrid, topGrid) == false)
            {
                OnConstraintAdded(GridLinkTypeEnum.Physical, topGrid);
            }

            if (MyCubeGridGroups.Static.GetGroups(GridLinkTypeEnum.Logical).LinkExists(EntityId, CubeGrid, topGrid) == false)
            {
                OnConstraintAdded(GridLinkTypeEnum.Logical, topGrid);
            }

            if (Sync.IsServer)
            {
                MatrixD masterToSlave = topBlock.CubeGrid.WorldMatrix * MatrixD.Invert(WorldMatrix);

                m_connectionState.Value = new State()
                {
                    TopBlockId = m_weldedTopBlockId, MasterToSlave = masterToSlave
                };
                m_weldedEntityId.Value = m_weldedTopBlockId;
            }

            m_topGrid  = topGrid;
            m_topBlock = topBlock;
            m_welded   = true;

            m_isWelding = false;
            RaisePropertiesChanged();
        }
コード例 #26
0
        protected override bool CreateConstraint(MyAttachableTopBlockBase topBlock)
        {
            if (!base.CreateConstraint(topBlock))
            {
                return(false);
            }
            var matAD =
                MatrixD.CreateWorld(
                    Vector3D.Transform(Vector3D.Transform(m_constraintBasePos, Subpart3.WorldMatrix),
                                       CubeGrid.PositionComp.WorldMatrixNormalizedInv), PositionComp.LocalMatrix.Forward,
                    PositionComp.LocalMatrix.Up);
            var matBD = MatrixD.CreateWorld(TopBlock.Position * TopBlock.CubeGrid.GridSize,
                                            TopBlock.PositionComp.LocalMatrix.Forward, TopBlock.PositionComp.LocalMatrix.Up);
            var matA = (Matrix)matAD;
            var matB = (Matrix)matBD;

            m_fixedData = new HkFixedConstraintData();
            m_fixedData.SetInertiaStabilizationFactor(10);
            m_fixedData.SetSolvingMethod(HkSolvingMethod.MethodStabilized);
            m_fixedData.SetInBodySpace(matA, matB, CubeGrid.Physics, TopGrid.Physics);

            //Dont dispose the fixed data or we wont have access to them

            m_constraint = new HkConstraint(CubeGrid.Physics.RigidBody, topBlock.CubeGrid.Physics.RigidBody,
                                            m_fixedData);
            m_constraint.WantRuntime = true;

            CubeGrid.Physics.AddConstraint(m_constraint);
            if (!m_constraint.InWorld)
            {
                Debug.Fail("Constraint was not added to world");
                CubeGrid.Physics.RemoveConstraint(m_constraint);
                m_constraint.Dispose();
                m_constraint = null;
                m_fixedData  = null;
                return(false);
            }
            m_constraint.Enabled = true;
            return(true);
        }
コード例 #27
0
 private bool TryAttach(MyAttachableTopBlockBase top, bool updateGroup = true)
 {
     return(CanAttach(top) && Attach(top, updateGroup));
 }
コード例 #28
0
        protected override bool Attach(MyAttachableTopBlockBase rotor, bool updateGroup = true)
        {
            Debug.Assert(rotor != null, "Rotor cannot be null!");
            Debug.Assert(m_constraint == null, "Already attached, call detach first!");


            if (rotor is MyMotorRotor)
            {
                if (CubeGrid.Physics != null && CubeGrid.Physics.Enabled)
                {
                    m_topBlock = rotor;
                    m_topGrid = m_topBlock.CubeGrid;
                    var rotorBody = m_topGrid.Physics.RigidBody;
                    rotorBody.MaxAngularVelocity = float.MaxValue;
                    rotorBody.Restitution = 0.5f;
                    CubeGrid.GetPhysicsBody().HavokWorld.BreakOffPartsUtil.UnmarkEntityBreakable(rotorBody);
                    if (MyFakes.WHEEL_SOFTNESS)
                    {
                        HkUtils.SetSoftContact(rotorBody, null, MyPhysicsConfig.WheelSoftnessRatio, MyPhysicsConfig.WheelSoftnessVelocity);
                    }
                    var info = HkGroupFilter.CalcFilterInfo(rotorBody.Layer, CubeGrid.GetPhysicsBody().HavokCollisionSystemID, 1, 1);
                    rotorBody.SetCollisionFilterInfo(info);
                    HkWheelConstraintData data = new HkWheelConstraintData();
                    var suspensionAx = PositionComp.LocalMatrix.Forward;
                    var posA = DummyPosition + (suspensionAx * m_height);
                    var posB = (rotor as MyMotorRotor).DummyPosLoc;
                    var axisA = PositionComp.LocalMatrix.Up;
                    var axisAPerp = PositionComp.LocalMatrix.Forward;
                    var axisB = rotor.PositionComp.LocalMatrix.Up;
                    //empirical values because who knows what havoc sees behind this 
                    //docs say one value should mean same effect for 2 ton or 200 ton vehicle 
                    //but we have virtual mass blocks so real mass doesnt corespond to actual "weight" in game and varying gravity
                    data.SetSuspensionDamping(m_damping);
                    data.SetSuspensionStrength(m_strenth);
                    //Min/MaxHeight also define the limits of the suspension and SuspensionTravel lowers this limit
                    data.SetSuspensionMinLimit((BlockDefinition.MinHeight - m_height) * SuspensionTravel);
                    data.SetSuspensionMaxLimit((BlockDefinition.MaxHeight - m_height) * SuspensionTravel);
                    data.SetInBodySpace(posB, posA, axisB, axisA, suspensionAx, suspensionAx, RotorGrid.Physics, CubeGrid.Physics);
                    m_constraint = new HkConstraint(rotorBody, CubeGrid.Physics.RigidBody, data);

                    m_constraint.WantRuntime = true;
                    CubeGrid.Physics.AddConstraint(m_constraint);
                    if (!m_constraint.InWorld)
                    {
                        Debug.Fail("Constraint not added!");
                        CubeGrid.Physics.RemoveConstraint(m_constraint);
                        m_constraint = null;
                        return false;
                    }
                    m_constraint.Enabled = true;

                    m_topBlock.Attach(this);
                    m_isAttached = true;
                    PropagateFriction(m_friction);
                    UpdateIsWorking();

                    if (m_updateBrakeNeeded)
                    {
                        UpdateBrake();
                    }
                    if (m_updateFrictionNeeded)
                    {
                        FrictionChanged();
                    }


                    if (updateGroup)
                    {
                        OnConstraintAdded(GridLinkTypeEnum.Physical, m_topGrid);
                        OnConstraintAdded(GridLinkTypeEnum.Logical, m_topGrid);
                    }

                    return true;
                }
            }
            return false;
        }
コード例 #29
0
        public virtual bool Detach(bool updateGroup = true)
        {
            var tmptopGrid = m_topBlock == null ? null: m_topBlock.CubeGrid;
            if (m_connectionState.Value.Welded || m_welded)
            {
                UnweldGroup();
            }
            else
            {
                if (updateGroup && tmptopGrid != null && (m_connectionState.Value.Welded == false || m_isWelding == false))
                {
                    OnConstraintRemoved(GridLinkTypeEnum.Physical, tmptopGrid);
                    OnConstraintRemoved(GridLinkTypeEnum.Logical, tmptopGrid);
                }
            }

            //Debug.Assert(m_topGrid != null);

            DisposeConstraint();
     
            if (m_topBlock != null)
            {
                m_topBlock.Detach(m_connectionState.Value.Welded || m_isWelding);         
 
                if(updateGroup)
                {
                    tmptopGrid.OnPhysicsChanged -= cubeGrid_OnPhysicsChanged;     
                    if (Sync.IsServer)
                    {                       
                        m_connectionState.Value = new State() { TopBlockId = 0, Welded = false };
                    }
                }
            }

           
            m_topGrid = null;
            m_topBlock = null;
            m_isAttached = false;

            UpdateText();
            return true;
        }
コード例 #30
0
 protected override void CreateTopGrid(out MyCubeGrid topGrid, out MyAttachableTopBlockBase topBlock, long ownerId)
 {
     CreateTopGrid(out topGrid, out topBlock, ownerId, MyDefinitionManager.Static.TryGetDefinitionGroup(BlockDefinition.TopPart));
 }
コード例 #31
0
        protected override bool Attach(MyAttachableTopBlockBase rotor, bool updateGroup = true)
        {
            Debug.Assert(rotor != null, "Rotor cannot be null!");
            Debug.Assert(m_constraint == null, "Already attached, call detach first!");


            if (rotor is MyMotorRotor && base.Attach(rotor,updateGroup))
            {
                CreateConstraint(rotor);
                
                PropagateFriction(m_friction);
                UpdateIsWorking();

                if (m_updateBrakeNeeded)
                {
                    UpdateBrake();
                }
                return true;
            }
            return false;
        }
コード例 #32
0
        protected void TryForceWeldServer()
        {
            if (m_topBlock == null && (m_connectionState.Value.TopBlockId.HasValue))
            {
                TryGetTop();
                NeedsUpdate |= MyEntityUpdateEnum.BEFORE_NEXT_FRAME;
                return;
            }

            if(m_topBlockToReattach != null && m_forceWeld)
            {
                m_topBlock = m_topBlockToReattach;
                m_topGrid = m_topBlock.CubeGrid;
                m_topBlockToReattach = null;
            }

            if (m_topBlock != null)
            {
                if (m_forceWeld || m_speedWeld)
                {
                    if (m_welded == false)
                    {
                        WeldGroup(false);
                    }
                }
                else if (m_welded)
                {
                    UnweldGroup();
                    m_forceApply = true;
                    TryAttach();
                }
            }

        }
コード例 #33
0
 protected virtual bool CanPlaceRotor(MyAttachableTopBlockBase rotorBlock, long builtBy)
 {
     return(true);
 }
コード例 #34
0
ファイル: MyMotorStator.cs プロジェクト: Furt/SpaceEngineers
 private void SetConstraintPosition(MyAttachableTopBlockBase rotor, HkLimitedHingeConstraintData data)
 {
     var posA = DummyPosition;
     var posB = rotor.Position * rotor.CubeGrid.GridSize;
     var axisA = PositionComp.LocalMatrix.Up;
     var axisAPerp = PositionComp.LocalMatrix.Forward;
     var axisB = rotor.PositionComp.LocalMatrix.Up;
     var axisBPerp = rotor.PositionComp.LocalMatrix.Forward;
     data.SetInBodySpace(posA, posB, axisA, axisB, axisAPerp, axisBPerp, CubeGrid.Physics, TopGrid.Physics);
 }
コード例 #35
0
        public override void OnUnregisteredFromGridSystems()
        {
            base.OnUnregisteredFromGridSystems();

            if (Sync.IsServer)
            {
                if (m_topBlock != null)
                {
                    m_topBlockToReattach = m_topBlock;
                    Detach(true);
                }
                CubeGrid.OnGridSplit -= CubeGrid_OnGridSplit;
            }
        }
コード例 #36
0
        public void ReattachTop(MyAttachableTopBlockBase top)
        {
            if (m_topBlock != null || m_welded)
            {
                Detach();
            }

            m_topBlockToReattach = top;
            // Rotor not found by EntityId or not in scene, try again in 10 frames
            NeedsUpdate |= MyEntityUpdateEnum.BEFORE_NEXT_FRAME;

        }
コード例 #37
0
        bool CanAttach(MyAttachableTopBlockBase top)
        {
            bool closed = MarkedForClose || Closed || CubeGrid.MarkedForClose || CubeGrid.Closed;
            if(closed)
            {
                return false;
            }

            bool topClosed = top.MarkedForClose || top.Closed || top.CubeGrid.MarkedForClose || top.CubeGrid.Closed;

            if(topClosed)
            {
                return false;
            }

            bool notInWorld = CubeGrid.Physics == null ||
                CubeGrid.Physics.RigidBody == null || CubeGrid.Physics.RigidBody.InWorld == false || CubeGrid.Physics.RigidBody.IsAddedToWorld == false;

            if(notInWorld)
            {
                return false;
            }

            bool topNotInWorld = top.CubeGrid.Physics == null || top.CubeGrid.Physics.RigidBody == null ||
                top.CubeGrid.Physics.RigidBody.InWorld == false || top.CubeGrid.Physics.RigidBody.IsAddedToWorld == false;

            if(topNotInWorld)
            {
                return false;
            }

            if(top.CubeGrid.Physics.HavokWorld != CubeGrid.Physics.HavokWorld)
            {
                return false;
            }
            return true;
        }
コード例 #38
0
        private void FindTopServer(MyEntityUpdateEnum updateFlags)
        {
            MyAttachableTopBlockBase top = null;
            if (m_topBlockToReattach != null)
            {
                top = m_topBlockToReattach;
            }
            else
            {
                top = FindMatchingTop();
            }

            if (top != null)
            {
                if (CanDetach())
                {
                    Detach();
                }

                if (TryAttach(top))
                {
                    m_topBlockToReattach = null;
                }
                else
                {
                    updateFlags |= MyEntityUpdateEnum.EACH_10TH_FRAME;
                }

            }
            else
            {
                updateFlags |= MyEntityUpdateEnum.EACH_10TH_FRAME;
            }
        }
コード例 #39
0
 private void CreateTopGrid(out MyCubeGrid topGrid, out MyAttachableTopBlockBase topBlock, long ownerId)
 {
     CreateTopGrid(out topGrid, out topBlock, ownerId, MyDefinitionManager.Static.TryGetDefinitionGroup(((MyMechanicalConnectionBlockBaseDefinition)BlockDefinition).TopPart));
 }
コード例 #40
0
 public override void OnRemovedFromScene(object source)
 {
     base.OnRemovedFromScene(source);
     m_topBlockToReattach = m_topBlock;
     Detach(true);
     CubeGrid.OnPhysicsChanged -= cubeGrid_OnPhysicsChanged;
 }
コード例 #41
0
ファイル: MyMotorBase.cs プロジェクト: Chrus/SpaceEngineers
 protected virtual bool CanPlaceRotor(MyAttachableTopBlockBase rotorBlock, long builtBy)
 {
     return true;
 }
コード例 #42
0
 protected override void Closing()
 {
     CubeGrid.OnPhysicsChanged -= cubeGrid_OnPhysicsChanged;
     Detach();
     m_topBlockToReattach = null;
     base.Closing();
 }
コード例 #43
0
ファイル: MyMotorBase.cs プロジェクト: Chrus/SpaceEngineers
        protected void CreateRotorGrid(out MyCubeGrid rotorGrid, out MyAttachableTopBlockBase rotorBlock, long builtBy, MyCubeBlockDefinitionGroup rotorGroup)
        {
            Debug.Assert(Sync.IsServer, "Rotor grid can be created only on server");
            if (rotorGroup == null)
            {
                rotorGrid = null;
                rotorBlock = null;
                return;
            }

            var gridSize = CubeGrid.GridSizeEnum;

            float size = MyDefinitionManager.Static.GetCubeSize(gridSize);
            var matrix = MatrixD.CreateWorld(Vector3D.Transform(DummyPosition, CubeGrid.WorldMatrix), WorldMatrix.Forward, WorldMatrix.Up);
            var definition = rotorGroup[gridSize];
            Debug.Assert(definition != null);

            var block = MyCubeGrid.CreateBlockObjectBuilder(definition, Vector3I.Zero, MyBlockOrientation.Identity, MyEntityIdentifier.AllocateId(), OwnerId, fullyBuilt: MySession.Static.CreativeMode);

            var gridBuilder = MyObjectBuilderSerializer.CreateNewObject<MyObjectBuilder_CubeGrid>();
            gridBuilder.GridSizeEnum = gridSize;
            gridBuilder.IsStatic = false;
            gridBuilder.PositionAndOrientation = new MyPositionAndOrientation(matrix);
            gridBuilder.CubeBlocks.Add(block);

            var grid = MyEntityFactory.CreateEntity<MyCubeGrid>(gridBuilder);
            grid.Init(gridBuilder);

            rotorGrid = grid;
            MyMotorRotor rotor = (MyMotorRotor)rotorGrid.GetCubeBlock(Vector3I.Zero).FatBlock;
            rotorBlock = rotor;
            rotorGrid.PositionComp.SetPosition(rotorGrid.WorldMatrix.Translation - (Vector3D.Transform(rotor.DummyPosLoc, rotorGrid.WorldMatrix) - rotorGrid.WorldMatrix.Translation));

            if (!CanPlaceRotor(rotorBlock, builtBy))
            {
                rotorGrid = null;
                rotorBlock = null;
                grid.Close();
                return;
            }
      
            MyEntities.Add(grid);

            if (MyFakes.ENABLE_SENT_GROUP_AT_ONCE)
            {
                MyMultiplayer.ReplicateImmediatelly(MyExternalReplicable.FindByObject(grid), MyExternalReplicable.FindByObject(CubeGrid));
            }

            MatrixD masterToSlave = rotorBlock.CubeGrid.WorldMatrix * MatrixD.Invert(WorldMatrix);
            m_connectionState.Value = new State() { TopBlockId = rotorBlock.EntityId, MasterToSlave = masterToSlave};
        }
コード例 #44
0
ファイル: MyPistonBase.cs プロジェクト: Furt/SpaceEngineers
        protected override bool CreateConstraint(MyAttachableTopBlockBase topBlock)
        {
            if (!base.CreateConstraint(topBlock))
                return false;
            var matAD =
                MatrixD.CreateWorld(
                    Vector3D.Transform(Vector3D.Transform(m_constraintBasePos, Subpart3.WorldMatrix),
                        CubeGrid.PositionComp.WorldMatrixNormalizedInv), PositionComp.LocalMatrix.Forward,
                    PositionComp.LocalMatrix.Up);
            var matBD = MatrixD.CreateWorld(TopBlock.Position*TopBlock.CubeGrid.GridSize,
                TopBlock.PositionComp.LocalMatrix.Forward, TopBlock.PositionComp.LocalMatrix.Up);
            var matA = (Matrix) matAD;
            var matB = (Matrix) matBD;
            m_fixedData = new HkFixedConstraintData();
            m_fixedData.SetInertiaStabilizationFactor(10);
            m_fixedData.SetSolvingMethod(HkSolvingMethod.MethodStabilized);
            m_fixedData.SetInBodySpace(matA, matB, CubeGrid.Physics, TopGrid.Physics);

            //Dont dispose the fixed data or we wont have access to them

            m_constraint = new HkConstraint(CubeGrid.Physics.RigidBody, topBlock.CubeGrid.Physics.RigidBody,
                m_fixedData);
            m_constraint.WantRuntime = true;

            CubeGrid.Physics.AddConstraint(m_constraint);
            if (!m_constraint.InWorld)
            {
                Debug.Fail("Constraint was not added to world");
                CubeGrid.Physics.RemoveConstraint(m_constraint);
                m_constraint.Dispose();
                m_constraint = null;
                m_fixedData = null;
                return false;
            }
            m_constraint.Enabled = true;
            return true;
        }
コード例 #45
0
ファイル: MyMotorBase.cs プロジェクト: Chrus/SpaceEngineers
 protected override void CreateTopGrid(out MyCubeGrid rotorGrid, out MyAttachableTopBlockBase rotorBlock, long builtBy)
 {
     CreateRotorGrid(out rotorGrid, out rotorBlock, builtBy, MyDefinitionManager.Static.TryGetDefinitionGroup(MotorDefinition.RotorPart));
 }
コード例 #46
0
ファイル: MyPistonBase.cs プロジェクト: Furt/SpaceEngineers
        protected override bool Attach(MyAttachableTopBlockBase topBlock, bool updateGroup = true)
        {
            Debug.Assert(topBlock != null, "Top block cannot be null!");

            MyPistonTop pistonTop = topBlock as MyPistonTop;
            if (pistonTop != null && base.Attach(topBlock, updateGroup))
            {
                Debug.Assert(m_constraint == null, "Contraint already attached, call detach first!");
                Debug.Assert(m_connectionState.Value.TopBlockId.HasValue && (m_connectionState.Value.TopBlockId.Value == 0 || m_connectionState.Value.TopBlockId.Value == topBlock.EntityId), "m_topBlockId must be set prior calling Attach!");

                UpdateAnimation();

                CreateConstraint(topBlock);
                 
                if (updateGroup)
                {
                    m_conveyorEndpoint.Attach(pistonTop.ConveyorEndpoint as MyAttachableConveyorEndpoint);
                }

                UpdateText();
                return true;
            }
            return false;
        }
コード例 #47
0
 protected abstract void CreateTopGrid(out MyCubeGrid topGrid, out MyAttachableTopBlockBase topBlock, long ownerId);
コード例 #48
0
        protected override bool CanPlaceRotor(MyAttachableTopBlockBase rotorBlock, long builtBy)
        {
            // Compute the rough actual position for the wheel, this improves the detection if it can be placed
            float wheelDistance = BlockDefinition.Size.Y * CubeGrid.GridSize - 0.2f * CubeGrid.GridSize;
            Vector3D wheelPosition = this.WorldMatrix.Translation + this.WorldMatrix.Up * wheelDistance;
            float wheelRadius = rotorBlock.ModelCollision.HavokCollisionShapes[0].ConvexRadius * 0.9f;

            // First test if we intersect any blocks of our own grid
            BoundingSphereD sphere = rotorBlock.Model.BoundingSphere;
            sphere.Center = wheelPosition;
            sphere.Radius = wheelRadius;
            CubeGrid.GetBlocksInsideSphere(ref sphere, m_tmpSet);

            // If we intersect more than 1 block (because wheel sometimes intersects suspension), don't add wheel
            if (m_tmpSet.Count > 1)
            {
                m_tmpSet.Clear();
                if (builtBy == MySession.Static.LocalPlayerId)
                    MyHud.Notifications.Add(MyNotificationSingletons.WheelNotPlaced);
                return false;
            }

            m_tmpSet.Clear();

            // Next test if we intersect any physics objects
            HkSphereShape spShape = new HkSphereShape(wheelRadius);
            Quaternion q = Quaternion.Identity;
            MyPhysics.GetPenetrationsShape(rotorBlock.ModelCollision.HavokCollisionShapes[0], ref wheelPosition, ref q, m_tmpList, MyPhysics.CollisionLayers.DefaultCollisionLayer);

            // If we have any collisions with anything other than our own grid, don't add the wheel
            // We already checked for inner-grid collisions in the previous case
            for (int i = 0; i < m_tmpList.Count; i++)
            {
                MyCubeGrid grid = m_tmpList[i].GetCollisionEntity() as MyCubeGrid;
                if (grid == null || grid != CubeGrid)
                {
                    m_tmpList.Clear();
                    if (builtBy == MySession.Static.LocalPlayerId)
                        MyHud.Notifications.Add(MyNotificationSingletons.WheelNotPlaced);
                    return false;
                }
            }

            m_tmpList.Clear();

            return true;
        }
コード例 #49
0
ファイル: MyMotorStator.cs プロジェクト: Furt/SpaceEngineers
 protected override bool Attach(MyAttachableTopBlockBase rotor, bool updateGroup = true)
 {
     if (rotor is MyMotorRotor && base.Attach(rotor, updateGroup))
     {
         CreateConstraint(rotor);
         
         UpdateText();
         return true;
     }
     return false;
 }
コード例 #50
0
        private void WeldGroup(bool force)
        {
            var topBlock = m_topBlock;
            MyCubeGrid topGrid = m_topBlock.CubeGrid;

            m_isWelding = true;

            if (m_isAttached)
            {
                Detach(false);
            }

            MyWeldingGroups.Static.CreateLink(EntityId, CubeGrid, topGrid);

            if (MyCubeGridGroups.Static.GetGroups(GridLinkTypeEnum.Physical).LinkExists(EntityId, CubeGrid, topGrid) == false)
            {
                OnConstraintAdded(GridLinkTypeEnum.Physical, topGrid);
            }

            if (MyCubeGridGroups.Static.GetGroups(GridLinkTypeEnum.Logical).LinkExists(EntityId, CubeGrid, topGrid) == false)
            {
                OnConstraintAdded(GridLinkTypeEnum.Logical, topGrid);
            }

            if (Sync.IsServer)
            {
                MatrixD masterToSlave = topBlock.CubeGrid.WorldMatrix * MatrixD.Invert(WorldMatrix);
                m_connectionState.Value = new State() { TopBlockId = topBlock.EntityId, MasterToSlave = masterToSlave, Welded = true,Force = force};
               
            }

            topBlock.Attach(this);
            topBlock.CubeGrid.OnPhysicsChanged += cubeGrid_OnPhysicsChanged;

            m_welded = true;
            m_topGrid = topGrid;
            m_topBlock = topBlock;

            m_isWelding = false;
            RaisePropertiesChanged();
        }
コード例 #51
0
        protected void TryForceWeldServer()
        {
            if (m_topBlock == null && (m_connectionState.Value.TopBlockId.HasValue))
            {
                TryGetTop();
            }

            if(m_topBlockToReattach != null && m_forceWeld)
            {
                m_topBlock = m_topBlockToReattach;
                m_topGrid = m_topBlock.CubeGrid;
                m_topBlockToReattach = null;
            }

            if (m_topBlock != null)
            {
                if (m_forceWeld)
                {
                    if (m_welded == false)
                    {
                        WeldGroup(false);
                    }
                }
                else if (m_welded)
                {
                    UnweldGroup();
                    m_forceApply = true;
                    TryAttach();
                }
            }

        }
コード例 #52
0
ファイル: MyMotorStator.cs プロジェクト: Furt/SpaceEngineers
        protected override bool CreateConstraint(MyAttachableTopBlockBase rotor)
        {
            if (!base.CreateConstraint(rotor))
                return false;
            Debug.Assert(rotor != null, "Rotor cannot be null!");
            Debug.Assert(m_constraint == null, "Already attached, call detach first!");
            Debug.Assert(
                m_connectionState.Value.TopBlockId == 0 || m_connectionState.Value.TopBlockId == rotor.EntityId,
                "m_rotorBlockId must be set prior calling Attach");


            var rotorBody = TopGrid.Physics.RigidBody;
            var data = new HkLimitedHingeConstraintData();
            m_motor = new HkVelocityConstraintMotor(1.0f, 1000000f);

            data.SetSolvingMethod(HkSolvingMethod.MethodStabilized);
            data.Motor = m_motor;
            data.DisableLimits();

            SetConstraintPosition(rotor, data);
            m_constraint = new HkConstraint(CubeGrid.Physics.RigidBody, rotorBody, data);

            m_constraint.WantRuntime = true;
            CubeGrid.Physics.AddConstraint(m_constraint);
            if (!m_constraint.InWorld)
            {
                CubeGrid.Physics.RemoveConstraint(m_constraint);
                m_constraint.Dispose();
                m_constraint = null;
                return false;
            }

            m_constraint.Enabled = true;

            SetAngleToPhysics();
            return true;
        }
コード例 #53
0
        protected virtual bool Attach(MyAttachableTopBlockBase topBlock, bool updateGroup = true)
        {
            if (topBlock.CubeGrid.Physics == null)
                return false;

            if (CubeGrid.Physics != null && CubeGrid.Physics.Enabled)
            {
                m_topBlock = topBlock;
                m_topGrid = m_topBlock.CubeGrid;

                if (updateGroup)
                {
                    OnConstraintAdded(GridLinkTypeEnum.Physical, m_topGrid);
                    OnConstraintAdded(GridLinkTypeEnum.Logical, m_topGrid);
                    m_topGrid.OnPhysicsChanged += cubeGrid_OnPhysicsChanged;
                }

                if (CubeGrid.Physics.RigidBody == m_topGrid.Physics.RigidBody)
                {                
                    if (m_welded)
                    {
                        m_isAttached = true;
                        return true;
                    }
                    else 
                    {
                        m_topAndBottomSamePhysicsBody.Value = true;
                        m_isAttached = false;
                        return false;
                    }
                }
                else
                {
                    m_topAndBottomSamePhysicsBody.Value = false;
                }


                if (m_connectionState.Value.MasterToSlave.HasValue)
                {
                    m_topBlock.CubeGrid.WorldMatrix = MatrixD.Multiply(m_connectionState.Value.MasterToSlave.Value, this.WorldMatrix);
                }

                return true;
            }
            return m_welded;
        }
コード例 #54
0
 protected override void CreateTopGrid(out MyCubeGrid topGrid, out MyAttachableTopBlockBase topBlock, long ownerId)
 {
     CreateTopGrid(out topGrid, out topBlock, ownerId, MyDefinitionManager.Static.TryGetDefinitionGroup(BlockDefinition.TopPart));
 }
コード例 #55
0
 private bool TryAttach(MyAttachableTopBlockBase top)
 {
     bool attached = false;
     if (CanAttach(top))
     {
         attached = Attach(top);
         if ((attached || m_topAndBottomSamePhysicsBody) && Sync.IsServer)
         {
             MatrixD masterToSlave = top.CubeGrid.WorldMatrix * MatrixD.Invert(WorldMatrix);
             m_connectionState.Value = new State() { TopBlockId = top.EntityId, MasterToSlave = masterToSlave, Welded = m_welded};
         }
     }
     return attached;
 }
コード例 #56
0
        protected override bool Attach(MyAttachableTopBlockBase topBlock, bool updateGroup = true)
        {
            Debug.Assert(topBlock != null, "Top block cannot be null!");

            if (CubeGrid == topBlock.CubeGrid)
                return false;

            MyPistonTop pistonTop = topBlock as MyPistonTop;
            if (pistonTop != null && base.Attach(topBlock, updateGroup))
            {
                Debug.Assert(m_constraint == null, "Contraint already attached, call detach first!");
                Debug.Assert(m_connectionState.Value.TopBlockId.HasValue && (m_connectionState.Value.TopBlockId.Value == 0 || m_connectionState.Value.TopBlockId.Value == topBlock.EntityId), "m_topBlockId must be set prior calling Attach!");

                UpdateAnimation();

                var matAD = MatrixD.CreateWorld(Vector3D.Transform(Vector3D.Transform(m_constraintBasePos, Subpart3.WorldMatrix), CubeGrid.PositionComp.WorldMatrixNormalizedInv), PositionComp.LocalMatrix.Forward, PositionComp.LocalMatrix.Up);
                var matBD = MatrixD.CreateWorld(m_topBlock.Position * m_topBlock.CubeGrid.GridSize, m_topBlock.PositionComp.LocalMatrix.Forward, m_topBlock.PositionComp.LocalMatrix.Up);
                var matA = (Matrix)matAD;
                var matB = (Matrix)matBD;
                m_fixedData = new HkFixedConstraintData();
                m_fixedData.SetInertiaStabilizationFactor(10);
                m_fixedData.SetSolvingMethod(HkSolvingMethod.MethodStabilized);
                m_fixedData.SetInBodySpace(matA, matB, CubeGrid.Physics, m_topGrid.Physics);

                //Dont dispose the fixed data or we wont have access to them

                m_constraint = new HkConstraint(CubeGrid.Physics.RigidBody, topBlock.CubeGrid.Physics.RigidBody, m_fixedData);
                m_constraint.WantRuntime = true;

                CubeGrid.Physics.AddConstraint(m_constraint);
                if (!m_constraint.InWorld)
                {
                    Debug.Fail("Constraint was not added to world");
                    CubeGrid.Physics.RemoveConstraint(m_constraint);
                    m_constraint.Dispose();
                    m_constraint = null;
                    m_fixedData = null;
                    return false;
                }
                m_constraint.Enabled = true;

                m_topBlock = topBlock;
                m_topGrid = topBlock.CubeGrid;
                topBlock.Attach(this);
                m_isAttached = true;

                if (updateGroup)
                {
                    m_conveyorEndpoint.Attach(pistonTop.ConveyorEndpoint as MyAttachableConveyorEndpoint);
                }

                UpdateText();
                return true;
            }
            return false;
        }
コード例 #57
0
        public void Reattach(bool force = false)
        {
            if (m_isWelding || m_welded || m_topBlock == null || m_topBlock.Closed)
            {
                return;
            }

            var top = m_topBlock;
            bool detached = Detach(force);

            if (Sync.IsServer)
            {
                m_connectionState.Value = new State() { TopBlockId = 0, MasterToSlave = null };
            }

            if (CanAttach(top))
            {
                m_topBlock = top;
                m_topGrid = top.CubeGrid;

                bool attached = Attach(top, force);

                if (attached && Sync.IsServer)
                {
                    MatrixD masterToSlave = top.CubeGrid.WorldMatrix * MatrixD.Invert(WorldMatrix);
                    m_connectionState.Value = new State() { TopBlockId = top.EntityId, MasterToSlave = masterToSlave, Force = force };
                }

                //Debug.Assert(detached && attached);
                if (!top.MarkedForClose && top.CubeGrid.Physics != null)
                {
                    top.CubeGrid.Physics.ForceActivate();
                }
            }
            else
            {
                if (MyCubeGridGroups.Static.GetGroups(GridLinkTypeEnum.Physical).LinkExists(EntityId, CubeGrid, top.CubeGrid))
                {
                    OnConstraintRemoved(GridLinkTypeEnum.Physical, top.CubeGrid);
                }

                if (MyCubeGridGroups.Static.GetGroups(GridLinkTypeEnum.Logical).LinkExists(EntityId, CubeGrid, top.CubeGrid))
                {
                    OnConstraintRemoved(GridLinkTypeEnum.Logical, top.CubeGrid);
                }

                if (Sync.IsServer && top != null)
                {
                    top.Attach(this);
                }
            }
        }
コード例 #58
0
        private void CreateTopGrid(out MyCubeGrid topGrid, out MyAttachableTopBlockBase topBlock, long builtBy, MyCubeBlockDefinitionGroup topGroup)
        {
            if (topGroup == null)
            {
                topGrid = null;
                topBlock = null;
                return;
            }

            var gridSize = CubeGrid.GridSizeEnum;

            float size = MyDefinitionManager.Static.GetCubeSize(gridSize);
            var matrix = MatrixD.CreateWorld(Vector3D.Transform(m_constraintBasePos, Subpart3.WorldMatrix), WorldMatrix.Forward, WorldMatrix.Up);

            var definition = topGroup[gridSize];
            Debug.Assert(definition != null);

            var block = MyCubeGrid.CreateBlockObjectBuilder(definition, Vector3I.Zero, MyBlockOrientation.Identity, MyEntityIdentifier.AllocateId(), OwnerId, fullyBuilt: MySession.Static.CreativeMode);

            var gridBuilder = MyObjectBuilderSerializer.CreateNewObject<MyObjectBuilder_CubeGrid>();
            gridBuilder.GridSizeEnum = gridSize;
            gridBuilder.IsStatic = false;
            gridBuilder.PositionAndOrientation = new MyPositionAndOrientation(matrix);
            gridBuilder.CubeBlocks.Add(block);

            var grid = MyEntityFactory.CreateEntity<MyCubeGrid>(gridBuilder);
            grid.Init(gridBuilder);

            topGrid = grid;
            topBlock = (MyPistonTop)topGrid.GetCubeBlock(Vector3I.Zero).FatBlock;

            if (!CanPlaceTop(topBlock, builtBy))
            {
                topGrid = null;
                topBlock = null;
                grid.Close();
                return;
            }
            //topGrid.SetPosition(topGrid.WorldMatrix.Translation - (topBlock.WorldMatrix.Translation/*Vector3.Transform(topBlock.DummyPosLoc, topGrid.WorldMatrix) - topGrid.WorldMatrix.Translation*/));
      
            MyEntities.Add(grid);
            if (MyFakes.ENABLE_SENT_GROUP_AT_ONCE)
            {
                MyMultiplayer.ReplicateImmediatelly(MyExternalReplicable.FindByObject(grid), MyExternalReplicable.FindByObject(CubeGrid));
            }
        }
コード例 #59
0
 protected abstract void CreateTopGrid(out MyCubeGrid topGrid, out MyAttachableTopBlockBase topBlock, long ownerId);
コード例 #60
0
        protected virtual bool CanPlaceTop(MyAttachableTopBlockBase topBlock, long builtBy)
        {
            // Compute the rough actual position for the head, this improves the detection if it can be placed
            float topDistance = (Subpart3.Model.BoundingBoxSize.Y);
            Vector3D topPosition = this.Subpart3.WorldMatrix.Translation + this.WorldMatrix.Up * topDistance;
            float topRadius = topBlock.ModelCollision.HavokCollisionShapes[0].ConvexRadius * 0.9f;

            // First test if we intersect any blocks of our own grid
            BoundingSphereD sphere = topBlock.Model.BoundingSphere;
            sphere.Center = topPosition;
            sphere.Radius = topRadius;
            CubeGrid.GetBlocksInsideSphere(ref sphere, m_tmpSet);

            // If we intersect more than 1 block (because top sometimes intersects piston), don't add top
            if (m_tmpSet.Count > 1)
            {
                m_tmpSet.Clear();
                if (builtBy == MySession.Static.LocalPlayerId)
                    MyHud.Notifications.Add(MyNotificationSingletons.HeadNotPlaced);
                return false;
            }

            m_tmpSet.Clear();

            // Next test if we intersect any physics objects
            HkSphereShape spShape = new HkSphereShape(topRadius);
            Quaternion q = Quaternion.Identity;
            MyPhysics.GetPenetrationsShape(topBlock.ModelCollision.HavokCollisionShapes[0], ref topPosition, ref q, m_penetrations, MyPhysics.CollisionLayers.DefaultCollisionLayer);

            // If we have any collisions with anything other than our own grid, don't add the head
            // We already checked for inner-grid collisions in the previous case
            for (int i = 0; i < m_penetrations.Count; i++)
            {
                MyCubeGrid grid = m_penetrations[i].GetCollisionEntity().GetTopMostParent() as MyCubeGrid;
                if (grid == null || grid != CubeGrid)
                {
                    m_penetrations.Clear();
                    if (builtBy == MySession.Static.LocalPlayerId)
                        MyHud.Notifications.Add(MyNotificationSingletons.HeadNotPlaced);
                    return false;
                }
            }

            m_penetrations.Clear();

            return true;
        }