예제 #1
0
    public GridStats(IMyCubeGrid grid)
    {
        this.grid = grid;
        var tot       = 0;
        var termblock = 0;
        var damaged   = 0;

        for (var z = grid.Min.Z; z <= grid.Max.Z; z++)
        {
            for (var y = grid.Min.Y; y <= grid.Max.Y; y++)
            {
                for (var x = grid.Min.X; x <= grid.Max.X; x++)
                {
                    if (grid.CubeExists(new Vector3I(x, y, z)))
                    {
                        tot++;
                        var block = grid.GetCubeBlock(new Vector3I(x, y, z));
                        if (block != null)
                        {
                            termblock++;
                            if (!block.IsFullIntegrity)
                            {
                                damaged++;
                            }
                        }
                    }
                }
            }
        }
        this.total          = tot;
        this.terminal_block = termblock;
        this.damaged        = damaged;
    }
예제 #2
0
    public void draw(IScaledPixelDrawer drawer)
    {
        Func <Vector3I, Vector2I> project = v => new Vector2I(v.X, v.Z);

        var armor    = new List <Vector2I>();
        var pristine = new List <Vector2I>();
        var dented   = new List <Vector2I>();
        var damaged  = new List <Vector2I>();
        var broken   = new List <Vector2I>();

        var lengths = gridMax - gridMin + new Vector3I(1, 1, 1);

        drawer.setScale(project(lengths).X, project(lengths).Y);

        foreach (var pos in gridBlocks)
        {
            var      block = grid.GetCubeBlock(pos);
            Vector2I ppos  = project(pos - gridMin);

            if (grid.CubeExists(pos))
            {
                if (block == null)                   // Armor block
                {
                    armor.Add(ppos);
                }
                else if (block.IsFullIntegrity)
                {
                    pristine.Add(ppos);
                }
                else
                {
                    var health = (block.BuildIntegrity - block.CurrentDamage) / block.MaxIntegrity;
                    if (health < DENT_LIMIT)
                    {
                        damaged.Add(ppos);
                    }
                    else
                    {
                        dented.Add(ppos);
                    }
                }
            }
            else
            {
                broken.Add(ppos);
            }
        }

        armor.ForEach(p => drawer.drawPixel(p.X, p.Y, ARMOR_COLOR));
        pristine.ForEach(p => drawer.drawPixel(p.X, p.Y, PRISTINE_COLOR));
        dented.ForEach(p => drawer.drawPixel(p.X, p.Y, DENTED_COLOR));
        damaged.ForEach(p => drawer.drawPixel(p.X, p.Y, DAMAGED_COLOR));
        broken.ForEach(p => drawer.drawPixel(p.X, p.Y, BROKEN_COLOR));
    }
예제 #3
0
        public static void RayCastGrid(this IMyCubeGrid grid, Vector3 rayStart, Vector3 direction, Action <Vector3I> visitor)
        {
            Matrix worldToLocal = Matrix.Invert(grid.WorldMatrix);

            direction.Normalize();
            Vector3 transformedDirection = Vector3.TransformNormal(direction, worldToLocal);

            Vector3  currentPointF = Vector3.Transform(rayStart, worldToLocal) / grid.GridSize;
            Vector3I currentPoint  = Vector3I.Round(currentPointF);

            if (!Inside(grid.Min, grid.Max, currentPoint))
            {
                //find intersection
                BoundingBoxI bbI = new BoundingBoxI(grid.Min, grid.Max);
                var          hit = bbI.Intersects(new Ray(currentPointF, transformedDirection));
                if (!hit.HasValue)
                {
                    //Program.instance.Log($"No misses bounding box");
                    return; //no intersection
                }
                currentPointF += (float)hit.Value * transformedDirection;
                currentPoint   = Vector3I.Round(currentPointF);
            }

            //Program.instance.Log($"Starting at: {currentPoint}");
            //Program.instance.Log($"Direction at: {transformedDirection}");

            while (Inside(grid.Min, grid.Max, currentPoint))
            {
                if (grid.CubeExists(currentPoint))
                {
                    visitor(currentPoint);
                }

                float toXShift = ClosestGridBlockChange(currentPointF.X, transformedDirection.X);
                float toYShift = ClosestGridBlockChange(currentPointF.Y, transformedDirection.Y);
                float toZShift = ClosestGridBlockChange(currentPointF.Z, transformedDirection.Z);

                currentPointF += transformedDirection * Min(toXShift, toYShift, toZShift);
                currentPoint   = Vector3I.Round(currentPointF);

                //Program.instance.Log($"Shift by: {toXShift}, {toYShift}, {toZShift}");
                //Program.instance.Log($"Walk:{currentPoint}");
            }
        }
