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);
        }
        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);
        }
예제 #3
0
        public void DestroyCell(int toolLevel, int x, int y, int z, int newValue, bool noDrop, bool noParticleSystem)
        {
            int   cellValue = Terrain.GetCellValue(x, y, z);
            int   num       = Terrain.ExtractContents(cellValue);
            Block block     = BlocksManager.Blocks[num];

            if (num != 0)
            {
                bool showDebris = true;
                if (!noDrop)
                {
                    m_dropValues.Clear();
                    block.GetDropValues(this, cellValue, newValue, toolLevel, m_dropValues, out showDebris);
                    for (int i = 0; i < m_dropValues.Count; i++)
                    {
                        BlockDropValue dropValue = m_dropValues[i];
                        if (dropValue.Count > 0)
                        {
                            SubsystemBlockBehavior[] blockBehaviors = m_subsystemBlockBehaviors.GetBlockBehaviors(Terrain.ExtractContents(dropValue.Value));
                            for (int j = 0; j < blockBehaviors.Length; j++)
                            {
                                blockBehaviors[j].OnItemHarvested(x, y, z, cellValue, ref dropValue, ref newValue);
                            }
                            if (dropValue.Count > 0 && Terrain.ExtractContents(dropValue.Value) != 0)
                            {
                                Vector3 position = new Vector3(x, y, z) + new Vector3(0.5f);
                                m_subsystemPickables.AddPickable(dropValue.Value, dropValue.Count, position, null, null);
                            }
                        }
                    }
                }
                if (showDebris && !noParticleSystem && m_subsystemViews.CalculateDistanceFromNearestView(new Vector3(x, y, z)) < 16f)
                {
                    m_subsystemParticles.AddParticleSystem(block.CreateDebrisParticleSystem(this, new Vector3((float)x + 0.5f, (float)y + 0.5f, (float)z + 0.5f), cellValue, 1f));
                }
            }
            ChangeCell(x, y, z, newValue);
        }
