public Vector3 FindSafePlace()
        {
            Vector3 vector       = 0.5f * (m_componentCreature.ComponentBody.BoundingBox.Min + m_componentCreature.ComponentBody.BoundingBox.Max);
            Vector3?herdPosition = (m_componentHerdBehavior != null) ? m_componentHerdBehavior.FindHerdCenter() : null;
            float   num          = float.NegativeInfinity;
            Vector3 result       = vector;

            for (int i = 0; i < 40; i++)
            {
                Vector2 vector2 = m_random.Vector2(1f, 1f);
                float   y       = 0.4f * m_random.Float(-1f, 1f);
                Vector3 v       = Vector3.Normalize(new Vector3(vector2.X, y, vector2.Y));
                Vector3 vector3 = vector + m_random.Float(10f, 20f) * v;
                TerrainRaycastResult?terrainRaycastResult = m_subsystemTerrain.Raycast(vector, vector3, useInteractionBoxes : false, skipAirBlocks : false, delegate(int value, float d)
                {
                    int num3 = Terrain.ExtractContents(value);
                    return(!(BlocksManager.Blocks[num3] is WaterBlock));
                });
                Vector3 vector4 = terrainRaycastResult.HasValue ? (vector + v * terrainRaycastResult.Value.Distance) : vector3;
                float   num2    = ScoreSafePlace(vector, vector4, herdPosition);
                if (num2 > num)
                {
                    num    = num2;
                    result = vector4;
                }
            }
            return(result);
        }
        public Vector3?FindDestination()
        {
            Vector3 vector = 0.5f * (m_componentCreature.ComponentBody.BoundingBox.Min + m_componentCreature.ComponentBody.BoundingBox.Max);
            float   num    = 2f;
            Vector3?result = null;
            float   num2   = m_random.Float(10f, 16f);

            for (int i = 0; i < 16; i++)
            {
                Vector2 vector2 = m_random.Vector2(1f, 1f);
                float   y       = 0.3f * m_random.Float(-0.9f, 1f);
                Vector3 v       = Vector3.Normalize(new Vector3(vector2.X, y, vector2.Y));
                Vector3 vector3 = vector + num2 * v;
                TerrainRaycastResult?terrainRaycastResult = m_subsystemTerrain.Raycast(vector, vector3, useInteractionBoxes : false, skipAirBlocks : false, delegate(int value, float d)
                {
                    int num3 = Terrain.ExtractContents(value);
                    return(!(BlocksManager.Blocks[num3] is WaterBlock));
                });
                if (!terrainRaycastResult.HasValue)
                {
                    if (num2 > num)
                    {
                        result = vector3;
                        num    = num2;
                    }
                }
                else if (terrainRaycastResult.Value.Distance > num)
                {
                    result = vector + v * terrainRaycastResult.Value.Distance;
                    num    = terrainRaycastResult.Value.Distance;
                }
            }
            return(result);
        }
示例#3
0
        public object Raycast(Ray3 ray, RaycastMode mode, bool raycastTerrain = true, bool raycastBodies = true, bool raycastMovingBlocks = true)
        {
            float                     reach            = (m_subsystemGameInfo.WorldSettings.GameMode == GameMode.Creative) ? SettingsManager.CreativeReach : 5f;
            Vector3                   creaturePosition = ComponentCreature.ComponentCreatureModel.EyePosition;
            Vector3                   start            = ray.Position;
            Vector3                   direction        = Vector3.Normalize(ray.Direction);
            Vector3                   end                       = ray.Position + direction * 15f;
            Point3                    startCell                 = Terrain.ToCell(start);
            BodyRaycastResult?        bodyRaycastResult         = m_subsystemBodies.Raycast(start, end, 0.35f, (ComponentBody body, float distance) => (Vector3.DistanceSquared(start + distance * direction, creaturePosition) <= reach * reach && body.Entity != base.Entity && !body.IsChildOfBody(ComponentCreature.ComponentBody) && !ComponentCreature.ComponentBody.IsChildOfBody(body) && Vector3.Dot(Vector3.Normalize(body.BoundingBox.Center() - start), direction) > 0.7f) ? true : false);
            MovingBlocksRaycastResult?movingBlocksRaycastResult = m_subsystemMovingBlocks.Raycast(start, end, extendToFillCells: true);
            TerrainRaycastResult?     terrainRaycastResult      = m_subsystemTerrain.Raycast(start, end, useInteractionBoxes : true, skipAirBlocks : true, delegate(int value, float distance)
            {
                if (Vector3.DistanceSquared(start + distance * direction, creaturePosition) <= reach * reach)
                {
                    Block block = BlocksManager.Blocks[Terrain.ExtractContents(value)];
                    if (distance == 0f && block is CrossBlock && Vector3.Dot(direction, new Vector3(startCell) + new Vector3(0.5f) - start) < 0f)
                    {
                        return(false);
                    }
                    if (mode == RaycastMode.Digging)
                    {
                        return(!block.IsDiggingTransparent);
                    }
                    if (mode == RaycastMode.Interaction)
                    {
                        if (block.IsPlacementTransparent)
                        {
                            return(block.IsInteractive(m_subsystemTerrain, value));
                        }
                        return(true);
                    }
                    if (mode == RaycastMode.Gathering)
                    {
                        return(block.IsGatherable);
                    }
                }
                return(false);
            });
            float num  = bodyRaycastResult.HasValue ? bodyRaycastResult.Value.Distance : float.PositiveInfinity;
            float num2 = movingBlocksRaycastResult.HasValue ? movingBlocksRaycastResult.Value.Distance : float.PositiveInfinity;
            float num3 = terrainRaycastResult.HasValue ? terrainRaycastResult.Value.Distance : float.PositiveInfinity;

            if (num < num2 && num < num3)
            {
                return(bodyRaycastResult.Value);
            }
            if (num2 < num && num2 < num3)
            {
                return(movingBlocksRaycastResult.Value);
            }
            if (num3 < num && num3 < num2)
            {
                return(terrainRaycastResult.Value);
            }
            return(new Ray3(start, direction));
        }
