示例#1
0
        public override void Update()
        {
            int value = m_subsystemTerrain.Terrain.GetCellValue(m_componentBlockEntity.Coordinates.X, m_componentBlockEntity.Coordinates.Y, m_componentBlockEntity.Coordinates.Z);
            int data  = Terrain.ExtractData(value);

            if (m_dispenseButton.IsClicked)
            {
                data  = DispenserBlock.SetMode(data, DispenserBlock.Mode.Dispense);
                value = Terrain.ReplaceData(value, data);
                m_subsystemTerrain.ChangeCell(m_componentBlockEntity.Coordinates.X, m_componentBlockEntity.Coordinates.Y, m_componentBlockEntity.Coordinates.Z, value);
            }
            if (m_shootButton.IsClicked)
            {
                data  = DispenserBlock.SetMode(data, DispenserBlock.Mode.Shoot);
                value = Terrain.ReplaceData(value, data);
                m_subsystemTerrain.ChangeCell(m_componentBlockEntity.Coordinates.X, m_componentBlockEntity.Coordinates.Y, m_componentBlockEntity.Coordinates.Z, value);
            }
            if (m_acceptsDropsBox.IsClicked)
            {
                data  = DispenserBlock.SetAcceptsDrops(data, !DispenserBlock.GetAcceptsDrops(data));
                value = Terrain.ReplaceData(value, data);
                m_subsystemTerrain.ChangeCell(m_componentBlockEntity.Coordinates.X, m_componentBlockEntity.Coordinates.Y, m_componentBlockEntity.Coordinates.Z, value);
            }
            DispenserBlock.Mode mode = DispenserBlock.GetMode(data);
            m_dispenseButton.IsChecked  = (mode == DispenserBlock.Mode.Dispense);
            m_shootButton.IsChecked     = (mode == DispenserBlock.Mode.Shoot);
            m_acceptsDropsBox.IsChecked = DispenserBlock.GetAcceptsDrops(data);
            if (!m_componentDispenser.IsAddedToProject)
            {
                base.ParentWidget.Children.Remove(this);
            }
        }
        public override bool OnUse(Ray3 ray, ComponentMiner componentMiner)
        {
            TerrainRaycastResult?terrainRaycastResult = componentMiner.Raycast <TerrainRaycastResult>(ray, RaycastMode.Interaction);

            if (terrainRaycastResult.HasValue && terrainRaycastResult.Value.CellFace.Face == 4)
            {
                int y = terrainRaycastResult.Value.CellFace.Y;
                for (int i = terrainRaycastResult.Value.CellFace.X - 1; i <= terrainRaycastResult.Value.CellFace.X + 1; i++)
                {
                    for (int j = terrainRaycastResult.Value.CellFace.Z - 1; j <= terrainRaycastResult.Value.CellFace.Z + 1; j++)
                    {
                        int cellValue = m_subsystemTerrain.Terrain.GetCellValue(i, y, j);
                        if (Terrain.ExtractContents(cellValue) == 168)
                        {
                            int data  = SoilBlock.SetNitrogen(Terrain.ExtractData(cellValue), 3);
                            int value = Terrain.ReplaceData(cellValue, data);
                            m_subsystemTerrain.ChangeCell(i, y, j, value);
                        }
                    }
                }
                m_subsystemAudio.PlayRandomSound("Audio/Impacts/Dirt", 0.5f, 0f, new Vector3(terrainRaycastResult.Value.CellFace.X, terrainRaycastResult.Value.CellFace.Y, terrainRaycastResult.Value.CellFace.Z), 3f, autoDelay: true);
                Vector3 position = new Vector3((float)terrainRaycastResult.Value.CellFace.X + 0.5f, (float)terrainRaycastResult.Value.CellFace.Y + 1.5f, (float)terrainRaycastResult.Value.CellFace.Z + 0.5f);
                Block   block    = BlocksManager.Blocks[Terrain.ExtractContents(componentMiner.ActiveBlockValue)];
                m_subsystemParticles.AddParticleSystem(block.CreateDebrisParticleSystem(m_subsystemTerrain, position, componentMiner.ActiveBlockValue, 1.25f));
                componentMiner.RemoveActiveTool(1);
                return(true);
            }
            return(false);
        }