예제 #4
0
        public bool Dig(TerrainRaycastResult raycastResult)
        {
            if (Dig1 != null)
            {
                return(Dig1(raycastResult));
            }

            bool result = false;

            m_lastDigFrameIndex = Time.FrameIndex;
            CellFace cellFace         = raycastResult.CellFace;
            int      cellValue        = m_subsystemTerrain.Terrain.GetCellValue(cellFace.X, cellFace.Y, cellFace.Z);
            int      num              = Terrain.ExtractContents(cellValue);
            Block    block            = BlocksManager.Blocks[num];
            int      activeBlockValue = ActiveBlockValue;
            int      num2             = Terrain.ExtractContents(activeBlockValue);
            Block    block2           = BlocksManager.Blocks[num2];

            if (!DigCellFace.HasValue || DigCellFace.Value.X != cellFace.X || DigCellFace.Value.Y != cellFace.Y || DigCellFace.Value.Z != cellFace.Z)
            {
                m_digStartTime = m_subsystemTime.GameTime;
                DigCellFace    = cellFace;
            }
            float num3 = CalculateDigTime(cellValue, num2);

            m_digProgress = ((num3 > 0f) ? MathUtils.Saturate((float)(m_subsystemTime.GameTime - m_digStartTime) / num3) : 1f);
            if (!CanUseTool(activeBlockValue))
            {
                m_digProgress = 0f;
                if (m_subsystemTime.PeriodicGameTimeEvent(5.0, m_digStartTime + 1.0))
                {
                    ComponentPlayer?.ComponentGui.DisplaySmallMessage(string.Format(LanguageControl.Get(fName, 1), block2.PlayerLevelRequired, block2.GetDisplayName(m_subsystemTerrain, activeBlockValue)), Color.White, blinking: true, playNotificationSound: true);
                }
            }
            bool flag = ComponentPlayer != null && !ComponentPlayer.ComponentInput.IsControlledByTouch && m_subsystemGameInfo.WorldSettings.GameMode == GameMode.Creative;

            if (flag || (m_lastPokingPhase <= 0.5f && PokingPhase > 0.5f))
            {
                if (m_digProgress >= 1f)
                {
                    DigCellFace = null;
                    if (flag)
                    {
                        Poke(forceRestart: true);
                    }
                    BlockPlacementData digValue = block.GetDigValue(m_subsystemTerrain, this, cellValue, activeBlockValue, raycastResult);
                    m_subsystemTerrain.DestroyCell(block2.ToolLevel, digValue.CellFace.X, digValue.CellFace.Y, digValue.CellFace.Z, digValue.Value, noDrop: false, noParticleSystem: false);
                    m_subsystemSoundMaterials.PlayImpactSound(cellValue, new Vector3(cellFace.X, cellFace.Y, cellFace.Z), 2f);
                    DamageActiveTool(1);
                    if (ComponentCreature.PlayerStats != null)
                    {
                        ComponentCreature.PlayerStats.BlocksDug++;
                    }
                    result = true;
                }
                else
                {
                    m_subsystemSoundMaterials.PlayImpactSound(cellValue, new Vector3(cellFace.X, cellFace.Y, cellFace.Z), 1f);
                    BlockDebrisParticleSystem particleSystem = block.CreateDebrisParticleSystem(m_subsystemTerrain, raycastResult.HitPoint(0.1f), cellValue, 0.35f);
                    base.Project.FindSubsystem <SubsystemParticles>(throwOnError: true).AddParticleSystem(particleSystem);
                }
            }
            return(result);
        }
        public void Update(float dt)
        {
            double totalElapsedGameTime = m_subsystemGameInfo.TotalElapsedGameTime;

            foreach (Projectile projectile in m_projectiles)
            {
                if (projectile.ToRemove)
                {
                    m_projectilesToRemove.Add(projectile);
                }
                else
                {
                    Block block = BlocksManager.Blocks[Terrain.ExtractContents(projectile.Value)];
                    if (totalElapsedGameTime - projectile.CreationTime > 40.0)
                    {
                        projectile.ToRemove = true;
                    }
                    TerrainChunk chunkAtCell = m_subsystemTerrain.Terrain.GetChunkAtCell(Terrain.ToCell(projectile.Position.X), Terrain.ToCell(projectile.Position.Z));
                    if (chunkAtCell == null || chunkAtCell.State <= TerrainChunkState.InvalidContents4)
                    {
                        projectile.NoChunk = true;
                        if (projectile.TrailParticleSystem != null)
                        {
                            projectile.TrailParticleSystem.IsStopped = true;
                        }
                    }
                    else
                    {
                        projectile.NoChunk = false;
                        Vector3              position             = projectile.Position;
                        Vector3              vector               = position + projectile.Velocity * dt;
                        Vector3              v                    = block.ProjectileTipOffset * Vector3.Normalize(projectile.Velocity);
                        BodyRaycastResult?   bodyRaycastResult    = m_subsystemBodies.Raycast(position + v, vector + v, 0.2f, (ComponentBody body, float distance) => true);
                        TerrainRaycastResult?terrainRaycastResult = m_subsystemTerrain.Raycast(position + v, vector + v, useInteractionBoxes: false, skipAirBlocks: true, (int value, float distance) => BlocksManager.Blocks[Terrain.ExtractContents(value)].IsCollidable);
                        bool flag = block.DisintegratesOnHit;
                        if (terrainRaycastResult.HasValue || bodyRaycastResult.HasValue)
                        {
                            CellFace?                cellFace       = terrainRaycastResult.HasValue ? new CellFace?(terrainRaycastResult.Value.CellFace) : null;
                            ComponentBody            componentBody  = bodyRaycastResult.HasValue ? bodyRaycastResult.Value.ComponentBody : null;
                            SubsystemBlockBehavior[] blockBehaviors = m_subsystemBlockBehaviors.GetBlockBehaviors(Terrain.ExtractContents(projectile.Value));
                            for (int i = 0; i < blockBehaviors.Length; i++)
                            {
                                flag |= blockBehaviors[i].OnHitAsProjectile(cellFace, componentBody, projectile);
                            }
                            projectile.ToRemove |= flag;
                        }
                        Vector3?vector2 = null;
                        if (bodyRaycastResult.HasValue && (!terrainRaycastResult.HasValue || bodyRaycastResult.Value.Distance < terrainRaycastResult.Value.Distance))
                        {
                            if (projectile.Velocity.Length() > 10f)
                            {
                                ComponentMiner.AttackBody(bodyRaycastResult.Value.ComponentBody, projectile.Owner, bodyRaycastResult.Value.HitPoint(), Vector3.Normalize(projectile.Velocity), block.GetProjectilePower(projectile.Value), isMeleeAttack: false);
                                if (projectile.Owner != null && projectile.Owner.PlayerStats != null)
                                {
                                    projectile.Owner.PlayerStats.RangedHits++;
                                }
                            }
                            if (projectile.IsIncendiary)
                            {
                                bodyRaycastResult.Value.ComponentBody.Entity.FindComponent <ComponentOnFire>()?.SetOnFire(projectile?.Owner, m_random.Float(6f, 8f));
                            }
                            vector = position;
                            projectile.Velocity        *= -0.05f;
                            projectile.Velocity        += m_random.Vector3(0.33f * projectile.Velocity.Length());
                            projectile.AngularVelocity *= -0.05f;
                        }
                        else if (terrainRaycastResult.HasValue)
                        {
                            CellFace cellFace2 = terrainRaycastResult.Value.CellFace;
                            int      cellValue = m_subsystemTerrain.Terrain.GetCellValue(cellFace2.X, cellFace2.Y, cellFace2.Z);
                            int      num       = Terrain.ExtractContents(cellValue);
                            Block    block2    = BlocksManager.Blocks[num];
                            float    num2      = projectile.Velocity.Length();
                            SubsystemBlockBehavior[] blockBehaviors2 = m_subsystemBlockBehaviors.GetBlockBehaviors(num);
                            for (int j = 0; j < blockBehaviors2.Length; j++)
                            {
                                blockBehaviors2[j].OnHitByProjectile(cellFace2, projectile);
                            }
                            if (num2 > 10f && m_random.Float(0f, 1f) > block2.ProjectileResilience)
                            {
                                m_subsystemTerrain.DestroyCell(0, cellFace2.X, cellFace2.Y, cellFace2.Z, 0, noDrop: true, noParticleSystem: false);
                                m_subsystemSoundMaterials.PlayImpactSound(cellValue, position, 1f);
                            }
                            if (projectile.IsIncendiary)
                            {
                                m_subsystemFireBlockBehavior.SetCellOnFire(terrainRaycastResult.Value.CellFace.X, terrainRaycastResult.Value.CellFace.Y, terrainRaycastResult.Value.CellFace.Z, 1f);
                                Vector3 vector3 = projectile.Position - 0.75f * Vector3.Normalize(projectile.Velocity);
                                for (int k = 0; k < 8; k++)
                                {
                                    Vector3 v2 = (k == 0) ? Vector3.Normalize(projectile.Velocity) : m_random.Vector3(1.5f);
                                    TerrainRaycastResult?terrainRaycastResult2 = m_subsystemTerrain.Raycast(vector3, vector3 + v2, useInteractionBoxes: false, skipAirBlocks: true, (int value, float distance) => true);
                                    if (terrainRaycastResult2.HasValue)
                                    {
                                        m_subsystemFireBlockBehavior.SetCellOnFire(terrainRaycastResult2.Value.CellFace.X, terrainRaycastResult2.Value.CellFace.Y, terrainRaycastResult2.Value.CellFace.Z, 1f);
                                    }
                                }
                            }
                            if (num2 > 5f)
                            {
                                m_subsystemSoundMaterials.PlayImpactSound(cellValue, position, 1f);
                            }
                            if (block.IsStickable && num2 > 10f && m_random.Bool(block2.ProjectileStickProbability))
                            {
                                Vector3 v3 = Vector3.Normalize(projectile.Velocity);
                                float   s  = MathUtils.Lerp(0.1f, 0.2f, MathUtils.Saturate((num2 - 15f) / 20f));
                                vector2 = position + terrainRaycastResult.Value.Distance * Vector3.Normalize(projectile.Velocity) + v3 * s;
                            }
                            else
                            {
                                Plane plane = cellFace2.CalculatePlane();
                                vector = position;
                                if (plane.Normal.X != 0f)
                                {
                                    projectile.Velocity *= new Vector3(-0.3f, 0.3f, 0.3f);
                                }
                                if (plane.Normal.Y != 0f)
                                {
                                    projectile.Velocity *= new Vector3(0.3f, -0.3f, 0.3f);
                                }
                                if (plane.Normal.Z != 0f)
                                {
                                    projectile.Velocity *= new Vector3(0.3f, 0.3f, -0.3f);
                                }
                                float num3 = projectile.Velocity.Length();
                                projectile.Velocity         = num3 * Vector3.Normalize(projectile.Velocity + m_random.Vector3(num3 / 6f, num3 / 3f));
                                projectile.AngularVelocity *= -0.3f;
                            }
                            MakeProjectileNoise(projectile);
                        }
                        if (terrainRaycastResult.HasValue || bodyRaycastResult.HasValue)
                        {
                            if (flag)
                            {
                                m_subsystemParticles.AddParticleSystem(block.CreateDebrisParticleSystem(m_subsystemTerrain, projectile.Position, projectile.Value, 1f));
                            }
                            else if (!projectile.ToRemove && (vector2.HasValue || projectile.Velocity.Length() < 1f))
                            {
                                if (projectile.ProjectileStoppedAction == ProjectileStoppedAction.TurnIntoPickable)
                                {
                                    int num4 = BlocksManager.DamageItem(projectile.Value, 1);
                                    if (num4 != 0)
                                    {
                                        if (vector2.HasValue)
                                        {
                                            CalculateVelocityAlignMatrix(block, vector2.Value, projectile.Velocity, out Matrix matrix);
                                            m_subsystemPickables.AddPickable(num4, 1, projectile.Position, Vector3.Zero, matrix);
                                        }
                                        else
                                        {
                                            m_subsystemPickables.AddPickable(num4, 1, position, Vector3.Zero, null);
                                        }
                                    }
                                    projectile.ToRemove = true;
                                }
                                else if (projectile.ProjectileStoppedAction == ProjectileStoppedAction.Disappear)
                                {
                                    projectile.ToRemove = true;
                                }
                            }
                        }
                        float num5 = projectile.IsInWater ? MathUtils.Pow(0.001f, dt) : MathUtils.Pow(block.ProjectileDamping, dt);
                        projectile.Velocity.Y      += -10f * dt;
                        projectile.Velocity        *= num5;
                        projectile.AngularVelocity *= num5;
                        projectile.Position         = vector;
                        projectile.Rotation        += projectile.AngularVelocity * dt;
                        if (projectile.TrailParticleSystem != null)
                        {
                            if (!m_subsystemParticles.ContainsParticleSystem((ParticleSystemBase)projectile.TrailParticleSystem))
                            {
                                m_subsystemParticles.AddParticleSystem((ParticleSystemBase)projectile.TrailParticleSystem);
                            }
                            Vector3 v4 = (projectile.TrailOffset != Vector3.Zero) ? Vector3.TransformNormal(projectile.TrailOffset, Matrix.CreateFromAxisAngle(Vector3.Normalize(projectile.Rotation), projectile.Rotation.Length())) : Vector3.Zero;
                            projectile.TrailParticleSystem.Position = projectile.Position + v4;
                            if (projectile.IsInWater)
                            {
                                projectile.TrailParticleSystem.IsStopped = true;
                            }
                        }
                        bool flag2 = IsWater(projectile.Position);
                        if (projectile.IsInWater != flag2)
                        {
                            if (flag2)
                            {
                                float num6 = new Vector2(projectile.Velocity.X + projectile.Velocity.Z).Length();
                                if (num6 > 6f && num6 > 4f * MathUtils.Abs(projectile.Velocity.Y))
                                {
                                    projectile.Velocity   *= 0.5f;
                                    projectile.Velocity.Y *= -1f;
                                    flag2 = false;
                                }
                                else
                                {
                                    projectile.Velocity *= 0.2f;
                                }
                                float?surfaceHeight = m_subsystemFluidBlockBehavior.GetSurfaceHeight(Terrain.ToCell(projectile.Position.X), Terrain.ToCell(projectile.Position.Y), Terrain.ToCell(projectile.Position.Z));
                                if (surfaceHeight.HasValue)
                                {
                                    m_subsystemParticles.AddParticleSystem(new WaterSplashParticleSystem(m_subsystemTerrain, new Vector3(projectile.Position.X, surfaceHeight.Value, projectile.Position.Z), large: false));
                                    m_subsystemAudio.PlayRandomSound("Audio/Splashes", 1f, m_random.Float(-0.2f, 0.2f), projectile.Position, 6f, autoDelay: true);
                                    MakeProjectileNoise(projectile);
                                }
                            }
                            projectile.IsInWater = flag2;
                        }
                        if (IsMagma(projectile.Position))
                        {
                            m_subsystemParticles.AddParticleSystem(new MagmaSplashParticleSystem(m_subsystemTerrain, projectile.Position, large: false));
                            m_subsystemAudio.PlayRandomSound("Audio/Sizzles", 1f, m_random.Float(-0.2f, 0.2f), projectile.Position, 3f, autoDelay: true);
                            projectile.ToRemove = true;
                            m_subsystemExplosions.TryExplodeBlock(Terrain.ToCell(projectile.Position.X), Terrain.ToCell(projectile.Position.Y), Terrain.ToCell(projectile.Position.Z), projectile.Value);
                        }
                        if (m_subsystemTime.PeriodicGameTimeEvent(1.0, (double)(projectile.GetHashCode() % 100) / 100.0) && (m_subsystemFireBlockBehavior.IsCellOnFire(Terrain.ToCell(projectile.Position.X), Terrain.ToCell(projectile.Position.Y + 0.1f), Terrain.ToCell(projectile.Position.Z)) || m_subsystemFireBlockBehavior.IsCellOnFire(Terrain.ToCell(projectile.Position.X), Terrain.ToCell(projectile.Position.Y + 0.1f) - 1, Terrain.ToCell(projectile.Position.Z))))
                        {
                            m_subsystemAudio.PlayRandomSound("Audio/Sizzles", 1f, m_random.Float(-0.2f, 0.2f), projectile.Position, 3f, autoDelay: true);
                            projectile.ToRemove = true;
                            m_subsystemExplosions.TryExplodeBlock(Terrain.ToCell(projectile.Position.X), Terrain.ToCell(projectile.Position.Y), Terrain.ToCell(projectile.Position.Z), projectile.Value);
                        }
                    }
                }
            }
            foreach (Projectile item in m_projectilesToRemove)
            {
                if (item.TrailParticleSystem != null)
                {
                    item.TrailParticleSystem.IsStopped = true;
                }
                m_projectiles.Remove(item);
                if (this.ProjectileRemoved != null)
                {
                    this.ProjectileRemoved(item);
                }
            }
            m_projectilesToRemove.Clear();
        }