示例#4
0
        public void ExplodeFireworks(Vector3 position, int data)
        {
            for (int i = 0; i < 3; i++)
            {
                Vector3 v = new Vector3(m_random.Float(-3f, 3f), -15f, m_random.Float(-3f, 3f));
                if (m_subsystemTerrain.Raycast(position, position + v, useInteractionBoxes: false, skipAirBlocks: true, null).HasValue)
                {
                    return;
                }
            }
            FireworksBlock.Shape shape = FireworksBlock.GetShape(data);
            float flickering           = FireworksBlock.GetFlickering(data) ? 0.66f : 0f;
            float particleSize         = (FireworksBlock.GetAltitude(data) > 0) ? 1.1f : 1f;
            Color color = FireworksBlock.FireworksColors[FireworksBlock.GetColor(data)];

            m_subsystemParticles.AddParticleSystem(new FireworksParticleSystem(position, color, shape, flickering, particleSize));
            m_subsystemAudio.PlayRandomSound("Audio/FireworksPop", 1f, m_random.Float(-0.4f, 0f), position, 80f, autoDelay: true);
            m_subsystemNoise.MakeNoise(position, 1f, 60f);
        }
示例#5
0
 public void StartDismounting()
 {
     if (!m_isAnimating && Mount != null)
     {
         float x = 0f;
         if (Mount.DismountOffset.X > 0f)
         {
             float   s      = Mount.DismountOffset.X + 0.5f;
             Vector3 vector = 0.5f * (ComponentCreature.ComponentBody.BoundingBox.Min + ComponentCreature.ComponentBody.BoundingBox.Max);
             TerrainRaycastResult?terrainRaycastResult  = m_subsystemTerrain.Raycast(vector, vector - s * ComponentCreature.ComponentBody.Matrix.Right, useInteractionBoxes: false, skipAirBlocks: true, null);
             TerrainRaycastResult?terrainRaycastResult2 = m_subsystemTerrain.Raycast(vector, vector + s * ComponentCreature.ComponentBody.Matrix.Right, useInteractionBoxes: false, skipAirBlocks: true, null);
             x = ((!terrainRaycastResult.HasValue) ? (0f - Mount.DismountOffset.X) : ((!terrainRaycastResult2.HasValue) ? Mount.DismountOffset.X : ((!(terrainRaycastResult.Value.Distance > terrainRaycastResult2.Value.Distance)) ? MathUtils.Min(terrainRaycastResult2.Value.Distance, Mount.DismountOffset.X) : (0f - MathUtils.Min(terrainRaycastResult.Value.Distance, Mount.DismountOffset.X)))));
         }
         m_isAnimating          = true;
         m_animationTime        = 0f;
         m_isDismounting        = true;
         m_targetPositionOffset = Mount.MountOffset + m_riderOffset + new Vector3(x, Mount.DismountOffset.Y, Mount.DismountOffset.Z);
         m_targetRotationOffset = Quaternion.CreateFromAxisAngle(Vector3.UnitY, MathUtils.Sign(x) * MathUtils.DegToRad(60f));
     }
 }
        public bool IsPassable(Vector3 p1, Vector3 p2, Vector3 boxSize)
        {
            Vector3 vector  = new Vector3(p1.X, p1.Y + 0.5f, p1.Z);
            Vector3 vector2 = new Vector3(p2.X, p2.Y + 0.5f, p2.Z);
            Vector3 v       = (0.5f * boxSize.X + 0.1f) * Vector3.Normalize(Vector3.Cross(Vector3.UnitY, vector2 - vector));

            if (m_subsystemTerrain.Raycast(vector, vector2, useInteractionBoxes: false, skipAirBlocks: true, SmoothingRaycastFunction_Obstacle).HasValue)
            {
                return(false);
            }
            if (m_subsystemTerrain.Raycast(vector - v, vector2 - v, useInteractionBoxes: false, skipAirBlocks: true, SmoothingRaycastFunction_Obstacle).HasValue)
            {
                return(false);
            }
            if (m_subsystemTerrain.Raycast(vector + v, vector2 + v, useInteractionBoxes: false, skipAirBlocks: true, SmoothingRaycastFunction_Obstacle).HasValue)
            {
                return(false);
            }
            if (m_subsystemTerrain.Raycast(vector + new Vector3(0f, -1f, 0f), vector2 + new Vector3(0f, -1f, 0f), useInteractionBoxes: false, skipAirBlocks: false, SmoothingRaycastFunction_Support).HasValue)
            {
                return(false);
            }
            if (m_subsystemTerrain.Raycast(vector + new Vector3(0f, -1f, 0f) - v, vector2 + new Vector3(0f, -1f, 0f) - v, useInteractionBoxes: false, skipAirBlocks: false, SmoothingRaycastFunction_Support).HasValue)
            {
                return(false);
            }
            if (m_subsystemTerrain.Raycast(vector + new Vector3(0f, -1f, 0f) + v, vector2 + new Vector3(0f, -1f, 0f) + v, useInteractionBoxes: false, skipAirBlocks: false, SmoothingRaycastFunction_Support).HasValue)
            {
                return(false);
            }
            return(true);
        }
        public override bool Simulate(float dt)
        {
            dt = MathUtils.Clamp(dt, 0f, 0.1f);
            float num  = MathUtils.Pow(0.04f, dt);
            bool  flag = false;

            for (int i = 0; i < base.Particles.Length; i++)
            {
                Particle particle = base.Particles[i];
                if (!particle.IsActive)
                {
                    continue;
                }
                flag = true;
                particle.TimeToLive -= dt;
                if (particle.TimeToLive > 0f)
                {
                    Vector3 position = particle.Position;
                    Vector3 vector   = position + particle.Velocity * dt;
                    TerrainRaycastResult?terrainRaycastResult = m_subsystemTerrain.Raycast(position, vector, useInteractionBoxes: false, skipAirBlocks: true, (int value, float distance) => BlocksManager.Blocks[Terrain.ExtractContents(value)].IsCollidable);
                    if (terrainRaycastResult.HasValue)
                    {
                        Plane plane = terrainRaycastResult.Value.CellFace.CalculatePlane();
                        vector = position;
                        if (plane.Normal.X != 0f)
                        {
                            particle.Velocity *= new Vector3(-0.1f, 0.1f, 0.1f);
                        }
                        if (plane.Normal.Y != 0f)
                        {
                            particle.Velocity *= new Vector3(0.1f, -0.1f, 0.1f);
                        }
                        if (plane.Normal.Z != 0f)
                        {
                            particle.Velocity *= new Vector3(0.1f, 0.1f, -0.1f);
                        }
                    }
                    particle.Position    = vector;
                    particle.Velocity.Y += -10f * dt;
                    particle.Velocity   *= num;
                    particle.Color      *= MathUtils.Saturate(particle.TimeToLive);
                    particle.TextureSlot = (int)(8.99f * MathUtils.Saturate(2f - particle.TimeToLive));
                }
                else
                {
                    particle.IsActive = false;
                }
            }
            return(!flag);
        }
        public Projectile FireProjectile(int value, Vector3 position, Vector3 velocity, Vector3 angularVelocity, ComponentCreature owner)
        {
            int     num    = Terrain.ExtractContents(value);
            Block   block  = BlocksManager.Blocks[num];
            Vector3 v      = Vector3.Normalize(velocity);
            Vector3 vector = position;

            if (owner != null)
            {
                Ray3        ray         = new Ray3(position + v * 5f, -v);
                BoundingBox boundingBox = owner.ComponentBody.BoundingBox;
                boundingBox.Min -= new Vector3(0.4f);
                boundingBox.Max += new Vector3(0.4f);
                float?num2 = ray.Intersection(boundingBox);
                if (num2.HasValue)
                {
                    if (num2.Value == 0f)
                    {
                        return(null);
                    }
                    vector = position + v * (5f - num2.Value + 0.1f);
                }
            }
            Vector3 end = vector + v * block.ProjectileTipOffset;

            if (!m_subsystemTerrain.Raycast(position, end, useInteractionBoxes: false, skipAirBlocks: true, (int testValue, float distance) => BlocksManager.Blocks[Terrain.ExtractContents(testValue)].IsCollidable).HasValue)
            {
                Projectile projectile = AddProjectile(value, vector, velocity, angularVelocity, owner);
                SubsystemBlockBehavior[] blockBehaviors = m_subsystemBlockBehaviors.GetBlockBehaviors(num);
                for (int i = 0; i < blockBehaviors.Length; i++)
                {
                    blockBehaviors[i].OnFiredAsProjectile(projectile);
                }
                return(projectile);
            }
            return(null);
        }
