예제 #1
0
파일: Projector.cs 프로젝트: zrisher/ARMS
        private void Actual_OnBlockRemoved(IMySlimBlock obj)
        {
            SeenHolo sh;

            if (!m_holoEntities.TryGetValue(obj.CubeGrid.EntityId, out sh))
            {
                Log.DebugLog("failed lookup of grid: " + obj.CubeGrid.DisplayName, Logger.severity.ERROR);
                obj.CubeGrid.OnBlockAdded   -= Actual_OnBlockAdded;
                obj.CubeGrid.OnBlockRemoved -= Actual_OnBlockRemoved;
                return;
            }

            Vector3I    position = obj.Position;
            IMyCubeGrid holo     = (IMyCubeGrid)sh.Holo;

            holo.RemoveBlock(holo.GetCubeBlock(position));
        }
예제 #2
0
파일: Projector.cs 프로젝트: zrisher/ARMS
        /// <summary>
        /// Updates the appearance of the block if the integrity has changed. Only used for welding/griding.
        /// </summary>
        private static void UpdateBlockModel(IMySlimBlock realBlock, IMyCubeGrid holoGrid)
        {
            IMySlimBlock holoBlock = holoGrid.GetCubeBlock(realBlock.Position);

            Logger.DebugLog("holoBlock == null", Logger.severity.FATAL, condition: holoBlock == null);

            float realIntegrityRatio = (realBlock.BuildIntegrity - realBlock.CurrentDamage) / realBlock.MaxIntegrity;
            float holoIntegrityRatio = (holoBlock.BuildIntegrity - holoBlock.CurrentDamage) / holoBlock.MaxIntegrity;

            if (realIntegrityRatio == holoIntegrityRatio)
            {
                return;
            }

            float min, max;

            if (realIntegrityRatio > holoIntegrityRatio)
            {
                max = realIntegrityRatio;
                min = holoIntegrityRatio;
            }
            else
            {
                max = holoIntegrityRatio;
                min = realIntegrityRatio;
            }

            if (((MyCubeBlockDefinition)realBlock.BlockDefinition).ModelChangeIsNeeded(min, max))
            {
                holoGrid.RemoveBlock(holoBlock);

                MyObjectBuilder_CubeBlock objBuilder = realBlock.GetObjectBuilder();
                objBuilder.EntityId = 0L;
                holoGrid.AddBlock(objBuilder, false);

                IMyCubeBlock cubeBlock = holoGrid.GetCubeBlock(realBlock.Position).FatBlock;
                if (cubeBlock != null)
                {
                    SetupProjection(cubeBlock);
                }
            }
        }
예제 #3
0
        /// <summary>
        /// Updates the appearance of the block if the integrity has changed. Only used for welding/griding.
        /// </summary>
        private static void UpdateBlockModel(IMySlimBlock realBlock, IMyCubeGrid holoGrid)
        {
            IMySlimBlock holoBlock = holoGrid.GetCubeBlock(realBlock.Position);
            Static.logger.debugLog(holoBlock == null, "holoBlock == null", Logger.severity.FATAL);

            float realIntegrityRatio = (realBlock.BuildIntegrity - realBlock.CurrentDamage) / realBlock.MaxIntegrity;
            float holoIntegrityRatio = (holoBlock.BuildIntegrity - holoBlock.CurrentDamage) / holoBlock.MaxIntegrity;

            if (realIntegrityRatio == holoIntegrityRatio)
                return;

            float min, max;
            if (realIntegrityRatio > holoIntegrityRatio)
            {
                max = realIntegrityRatio;
                min = holoIntegrityRatio;
            }
            else
            {
                max = holoIntegrityRatio;
                min = realIntegrityRatio;
            }

            if (((MyCubeBlockDefinition)realBlock.BlockDefinition).ModelChangeIsNeeded(min, max))
            {
                holoGrid.RemoveBlock(holoBlock);

                MyObjectBuilder_CubeBlock objBuilder = realBlock.GetObjectBuilder();
                objBuilder.EntityId = 0L;
                holoGrid.AddBlock(objBuilder, false);

                IMyCubeBlock cubeBlock = holoGrid.GetCubeBlock(realBlock.Position).FatBlock;
                if (cubeBlock != null)
                    SetupProjection(cubeBlock);
            }
        }