示例#3
0
        public override void OnNeighborBlockChanged(int x, int y, int z, int neighborX, int neighborY, int neighborZ)
        {
            if (Utils.SubsystemGameInfo.WorldSettings.EnvironmentBehaviorMode != EnvironmentBehaviorMode.Living || y <= 0)
            {
                return;
            }
            int value = Utils.Terrain.GetCellValue(x, y - 1, z);

            if (!Utils.SubsystemCollapsingBlockBehavior.IsCollapseSupportBlock(value))
            {
                var list = new List <MovingBlock>();
                int i;
                for (i = y; i < 128; i++)
                {
                    value = Utils.Terrain.GetCellValue(x, i, z);
                    if (Terrain.ExtractContents(value) != 67 || (Terrain.ExtractData(value) & 65536) == 0)
                    {
                        break;
                    }
                    list.Add(new MovingBlock
                    {
                        Value  = value,
                        Offset = new Point3(0, i - y, 0)
                    });
                }
                if (list.Count != 0 && Utils.SubsystemMovingBlocks.AddMovingBlockSet(new Vector3(x, y, z), new Vector3(x, -list.Count - 1, z), 0f, 10f, 0.7f, new Vector2(0f), list, "CollapsingBlock", null, true) != null)
                {
                    for (i = 0; i < list.Count; i++)
                    {
                        Point3 point = list[i].Offset;
                        SubsystemTerrain.ChangeCell(point.X + x, point.Y + y, point.Z + z, 0);
                    }
                }
            }
        }
        public void FreezeThawAndDepositSnow(TerrainChunk chunk)
        {
            Terrain terrain = SubsystemTerrain.Terrain;

            for (int i = 0; i < 16; i++)
            {
                for (int j = 0; j < 16; j++)
                {
                    if (m_random.Int() % 2 == 0)
                    {
                        continue;
                    }
                    int topHeightFast = chunk.GetTopHeightFast(i, j);
                    int cellValueFast = chunk.GetCellValueFast(i, topHeightFast, j);
                    int num           = Terrain.ExtractContents(cellValueFast);
                    int num2          = chunk.Origin.X + i;
                    int num3          = topHeightFast;
                    int num4          = chunk.Origin.Y + j;
                    PrecipitationShaftInfo precipitationShaftInfo = GetPrecipitationShaftInfo(num2, num4);
                    if (precipitationShaftInfo.Type == PrecipitationType.Snow)
                    {
                        if (num == 18)
                        {
                            int  cellContents  = terrain.GetCellContents(num2 + 1, num3, num4);
                            int  cellContents2 = terrain.GetCellContents(num2 - 1, num3, num4);
                            int  cellContents3 = terrain.GetCellContents(num2, num3, num4 - 1);
                            int  cellContents4 = terrain.GetCellContents(num2, num3, num4 + 1);
                            bool num5          = cellContents != 18 && cellContents != 0;
                            bool flag          = cellContents2 != 18 && cellContents2 != 0;
                            bool flag2         = cellContents3 != 18 && cellContents3 != 0;
                            bool flag3         = cellContents4 != 18 && cellContents4 != 0;
                            if (num5 | flag | flag2 | flag3)
                            {
                                SubsystemTerrain.ChangeCell(num2, num3, num4, Terrain.MakeBlockValue(62));
                            }
                        }
                        else if (precipitationShaftInfo.Intensity > 0.5f && SubsystemSnowBlockBehavior.CanSupportSnow(cellValueFast) && (num != 62 || ShaftHasSnowOnIce(num2, num4)) && num3 + 1 < 255)
                        {
                            SubsystemTerrain.ChangeCell(num2, num3 + 1, num4, Terrain.MakeBlockValue(61));
                        }
                    }
                    else
                    {
                        switch (num)
                        {
                        case 61:
                            SubsystemTerrain.DestroyCell(0, num2, num3, num4, 0, noDrop: true, noParticleSystem: true);
                            break;

                        case 62:
                            SubsystemTerrain.DestroyCell(0, num2, num3, num4, 0, noDrop: false, noParticleSystem: true);
                            break;
                        }
                    }
                }
            }
        }
示例#5
0
 public void Paint(SubsystemTerrain terrain, int x, int y, int z)
 {
     Cell[] cells = Cells;
     for (int i = 0; i < cells.Length; i++)
     {
         Cell cell = cells[i];
         int  x2   = cell.X + x;
         int  y2   = cell.Y + y;
         int  z2   = cell.Z + z;
         terrain.ChangeCell(x2, y2, z2, cell.Value);
     }
 }
        public override bool OnUse(Ray3 ray, ComponentMiner componentMiner)
        {
            TerrainRaycastResult?terrainRaycastResult = componentMiner.Raycast <TerrainRaycastResult>(ray, RaycastMode.Interaction);

            if (terrainRaycastResult.HasValue)
            {
                if (terrainRaycastResult.Value.CellFace.Face == 4)
                {
                    int   cellValue = m_subsystemTerrain.Terrain.GetCellValue(terrainRaycastResult.Value.CellFace.X, terrainRaycastResult.Value.CellFace.Y, terrainRaycastResult.Value.CellFace.Z);
                    int   num       = Terrain.ExtractContents(cellValue);
                    Block block     = BlocksManager.Blocks[num];
                    switch (num)
                    {
                    case 2:
                    {
                        int value2 = Terrain.ReplaceContents(cellValue, 168);
                        m_subsystemTerrain.ChangeCell(terrainRaycastResult.Value.CellFace.X, terrainRaycastResult.Value.CellFace.Y, terrainRaycastResult.Value.CellFace.Z, value2);
                        m_subsystemAudio.PlayRandomSound("Audio/Impacts/Dirt", 0.5f, 0f, new Vector3(terrainRaycastResult.Value.CellFace.X, terrainRaycastResult.Value.CellFace.Y, terrainRaycastResult.Value.CellFace.Z), 3f, autoDelay: true);
                        Vector3 position2 = new Vector3((float)terrainRaycastResult.Value.CellFace.X + 0.5f, (float)terrainRaycastResult.Value.CellFace.Y + 1.25f, (float)terrainRaycastResult.Value.CellFace.Z + 0.5f);
                        m_subsystemParticles.AddParticleSystem(block.CreateDebrisParticleSystem(m_subsystemTerrain, position2, cellValue, 0.5f));
                        break;
                    }

                    case 8:
                    {
                        int value = Terrain.ReplaceContents(cellValue, 2);
                        m_subsystemTerrain.ChangeCell(terrainRaycastResult.Value.CellFace.X, terrainRaycastResult.Value.CellFace.Y, terrainRaycastResult.Value.CellFace.Z, value);
                        m_subsystemAudio.PlayRandomSound("Audio/Impacts/Plant", 0.5f, 0f, new Vector3(terrainRaycastResult.Value.CellFace.X, terrainRaycastResult.Value.CellFace.Y, terrainRaycastResult.Value.CellFace.Z), 3f, autoDelay: true);
                        Vector3 position = new Vector3((float)terrainRaycastResult.Value.CellFace.X + 0.5f, (float)terrainRaycastResult.Value.CellFace.Y + 1.2f, (float)terrainRaycastResult.Value.CellFace.Z + 0.5f);
                        m_subsystemParticles.AddParticleSystem(block.CreateDebrisParticleSystem(m_subsystemTerrain, position, cellValue, 0.75f));
                        break;
                    }
                    }
                }
                componentMiner.DamageActiveTool(1);
                return(true);
            }
            return(false);
        }