示例#9
0
        public override bool Simulate(float dt)
        {
            dt = MathUtils.Clamp(dt, 0f, 0.1f);
            float num  = MathUtils.Pow(0.2f, dt);
            float num2 = MathUtils.Pow(1E-07f, dt);
            bool  flag = false;

            for (int i = 0; i < base.Particles.Length; i++)
            {
                Particle particle = base.Particles[i];
                if (!particle.IsActive)
                {
                    continue;
                }
                flag = true;
                particle.TimeToLive -= dt;
                if (particle.TimeToLive > 0f)
                {
                    Vector3 position = particle.Position;
                    Vector3 vector   = position + particle.Velocity * dt;
                    TerrainRaycastResult?terrainRaycastResult = m_subsystemTerrain.Raycast(position, vector, useInteractionBoxes: false, skipAirBlocks: true, (int value, float distance) => BlocksManager.Blocks[Terrain.ExtractContents(value)].IsCollidable);
                    if (terrainRaycastResult.HasValue)
                    {
                        particle.Velocity          = Vector3.Zero;
                        particle.Position          = terrainRaycastResult.Value.HitPoint(0.03f);
                        particle.HighDampingFactor = m_random.Float(0.5f, 1f);
                        if (terrainRaycastResult.Value.CellFace.Face >= 4)
                        {
                            particle.NoGravity = true;
                        }
                    }
                    else
                    {
                        particle.Position = vector;
                    }
                    if (!particle.NoGravity)
                    {
                        particle.Velocity.Y += -9.81f * dt;
                    }
                    particle.Velocity *= ((particle.HighDampingFactor > 0f) ? (num2 * particle.HighDampingFactor) : num);
                    particle.Color     = m_color * MathUtils.Saturate(1.5f * particle.TimeToLive * particle.Alpha);
                }
                else
                {
                    particle.IsActive = false;
                }
            }
            return(!flag);
        }