예제 #4
0
    private void finishWalk()
    {
        try {
            while (true)
            {
                var pos = visitQueue.Dequeue();

                if (visited.Add(pos))
                {
                    if (cubeGrid.CubeExists(pos))
                    {
                        full.Add(pos);
                        visitQueue.Enqueue(new Vector3I(pos.X - 1, pos.Y, pos.Z));
                        visitQueue.Enqueue(new Vector3I(pos.X + 1, pos.Y, pos.Z));
                        visitQueue.Enqueue(new Vector3I(pos.X, pos.Y - 1, pos.Z));
                        visitQueue.Enqueue(new Vector3I(pos.X, pos.Y + 1, pos.Z));
                        visitQueue.Enqueue(new Vector3I(pos.X, pos.Y, pos.Z - 1));
                        visitQueue.Enqueue(new Vector3I(pos.X, pos.Y, pos.Z + 1));
                    }
                }
            }
        } catch (InvalidOperationException) {}
    }
예제 #5
0
        /// <summary>
        /// Yields the first occupied cells encountered when raycasting a grid in a given base direction.
        /// </summary>
        /// <param name="grid">The grid to get blocks from.</param>
        /// <param name="baseDirection">The direction of ray.</param>
        public static IEnumerable <Vector3I> FirstBlocks(this IMyCubeGrid grid, Vector3I baseDirection)
        {
            Logger.DebugLog("baseDirection(" + baseDirection + ") has a magnitude", Logger.severity.FATAL, condition: baseDirection.RectangularLength() != 1);

            BoundingBox localAABB = grid.LocalAABB;

            Vector3I min = grid.Min, max = grid.Max;

            // ???
            //Vector3 minF; Vector3.Divide(ref localAABB.Min, grid.GridSize, out minF);
            //Vector3 maxF; Vector3.Divide(ref localAABB.Max, grid.GridSize, out maxF);
            //Vector3I min, max;

            //Func<float, int> round = f => (int)Math.Round(f);
            //minF.ApplyOperation(round, out min);
            //maxF.ApplyOperation(round, out max);

            Vector3I perp0, perp1;

            perp0 = Base6Directions.GetIntVector(Base6Directions.GetPerpendicular(Base6Directions.GetDirection(baseDirection)));
            Vector3I.Cross(ref baseDirection, ref perp0, out perp1);

            int baseStart; Vector3I.Dot(ref baseDirection, ref min, out baseStart);
            int baseEnd; Vector3I.Dot(ref baseDirection, ref max, out baseEnd);

            if (baseStart > baseEnd)
            {
                int temp = baseStart;
                baseStart = baseEnd;
                baseEnd   = temp;
            }
            bool incrementBase = baseStart <= baseEnd;

            int perp0Min; Vector3I.Dot(ref perp0, ref min, out perp0Min);
            int perp0Max; Vector3I.Dot(ref perp0, ref max, out perp0Max);

            if (perp0Max < perp0Min)
            {
                int temp = perp0Max;
                perp0Max = perp0Min;
                perp0Min = temp;
            }

            int perp1Min; Vector3I.Dot(ref perp1, ref min, out perp1Min);
            int perp1Max; Vector3I.Dot(ref perp1, ref max, out perp1Max);

            if (perp1Max < perp1Min)
            {
                int temp = perp1Max;
                perp1Max = perp1Min;
                perp1Min = temp;
            }

            Logger.TraceLog("min: " + min + ", max: " + max, Logger.severity.DEBUG);
            Logger.TraceLog("base: " + baseDirection + ", perp0: " + perp0 + ", perp1: " + perp1, Logger.severity.DEBUG);
            Logger.TraceLog("base range: " + baseStart + ":" + baseEnd, Logger.severity.DEBUG);
            Logger.TraceLog("perp0 range: " + perp0Min + ":" + perp0Max, Logger.severity.DEBUG);
            Logger.TraceLog("perp1 range: " + perp1Min + ":" + perp1Max, Logger.severity.DEBUG);

            for (int perp0Value = perp0Min; perp0Value <= perp0Max; perp0Value++)
            {
                for (int perp1Value = perp1Min; perp1Value <= perp1Max; perp1Value++)
                {
                    int baseValue = baseStart;
                    while (true)
                    {
                        Vector3I cell = baseValue * baseDirection + perp0Value * perp0 + perp1Value * perp1;

                        if (grid.CubeExists(cell))
                        {
                            yield return(cell);

                            break;
                        }

                        if (baseValue == baseEnd)
                        {
                            break;
                        }
                        if (incrementBase)
                        {
                            baseValue++;
                        }
                        else
                        {
                            baseValue--;
                        }
                    }
                }
            }

            yield break;
        }