예제 #4
0
        //
        // == SessionComponent Hooks
        //
        public override void UpdateBeforeSimulation()
        {
            try
            {
                if (MyAPIGateway.Session == null || MyAPIGateway.Utilities == null || MyAPIGateway.Multiplayer == null) // exit if api is not ready
                {
                    return;
                }

                if (!Inited) // init and set handlers
                {
                    Init();
                }

                if (Settings == null) // request or load setting
                {
                    GetSettings();    // if server, settings will be set a this call, so it safe
                }
                if (!IsServer)        // if client exit at this point. Cleaning works only on server side.
                {
                    return;
                }

                if (Frame++ % 10 == 0)
                {
                    HashSet <IMyEntity> entities = new HashSet <IMyEntity>();
                    MyAPIGateway.Entities.GetEntities(entities, x => x is IMyCubeGrid);
                    foreach (IMyEntity entity in entities)
                    {
                        IMyCubeGrid grid = entity as IMyCubeGrid;
                        if (grid == null)
                        {
                            continue;
                        }

                        // if this grid have an active BS, then turn off destructible for grid
                        gridDestructible(grid, !isActiveBeaconSecurity(grid));

                        if (!eventedGrids.Contains(grid))
                        { // skip if already added actions
                            grid.OnBlockAdded += BuildHandler.grid_OnBlockAdded;
                            eventedGrids.Add(grid);
                            Logger.Log.Debug("OnBlockAdded event added to {0} grids.", grid.EntityId);
                        }
                    }

                    // Remove block from queues
                    foreach (var block in queueRemoveBlocks)
                    {
                        IMyCubeGrid grid = block.CubeGrid as IMyCubeGrid;
                        if (grid == null)
                        {
                            continue;
                        }
                        grid.RemoveBlock(block, true);
                        if (block.FatBlock != null)
                        {
                            block.FatBlock.Close();
                        }
                    }
                    queueRemoveBlocks.Clear();
                }

                if (Settings.CleaningFrequency == 0)
                {
                    return;
                }
                #region Cleanup
                if ((DateTime.Now - m_cleaning).TotalSeconds > Settings.CleaningFrequency) // Cleaning by frequency
                {
                    Logger.Log.Debug("Time for cleaning, from last {0} secs elapsed.", (DateTime.Now - m_cleaning).TotalSeconds);
                    m_cleaning = DateTime.Now;
                    HashSet <IMyEntity> entities = new HashSet <IMyEntity>();
                    MyAPIGateway.Entities.GetEntities(entities, x => x is IMyCubeGrid);

                    int removed = 0;
                    List <IMySlimBlock> ToRemove = new List <IMySlimBlock>();

                    HashSet <long>            AlreadyCounted  = new HashSet <long>();
                    Dictionary <long, long[]> PerFactionCount = new Dictionary <long, long[]>();
                    Dictionary <long, long[]> PerPlayerCount  = new Dictionary <long, long[]>();

                    foreach (IMyCubeGrid grid in entities)
                    {
                        var blocks = new List <IMySlimBlock>();
                        grid.GetBlocks(blocks, x => x.FatBlock != null);
                        foreach (IMySlimBlock block in blocks)
                        {
                            //Logger.Log.Debug("Check block {0} {1}", block.FatBlock.DisplayNameText, block.FatBlock.ToString());
                            BeaconSecurity bs = block.FatBlock.GameLogic as BeaconSecurity;
                            if (bs == null || !bs.IsBeaconSecurity || bs.OwnerId == 0)
                            {
                                continue;
                            }

                            if (!AlreadyCounted.Contains(block.FatBlock.EntityId))
                            {
                                AlreadyCounted.Add(block.FatBlock.EntityId);
                            }
                            else
                            {
                                continue;
                            }

                            // Priority for players limit.

                            if (!PerPlayerCount.ContainsKey(bs.OwnerId)) // if there no counts, add it
                            {
                                PerPlayerCount[bs.OwnerId] = new long[] { 0, 0 }
                            }
                            ;
                            PerPlayerCount[bs.OwnerId][0]++;
                            if (bs.OwnerId != 0 && PerPlayerCount[bs.OwnerId][0] > Settings.LimitPerPlayer)
                            {
                                PerPlayerCount[bs.OwnerId][1]++;
                                ToRemove.Add(block);
                                continue;
                            }

                            IMyFaction faction = MyAPIGateway.Session.Factions.TryGetPlayerFaction(bs.OwnerId);
                            if (faction != null)
                            {
                                if (!PerFactionCount.ContainsKey(faction.FactionId))
                                {
                                    PerFactionCount[faction.FactionId] = new long[] { 0, 0 }
                                }
                                ;
                                PerFactionCount[faction.FactionId][0]++;

                                if (PerFactionCount[faction.FactionId][0] > Settings.LimitPerFaction)
                                {
                                    PerFactionCount[faction.FactionId][1]++;
                                    ToRemove.Add(block);
                                }
                            }
                        }
                        foreach (IMySlimBlock block in ToRemove)
                        {
                            grid.RemoveBlock(block, true);
                        }
                        removed += ToRemove.Count;
                        ToRemove.Clear();
                    }

                    List <IMyPlayer> players = new List <IMyPlayer>();
                    MyAPIGateway.Players.GetPlayers(players);

                    // Send warn message about cleaning and restrictions!
                    foreach (long ownerId in PerPlayerCount.Keys)
                    {
                        if (ownerId == 0 || PerPlayerCount[ownerId][1] == 0)
                        {
                            continue;
                        }
                        IMyPlayer player = players.FirstOrDefault(x => x.PlayerID == ownerId);
                        if (player == null)
                        {
                            continue;
                        }
                        SyncPacket pckOut = new SyncPacket();
                        pckOut.proto   = SyncPacket.Version;
                        pckOut.command = (ushort)Command.MessageToChat;
                        pckOut.message = string.Format("Removed {0} entity as a result of limitations on the amount {1} per player.", PerPlayerCount[ownerId][1], Settings.LimitPerPlayer);
                        Core.SendMessage(pckOut, player.SteamUserId);
                    }

                    foreach (long factionId in PerFactionCount.Keys)
                    {
                        if (PerFactionCount[factionId][1] == 0)
                        {
                            continue;
                        }
                        IMyFaction faction = MyAPIGateway.Session.Factions.TryGetFactionById(factionId);
                        if (faction == null)
                        {
                            continue;
                        }

                        foreach (var member in faction.Members)
                        {
                            IMyPlayer player = players.FirstOrDefault(x => x.PlayerID == member.Key);
                            if (player == null)
                            {
                                continue;
                            }
                            SyncPacket pckOut = new SyncPacket();
                            pckOut.proto   = SyncPacket.Version;
                            pckOut.command = (ushort)Command.MessageToChat;
                            pckOut.message = string.Format("Removed {0} entity as a result of limitations on the amount {1} per faction.", PerFactionCount[factionId][1], Settings.LimitPerFaction);
                            Core.SendMessage(pckOut, player.SteamUserId);
                        }
                    }

                    if (removed > 0)
                    {
                        Logger.Log.Info("Cleaning, totaly removed {0} entities.", removed);
                    }
                }
                #endregion Cleanup
            }
            catch (Exception ex)
            {
                Logger.Log.Error("EXCEPTION at BeaconSecurity.UpdateBeforeSimulation(): {0} {1}", ex.Message, ex.StackTrace);
            }
        }
예제 #5
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);
            }
        }