示例#7
0
        public void SimulateExplosion(int x, int y, int z, float pressure, bool isIncendiary)
        {
            float num = MathUtils.Max(0.13f * MathUtils.Pow(pressure, 0.5f), 1f);

            m_subsystemTerrain.ChangeCell(x, y, z, Terrain.MakeBlockValue(0));
            SparseSpatialArray <bool> processed = new SparseSpatialArray <bool>(x, y, z, outside: true);
            List <ProcessPoint>       list      = new List <ProcessPoint>();
            List <ProcessPoint>       list2     = new List <ProcessPoint>();
            List <ProcessPoint>       list3     = new List <ProcessPoint>();

            TryAddPoint(x, y, z, -1, pressure, isIncendiary, list, processed);
            int num2 = 0;
            int num3 = 0;

            while (list.Count > 0 || list2.Count > 0)
            {
                num2 += list.Count;
                num3++;
                float num4 = 5f * (float)MathUtils.Max(num3 - 7, 0);
                float num5 = pressure / (MathUtils.Pow(num2, 0.66f) + num4);
                if (num5 >= num)
                {
                    foreach (ProcessPoint item in list)
                    {
                        float num6 = m_pressureByPoint.Get(item.X, item.Y, item.Z);
                        float num7 = num5 + num6;
                        m_pressureByPoint.Set(item.X, item.Y, item.Z, num7);
                        if (item.Axis == 0)
                        {
                            TryAddPoint(item.X - 1, item.Y, item.Z, 0, num7, isIncendiary, list3, processed);
                            TryAddPoint(item.X + 1, item.Y, item.Z, 0, num7, isIncendiary, list3, processed);
                            TryAddPoint(item.X, item.Y - 1, item.Z, -1, num7, isIncendiary, list2, processed);
                            TryAddPoint(item.X, item.Y + 1, item.Z, -1, num7, isIncendiary, list2, processed);
                            TryAddPoint(item.X, item.Y, item.Z - 1, -1, num7, isIncendiary, list2, processed);
                            TryAddPoint(item.X, item.Y, item.Z + 1, -1, num7, isIncendiary, list2, processed);
                        }
                        else if (item.Axis == 1)
                        {
                            TryAddPoint(item.X - 1, item.Y, item.Z, -1, num7, isIncendiary, list2, processed);
                            TryAddPoint(item.X + 1, item.Y, item.Z, -1, num7, isIncendiary, list2, processed);
                            TryAddPoint(item.X, item.Y - 1, item.Z, 1, num7, isIncendiary, list3, processed);
                            TryAddPoint(item.X, item.Y + 1, item.Z, 1, num7, isIncendiary, list3, processed);
                            TryAddPoint(item.X, item.Y, item.Z - 1, -1, num7, isIncendiary, list2, processed);
                            TryAddPoint(item.X, item.Y, item.Z + 1, -1, num7, isIncendiary, list2, processed);
                        }
                        else if (item.Axis == 2)
                        {
                            TryAddPoint(item.X - 1, item.Y, item.Z, -1, num7, isIncendiary, list2, processed);
                            TryAddPoint(item.X + 1, item.Y, item.Z, -1, num7, isIncendiary, list2, processed);
                            TryAddPoint(item.X, item.Y - 1, item.Z, -1, num7, isIncendiary, list2, processed);
                            TryAddPoint(item.X, item.Y + 1, item.Z, -1, num7, isIncendiary, list2, processed);
                            TryAddPoint(item.X, item.Y, item.Z - 1, 2, num7, isIncendiary, list3, processed);
                            TryAddPoint(item.X, item.Y, item.Z + 1, 2, num7, isIncendiary, list3, processed);
                        }
                        else
                        {
                            TryAddPoint(item.X - 1, item.Y, item.Z, 0, num7, isIncendiary, list3, processed);
                            TryAddPoint(item.X + 1, item.Y, item.Z, 0, num7, isIncendiary, list3, processed);
                            TryAddPoint(item.X, item.Y - 1, item.Z, 1, num7, isIncendiary, list3, processed);
                            TryAddPoint(item.X, item.Y + 1, item.Z, 1, num7, isIncendiary, list3, processed);
                            TryAddPoint(item.X, item.Y, item.Z - 1, 2, num7, isIncendiary, list3, processed);
                            TryAddPoint(item.X, item.Y, item.Z + 1, 2, num7, isIncendiary, list3, processed);
                        }
                    }
                }
                List <ProcessPoint> list4 = list;
                list4.Clear();
                list  = list2;
                list2 = list3;
                list3 = list4;
            }
        }
