Пример #1
0
        public override void LoadData()
        {
            Instance      = this;
            Log.ModName   = "Advanced Welding";
            Log.AutoClose = false;

            Networking.LogInfo      = (msg) => Log.Info(msg, null);
            Networking.LogError     = (err) => Log.Error(err);
            Networking.LogException = (ex) => Log.Error(ex);
            Networking.Register(ModContext);

            DetachHandler    = new DetachHandler(this);
            PrecisionHandler = new PrecisionHandler(this);
            WeldPadHandler   = new WeldPadHandler(this);
            MergeHandler     = new MergeHandler(this);

            if (Networking.IsPlayer)
            {
                GrinderHandler = new GrinderHandler(this);
                ChatCommands   = new ChatCommands(this);
                Notifications  = new Notifications(this);
            }

            if (MyAPIGateway.Session.IsServer)
            {
                GrindDamageHandler = new GrindDamageHandler(this);
            }
        }
Пример #2
0
        public override void UpdateAfterSimulation10()
        {
            try
            {
                BlocksInTheWay.Clear();
                DeleteWeldPads.Clear();

                if (Handler.Pads.Count <= 1)
                {
                    return;
                }

                if (!ThisPad.IsWorking)
                {
                    return;
                }

                if (OtherPad != null && (OtherPad.Closed || OtherPad.MarkedForClose || OtherPad.CubeGrid?.Physics == null || !OtherPad.IsWorking))
                {
                    OtherPad = null;
                    return;
                }

                bool isMaster = (OtherPad == null ? true : ThisPad.EntityId > OtherPad.EntityId);
                if (!isMaster)
                {
                    return; // only one pad 'thinks'
                }
                IMyCubeGrid padGrid = ThisPad.CubeGrid;

                MatrixD  padMatrix  = ThisPad.WorldMatrix;
                Vector3D padForward = padMatrix.GetDirectionVector(DirForward);
                Vector3D padPos     = padMatrix.Translation + padForward * -(padGrid.GridSize / 2);

                //MyTransparentGeometry.AddPointBillboard(MyStringId.GetOrCompute("WhiteDot"), Color.Lime, padPos, 0.1f, 0, blendType: BlendTypeEnum.AdditiveTop);

                if (OtherPad == null)
                {
                    double minDistance = (ThisPad.CubeGrid.GridSize * ThisPad.CubeGrid.GridSize);

                    IMyCubeBlock closestPad    = null;
                    WeldPad      closestLogic  = null;
                    double       closestDistSq = double.MaxValue;

                    foreach (IMyCubeBlock p in Handler.Pads)
                    {
                        if (p.EntityId == ThisPad.EntityId ||
                            p.CubeGrid == ThisPad.CubeGrid ||
                            p.CubeGrid?.Physics == null ||
                            p.CubeGrid.GridSizeEnum != padGrid.GridSizeEnum ||
                            (padGrid.IsStatic && p.CubeGrid.IsStatic) ||
                            !p.IsWorking)
                        {
                            continue;
                        }

                        Vector3D pForward = p.WorldMatrix.GetDirectionVector(DirForward);

                        // not pointed at eachother, skip
                        if (Vector3D.Dot(pForward, padForward) > -0.5)
                        {
                            continue;
                        }

                        WeldPad otherLogic = p.GameLogic.GetAs <WeldPad>();
                        if (otherLogic == null)
                        {
                            continue;
                        }

                        Vector3D otherPos = p.WorldMatrix.Translation + (pForward * -(p.CubeGrid.GridSize / 2));
                        double   distSq   = Vector3D.DistanceSquared(padPos, otherPos);

                        //MyTransparentGeometry.AddPointBillboard(MyStringId.GetOrCompute("WhiteDot"), Color.Red, otherPos, 0.1f, 0, blendType: BlendTypeEnum.AdditiveTop);

                        if (distSq < closestDistSq && distSq <= minDistance)
                        {
                            closestDistSq = distSq;
                            closestPad    = p;
                            closestLogic  = otherLogic;
                        }
                    }

                    if (closestPad == null)
                    {
                        return;
                    }

                    OtherPad = closestPad;
                    closestLogic.OtherPad = ThisPad;
                }

                Vector3D otherPadPos     = OtherPad.WorldMatrix.Translation + (-OtherPad.WorldMatrix.GetDirectionVector(DirForward) * (OtherPad.CubeGrid.GridSize / 2));
                double   distanceSquared = Vector3D.DistanceSquared(padPos, otherPadPos);
                if (distanceSquared > OtherPad.CubeGrid.GridSize * OtherPad.CubeGrid.GridSize)
                {
                    WeldPad otherLogic = OtherPad.GameLogic.GetAs <WeldPad>();
                    otherLogic.OtherPad = null;

                    OtherPad = null;
                    return;
                }

                IMyCubeGrid otherGrid = OtherPad.CubeGrid;
                double      axisDot   = Math.Round(Vector3D.Dot(ThisPad.WorldMatrix.Up, OtherPad.WorldMatrix.Up), 2);
                double      rollDot   = Math.Round(Vector3D.Dot(ThisPad.WorldMatrix.Right, OtherPad.WorldMatrix.GetDirectionVector(OtherPad.WorldMatrix.GetClosestDirection(ThisPad.WorldMatrix.Right))), 2);

                double distReq = (padGrid.GridSizeEnum == MyCubeSize.Large ? 0.5 : 0.25);
                double dist    = Math.Sqrt(distanceSquared) - distReq;

                if (dist <= 0 && axisDot == -1.0 && rollDot == 1.0)
                {
                    if (!CanMergeCubes(ThisPad, OtherPad, MergeHandler.CalculateOffset(ThisPad, OtherPad), BlocksInTheWay, DeleteWeldPads))
                    {
                        //bool otherWeldPadsInTheWay = false;
                        //foreach(IMySlimBlock block in DrawInTheWay)
                        //{
                        //    if(IsWeldPad(block.BlockDefinition.Id))
                        //    {
                        //        otherWeldPadsInTheWay = true;
                        //        break;
                        //    }
                        //}

                        //if(otherWeldPadsInTheWay)
                        //    SetToolStatus("WeldPad: Can't merge, other weld pads in the way, use only one pair!", MyFontEnum.Red, 1000);
                        //else

                        SetPadStatus("WeldPad: Can't merge, some blocks would overlap!", MyFontEnum.Red, 1000);

                        if (!Handler.PadDraw.Contains(this))
                        {
                            Handler.PadDraw.Add(this);
                        }

                        return;
                    }

                    //if(MyAPIGateway.GridGroups.HasConnection(pad.CubeGrid, otherPad.CubeGrid, GridLinkTypeEnum.Physical))
                    //{
                    //    SetToolStatus("WeldPad: Can't merge physically connected grids!", MyFontEnum.Red, 1000);
                    //    return;
                    //}

                    //SetToolStatus("WeldPad: Succesfully fake merged", MyFontEnum.Green, 1000);
                    //return;

                    if (!MyAPIGateway.Multiplayer.IsServer)
                    {
                        Log.Info("Merge checks out clientside, waiting for server...");
                    }
                    else
                    {
                        Log.Info($"Queued for merge {padGrid} and {otherGrid}");

                        AdvancedWeldingMod.Instance.MergeHandler.ScheduleMerge(ThisPad, OtherPad);

                        padGrid.RemoveBlock(ThisPad.SlimBlock);
                        otherGrid.RemoveBlock(OtherPad.SlimBlock);

                        // remove other weldpads that get in the way
                        foreach (IMySlimBlock block in DeleteWeldPads)
                        {
                            block.CubeGrid.RemoveBlock(block);
                            Log.Info($"   removed weldpad that was in the way at {block.Position.ToString()} on {block.CubeGrid.ToString()}");
                        }
                    }

                    WeldPad otherLogic = OtherPad.GameLogic.GetAs <WeldPad>();
                    otherLogic.OtherPad = null;

                    OtherPad = null;

                    SetPadStatus("WeldPad: Succesfully merged", MyFontEnum.Green, 1000);
                }
                else
                {
                    // double dist = Math.Abs(((distSq - distReq) - pad.CubeGrid.GridSize) / pad.CubeGrid.GridSize) * 100;
                    double axisDist = 100 - ((Math.Abs(axisDot - -1.0) / 2) * 100);
                    double rollDist = 100 - ((Math.Abs(rollDot - 1.0) / 2) * 100);

                    SetPadStatus($"WeldPad: Distance = {Math.Max(dist, 0).ToString("0.00")}m, axis = {axisDist.ToString("0.00")}%, roll = {rollDist.ToString("0.00")}%", MyFontEnum.Blue);

                    //MyAPIGateway.Utilities.ShowNotification("[debug] offset="+AdvancedWelding.CalculateOffset(padGrid, otherGrid, pad)+"; offset2="+AdvancedWelding.CalculateOffset(otherGrid, padGrid, otherPad), 160, MyFontEnum.Blue);
                    //MyAPIGateway.Utilities.ShowNotification("[debug] offset="+AdvancedWelding.CalculateOffset(pad, otherPad)+"; offset2="+AdvancedWelding.CalculateOffset(otherPad, pad), 160, MyFontEnum.Blue);

                    //MyAPIGateway.Utilities.ShowNotification("[debug] dist="+Math.Round(Math.Sqrt(distSq), 3), 160, MyFontEnum.Blue);
                    //MyAPIGateway.Utilities.ShowNotification("[debug] distSq="+Math.Round(distSq, 2)+"; axis="+axisDot+"; rotation="+rotationDot, 160, MyFontEnum.Blue);

                    // magnetism...
                    //Vector3D dir = (otherPos - pos);

                    //if(!padGrid.IsStatic)
                    //    padGrid.Physics.AddForce(MyPhysicsForceType.APPLY_WORLD_FORCE, dir * 5 * otherPad.Mass, pos, null);

                    //if(!otherGrid.IsStatic)
                    //    otherGrid.Physics.AddForce(MyPhysicsForceType.APPLY_WORLD_FORCE, -dir * 5 * pad.Mass, otherPos, null);
                }
            }
            catch (Exception e)
            {
                Log.Error(e);
            }
        }