示例#10
0
        public float ScoreIntroSpawnPosition(Vector2 desiredSpawnPosition, int x, int z)
        {
            float num  = -0.01f * Vector2.Distance(new Vector2(x, z), desiredSpawnPosition);
            int   num2 = m_subsystemTerrain.Terrain.CalculateTopmostCellHeight(x, z);

            if (num2 < 64 || num2 > 85)
            {
                num -= 5f;
            }
            if (m_subsystemTerrain.Terrain.GetSeasonalTemperature(x, z) < 8)
            {
                num -= 5f;
            }
            int cellContents = m_subsystemTerrain.Terrain.GetCellContents(x, num2, z);

            if (BlocksManager.Blocks[cellContents].IsTransparent)
            {
                num -= 5f;
            }
            for (int i = x - 1; i <= x + 1; i++)
            {
                for (int j = z - 1; j <= z + 1; j++)
                {
                    if (m_subsystemTerrain.Terrain.GetCellContents(i, num2 + 2, j) != 0)
                    {
                        num -= 1f;
                    }
                }
            }
            Vector2 vector  = ComponentIntro.FindOceanDirection(m_subsystemTerrain.TerrainContentsGenerator, new Vector2(x, z));
            Vector3 vector2 = new Vector3(x, (float)num2 + 1.5f, z);

            for (int k = -1; k <= 1; k++)
            {
                Vector3 end = vector2 + new Vector3(30f * vector.X, 5f * (float)k, 30f * vector.Y);
                TerrainRaycastResult?terrainRaycastResult = m_subsystemTerrain.Raycast(vector2, end, useInteractionBoxes: false, skipAirBlocks: true, (int value, float distance) => Terrain.ExtractContents(value) != 0);
                if (terrainRaycastResult.HasValue)
                {
                    CellFace cellFace      = terrainRaycastResult.Value.CellFace;
                    int      cellContents2 = m_subsystemTerrain.Terrain.GetCellContents(cellFace.X, cellFace.Y, cellFace.Z);
                    if (cellContents2 != 18 && cellContents2 != 0)
                    {
                        num -= 2f;
                    }
                }
            }
            return(num);
        }
        public Vector3?FindSurfaceDestination()
        {
            Vector3 vector  = 0.5f * (m_componentCreature.ComponentBody.BoundingBox.Min + m_componentCreature.ComponentBody.BoundingBox.Max);
            Vector3 forward = m_componentCreature.ComponentBody.Matrix.Forward;
            float   s       = 2f * m_componentCreature.ComponentBody.ImmersionDepth;

            for (int i = 0; i < 16; i++)
            {
                Vector2 vector2 = (i < 4) ? (new Vector2(forward.X, forward.Z) + m_random.Vector2(0f, 0.25f)) : m_random.Vector2(0.5f, 1f);
                Vector3 v       = Vector3.Normalize(new Vector3(vector2.X, 1f, vector2.Y));
                Vector3 end     = vector + s * v;
                TerrainRaycastResult?terrainRaycastResult = m_subsystemTerrain.Raycast(vector, end, useInteractionBoxes: false, skipAirBlocks: false, (int value, float d) => Terrain.ExtractContents(value) != 18);
                if (terrainRaycastResult.HasValue && Terrain.ExtractContents(terrainRaycastResult.Value.Value) == 0)
                {
                    return(new Vector3((float)terrainRaycastResult.Value.CellFace.X + 0.5f, terrainRaycastResult.Value.CellFace.Y, (float)terrainRaycastResult.Value.CellFace.Z + 0.5f));
                }
            }
            return(null);
        }
示例#12
0
        public bool CanSleep(out string reason)
        {
            Block block = m_componentPlayer.ComponentBody.StandingOnValue.HasValue ? BlocksManager.Blocks[Terrain.ExtractContents(m_componentPlayer.ComponentBody.StandingOnValue.Value)] : null;

            if (block == null || m_componentPlayer.ComponentBody.ImmersionDepth > 0f)
            {
                reason = LanguageControl.Get(fName, 1);
                return(false);
            }
            if (block != null && block.SleepSuitability == 0f)
            {
                reason = LanguageControl.Get(fName, 2);
                return(false);
            }
            if (m_componentPlayer.ComponentVitalStats.Sleep > 0.99f)
            {
                reason = LanguageControl.Get(fName, 3);
                return(false);
            }
            if (m_componentPlayer.ComponentVitalStats.Wetness > 0.95f)
            {
                reason = LanguageControl.Get(fName, 4);
                return(false);
            }
            for (int i = -1; i <= 1; i++)
            {
                for (int j = -1; j <= 1; j++)
                {
                    Vector3 start = m_componentPlayer.ComponentBody.Position + new Vector3(i, 1f, j);
                    Vector3 end   = new Vector3(start.X, 255f, start.Z);
                    if (!m_subsystemTerrain.Raycast(start, end, useInteractionBoxes: false, skipAirBlocks: true, (int value, float distance) => Terrain.ExtractContents(value) != 0).HasValue)
                    {
                        reason = LanguageControl.Get(fName, 5);
                        return(false);
                    }
                }
            }
            reason = string.Empty;
            return(true);
        }