예제 #6
0
파일: Painting.cs 프로젝트: THDigi/PaintGun
        Vector3I?MirrorPaint(bool sync, IMyCubeGrid grid, int axis, MirrorData mirrorPlanes, bool odd, Vector3I originalPosition, PaintMaterial paint, List <Vector3I> alreadyMirrored, ulong originalSenderSteamId)
        {
            Vector3I?mirrorPosition = null;

            switch (axis)
            {
            case 0:
                if (mirrorPlanes.X.HasValue)
                {
                    mirrorPosition = originalPosition + new Vector3I(((mirrorPlanes.X.Value - originalPosition.X) * 2) - (odd ? 1 : 0), 0, 0);
                }
                break;

            case 1:
                if (mirrorPlanes.Y.HasValue)
                {
                    mirrorPosition = originalPosition + new Vector3I(0, ((mirrorPlanes.Y.Value - originalPosition.Y) * 2) - (odd ? 1 : 0), 0);
                }
                break;

            case 2:
                if (mirrorPlanes.Z.HasValue)
                {
                    mirrorPosition = originalPosition + new Vector3I(0, 0, ((mirrorPlanes.Z.Value - originalPosition.Z) * 2) + (odd ? 1 : 0));     // reversed on odd
                }
                break;
            }

            if (mirrorPosition.HasValue && originalPosition != mirrorPosition.Value && !alreadyMirrored.Contains(mirrorPosition.Value) && grid.CubeExists(mirrorPosition.Value))
            {
                alreadyMirrored.Add(mirrorPosition.Value);
                PaintBlock(sync, grid, mirrorPosition.Value, paint, originalSenderSteamId);
            }

            return(mirrorPosition);
        }
예제 #7
0
        private void update_terminal_block_status(int limit)
        {
            int count = 0;

            blocks_terminal = new List <IMyTerminalBlock>();
            GridTerminalSystem.GetBlocksOfType <IMyTerminalBlock>(blocks_terminal);
            if (terminal_blocks_index >= blocks_terminal.Count)
            {
                terminal_blocks_index = 0;
            }
            while (count < limit && terminal_blocks_index < blocks_terminal.Count)
            {
                count++;
                IMyTerminalBlock block = blocks_terminal[terminal_blocks_index];
                Vector3I         pos   = block.Position;
                if (!coords_ship_full.Contains(pos))
                {  //ignore blocks we didn't find at initialization. (safer)
                    terminal_blocks_index++;
                    continue;
                }
                if (!myGrid.CubeExists(block.Position))
                { //Note :if the block is gone we can still reference it.
                    safely_remove(coords_terminal_now, pos);
                    safely_remove(coords_terminal_working, pos);
                    safely_remove(coords_terminal_nothacked, pos);
                    safely_remove(coords_gyro_now, pos);
                    safely_remove(coords_thrust_now, pos);
                    safely_remove(coords_weapon_now, pos);
                    safely_remove(coords_power_now, pos);
                }
                else if (coords_terminal_full.Contains(pos))
                {
                    safely_add(coords_terminal_now, pos);
                    if (block.IsFunctional)
                    {
                        safely_add(coords_terminal_working, pos);
                    }
                    if (!block.IsBeingHacked)
                    {
                        safely_add(coords_terminal_nothacked, pos);
                    }
                    if (!block.IsFunctional)
                    {
                        safely_remove(coords_terminal_working, pos);
                    }
                    if (block.IsBeingHacked)
                    {
                        safely_remove(coords_terminal_nothacked, pos);
                    }
                    if (block is IMyThrust)
                    {
                        safely_add(coords_thrust_now, pos); safely_add(coords_thrust_full, pos);
                    }
                    if (block is IMyGyro)
                    {
                        safely_add(coords_gyro_now, pos); safely_add(coords_gyro_full, pos);
                    }
                    if (is_weapon(block))
                    {
                        safely_add(coords_weapon_now, pos); safely_add(coords_weapon_full, pos);
                    }
                    if (is_power(block))
                    {
                        safely_add(coords_power_now, pos); safely_add(coords_power_full, pos);
                    }
                }
                terminal_blocks_index++;
            }
        }