示例#8
0
        public bool MovePiston(Point3 position, int length)
        {
            Terrain    terrain      = m_subsystemTerrain.Terrain;
            int        data         = Terrain.ExtractData(terrain.GetCellValue(position.X, position.Y, position.Z));
            int        face         = PistonBlock.GetFace(data);
            PistonMode mode         = PistonBlock.GetMode(data);
            int        maxExtension = PistonBlock.GetMaxExtension(data);
            int        pullCount    = PistonBlock.GetPullCount(data);
            int        speed        = PistonBlock.GetSpeed(data);
            Point3     point        = CellFace.FaceToPoint3(face);

            length = MathUtils.Clamp(length, 0, maxExtension + 1);
            int num = 0;

            m_movingBlocks.Clear();
            Point3      offset = point;
            MovingBlock item;

            while (m_movingBlocks.Count < 8)
            {
                int cellValue = terrain.GetCellValue(position.X + offset.X, position.Y + offset.Y, position.Z + offset.Z);
                int num2      = Terrain.ExtractContents(cellValue);
                int face2     = PistonHeadBlock.GetFace(Terrain.ExtractData(cellValue));
                if (num2 != 238 || face2 != face)
                {
                    break;
                }
                DynamicArray <MovingBlock> movingBlocks = m_movingBlocks;
                item = new MovingBlock
                {
                    Offset = offset,
                    Value  = cellValue
                };
                movingBlocks.Add(item);
                offset += point;
                num++;
            }
            if (length > num)
            {
                DynamicArray <MovingBlock> movingBlocks2 = m_movingBlocks;
                item = new MovingBlock
                {
                    Offset = Point3.Zero,
                    Value  = Terrain.MakeBlockValue(238, 0, PistonHeadBlock.SetFace(PistonHeadBlock.SetMode(PistonHeadBlock.SetIsShaft(0, num > 0), mode), face))
                };
                movingBlocks2.Add(item);
                int num3 = 0;
                while (num3 < 8)
                {
                    int cellValue2 = terrain.GetCellValue(position.X + offset.X, position.Y + offset.Y, position.Z + offset.Z);
                    if (!IsBlockMovable(cellValue2, face, position.Y + offset.Y, out bool isEnd))
                    {
                        break;
                    }
                    DynamicArray <MovingBlock> movingBlocks3 = m_movingBlocks;
                    item = new MovingBlock
                    {
                        Offset = offset,
                        Value  = cellValue2
                    };
                    movingBlocks3.Add(item);
                    num3++;
                    offset += point;
                    if (isEnd)
                    {
                        break;
                    }
                }
                if (!IsBlockBlocking(terrain.GetCellValue(position.X + offset.X, position.Y + offset.Y, position.Z + offset.Z)))
                {
                    GetSpeedAndSmoothness(speed, out float speed2, out Vector2 smoothness);
                    Point3 p = position + (length - num) * point;
                    if (m_subsystemMovingBlocks.AddMovingBlockSet(new Vector3(position) + 0.01f * new Vector3(point), new Vector3(p), speed2, 0f, 0f, smoothness, m_movingBlocks, "Piston", position, testCollision: true) != null)
                    {
                        m_allowPistonHeadRemove = true;
                        try
                        {
                            foreach (MovingBlock movingBlock in m_movingBlocks)
                            {
                                if (movingBlock.Offset != Point3.Zero)
                                {
                                    m_subsystemTerrain.ChangeCell(position.X + movingBlock.Offset.X, position.Y + movingBlock.Offset.Y, position.Z + movingBlock.Offset.Z, 0);
                                }
                            }
                        }
                        finally
                        {
                            m_allowPistonHeadRemove = false;
                        }
                        m_subsystemTerrain.ChangeCell(position.X, position.Y, position.Z, Terrain.MakeBlockValue(237, 0, PistonBlock.SetIsExtended(data, isExtended: true)));
                        m_subsystemAudio.PlaySound("Audio/Piston", 1f, 0f, new Vector3(position), 2f, autoDelay: true);
                    }
                }
                return(false);
            }
            if (length < num)
            {
                if (mode != 0)
                {
                    int num4 = 0;
                    for (int i = 0; i < pullCount + 1; i++)
                    {
                        int cellValue3 = terrain.GetCellValue(position.X + offset.X, position.Y + offset.Y, position.Z + offset.Z);
                        if (!IsBlockMovable(cellValue3, face, position.Y + offset.Y, out bool isEnd2))
                        {
                            break;
                        }
                        DynamicArray <MovingBlock> movingBlocks4 = m_movingBlocks;
                        item = new MovingBlock
                        {
                            Offset = offset,
                            Value  = cellValue3
                        };
                        movingBlocks4.Add(item);
                        offset += point;
                        num4++;
                        if (isEnd2)
                        {
                            break;
                        }
                    }
                    if (mode == PistonMode.StrictPulling && num4 < pullCount + 1)
                    {
                        return(false);
                    }
                }
                GetSpeedAndSmoothness(speed, out float speed3, out Vector2 smoothness2);
                float   s = (length == 0) ? 0.01f : 0f;
                Vector3 targetPosition = new Vector3(position) + (length - num) * new Vector3(point) + s * new Vector3(point);
                if (m_subsystemMovingBlocks.AddMovingBlockSet(new Vector3(position), targetPosition, speed3, 0f, 0f, smoothness2, m_movingBlocks, "Piston", position, testCollision: true) != null)
                {
                    m_allowPistonHeadRemove = true;
                    try
                    {
                        foreach (MovingBlock movingBlock2 in m_movingBlocks)
                        {
                            m_subsystemTerrain.ChangeCell(position.X + movingBlock2.Offset.X, position.Y + movingBlock2.Offset.Y, position.Z + movingBlock2.Offset.Z, 0);
                        }
                    }
                    finally
                    {
                        m_allowPistonHeadRemove = false;
                    }
                    m_subsystemAudio.PlaySound("Audio/Piston", 1f, 0f, new Vector3(position), 2f, autoDelay: true);
                }
                return(false);
            }
            return(true);
        }
        public void Update(float dt)
        {
            Point3 coordinates = m_componentBlockEntity.Coordinates;

            if (m_heatLevel > 0f)
            {
                m_fireTimeRemaining = MathUtils.Max(0f, m_fireTimeRemaining - dt);
                if (m_fireTimeRemaining == 0f)
                {
                    m_heatLevel = 0f;
                }
            }
            if (m_updateSmeltingRecipe)
            {
                m_updateSmeltingRecipe = false;
                float heatLevel = 0f;
                if (m_heatLevel > 0f)
                {
                    heatLevel = m_heatLevel;
                }
                else
                {
                    Slot slot = m_slots[FuelSlotIndex];
                    if (slot.Count > 0)
                    {
                        int num = Terrain.ExtractContents(slot.Value);
                        heatLevel = BlocksManager.Blocks[num].FuelHeatLevel;
                    }
                }
                CraftingRecipe craftingRecipe = FindSmeltingRecipe(heatLevel);
                if (craftingRecipe != m_smeltingRecipe)
                {
                    m_smeltingRecipe   = ((craftingRecipe != null && craftingRecipe.ResultValue != 0) ? craftingRecipe : null);
                    m_smeltingProgress = 0f;
                }
            }
            if (m_smeltingRecipe == null)
            {
                m_heatLevel         = 0f;
                m_fireTimeRemaining = 0f;
            }
            if (m_smeltingRecipe != null && m_fireTimeRemaining <= 0f)
            {
                Slot slot2 = m_slots[FuelSlotIndex];
                if (slot2.Count > 0)
                {
                    int   num2  = Terrain.ExtractContents(slot2.Value);
                    Block block = BlocksManager.Blocks[num2];
                    if (block.GetExplosionPressure(slot2.Value) > 0f)
                    {
                        slot2.Count = 0;
                        m_subsystemExplosions.TryExplodeBlock(coordinates.X, coordinates.Y, coordinates.Z, slot2.Value);
                    }
                    else if (block.FuelHeatLevel > 0f)
                    {
                        slot2.Count--;
                        m_fireTimeRemaining = block.FuelFireDuration;
                        m_heatLevel         = block.FuelHeatLevel;
                    }
                }
            }
            if (m_fireTimeRemaining <= 0f)
            {
                m_smeltingRecipe   = null;
                m_smeltingProgress = 0f;
            }
            if (m_smeltingRecipe != null)
            {
                m_smeltingProgress = MathUtils.Min(m_smeltingProgress + 0.15f * dt, 1f);
                if (m_smeltingProgress >= 1f)
                {
                    for (int i = 0; i < m_furnaceSize; i++)
                    {
                        if (m_slots[i].Count > 0)
                        {
                            m_slots[i].Count--;
                        }
                    }
                    m_slots[ResultSlotIndex].Value  = m_smeltingRecipe.ResultValue;
                    m_slots[ResultSlotIndex].Count += m_smeltingRecipe.ResultCount;
                    if (m_smeltingRecipe.RemainsValue != 0 && m_smeltingRecipe.RemainsCount > 0)
                    {
                        m_slots[RemainsSlotIndex].Value  = m_smeltingRecipe.RemainsValue;
                        m_slots[RemainsSlotIndex].Count += m_smeltingRecipe.RemainsCount;
                    }
                    m_smeltingRecipe       = null;
                    m_smeltingProgress     = 0f;
                    m_updateSmeltingRecipe = true;
                }
            }
            TerrainChunk chunkAtCell = m_subsystemTerrain.Terrain.GetChunkAtCell(coordinates.X, coordinates.Z);

            if (chunkAtCell != null && chunkAtCell.State == TerrainChunkState.Valid)
            {
                int cellValue = m_subsystemTerrain.Terrain.GetCellValue(coordinates.X, coordinates.Y, coordinates.Z);
                m_subsystemTerrain.ChangeCell(coordinates.X, coordinates.Y, coordinates.Z, Terrain.ReplaceContents(cellValue, (m_heatLevel > 0f) ? 65 : 64));
            }
        }