示例#13
0
 public Vector3?FindDestination()
 {
     for (int i = 0; i < 8; i++)
     {
         Vector2 vector  = m_random.Vector2(1f, 1f);
         float   y       = 0.2f * m_random.Float(-0.8f, 1f);
         Vector3 v       = Vector3.Normalize(new Vector3(vector.X, y, vector.Y));
         Vector3 vector2 = m_componentCreature.ComponentBody.Position + m_random.Float(8f, 16f) * v;
         TerrainRaycastResult?terrainRaycastResult = m_subsystemTerrain.Raycast(m_componentCreature.ComponentBody.Position, vector2, useInteractionBoxes : false, skipAirBlocks : false, delegate(int value, float d)
         {
             int num = Terrain.ExtractContents(value);
             return(!(BlocksManager.Blocks[num] is WaterBlock));
         });
         if (!terrainRaycastResult.HasValue)
         {
             return(vector2);
         }
         if (terrainRaycastResult.Value.Distance > 4f)
         {
             return(m_componentCreature.ComponentBody.Position + v * terrainRaycastResult.Value.Distance);
         }
     }
     return(null);
 }
        public override bool Simulate(float dt)
        {
            int num  = Terrain.ToCell(Position.X);
            int num2 = Terrain.ToCell(Position.Y);
            int num3 = Terrain.ToCell(Position.Z);
            int x    = 0;

            x = MathUtils.Max(x, m_subsystemTerrain.Terrain.GetCellLight(num + 1, num2, num3));
            x = MathUtils.Max(x, m_subsystemTerrain.Terrain.GetCellLight(num - 1, num2, num3));
            x = MathUtils.Max(x, m_subsystemTerrain.Terrain.GetCellLight(num, num2 + 1, num3));
            x = MathUtils.Max(x, m_subsystemTerrain.Terrain.GetCellLight(num, num2 - 1, num3));
            x = MathUtils.Max(x, m_subsystemTerrain.Terrain.GetCellLight(num, num2, num3 + 1));
            x = MathUtils.Max(x, m_subsystemTerrain.Terrain.GetCellLight(num, num2, num3 - 1));
            Color white = Color.White;
            float num4  = LightingManager.LightIntensityByLightValue[x];

            white  *= num4;
            white.A = byte.MaxValue;
            dt      = MathUtils.Clamp(dt, 0f, 0.1f);
            float num5 = MathUtils.Pow(0.03f, dt);

            m_duration += dt;
            if (m_duration > 3.5f)
            {
                IsStopped = true;
            }
            float num6 = MathUtils.Saturate(1.3f * SimplexNoise.Noise(3f * m_duration + (float)(GetHashCode() % 100)) - 0.3f);
            float num7 = 30f * num6;

            m_toGenerate += num7 * dt;
            bool flag = false;

            for (int i = 0; i < base.Particles.Length; i++)
            {
                Particle particle = base.Particles[i];
                if (particle.IsActive)
                {
                    flag = true;
                    particle.TimeToLive -= dt;
                    if (particle.TimeToLive > 0f)
                    {
                        Vector3 position = particle.Position;
                        Vector3 vector   = position + particle.Velocity * dt;
                        TerrainRaycastResult?terrainRaycastResult = m_subsystemTerrain.Raycast(position, vector, useInteractionBoxes: false, skipAirBlocks: true, (int value, float distance) => BlocksManager.Blocks[Terrain.ExtractContents(value)].IsCollidable);
                        if (terrainRaycastResult.HasValue)
                        {
                            Plane plane = terrainRaycastResult.Value.CellFace.CalculatePlane();
                            vector = position;
                            if (plane.Normal.X != 0f)
                            {
                                particle.Velocity *= new Vector3(-0.05f, 0.05f, 0.05f);
                            }
                            if (plane.Normal.Y != 0f)
                            {
                                particle.Velocity *= new Vector3(0.05f, -0.05f, 0.05f);
                            }
                            if (plane.Normal.Z != 0f)
                            {
                                particle.Velocity *= new Vector3(0.05f, 0.05f, -0.05f);
                            }
                        }
                        particle.Position    = vector;
                        particle.Velocity.Y += -9.81f * dt;
                        particle.Velocity   *= num5;
                        particle.Color      *= MathUtils.Saturate(particle.TimeToLive);
                        particle.TextureSlot = (int)(8.99f * MathUtils.Saturate(3f - particle.TimeToLive));
                    }
                    else
                    {
                        particle.IsActive = false;
                    }
                }
                else if (!IsStopped && m_toGenerate >= 1f)
                {
                    Vector3 v = m_random.Vector3(0f, 1f);
                    particle.IsActive   = true;
                    particle.Position   = Position + 0.05f * v;
                    particle.Color      = Color.MultiplyColorOnly(white, m_random.Float(0.7f, 1f));
                    particle.Velocity   = MathUtils.Lerp(1f, 2.5f, num6) * Vector3.Normalize(Direction + 0.25f * v);
                    particle.TimeToLive = 3f;
                    particle.Size       = new Vector2(0.1f);
                    particle.FlipX      = m_random.Bool();
                    particle.FlipY      = m_random.Bool();
                    m_toGenerate       -= 1f;
                }
            }
            if (IsStopped)
            {
                return(!flag);
            }
            return(false);
        }
