public void Draw() { if (PadDraw.Count == 0) { return; } const float DepthRatio = 0.05f; const float LineWidth = 0.02f * DepthRatio; Color color = Color.Red * 0.5f; MatrixD camMatrix = MyAPIGateway.Session.Camera.WorldMatrix; for (int i = (PadDraw.Count - 1); i >= 0; i--) { WeldPad pad = PadDraw[i]; if (pad.BlocksInTheWay.Count == 0) { PadDraw.RemoveAtFast(i); return; } if (!pad.SeeWeldPadInfo()) { continue; } foreach (IMySlimBlock block in pad.BlocksInTheWay) { MyCubeBlockDefinition def = (MyCubeBlockDefinition)block.BlockDefinition; Matrix localMatrix; block.Orientation.GetMatrix(out localMatrix); localMatrix.Translation = new Vector3(block.Position) * block.CubeGrid.GridSize; MatrixD worldMatrix = localMatrix * block.CubeGrid.WorldMatrix; Vector3 halfSize = def.Size * (block.CubeGrid.GridSize / 2); BoundingBoxD localBB = new BoundingBoxD(-halfSize, halfSize); // for always-on-top draw Vector3D center = camMatrix.Translation + ((worldMatrix.Translation - camMatrix.Translation) * DepthRatio); MatrixD.Rescale(ref worldMatrix, DepthRatio); worldMatrix.Translation = center; MySimpleObjectDraw.DrawTransparentBox(ref worldMatrix, ref localBB, ref color, MySimpleObjectRasterizer.Wireframe, 1, LineWidth, lineMaterial: LineMaterial, blendType: BlendTypeEnum.PostPP); } } }
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); } }