示例#10
0
        void UpdateCornerState(int value, int x, int y, int z, int step)
        {
            var resultType      = default(int?);
            var neighbors       = new bool[4];
            var raisedNeighbors = new bool[4];

            for (int i = 0; i < 4; i++)
            {
                for (int k = 0; k < 3; k++)
                {
                    var p   = m_pointsToUpdate[i, k];
                    int val = SubsystemTerrain.Terrain.GetCellValueFastChunkExists(x + p.X, y + p.Y, z + p.Z);
                    if (Terrain.ExtractContents(val) == RailBlock.Index)
                    {
                        if (k == 1)
                        {
                            raisedNeighbors[i] = RailBlock.CanConnectTo(RailBlock.GetRailType(Terrain.ExtractData(val)), i);
                        }
                        else
                        {
                            neighbors[i] = RailBlock.CanConnectTo(RailBlock.GetRailType(Terrain.ExtractData(val)), i);
                        }
                        if (step > 0)
                        {
                            UpdateCornerState(val, x + p.X, y + p.Y, z + p.Z, step - 1);
                        }
                        break;
                    }
                }
            }

            if (neighbors[0] && neighbors[3])
            {
                resultType = 1;
            }
            else if (neighbors[0] && neighbors[1])
            {
                resultType = 2;
            }
            else if (neighbors[1] && neighbors[2])
            {
                resultType = 3;
            }
            else if (neighbors[2] && neighbors[3])
            {
                resultType = 0;
            }
            else if (raisedNeighbors[2])
            {
                resultType = 6;
            }
            else if (raisedNeighbors[0])
            {
                resultType = 8;
            }
            else if (raisedNeighbors[3])
            {
                resultType = 7;
            }
            else if (raisedNeighbors[1])
            {
                resultType = 9;
            }
            else if (neighbors[0] || neighbors[2])
            {
                resultType = 4;
            }
            else if (neighbors[1] || neighbors[3])
            {
                resultType = 5;
            }

            if (resultType.HasValue)
            {
                SubsystemTerrain.ChangeCell(x, y, z, Terrain.MakeBlockValue(RailBlock.Index, 0, RailBlock.SetRailType(0, resultType.Value)));
            }
        }
        void InitCommands()
        {
            commands["msg"] = new CommandDefination
            {
                Usage        = "msg @a/r/p/e <string> [bool=true] [bool=true]",
                AutoComplete = (obj) => obj.Enum(enumCreatureType).String().Bool().Bool(),
                Operation    = (obj) =>
                {
                    string type = obj.NextString();
                    string msg  = obj.NextString();
                    bool   b1   = obj.NextBool(true);
                    bool   b2   = obj.NextBool(true);
                    FindPlayer(type, obj, (a) =>
                    {
                        a.ComponentGui.DisplaySmallMessage(msg, b1, b2);
                    });
                }
            };

            commands["msgl"] = new CommandDefination
            {
                Usage        = "msgl @a/r/p/e <string> <string> <string> [float=5] [float=0]",
                AutoComplete = (obj) => obj.Enum(enumCreatureType).String().String().Float().Float(),
                Operation    = (obj) =>
                {
                    string type = obj.NextString();
                    string m1   = obj.NextString();
                    string m2   = obj.NextString();
                    float  f1   = obj.NextFloat(5);
                    float  f2   = obj.NextFloat(0);
                    FindPlayer(type, obj, (a) =>
                    {
                        a.ComponentGui.DisplayLargeMessage(m1, m2, f1, f2);
                    });
                }
            };

            commands["kill"] = new CommandDefination
            {
                Usage        = "kill @a/r/p/e [string=magic]",
                AutoComplete = (obj) => obj.Enum(enumCreatureType).String(),
                Operation    = (obj) =>
                {
                    string type   = obj.NextString();
                    string reason = obj.NextString("magic");
                    EnumCreatures(type, obj, (c) =>
                    {
                        c.ComponentHealth.Injure(1, null, true, reason);
                    });
                }
            };

            commands["health"] = new CommandDefination
            {
                Usage        = "health heal/injure [float=1] [string=magic]",
                AutoComplete = (obj) => obj.Enum(new string[] { "heal", "injure" }).Float().String(),
                Operation    = (obj) =>
                {
                    string type = obj.NextString();
                    switch (type)
                    {
                    case "heal":
                        float amount1 = obj.NextFloat(1);
                        obj.Creature.ComponentHealth.Heal(amount1);
                        break;

                    case "injure":
                        float  amount = obj.NextFloat(1);
                        string reason = obj.NextString("magic");
                        obj.Creature.ComponentHealth.Injure(amount, null, true, reason);
                        break;

                    default:
                        throw new Exception("usage: health heal/injure [float=1] [string=magic]");
                    }
                }
            };

            commands["strike"] = new CommandDefination
            {
                Usage        = "strike <vector3>",
                AutoComplete = (obj) => obj.Vector3(),
                Operation    = (obj) =>
                {
                    subsystemSky.MakeLightningStrike(obj.NextVector3());
                }
            };

            commands["setblock"] = new CommandDefination
            {
                Usage        = "setblock <point3> <int>",
                AutoComplete = (obj) => obj.Point3().Int(),
                Operation    = (s) =>
                {
                    var p = s.NextPoint3();
                    subsystemTerrain.ChangeCell(p.X, p.Y, p.Z, s.NextInt());
                }
            };

            commands["place"] = new CommandDefination
            {
                Usage        = "place <point3> <int> [bool=false] [bool=false]",
                AutoComplete = (obj) => obj.Point3().Int().Bool().Bool(),
                Operation    = (obj) =>
                {
                    var p = obj.NextPoint3();
                    subsystemTerrain.DestroyCell(2, p.X, p.Y, p.Z, obj.NextInt(), obj.NextBool(false), obj.NextBool(false));
                }
            };

            commands["fill"] = new CommandDefination
            {
                Usage        = "fill <point3> <point3>",
                AutoComplete = (obj) => obj.Point3().Point3().Int(),
                Operation    = (obj) =>
                {
                    var p1     = obj.NextPoint3();
                    var p2     = obj.NextPoint3();
                    var startx = Math.Min(p1.X, p2.X);
                    var endx   = Math.Max(p1.X, p2.X);
                    var starty = Math.Min(p1.Y, p2.Y);
                    var endy   = Math.Max(p1.Y, p2.Y);
                    var startz = Math.Min(p1.Z, p2.Z);
                    var endz   = Math.Max(p1.Z, p2.Z);

                    var val = obj.NextInt();

                    for (int x = startx; x <= endx; x++)
                    {
                        for (int y = starty; y <= endy; y++)
                        {
                            for (int z = startz; z <= endz; z++)
                            {
                                subsystemTerrain.Terrain.SetCellValueFast(x, y, z, val);
                            }
                        }
                    }

                    var startChunk = Terrain.ToChunk(startx, startz);
                    var endChunk   = Terrain.ToChunk(endx, endz);

                    for (int x = startChunk.X; x <= endChunk.X; x++)
                    {
                        for (int y = startChunk.Y; y <= endChunk.Y; y++)
                        {
                            var c = subsystemTerrain.Terrain.GetChunkAtCoords(x, y);
                            if (c != null)
                            {
                                subsystemTerrain.TerrainUpdater.DowngradeChunkNeighborhoodState(c.Coords, 1, TerrainChunkState.InvalidLight, false);
                            }
                        }
                    }
                }
            };

            commands["time"] = new CommandDefination
            {
                Usage        = "time add/set <float>",
                AutoComplete = (obj) => obj.Enum(new string[] { "add", "set" }).Float(),
                Operation    = (obj) =>
                {
                    switch (obj.NextString())
                    {
                    case "add":
                        subsystemTime.TimeOfDayOffset += obj.NextFloat();
                        break;

                    case "set":
                        subsystemTime.TimeOfDayOffset = obj.NextFloat();
                        break;

                    default:
                        throw new Exception("usage: time add/set <float>");
                    }
                }
            };

            commands["execute"] = new CommandDefination
            {
                Usage        = "execute @a/r/p/e <another command>",
                AutoComplete = (obj) =>
                {
                    obj.Enum(enumCreatureType);
                    AutoCompleteCommand(obj.CommandStream.GetAllLeft(), obj.Reciver);
                },
                Operation = (obj) =>
                {
                    var type    = obj.NextString();
                    var command = obj.GetAllLeft();

                    EnumCreatures(type, obj, (a) =>
                    {
                        RunCommand(a, command);
                    });
                }
            };

            commands["setdata"] = new CommandDefination
            {
                Usage        = "setdata <creature data> <data type>",
                AutoComplete = (obj) =>
                {
                    obj.Enum(creatureDatas.Keys);
                    string component = obj.CommandStream.Last;
                    int    i         = creatureDatas[component];
                    switch (i)
                    {
                    case 0:
                        obj.Any(typeof(ComponentLocomotion).GetProperty(component).PropertyType);
                        break;

                    case 1:
                        obj.Any(typeof(ComponentHealth).GetProperty(component).PropertyType);
                        break;

                    case 2:
                        obj.Any(typeof(ComponentBody).GetProperty(component).PropertyType);
                        break;
                    }
                },
                Operation = (s) =>
                {
                    while (s.HasNext)
                    {
                        var          component = s.NextString();
                        PropertyInfo p;
                        if (creatureDatas.TryGetValue(component, out int i))
                        {
                            switch (i)
                            {
                            case 0:
                                p = typeof(ComponentLocomotion).GetProperty(component);
                                p.SetValue(s.Creature.ComponentLocomotion, s.Next(p.PropertyType), null);
                                break;

                            case 1:
                                p = typeof(ComponentHealth).GetProperty(component);
                                p.SetValue(s.Creature.ComponentHealth, s.Next(p.PropertyType), null);
                                break;

                            case 2:
                                p = typeof(ComponentBody).GetProperty(component);
                                p.SetValue(s.Creature.ComponentBody, s.Next(p.PropertyType), null);
                                break;
                            }
                        }
                        else
                        {
                            throw new Exception(component + " is not a creature data");
                        }
                    }
                }
            };

            commands["gameinfo"] = new CommandDefination
            {
                Usage        = "gameinfo <info name> <info value>",
                AutoComplete = (obj) =>
                {
                    Type settings = typeof(WorldSettings);
                    obj.Enum(settings.GetFields().Select(f => f.Name));
                    obj.Any(settings.GetField(obj.CommandStream.Last).FieldType);
                },
                Operation = (s) =>
                {
                    var setting = s.NextString();
                    var val     = s.NextString();
                    var f       = typeof(WorldSettings).GetField(setting);
                    if (f != null)
                    {
                        f.SetValue(GameManager.WorldInfo.WorldSettings, ChangeType(val, f.FieldType));
                    }
                }
            };

            commands["summon"] = new CommandDefination
            {
                Usage        = "summon <animal name> <vector3> [float=0]",
                AutoComplete = (obj) => obj.String().Vector3().Float(),
                Operation    = (s) =>
                {
                    var    name     = s.NextString();
                    var    position = s.NextVector3();
                    var    rotation = s.NextFloat(0);
                    Entity entity   = DatabaseManager.CreateEntity(Project, creatureTemplateNames[name], true);
                    entity.FindComponent <ComponentBody>(true).Position       = position;
                    entity.FindComponent <ComponentBody>(true).Rotation       = Quaternion.CreateFromAxisAngle(Vector3.UnitY, rotation);
                    entity.FindComponent <ComponentSpawn>(true).SpawnDuration = 0.25f;
                    Project.AddEntity(entity);
                }
            };

            commands["tp"] = new CommandDefination
            {
                Usage        = "tp <vector3>",
                AutoComplete = (obj) => obj.Vector3(),
                Operation    = s => s.Creature.ComponentBody.Position = s.NextVector3()
            };

            commands["additem"] = new CommandDefination
            {
                Usage        = "additem <vector3> <int> [int=1] [vector=0,0,0]",
                AutoComplete = (obj) => obj.Vector3().Int().Int().Vector3(),
                Operation    = s =>
                {
                    var     position = s.NextVector3();
                    var     val      = s.NextInt();
                    var     count    = s.NextInt(1);
                    Vector3?speed    = null;
                    if (s.HasNext)
                    {
                        speed = s.NextVector3();
                    }
                    Project.FindSubsystem <SubsystemPickables>(true).AddPickable(s.NextInt(), s.NextInt(1), position, speed, null);
                }
            };

            commands["give"] = new CommandDefination
            {
                Usage        = "give @a/r/p/e <int> [int=1]",
                AutoComplete = (obj) => obj.Enum(enumCreatureType).Int().Int(),
                Operation    = s =>
                {
                    var enumType = s.NextString();
                    var val      = s.NextInt();
                    var count    = s.NextInt(1);

                    FindPlayer(enumType, s, (p) => ComponentInventoryBase.AcquireItems(p.ComponentMiner.Inventory, val, count));
                }
            };

            foreach (string name in commands.Keys)
            {
                commandUsage[commands[name].Usage] = name;
            }
        }

        void LoadBlockIds()
        {
            foreach (Block b in BlocksManager.Blocks)
            {
                foreach (int id in b.GetCreativeValues())
                {
                    var name = b.GetDisplayName(subsystemTerrain, id).Replace(' ', '_').ToLower();
                    blockIds[name] = id;
                }
                blockIds[b.DefaultDisplayName.Replace(' ', '_').ToLower()] = b.BlockIndex;
            }
        }

        void FindPlayer(string type, CommandStream s, Action <ComponentPlayer> a)
        {
            if (type[0] == '@')
            {
                EnumCreatures(type, s, c =>
                {
                    if (c is ComponentPlayer)
                    {
                        a(c as ComponentPlayer);
                    }
                });
            }
            else
            {
                FindPlayerByName(type, a);
            }
        }

        void FindPlayerByName(string name, Action <ComponentPlayer> a)
        {
            foreach (ComponentPlayer p in subsystemPlayers.ComponentPlayers)
            {
                if (p.PlayerData.Name == name)
                {
                    a(p);
                }
                else
                {
                    throw new WrongArgTypeException(name, "player");
                }
            }
        }

        void LoadCreatureTemplateNames()
        {
            var paramterType = DatabaseManager.GameDatabase.ParameterType;
            var entities     = DatabaseManager.GameDatabase.Database.Root.GetExplicitNestingChildren(paramterType, false);
            var displayName  = new Guid("715ff548-ef2b-430e-8e6b-51b934e5da1d");

            foreach (TemplatesDatabase.DatabaseObject o in entities)
            {
                if (o.EffectiveInheritanceRoot.Guid == displayName && o.Value.ToString() != string.Empty)
                {
                    creatureTemplateNames[o.NestingParent.NestingParent.Name.ToLower()] = o.Value.ToString();
                    //Log.Information("{0}, {1}", o.NestingParent.NestingParent.Name, o.Value);
                }
            }
        }

        void LoadCreatureDatas()
        {
            foreach (PropertyInfo p in typeof(ComponentLocomotion).GetRuntimeProperties())
            {
                if (CommandStream.IsTypeSupported(p.PropertyType))
                {
                    creatureDatas[p.Name] = 0;
                }
            }
            foreach (PropertyInfo p in typeof(ComponentHealth).GetRuntimeProperties())
            {
                if (CommandStream.IsTypeSupported(p.PropertyType))
                {
                    creatureDatas[p.Name] = 1;
                }
            }
            foreach (PropertyInfo p in typeof(ComponentBody).GetRuntimeProperties())
            {
                if (CommandStream.IsTypeSupported(p.PropertyType))
                {
                    creatureDatas[p.Name] = 2;
                }
            }
        }

        void EnumCreatures(string type, CommandStream s, Action <ComponentCreature> a)
        {
            var data = new EnumData(type, subsystemCreature.Creatures.Count, s.ExePosition);

            if (data.name == "player")
            {
                data.name = string.Empty;
                SearchCreature(data, SortCreatures(data, subsystemPlayers.ComponentPlayers), a);
            }
            else
            {
                SearchCreature(data, SortCreatures(data, subsystemCreature.Creatures), a);
            }
        }

        List <ComponentCreature> SortCreatures <T>(EnumData data, IEnumerable <T> collection) where T : ComponentCreature
        {
            var l = new List <ComponentCreature>();

            if (data.mode1 == SearchingMode1.Regular)
            {
                foreach (ComponentCreature c in collection)
                {
                    if (CheckCreatureWithData(data, c))
                    {
                        l.Add(c);
                    }
                }
            }
            else if (data.mode1 == SearchingMode1.Nearest)
            {
                var v    = new Vector3(data.x, data.y, data.z);
                var dict = new Dictionary <float, ComponentCreature>();
                foreach (ComponentCreature c in collection)
                {
                    if (CheckCreatureWithData(data, c))
                    {
                        dict.Add(Vector3.DistanceSquared(v, c.ComponentBody.Position), c);
                    }
                }
                var l2 = new List <float>();
                foreach (float i in dict.Keys)
                {
                    l2.Add(i);
                }
                l2.Sort(delegate(float i1, float i2)
                {
                    if (i1 > i2)
                    {
                        return(1);
                    }
                    return(-1);
                });

                foreach (float i in l2)
                {
                    l.Add(dict[i]);
                }
            }
            else
            {
                foreach (ComponentCreature c in collection)
                {
                    if (CheckCreatureWithData(data, c))
                    {
                        l.Add(c);
                    }
                }
                var r     = new Random();
                var count = l.Count;

                int n = l.Count;
                while (n > 1)
                {
                    n--;
                    int k     = r.UniformInt(0, n);
                    var value = l[k];
                    l[k] = l[n];
                    l[n] = value;
                }
            }

            return(l);
        }

        void SearchCreature(EnumData data, List <ComponentCreature> sorted, Action <ComponentCreature> a)
        {
            for (int i = 0; i < data.count; i++)
            {
                if (i >= sorted.Count)
                {
                    return;
                }
                a.Invoke(sorted[i]);
            }
        }

        bool CheckCreatureWithData(EnumData data, ComponentCreature c)
        {
            if (data.name != string.Empty)
            {
                string dataname;
                if (data.name[0] == '!')
                {
                    Log.Information(c.DisplayName);
                    if (creatureTemplateNames.TryGetValue(data.name.Substring(1), out dataname))
                    {
                        if (dataname == c.DisplayName)
                        {
                            return(false);
                        }
                    }
                    else
                    {
                        return(false);
                    }
                }
                else
                {
                    if (creatureTemplateNames.TryGetValue(data.name, out dataname))
                    {
                        if (dataname != c.DisplayName)
                        {
                            return(false);
                        }
                    }
                    else
                    {
                        return(false);
                    }
                }
            }
            switch (data.SearchingMode)
            {
            case SearchingMode.Radius:
                if (data.r > 0)
                {
                    if (Vector3.DistanceSquared(new Vector3(data.x, data.y, data.z), c.ComponentBody.Position) >= data.r2)
                    {
                        return(false);
                    }
                }
                else
                {
                    if (Vector3.DistanceSquared(new Vector3(data.x, data.y, data.z), c.ComponentBody.Position) <= data.r2)
                    {
                        return(false);
                    }
                }
                break;

            case SearchingMode.Volume:
                var p = c.ComponentBody.Position;
                var x = p.X - data.x;
                var y = p.Y - data.y;
                var z = p.Z - data.z;
                if (x < 0 && x > data.dx && y < 0 && y > data.dy && z < 0 && z > data.dz)
                {
                    return(false);
                }
                break;
            }
            return(true);
        }