示例#15
0
 public void Update(float dt)
 {
     if (m_subsystemTime.GameTime >= m_nextUpdateTime)
     {
         m_nextUpdateTime = m_subsystemTime.GameTime + (double)m_random.Float(0.09f, 0.11f);
         m_walkOrder      = null;
         m_flyOrder       = null;
         m_swimOrder      = null;
         m_turnOrder      = Vector2.Zero;
         m_jumpOrder      = 0f;
         if (Destination.HasValue)
         {
             Vector3 position = m_componentCreature.ComponentBody.Position;
             Vector3 forward  = m_componentCreature.ComponentBody.Matrix.Forward;
             Vector3 v        = AvoidNearestBody(position, Destination.Value);
             Vector3 vector   = v - position;
             float   num      = vector.LengthSquared();
             Vector2 vector2  = new Vector2(v.X, v.Z) - new Vector2(position.X, position.Z);
             float   num2     = vector2.LengthSquared();
             float   x        = Vector2.Angle(forward.XZ, vector.XZ);
             float   num3     = ((m_componentCreature.ComponentBody.CollisionVelocityChange * new Vector3(1f, 0f, 1f)).LengthSquared() > 0f && m_componentCreature.ComponentBody.StandingOnValue.HasValue) ? 0.15f : 0.4f;
             if (m_subsystemTime.GameTime >= m_lastStuckCheckTime + (double)num3 || !m_lastStuckCheckPosition.HasValue)
             {
                 m_lastStuckCheckTime = m_subsystemTime.GameTime;
                 if (MathUtils.Abs(x) > MathUtils.DegToRad(20f) || !m_lastStuckCheckPosition.HasValue || Vector3.Dot(position - m_lastStuckCheckPosition.Value, Vector3.Normalize(vector)) > 0.2f)
                 {
                     m_lastStuckCheckPosition = position;
                     m_stuckCount             = 0;
                 }
                 else
                 {
                     m_stuckCount++;
                 }
                 IsStuck = (m_stuckCount >= 4);
             }
             if (m_componentCreature.ComponentLocomotion.FlySpeed > 0f && (num > 9f || vector.Y > 0.5f || vector.Y < -1.5f || (!m_componentCreature.ComponentBody.StandingOnValue.HasValue && m_componentCreature.ComponentBody.ImmersionFactor == 0f)) && m_componentCreature.ComponentBody.ImmersionFactor < 1f)
             {
                 float   y      = MathUtils.Min(0.08f * vector2.LengthSquared(), 12f);
                 Vector3 v2     = v + new Vector3(0f, y, 0f);
                 Vector3 value2 = Speed * Vector3.Normalize(v2 - position);
                 value2.Y    = MathUtils.Max(value2.Y, -0.5f);
                 m_flyOrder  = value2;
                 m_turnOrder = new Vector2(MathUtils.Clamp(x, -1f, 1f), 0f);
             }
             else if (m_componentCreature.ComponentLocomotion.SwimSpeed > 0f && m_componentCreature.ComponentBody.ImmersionFactor > 0.5f)
             {
                 Vector3 value3 = Speed * Vector3.Normalize(v - position);
                 value3.Y    = MathUtils.Clamp(value3.Y, -0.5f, 0.5f);
                 m_swimOrder = value3;
                 m_turnOrder = new Vector2(MathUtils.Clamp(x, -1f, 1f), 0f);
             }
             else if (m_componentCreature.ComponentLocomotion.WalkSpeed > 0f)
             {
                 if (IsTerrainSafeToGo(position, vector))
                 {
                     m_turnOrder = new Vector2(MathUtils.Clamp(x, -1f, 1f), 0f);
                     if (num2 > 1f)
                     {
                         m_walkOrder = new Vector2(0f, MathUtils.Lerp(Speed, 0f, MathUtils.Saturate((MathUtils.Abs(x) - 0.33f) / 0.66f)));
                         if (Speed >= 1f && m_componentCreature.ComponentLocomotion.InAirWalkFactor >= 1f && num > 1f && m_random.Float(0f, 1f) < 0.05f)
                         {
                             m_jumpOrder = 1f;
                         }
                     }
                     else
                     {
                         float x2 = Speed * MathUtils.Min(1f * MathUtils.Sqrt(num2), 1f);
                         m_walkOrder = new Vector2(0f, MathUtils.Lerp(x2, 0f, MathUtils.Saturate(2f * MathUtils.Abs(x))));
                     }
                 }
                 else
                 {
                     IsStuck = true;
                 }
                 if (num2 < 1f && vector.Y < -0.1f)
                 {
                     m_componentCreature.ComponentBody.IsSmoothRiseEnabled = false;
                 }
                 else
                 {
                     m_componentCreature.ComponentBody.IsSmoothRiseEnabled = true;
                 }
                 if (num2 < 1f && (vector.Y < -0.5f || vector.Y > 1f))
                 {
                     if (vector.Y > 0f && m_random.Float(0f, 1f) < 0.05f)
                     {
                         m_jumpOrder = 1f;
                     }
                     if (!m_aboveBelowTime.HasValue)
                     {
                         m_aboveBelowTime = m_subsystemTime.GameTime;
                     }
                     else if (m_subsystemTime.GameTime - m_aboveBelowTime.Value > 2.0 && m_componentCreature.ComponentBody.StandingOnValue.HasValue)
                     {
                         IsStuck = true;
                     }
                 }
                 else
                 {
                     m_aboveBelowTime = null;
                 }
             }
             if ((!IgnoreHeightDifference) ? (num <= Range * Range) : (num2 <= Range * Range))
             {
                 if (RaycastDestination)
                 {
                     if (!m_subsystemTerrain.Raycast(position + new Vector3(0f, 0.5f, 0f), v + new Vector3(0f, 0.5f, 0f), useInteractionBoxes: false, skipAirBlocks: true, (int value, float distance) => BlocksManager.Blocks[Terrain.ExtractContents(value)].IsCollidable).HasValue)
                     {
                         Destination = null;
                     }
                 }
                 else
                 {
                     Destination = null;
                 }
             }
         }
         if (!Destination.HasValue && m_componentCreature.ComponentLocomotion.FlySpeed > 0f && !m_componentCreature.ComponentBody.StandingOnValue.HasValue && m_componentCreature.ComponentBody.ImmersionFactor == 0f)
         {
             m_turnOrder = Vector2.Zero;
             m_walkOrder = null;
             m_swimOrder = null;
             m_flyOrder  = new Vector3(0f, -0.5f, 0f);
         }
     }
     m_componentCreature.ComponentLocomotion.WalkOrder  = CombineNullables(m_componentCreature.ComponentLocomotion.WalkOrder, m_walkOrder);
     m_componentCreature.ComponentLocomotion.SwimOrder  = CombineNullables(m_componentCreature.ComponentLocomotion.SwimOrder, m_swimOrder);
     m_componentCreature.ComponentLocomotion.TurnOrder += m_turnOrder;
     m_componentCreature.ComponentLocomotion.FlyOrder   = CombineNullables(m_componentCreature.ComponentLocomotion.FlyOrder, m_flyOrder);
     m_componentCreature.ComponentLocomotion.JumpOrder  = MathUtils.Max(m_jumpOrder, m_componentCreature.ComponentLocomotion.JumpOrder);
     m_jumpOrder = 0f;
 }
        public void Update(float dt)
        {
            double totalElapsedGameTime = m_subsystemGameInfo.TotalElapsedGameTime;
            float  num  = MathUtils.Pow(0.5f, dt);
            float  num2 = MathUtils.Pow(0.001f, dt);

            m_tmpPlayers.Clear();
            foreach (ComponentPlayer componentPlayer in m_subsystemPlayers.ComponentPlayers)
            {
                if (componentPlayer.ComponentHealth.Health > 0f)
                {
                    m_tmpPlayers.Add(componentPlayer);
                }
            }
            foreach (Pickable pickable in m_pickables)
            {
                if (pickable.ToRemove)
                {
                    m_pickablesToRemove.Add(pickable);
                }
                else
                {
                    Block  block = BlocksManager.Blocks[Terrain.ExtractContents(pickable.Value)];
                    int    num3  = m_pickables.Count - m_pickablesToRemove.Count;
                    float  num4  = MathUtils.Lerp(300f, 90f, MathUtils.Saturate((float)num3 / 60f));
                    double num5  = totalElapsedGameTime - pickable.CreationTime;
                    if (num5 > (double)num4)
                    {
                        pickable.ToRemove = true;
                    }
                    else
                    {
                        TerrainChunk chunkAtCell = m_subsystemTerrain.Terrain.GetChunkAtCell(Terrain.ToCell(pickable.Position.X), Terrain.ToCell(pickable.Position.Z));
                        if (chunkAtCell != null && chunkAtCell.State > TerrainChunkState.InvalidContents4)
                        {
                            Vector3 position = pickable.Position;
                            Vector3 vector   = position + pickable.Velocity * dt;
                            if (!pickable.FlyToPosition.HasValue && num5 > 0.5)
                            {
                                foreach (ComponentPlayer tmpPlayer in m_tmpPlayers)
                                {
                                    ComponentBody componentBody = tmpPlayer.ComponentBody;
                                    Vector3       v             = componentBody.Position + new Vector3(0f, 0.75f, 0f);
                                    float         num6          = (v - pickable.Position).LengthSquared();
                                    if (num6 < 3.0625f)
                                    {
                                        bool       flag      = Terrain.ExtractContents(pickable.Value) == 248;
                                        IInventory inventory = tmpPlayer.ComponentMiner.Inventory;
                                        if (flag || ComponentInventoryBase.FindAcquireSlotForItem(inventory, pickable.Value) >= 0)
                                        {
                                            if (num6 < 1f)
                                            {
                                                if (flag)
                                                {
                                                    tmpPlayer.ComponentLevel.AddExperience(pickable.Count, playSound: true);
                                                    pickable.ToRemove = true;
                                                }
                                                else
                                                {
                                                    pickable.Count = ComponentInventoryBase.AcquireItems(inventory, pickable.Value, pickable.Count);
                                                    if (pickable.Count == 0)
                                                    {
                                                        pickable.ToRemove = true;
                                                        m_subsystemAudio.PlaySound("Audio/PickableCollected", 0.7f, -0.4f, pickable.Position, 2f, autoDelay: false);
                                                    }
                                                }
                                            }
                                            else if (!pickable.StuckMatrix.HasValue)
                                            {
                                                pickable.FlyToPosition = v + 0.1f * MathUtils.Sqrt(num6) * componentBody.Velocity;
                                            }
                                        }
                                    }
                                }
                            }
                            if (pickable.FlyToPosition.HasValue)
                            {
                                Vector3 v2   = pickable.FlyToPosition.Value - pickable.Position;
                                float   num7 = v2.LengthSquared();
                                if (num7 >= 0.25f)
                                {
                                    pickable.Velocity = 6f * v2 / MathUtils.Sqrt(num7);
                                }
                                else
                                {
                                    pickable.FlyToPosition = null;
                                }
                            }
                            else
                            {
                                FluidBlock surfaceBlock;
                                float?     surfaceHeight;
                                Vector2?   vector2 = m_subsystemFluidBlockBehavior.CalculateFlowSpeed(Terrain.ToCell(pickable.Position.X), Terrain.ToCell(pickable.Position.Y + 0.1f), Terrain.ToCell(pickable.Position.Z), out surfaceBlock, out surfaceHeight);
                                if (!pickable.StuckMatrix.HasValue)
                                {
                                    TerrainRaycastResult?terrainRaycastResult = m_subsystemTerrain.Raycast(position, vector, useInteractionBoxes: false, skipAirBlocks: true, (int value, float distance) => BlocksManager.Blocks[Terrain.ExtractContents(value)].IsCollidable);
                                    if (terrainRaycastResult.HasValue)
                                    {
                                        int contents = Terrain.ExtractContents(m_subsystemTerrain.Terrain.GetCellValue(terrainRaycastResult.Value.CellFace.X, terrainRaycastResult.Value.CellFace.Y, terrainRaycastResult.Value.CellFace.Z));
                                        SubsystemBlockBehavior[] blockBehaviors = m_subsystemBlockBehaviors.GetBlockBehaviors(contents);
                                        for (int i = 0; i < blockBehaviors.Length; i++)
                                        {
                                            blockBehaviors[i].OnHitByProjectile(terrainRaycastResult.Value.CellFace, pickable);
                                        }
                                        if (m_subsystemTerrain.Raycast(position, position, useInteractionBoxes: false, skipAirBlocks: true, (int value2, float distance) => BlocksManager.Blocks[Terrain.ExtractContents(value2)].IsCollidable).HasValue)
                                        {
                                            int num8  = Terrain.ToCell(position.X);
                                            int num9  = Terrain.ToCell(position.Y);
                                            int num10 = Terrain.ToCell(position.Z);
                                            int num11 = 0;
                                            int num12 = 0;
                                            int num13 = 0;
                                            int?num14 = null;
                                            for (int j = -3; j <= 3; j++)
                                            {
                                                for (int k = -3; k <= 3; k++)
                                                {
                                                    for (int l = -3; l <= 3; l++)
                                                    {
                                                        if (!BlocksManager.Blocks[m_subsystemTerrain.Terrain.GetCellContents(j + num8, k + num9, l + num10)].IsCollidable)
                                                        {
                                                            int num15 = j * j + k * k + l * l;
                                                            if (!num14.HasValue || num15 < num14.Value)
                                                            {
                                                                num11 = j + num8;
                                                                num12 = k + num9;
                                                                num13 = l + num10;
                                                                num14 = num15;
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                            if (num14.HasValue)
                                            {
                                                pickable.FlyToPosition = new Vector3(num11, num12, num13) + new Vector3(0.5f);
                                            }
                                            else
                                            {
                                                pickable.ToRemove = true;
                                            }
                                        }
                                        else
                                        {
                                            Plane plane = terrainRaycastResult.Value.CellFace.CalculatePlane();
                                            bool  flag2 = vector2.HasValue && vector2.Value != Vector2.Zero;
                                            if (plane.Normal.X != 0f)
                                            {
                                                float num16 = (flag2 || MathUtils.Sqrt(MathUtils.Sqr(pickable.Velocity.Y) + MathUtils.Sqr(pickable.Velocity.Z)) > 10f) ? 0.95f : 0.25f;
                                                pickable.Velocity *= new Vector3(0f - num16, num16, num16);
                                            }
                                            if (plane.Normal.Y != 0f)
                                            {
                                                float num17 = (flag2 || MathUtils.Sqrt(MathUtils.Sqr(pickable.Velocity.X) + MathUtils.Sqr(pickable.Velocity.Z)) > 10f) ? 0.95f : 0.25f;
                                                pickable.Velocity *= new Vector3(num17, 0f - num17, num17);
                                                if (flag2)
                                                {
                                                    pickable.Velocity.Y += 0.1f * plane.Normal.Y;
                                                }
                                            }
                                            if (plane.Normal.Z != 0f)
                                            {
                                                float num18 = (flag2 || MathUtils.Sqrt(MathUtils.Sqr(pickable.Velocity.X) + MathUtils.Sqr(pickable.Velocity.Y)) > 10f) ? 0.95f : 0.25f;
                                                pickable.Velocity *= new Vector3(num18, num18, 0f - num18);
                                            }
                                            vector = position;
                                        }
                                    }
                                }
                                else
                                {
                                    Vector3 vector3 = pickable.StuckMatrix.Value.Translation + pickable.StuckMatrix.Value.Up * block.ProjectileTipOffset;
                                    if (!m_subsystemTerrain.Raycast(vector3, vector3, useInteractionBoxes: false, skipAirBlocks: true, (int value, float distance) => BlocksManager.Blocks[Terrain.ExtractContents(value)].IsCollidable).HasValue)
                                    {
                                        pickable.Position    = pickable.StuckMatrix.Value.Translation;
                                        pickable.Velocity    = Vector3.Zero;
                                        pickable.StuckMatrix = null;
                                    }
                                }
                                if (surfaceBlock is WaterBlock && !pickable.SplashGenerated)
                                {
                                    m_subsystemParticles.AddParticleSystem(new WaterSplashParticleSystem(m_subsystemTerrain, pickable.Position, large: false));
                                    m_subsystemAudio.PlayRandomSound("Audio/Splashes", 1f, m_random.Float(-0.2f, 0.2f), pickable.Position, 6f, autoDelay: true);
                                    pickable.SplashGenerated = true;
                                }
                                else if (surfaceBlock is MagmaBlock && !pickable.SplashGenerated)
                                {
                                    m_subsystemParticles.AddParticleSystem(new MagmaSplashParticleSystem(m_subsystemTerrain, pickable.Position, large: false));
                                    m_subsystemAudio.PlayRandomSound("Audio/Sizzles", 1f, m_random.Float(-0.2f, 0.2f), pickable.Position, 3f, autoDelay: true);
                                    pickable.ToRemove        = true;
                                    pickable.SplashGenerated = true;
                                    m_subsystemExplosions.TryExplodeBlock(Terrain.ToCell(pickable.Position.X), Terrain.ToCell(pickable.Position.Y), Terrain.ToCell(pickable.Position.Z), pickable.Value);
                                }
                                else if (surfaceBlock == null)
                                {
                                    pickable.SplashGenerated = false;
                                }
                                if (m_subsystemTime.PeriodicGameTimeEvent(1.0, (double)(pickable.GetHashCode() % 100) / 100.0) && (m_subsystemTerrain.Terrain.GetCellContents(Terrain.ToCell(pickable.Position.X), Terrain.ToCell(pickable.Position.Y + 0.1f), Terrain.ToCell(pickable.Position.Z)) == 104 || m_subsystemFireBlockBehavior.IsCellOnFire(Terrain.ToCell(pickable.Position.X), Terrain.ToCell(pickable.Position.Y + 0.1f), Terrain.ToCell(pickable.Position.Z))))
                                {
                                    m_subsystemAudio.PlayRandomSound("Audio/Sizzles", 1f, m_random.Float(-0.2f, 0.2f), pickable.Position, 3f, autoDelay: true);
                                    pickable.ToRemove = true;
                                    m_subsystemExplosions.TryExplodeBlock(Terrain.ToCell(pickable.Position.X), Terrain.ToCell(pickable.Position.Y), Terrain.ToCell(pickable.Position.Z), pickable.Value);
                                }
                                if (!pickable.StuckMatrix.HasValue)
                                {
                                    if (vector2.HasValue && surfaceHeight.HasValue)
                                    {
                                        float num19 = surfaceHeight.Value - pickable.Position.Y;
                                        float num20 = MathUtils.Saturate(3f * num19);
                                        pickable.Velocity.X += 4f * dt * (vector2.Value.X - pickable.Velocity.X);
                                        pickable.Velocity.Y -= 10f * dt;
                                        pickable.Velocity.Y += 10f * (1f / block.Density * num20) * dt;
                                        pickable.Velocity.Z += 4f * dt * (vector2.Value.Y - pickable.Velocity.Z);
                                        pickable.Velocity.Y *= num2;
                                    }
                                    else
                                    {
                                        pickable.Velocity.Y -= 10f * dt;
                                        pickable.Velocity   *= num;
                                    }
                                }
                            }
                            pickable.Position = vector;
                        }
                    }
                }
            }
            foreach (Pickable item in m_pickablesToRemove)
            {
                m_pickables.Remove(item);
                if (this.PickableRemoved != null)
                {
                    this.PickableRemoved(item);
                }
            }
            m_pickablesToRemove.Clear();
        }