Ejemplo n.º 1
0
        public override IEnumerable <Status> Run()
        {
            Creature.IsCloaked = false;
            if (Zone != null)
            {
                var resourcesToStock = Creature.Inventory.Resources.Where(a => a.MarkedForRestock && Zone is Stockpile && (Zone as Stockpile).IsAllowed(a.Resource.TypeName)).ToList();

                foreach (var resource in resourcesToStock)
                {
                    var createdItem = Creature.Inventory.RemoveAndCreate(resource.Resource, Inventory.RestockType.RestockResource);
                    if (Zone.AddResource(resource.Resource))
                    {
                        var toss = new TossMotion(1.0f, 2.5f, createdItem.LocalTransform, Zone.GetBoundingBox().Center() + new Vector3(0.5f, 0.5f, 0.5f));

                        if (createdItem.GetRoot().GetComponent <Physics>().HasValue(out var physics))
                        {
                            physics.CollideMode = Physics.CollisionMode.None;
                        }

                        createdItem.AnimationQueue.Add(toss);
                        toss.OnComplete += createdItem.Die;

                        Creature.NoiseMaker.MakeNoise("Stockpile", Creature.AI.Position);
                        Creature.Stats.NumItemsGathered++;
                        Creature.CurrentCharacterMode = Creature.Stats.CurrentClass.AttackMode;
                        Creature.Sprite.ResetAnimations(Creature.Stats.CurrentClass.AttackMode);
                        Creature.Sprite.PlayAnimations(Creature.Stats.CurrentClass.AttackMode);

                        while (!Creature.Sprite.AnimPlayer.IsDone())
                        {
                            yield return(Status.Running);
                        }

                        yield return(Status.Running);
                    }
                    else
                    {
                        Creature.Inventory.AddResource(resource.Resource, Inventory.RestockType.RestockResource);
                        createdItem.Delete();
                    }
                }
            }

            Timer waitTimer = new Timer(1.0f, true);
            bool  removed   = Creature.World.RemoveResourcesFromSpecificZone(Resource, Zone);

            if (!removed)
            {
                yield return(Status.Fail);
            }
            else
            {
                var newEntity = Agent.Manager.RootComponent.AddChild(new ResourceEntity(Agent.Manager, Resource, Zone.GetBoundingBox().Center() + new Vector3(0.0f, 1.0f, 0.0f)));

                if (newEntity.GetRoot().GetComponent <Physics>().HasValue(out var newPhysics))
                {
                    newPhysics.CollideMode = Physics.CollisionMode.None;
                }

                var toss = new TossMotion(1.0f + MathFunctions.Rand(0.1f, 0.2f), 2.5f + MathFunctions.Rand(-0.5f, 0.5f), newEntity.LocalTransform, Agent.Position);
                newEntity.AnimationQueue.Add(toss);
                toss.OnComplete += () => newEntity.Die();

                Agent.Creature.Inventory.AddResource(Resource, Inventory.RestockType.None);
                Agent.Creature.Sprite.ResetAnimations(Creature.Stats.CurrentClass.AttackMode);
                while (!waitTimer.HasTriggered)
                {
                    Agent.Creature.CurrentCharacterMode = Creature.Stats.CurrentClass.AttackMode;
                    waitTimer.Update(DwarfTime.LastTime);
                    yield return(Status.Running);
                }
                Agent.Creature.CurrentCharacterMode = CharacterMode.Idle;
                yield return(Status.Success);
            }
        }
Ejemplo n.º 2
0
        public IEnumerable <Act.Status> PerformOnVoxel(Creature performer, Vector3 pos, KillVoxelTask DigAct, DwarfTime time, float bonus, string faction)
        {
            while (true)
            {
                if (!DigAct.Voxel.IsValid)
                {
                    yield return(Act.Status.Fail);

                    yield break;
                }

                Drawer2D.DrawLoadBar(performer.World.Camera, DigAct.Voxel.WorldPosition + Vector3.One * 0.5f, Color.White, Color.Black, 32, 1, (float)DigAct.VoxelHealth / DigAct.Voxel.Type.StartingHealth);

                switch (TriggerMode)
                {
                case AttackTrigger.Timer:
                    RechargeTimer.Update(time);
                    if (!RechargeTimer.HasTriggered)
                    {
                        yield return(Act.Status.Running);

                        continue;
                    }
                    break;

                case AttackTrigger.Animation:
                    if (!performer.Sprite.AnimPlayer.HasValidAnimation() ||
                        performer.Sprite.AnimPlayer.CurrentFrame < TriggerFrame)
                    {
                        if (performer.Sprite.AnimPlayer.HasValidAnimation())
                        {
                            performer.Sprite.AnimPlayer.Play();
                        }
                        yield return(Act.Status.Running);

                        continue;
                    }
                    break;
                }

                switch (Mode)
                {
                case AttackMode.Melee:
                {
                    DigAct.VoxelHealth -= (DamageAmount + bonus);

                    DigAct.Voxel.Type.HitSound.Play(DigAct.Voxel.WorldPosition);
                    if (HitParticles != "")
                    {
                        performer.Manager.World.ParticleManager.Trigger(HitParticles, DigAct.Voxel.WorldPosition, Color.White, 5);
                    }

                    if (HitAnimation != null)
                    {
                        IndicatorManager.DrawIndicator(HitAnimation, DigAct.Voxel.WorldPosition + Vector3.One * 0.5f,
                                                       10.0f, 1.0f, MathFunctions.RandVector2Circle() * 10, HitColor, MathFunctions.Rand() > 0.5f);
                    }

                    break;
                }

                case AttackMode.Ranged:
                {
                    throw new InvalidOperationException("Ranged attacks should never be used for digging.");
                    //LaunchProjectile(pos, DigAct.GetTargetVoxel().WorldPosition, null);
                    //break;
                }
                }
                yield return(Act.Status.Success);

                yield break;
            }
        }
Ejemplo n.º 3
0
        public void DoDamage(Creature performer, Body other, float bonus)
        {
            if (!String.IsNullOrEmpty(DiseaseToSpread))
            {
                var otherCreature = other.GetRoot().GetComponent <Creature>();
                if (otherCreature != null)
                {
                    var disease = DiseaseLibrary.GetDisease(DiseaseToSpread);
                    if (MathFunctions.RandEvent(disease.LikelihoodOfSpread))
                    {
                        otherCreature.AcquireDisease(DiseaseToSpread);
                    }
                }
            }

            var health = other.GetRoot().EnumerateAll().OfType <Health>().FirstOrDefault();

            if (health != null)
            {
                health.Damage(DamageAmount + bonus);
                var injury = DiseaseLibrary.GetRandomInjury();

                if (MathFunctions.RandEvent(injury.LikelihoodOfSpread))
                {
                    var creature = other.GetRoot().GetComponent <Creature>();
                    if (creature != null)
                    {
                        creature.AcquireDisease(injury.Name);
                    }
                }

                Vector3 knock = other.Position - performer.Physics.Position;
                knock.Normalize();
                knock *= 0.2f;
                if (other.AnimationQueue.Count == 0)
                {
                    other.AnimationQueue.Add(new KnockbackAnimation(0.15f, other.LocalTransform, knock));
                }
            }
            else
            {
                other.GetRoot().Die();
            }

            PlayNoise(other.GlobalTransform.Translation);
            if (HitParticles != "")
            {
                performer.Manager.World.ParticleManager.Trigger(HitParticles, other.LocalTransform.Translation, Color.White, 5);

                if (ShootLaser)
                {
                    performer.Manager.World.ParticleManager.TriggerRay(HitParticles, performer.AI.Position, other.LocalTransform.Translation);
                }
            }

            if (HitAnimation != null)
            {
                IndicatorManager.DrawIndicator(HitAnimation, other.BoundingBox.Center(), 10.0f, 1.0f, MathFunctions.RandVector2Circle(), Color.White, MathFunctions.Rand() > 0.5f);
            }

            Physics physics = other as Physics;

            if (physics != null)
            {
                Vector3 force = other.Position - performer.AI.Position;

                if (force.LengthSquared() > 0.01f)
                {
                    force.Normalize();
                    physics.ApplyForce(force * Knockback, 1.0f);
                }
            }
        }
Ejemplo n.º 4
0
        public void GenerateFauna(VoxelChunk chunk, ComponentManager components, ContentManager content, GraphicsDevice graphics, FactionLibrary factions)
        {
            int   waterHeight = (int)(SeaLevel * chunk.SizeY);
            Voxel v           = chunk.MakeVoxel(0, 0, 0);

            for (int x = 0; x < chunk.SizeX; x++)
            {
                for (int z = 0; z < chunk.SizeZ; z++)
                {
                    Vector2         vec       = new Vector2(x + chunk.Origin.X, z + chunk.Origin.Z) / PlayState.WorldScale;
                    Overworld.Biome biome     = Overworld.Map[(int)MathFunctions.Clamp(vec.X, 0, Overworld.Map.GetLength(0) - 1), (int)MathFunctions.Clamp(vec.Y, 0, Overworld.Map.GetLength(1) - 1)].Biome;
                    BiomeData       biomeData = BiomeLibrary.Biomes[biome];

                    int y = chunk.GetFilledVoxelGridHeightAt(x, chunk.SizeY - 1, z);

                    if (!chunk.IsCellValid(x, (int)(y - chunk.Origin.Y), z))
                    {
                        continue;
                    }

                    v.GridPosition = new Vector3(x, y, z);

                    if (chunk.Data.Water[v.Index].WaterLevel != 0 || y <= waterHeight)
                    {
                        continue;
                    }

                    foreach (FaunaData animal in biomeData.Fauna)
                    {
                        if (y <= 0 || !(PlayState.Random.NextDouble() < animal.SpawnProbability))
                        {
                            continue;
                        }


                        EntityFactory.CreateEntity <Body>(animal.Name, chunk.Origin + new Vector3(x, y, z) + Vector3.Up * 1.0f);

                        break;
                    }
                }
            }
        }
Ejemplo n.º 5
0
        public VoxelChunk GenerateChunk(Vector3 origin, int chunkSizeX, int chunkSizeY, int chunkSizeZ, ComponentManager components, ContentManager content, GraphicsDevice graphics)
        {
            float      waterHeight = SeaLevel;
            VoxelChunk c           = new VoxelChunk(Manager, origin, 1,
                                                    Manager.ChunkData.GetChunkID(origin + new Vector3(0.5f, 0.5f, 0.5f)), chunkSizeX, chunkSizeY, chunkSizeZ)
            {
                ShouldRebuild             = true,
                ShouldRecalculateLighting = true
            };

            Voxel voxel = c.MakeVoxel(0, 0, 0);

            for (int x = 0; x < chunkSizeX; x++)
            {
                for (int z = 0; z < chunkSizeZ; z++)
                {
                    Vector2 v = new Vector2(x + origin.X, z + origin.Z) / PlayState.WorldScale;

                    Overworld.Biome biome = Overworld.Map[(int)MathFunctions.Clamp(v.X, 0, Overworld.Map.GetLength(0) - 1), (int)MathFunctions.Clamp(v.Y, 0, Overworld.Map.GetLength(1) - 1)].Biome;

                    BiomeData biomeData = BiomeLibrary.Biomes[biome];

                    Vector2 pos         = new Vector2(x + origin.X, z + origin.Z) / PlayState.WorldScale;
                    float   hNorm       = Overworld.GetValue(Overworld.Map, pos, Overworld.ScalarFieldType.Height);
                    float   h           = MathFunctions.Clamp(hNorm * chunkSizeY, 0.0f, chunkSizeY - 2);
                    int     stoneHeight = (int)Math.Max(h - 2, 1);


                    for (int y = 0; y < chunkSizeY; y++)
                    {
                        voxel.GridPosition = new Vector3(x, y, z);
                        if (y == 0)
                        {
                            voxel.Type = VoxelLibrary.GetVoxelType("Bedrock");
                            continue;
                        }

                        if (y <= stoneHeight && stoneHeight > 1)
                        {
                            voxel.Type   = VoxelLibrary.GetVoxelType(biomeData.SubsurfVoxel);
                            voxel.Health = VoxelLibrary.GetVoxelType(biomeData.SubsurfVoxel).StartingHealth;
                        }

                        else if ((y == (int)h || y == stoneHeight) && hNorm > waterHeight)
                        {
                            if (biomeData.ClumpGrass &&
                                NoiseGenerator.Noise(pos.X / biomeData.ClumpSize, 0, pos.Y / biomeData.ClumpSize) >
                                biomeData.ClumpTreshold)
                            {
                                voxel.Type   = VoxelLibrary.GetVoxelType(biomeData.GrassVoxel);
                                voxel.Health = VoxelLibrary.GetVoxelType(biomeData.GrassVoxel).StartingHealth;
                            }
                            else if (!biomeData.ClumpGrass)
                            {
                                voxel.Type   = VoxelLibrary.GetVoxelType(biomeData.GrassVoxel);
                                voxel.Health = VoxelLibrary.GetVoxelType(biomeData.GrassVoxel).StartingHealth;
                            }
                            else
                            {
                                voxel.Type   = VoxelLibrary.GetVoxelType(biomeData.SoilVoxel);
                                voxel.Health = VoxelLibrary.GetVoxelType(biomeData.SoilVoxel).StartingHealth;
                            }
                        }
                        else if (y > h && y > 0)
                        {
                            voxel.Type = VoxelLibrary.GetVoxelType("empty");
                        }
                        else if (hNorm < waterHeight)
                        {
                            voxel.Type   = VoxelLibrary.GetVoxelType(biomeData.ShoreVoxel);
                            voxel.Health = VoxelLibrary.GetVoxelType(biomeData.ShoreVoxel).StartingHealth;
                        }
                        else
                        {
                            voxel.Type   = VoxelLibrary.GetVoxelType(biomeData.SoilVoxel);
                            voxel.Health = VoxelLibrary.GetVoxelType(biomeData.SoilVoxel).StartingHealth;
                        }
                    }
                }
            }


            GenerateOres(c, components, content, graphics);
            GenerateCaves(c);
            GenerateWater(c);

            GenerateLava(c);



            c.ShouldRebuildWater = true;
            return(c);
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Draws a line between two points of the given color and width by scaling and rotating a pixel
        /// </summary>
        /// <param Name="batch">The sprite batch to use.</param>
        /// <param Name="pixel">The pixel image to use.</param>
        /// <param Name="point1">The first point of the line.</param>
        /// <param Name="point2">The second point of the line.</param>
        /// <param Name="lineColor">The color of the line.</param>
        /// <param Name="width">The width, in pixels, of the line.</param>
        public static void DrawLine(SpriteBatch batch, Vector2 point1, Vector2 point2, Color lineColor, int width)
        {
            float   distance = Vector2.Distance(point1, point2);
            Vector2 normal   = (point2 - point1);

            normal.Normalize();

            batch.Draw(Pixel, new Rectangle((int)(point1.X), (int)(point1.Y) - width / 2, (int)distance, width), new Rectangle(0, 0, 1, 1), lineColor, MathFunctions.RectangularToPolar(normal).Y, Vector2.Zero, SpriteEffects.None, 0.0f);
            batch.Draw(Pixel, point1, null, lineColor, MathFunctions.RectangularToPolar(normal).Y, Vector2.Zero, new Vector2(distance, width), SpriteEffects.None, 0);
        }
Ejemplo n.º 7
0
        public void Start()
        {
            World.MakeAnnouncement("A storm is coming!", null);

            switch (TypeofStorm)
            {
            case StormType.RainStorm:
                SoundManager.PlaySound(ContentPaths.Audio.Oscar.sfx_gui_rain_storm_alert, 0.15f);
                break;

            case StormType.SnowStorm:
                SoundManager.PlaySound(ContentPaths.Audio.Oscar.sfx_gui_snow_storm_alert, 0.15f);
                break;
            }

            BoundingBox bounds         = World.ChunkManager.Bounds;
            Vector3     extents        = bounds.Extents();
            Vector3     center         = bounds.Center();
            Vector3     windNormalized = WindSpeed / WindSpeed.Length();
            Vector3     offset         = new Vector3(-windNormalized.X * extents.X + center.X, bounds.Max.Y + 5, -windNormalized.Z * extents.Z + center.Z);
            Vector3     perp           = new Vector3(-windNormalized.Z, 0, windNormalized.X);
            int         numClouds      = (int)(MathFunctions.RandInt(10, 100) * Intensity);
            int         numCloudLayers = MathFunctions.RandInt(1, 5);

            for (int layer = 0; layer < numCloudLayers; layer++)
            {
                for (int i = 0; i < numClouds; i++)
                {
                    Vector3 cloudPos = offset + perp * 5 * (i - numClouds / 2) + MathFunctions.RandVector3Cube() * 10 + windNormalized * 2 * layer;

                    Cloud cloud = new Cloud(World.ComponentManager, Intensity, 5, offset.Y + MathFunctions.Rand(-3.0f, 3.0f), cloudPos, TypeofStorm == StormType.RainStorm ? 0.15f : 0.0f)
                    {
                        Velocity    = WindSpeed * 0.5f,
                        TypeofStorm = TypeofStorm
                    };
                    Clouds.Add(cloud);
                    World.ComponentManager.RootComponent.AddChild(cloud);
                }
            }
            IsInitialized = true;
        }
Ejemplo n.º 8
0
        public BiomeData GetBiomeAt(Vector3 worldPos, Vector2 origin)
        {
            var v          = WorldToOverworld(worldPos, origin);
            var r          = WorldToOverworldRemainder(new Vector2(worldPos.X, worldPos.Z));
            var blendColor = BiomeBlend.Data[BiomeBlend.Index((int)MathFunctions.Clamp(r.X, 0, VoxelConstants.ChunkSizeX), (int)MathFunctions.Clamp(r.Y, 0, VoxelConstants.ChunkSizeZ))];
            var offsetV    = v + new Vector2((blendColor.R - 127.0f) / 128.0f, (blendColor.G - 127.0f) / 128.0f);
            var biome1     = Map[(int)MathFunctions.Clamp(v.X, 0, Map.GetLength(0) - 1), (int)MathFunctions.Clamp(v.Y, 0, Map.GetLength(1) - 1)].Biome;
            var biome2     = Map[(int)MathFunctions.Clamp(offsetV.X, 0, Map.GetLength(0) - 1), (int)MathFunctions.Clamp(offsetV.Y, 0, Map.GetLength(1) - 1)].Biome;

            return(Library.GetBiome(Math.Max(biome1, biome2)));
        }
Ejemplo n.º 9
0
        public List <Body> RemoveAndCreate(ResourceAmount resources)
        {
            List <Body> toReturn = new List <Body>();

            if (!Resources.RemoveResource(resources.CloneResource()))
            {
                return(toReturn);
            }

            for (int i = 0; i < resources.NumResources; i++)
            {
                Body newEntity = EntityFactory.CreateEntity <Body>(resources.ResourceType.ResourceName + " Resource",
                                                                   GlobalTransform.Translation + MathFunctions.RandVector3Cube() * 0.5f);
                toReturn.Add(newEntity);
            }

            return(toReturn);
        }
Ejemplo n.º 10
0
        /// <summary>
        /// Checks the voxels around the creature and reacts to changes in its immediate environment.
        /// For example this function determines when the creature is standing on solid ground.
        /// </summary>
        public void CheckNeighborhood(ChunkManager chunks, float dt)
        {
            var below = new VoxelHandle(chunks.ChunkData,
                                        GlobalVoxelCoordinate.FromVector3(Physics.GlobalTransform.Translation - Vector3.UnitY * 0.8f));
            var above = new VoxelHandle(chunks.ChunkData,
                                        GlobalVoxelCoordinate.FromVector3(Physics.GlobalTransform.Translation + Vector3.UnitY * 0.8f));

            if (above.IsValid)
            {
                IsHeadClear = above.IsEmpty;
            }
            if (below.IsValid && Physics.IsInLiquid)
            {
                IsOnGround = false;
            }
            else if (below.IsValid)
            {
                IsOnGround = !below.IsEmpty;
            }
            else
            {
                IsOnGround = false;
            }

            if (!IsOnGround)
            {
                if (CurrentCharacterMode != CharacterMode.Flying)
                {
                    if (Physics.Velocity.Y > 0.05)
                    {
                        CurrentCharacterMode = CharacterMode.Jumping;
                    }
                    else if (Physics.Velocity.Y < -0.05)
                    {
                        CurrentCharacterMode = CharacterMode.Falling;
                    }
                }

                if (Physics.IsInLiquid)
                {
                    CurrentCharacterMode = CharacterMode.Swimming;
                }
            }

            if (CurrentCharacterMode == CharacterMode.Falling && IsOnGround)
            {
                CurrentCharacterMode = CharacterMode.Idle;
            }

            if (Status.IsAsleep)
            {
                CurrentCharacterMode = CharacterMode.Sleeping;

                if (MathFunctions.RandEvent(0.01f))
                {
                    NoiseMaker.MakeNoise("Sleep", AI.Position, true);
                }
            }
            else if (currentCharacterMode == CharacterMode.Sleeping)
            {
                CurrentCharacterMode = CharacterMode.Idle;
            }

            if (World.Time.IsDay() && Status.IsAsleep && !Status.Energy.IsDissatisfied() && !Status.Health.IsCritical())
            {
                Status.IsAsleep = false;
            }
        }
Ejemplo n.º 11
0
 private static Color GetPixelAt(Color[] data, int x, int y, int width, int height)
 {
     return(data[MathFunctions.Clamp(y, 0, height - 1) * width + MathFunctions.Clamp(x, 0, width - 1)]);
 }
Ejemplo n.º 12
0
        /// <summary>
        /// Gets a stairstep stretching accross the box.
        /// </summary>
        /// <param name="box">The box.</param>
        /// <returns>A stairstep starting filled on the bottom row, pointing in the maximum x or z direction</returns>
        private IEnumerable <Vector3> GetStair(BoundingBox box, Vector3 start, Vector3 end, bool invert)
        {
            int minX = MathFunctions.FloorInt(box.Min.X + 0.5f);
            int minY = MathFunctions.FloorInt(box.Min.Y + 0.5f);
            int minZ = MathFunctions.FloorInt(box.Min.Z + 0.5f);
            int maxX = MathFunctions.FloorInt(box.Max.X - 0.5f);
            int maxY = MathFunctions.FloorInt(box.Max.Y - 0.5f);
            int maxZ = MathFunctions.FloorInt(box.Max.Z - 0.5f);

            // If not inverted, selects the Xs
            // If inverted, selects the Os
            //max y ----xOOOO
            //      --- xxOOO
            //      --- xxxOO
            //      --- xxxxO
            //min y --- xxxxx
            //        minx --- maxx
            float   dx          = box.Max.X - box.Min.X;
            float   dz          = box.Max.Z - box.Min.Z;
            Vector3 dir         = end - start;
            bool    direction   = dx > dz;
            bool    positiveDir = direction ? dir.X < 0 : dir.Z < 0;
            int     step        = 0;

            // Always make staircases go exactly to the top or bottom of the selection.
            if (direction && invert)
            {
                minY = maxY - (maxX - minX);
            }
            else if (direction)
            {
                maxY = minY + (maxX - minX);
            }
            else if (invert)
            {
                minY = maxY - (maxZ - minZ);
            }
            else
            {
                maxY = minY + (maxZ - minZ);
            }
            int dy = maxY - minY;

            // Start from the bottom of the stairs up to the top.
            for (int y = minY; y <= maxY; y++)
            {
                int carve = invert ? MathFunctions.Clamp(dy - step, 0, dy) : step;
                // If stairs are in x direction
                if (direction)
                {
                    if (positiveDir)
                    {
                        // Start from min x, and march up to maxY - y
                        for (int x = minX; x <= MathFunctions.Clamp(maxX - carve, minX, maxX); x++)
                        {
                            for (int z = minZ; z <= maxZ; z++)
                            {
                                yield return(new Vector3(x + 0.5f, y + 0.5f, z + 0.5f));
                            }
                        }
                    }
                    else
                    {
                        // Start from min x, and march up to maxY - y
                        for (int x = maxX; x >= MathFunctions.Clamp(minX + carve, minX, maxX); x--)
                        {
                            for (int z = minZ; z <= maxZ; z++)
                            {
                                yield return(new Vector3(x + 0.5f, y + 0.5f, z + 0.5f));
                            }
                        }
                    }
                    step++;
                }
                // Otherwise, they are in the z direction.
                else
                {
                    if (positiveDir)
                    {
                        // Start from min z, and march up to maxY - y
                        for (int z = minZ; z <= MathFunctions.Clamp(maxZ - carve, minZ, maxZ); z++)
                        {
                            for (int x = minX; x <= maxX; x++)
                            {
                                yield return(new Vector3(x + 0.5f, y + 0.5f, z + 0.5f));
                            }
                        }
                    }
                    else
                    {
                        // Start from min z, and march up to maxY - y
                        for (int z = maxZ; z >= MathFunctions.Clamp(minZ + carve, minZ, maxZ); z--)
                        {
                            for (int x = minX; x <= maxX; x++)
                            {
                                yield return(new Vector3(x + 0.5f, y + 0.5f, z + 0.5f));
                            }
                        }
                    }
                    step++;
                }
            }
        }
Ejemplo n.º 13
0
 private static GameComponent __factory2(ComponentManager Manager, Vector3 Position, Blackboard Data)
 {
     Weather.CreateForecast(Manager.World.Time.CurrentDate, Manager.World.ChunkManager.Bounds, Manager.World, 3);
     Weather.CreateStorm(MathFunctions.RandVector3Cube() * 10, MathFunctions.Rand(0.05f, 1.0f), Manager.World);
     return(new Cloud(Manager, 0.1f, 50, 40, Position, 0.0f));
 }
Ejemplo n.º 14
0
        override public void Update(DwarfTime gameTime, ChunkManager chunks, Camera camera)
        {
            base.Update(gameTime, chunks, camera);

            Storm.InitializeStatics();
            BoundingBox box = chunks.Bounds;

            box.Expand(10.0f);

            if (GlobalTransform.Translation.X < box.Min.X ||
                GlobalTransform.Translation.X > box.Max.X ||
                GlobalTransform.Translation.Z < box.Min.Z ||
                GlobalTransform.Translation.Z > box.Max.Z)
            {
                Die();
            }


            bool generateRainDrop = MathFunctions.RandEvent(Raininess * 0.75f);

            if (generateRainDrop)
            {
                for (int i = 0; i < MaxRainDrops; i++)
                {
                    if (!RainDrops[i].IsAlive)
                    {
                        RainDrops[i].IsAlive = true;
                        if (RainDrops[i].Particle != null)
                        {
                            RainDrops[i].Particle.LifeRemaining = 60.0f;
                            RainDrops[i].Particle.TimeAlive     = 0.0f;
                        }
                        RainDrops[i].Pos = MathFunctions.RandVector3Box(BoundingBox.Expand(5));
                        RainDrops[i].Pos = new Vector3(RainDrops[i].Pos.X, BoundingBox.Min.Y - 1, RainDrops[i].Pos.Z);
                        RainDrops[i].Vel = Vector3.Down * Storm.Properties[TypeofStorm].RainSpeed + Velocity;
                        break;
                    }
                }
            }

            bool generateLightning = LightningChance > 0.0f && MathFunctions.RandEvent((float)(LightningChance * 0.001f));

            if (generateLightning)
            {
                var below = VoxelHelpers.FindFirstVoxelBelowIncludingWater(new VoxelHandle(World.ChunkManager, GlobalVoxelCoordinate.FromVector3(new Vector3(Position.X, Math.Min(World.WorldSizeInVoxels.Y - 1, Position.Y), Position.Z))));
                if (below.IsValid && !below.IsEmpty)
                {
                    var above = VoxelHelpers.GetVoxelAbove(below);
                    if (above.IsValid)
                    {
                        EntityFactory.CreateEntity <Fire>("Fire", above.GetBoundingBox().Center());
                        List <Vector3> lightningStrikes = new List <Vector3>();
                        List <Color>   colors           = new List <Color>();
                        var            c = above.GetBoundingBox().Center();
                        for (float t = 0; t < 1.0f; t += 0.25f)
                        {
                            var p = c * t + Position * (1.0f - t);
                            lightningStrikes.Add(p + MathFunctions.RandVector3Box(-5, 5, 0, 0.1f, -5, 5));
                            colors.Add(Color.White);
                        }
                        lightningStrikes.Add(c);
                        colors.Add(Color.White);
                        Drawer3D.DrawLineList(lightningStrikes, colors, 0.3f);
                        SoundManager.PlaySound(ContentPaths.Audio.Oscar.sfx_gui_rain_storm_alert, MathFunctions.Rand(0.001f, 0.05f), MathFunctions.Rand(0.5f, 1.0f));
                        SoundManager.PlaySound(ContentPaths.Audio.Oscar.sfx_trap_destroyed, c, false, 1.0f, MathFunctions.Rand(-0.5f, 0.5f));
                        World.ParticleManager.Trigger("explode", c, Color.White, 10);
                    }
                }
            }

            Storm.StormProperties stormProperties = Storm.Properties[TypeofStorm];
            var rainEmitter = World.ParticleManager.Effects[stormProperties.RainEffect];
            var hitEmitter  = World.ParticleManager.Effects[stormProperties.HitEffect];

            for (int i = 0; i < MaxRainDrops; i++)
            {
                if (!RainDrops[i].IsAlive)
                {
                    continue;
                }

                RainDrops[i].Pos += RainDrops[i].Vel * DwarfTime.Dt;

                if (stormProperties.RainRandom > 0)
                {
                    RainDrops[i].Vel.X += MathFunctions.Rand(-1, 1) * stormProperties.RainRandom * DwarfTime.Dt;
                    RainDrops[i].Vel.Z += MathFunctions.Rand(-1, 1) * stormProperties.RainRandom * DwarfTime.Dt;
                }

                if (RainDrops[i].Pos.Y < 0)
                {
                    RainDrops[i].IsAlive = false;
                }

                if (!RainDrops[i].IsAlive && RainDrops[i].Particle != null)
                {
                    RainDrops[i].Particle.LifeRemaining = -1;
                }
                else if (RainDrops[i].IsAlive && RainDrops[i].Particle == null)
                {
                    RainDrops[i].Particle = rainEmitter.Emitters[0].CreateParticle(RainDrops[i].Pos,
                                                                                   RainDrops[i].Vel, Color.White);
                }
                else if (RainDrops[i].IsAlive && RainDrops[i].Particle != null)
                {
                    RainDrops[i].Particle.Position = RainDrops[i].Pos;
                    RainDrops[i].Particle.Velocity = RainDrops[i].Vel;
                }

                var test = new VoxelHandle(chunks, GlobalVoxelCoordinate.FromVector3(RainDrops[i].Pos));
                if (!test.IsValid || (test.IsEmpty && test.LiquidLevel == 0))
                {
                    continue;
                }

                RainDrops[i].IsAlive = false;

                var hitBodies = World.EnumerateIntersectingObjects(new BoundingBox(RainDrops[i].Pos - Vector3.One, RainDrops[i].Pos + Vector3.One));

                foreach (var body in hitBodies)
                {
                    if (body.Parent != Manager.RootComponent)
                    {
                        continue;
                    }

                    if (body.GetRoot().GetComponent <Flammable>().HasValue(out var flames))
                    {
                        flames.Heat *= 0.25f;
                    }

                    if (body.GetRoot().GetComponent <Seedling>().HasValue(out var seeds))
                    {
                        if (TypeofStorm == StormType.RainStorm)
                        {
                            seeds.GrowthTime += MathFunctions.Rand(1.0f, 12.0f);
                        }
                        else if (MathFunctions.RandEvent(0.01f))
                        {
                            seeds.GetRoot().Die();
                        }
                    }
                }

                hitEmitter.Trigger(1, RainDrops[i].Pos + Vector3.UnitY * 0.5f, Color.White);

                //if (!MathFunctions.RandEvent(0.1f)) continue;

                var above = test.IsEmpty ? test : VoxelHelpers.GetVoxelAbove(test);

                if (!above.IsValid || !above.IsEmpty)
                {
                    continue;
                }
                if (TypeofStorm == StormType.RainStorm &&
                    (above.LiquidLevel < WaterManager.maxWaterLevel && (above.LiquidType == LiquidType.Water)))
                {
                    above.LiquidLevel = (byte)Math.Min(WaterManager.maxWaterLevel, above.LiquidLevel + WaterManager.rainFallAmount);
                    above.LiquidType  = stormProperties.LiquidToCreate;
                }
                else if (TypeofStorm == StormType.SnowStorm && above.IsEmpty && above.LiquidLevel == 0)
                {
                    if (test.GrassType == 0)
                    {
                        test.GrassType  = Library.GetGrassType("snow").ID;
                        test.GrassDecay = Library.GetGrassType("snow").InitialDecayValue;
                    }
                    else
                    {
                        var existingGrass = Library.GetGrassType((byte)test.GrassType);
                        if (!String.IsNullOrEmpty(existingGrass.BecomeWhenSnowedOn))
                        {
                            var newGrass = Library.GetGrassType(existingGrass.BecomeWhenSnowedOn);
                            test.GrassType  = newGrass.ID;
                            test.GrassDecay = newGrass.InitialDecayValue;
                        }
                    }
                }
            }

            Matrix tf = LocalTransform;

            tf.Translation += Velocity * DwarfTime.Dt;
            LocalTransform  = tf;
        }
Ejemplo n.º 15
0
        public void Initialize(string blood)
        {
            HasMeat             = false;
            HasBones            = false;
            Physics.Orientation = Physics.OrientMode.RotateY;
            CreateSprite(Stats.CurrentClass, Manager);
            Hands = Physics.AddChild(new Grabber("hands", Manager, Matrix.Identity, new Vector3(0.1f, 0.1f, 0.1f), Vector3.Zero)) as Grabber;

            Sensors = Physics.AddChild(new EnemySensor(Manager, "EnemySensor", Matrix.Identity, new Vector3(20, 5, 20), Vector3.Zero)) as EnemySensor;

            AI = Physics.AddChild(new MudGolemAI(Manager, Sensors, Manager.World.PlanService)
            {
                Movement = { IsSessile = true, CanFly = false, CanSwim = false, CanWalk = false, CanClimb = false, CanClimbWalls = false }
            }) as CreatureAI;

            Attacks = new List <Attack>()
            {
                new Attack(Stats.CurrentClass.Attacks[0])
            };

            Inventory = Physics.AddChild(new Inventory(Manager, "Inventory", Physics.BoundingBox.Extents(), Physics.LocalBoundingBoxOffset)) as Inventory;

            var gems = ResourceLibrary.GetResourcesByTag(Resource.ResourceTags.Gem);

            for (int i = 0; i < 16; i++)
            {
                int num = MathFunctions.RandInt(1, 32 - i);
                Inventory.AddResource(new ResourceAmount(Datastructures.SelectRandom(gems), num));
                i += num - 1;
            }

            Matrix shadowTransform = Matrix.CreateRotationX((float)Math.PI * 0.5f);

            shadowTransform.Translation = new Vector3(0.0f, -0.5f, 0.0f);


            Physics.Tags.Add("MudGolem");
            Physics.Mass = 100;

            Physics.AddChild(new ParticleTrigger(blood, Manager, "Death Gibs", Matrix.Identity, Vector3.One, Vector3.Zero)
            {
                TriggerOnDeath = true,
                TriggerAmount  = 5,
                SoundToPlay    = ContentPaths.Audio.gravel
            });

            NoiseMaker.Noises["Hurt"] = new List <string>
            {
                ContentPaths.Audio.demon0,
                ContentPaths.Audio.gravel,
            };


            Physics.AddChild(new MinimapIcon(Manager, new NamedImageFrame(ContentPaths.GUI.map_icons, 16, 2, 1)));

            Stats.FullName = TextGenerator.GenerateRandom("$goblinname");
            //Stats.LastName = TextGenerator.GenerateRandom("$elffamily");
            Stats.Size = 4;
            Resistances[DamageType.Fire] = 5;
            Resistances[DamageType.Acid] = 5;
            Resistances[DamageType.Cold] = 5;
            Species = "Mud Golem";
        }
Ejemplo n.º 16
0
        private static void UpdateChunk(VoxelChunk chunk)
        {
            var addGrassToThese = new List <Tuple <VoxelHandle, byte> >();

            for (var y = 0; y < VoxelConstants.ChunkSizeY; ++y)
            {
                // Skip empty slices.
                if (chunk.Data.VoxelsPresentInSlice[y] == 0)
                {
                    continue;
                }

                for (var x = 0; x < VoxelConstants.ChunkSizeX; ++x)
                {
                    for (var z = 0; z < VoxelConstants.ChunkSizeZ; ++z)
                    {
                        var voxel = VoxelHandle.UnsafeCreateLocalHandle(chunk, new LocalVoxelCoordinate(x, y, z));

                        // Allow grass to decay
                        if (voxel.GrassType != 0)
                        {
                            var grass = Library.GetGrassType(voxel.GrassType);

                            if (grass.NeedsSunlight && !voxel.Sunlight)
                            {
                                voxel.GrassType = 0;
                            }
                            else if (grass.Decay)
                            {
                                if (voxel.GrassDecay == 0)
                                {
                                    var newDecal = Library.GetGrassType(grass.BecomeWhenDecays);
                                    if (newDecal != null)
                                    {
                                        voxel.GrassType = newDecal.ID;
                                    }
                                    else
                                    {
                                        voxel.GrassType = 0;
                                    }
                                }
                                else
                                {
                                    voxel.GrassDecay -= 1;
                                }
                            }
                        }
//#if false
                        else if (voxel.Type.GrassSpreadsHere)
                        {
                            // Spread grass onto this tile - but only from the same biome.

                            // Don't spread if there's an entity here.
                            var entityPresent = chunk.Manager.World.EnumerateIntersectingObjects(
                                new BoundingBox(voxel.WorldPosition + new Vector3(0.1f, 1.1f, 0.1f), voxel.WorldPosition + new Vector3(0.9f, 1.9f, 0.9f)),
                                CollisionType.Static).Any();
                            if (entityPresent)
                            {
                                continue;
                            }

                            // Don't spread if there's a voxel above us.
                            var voxelAbove = VoxelHelpers.GetVoxelAbove(voxel);
                            if (voxelAbove.IsValid && !voxelAbove.IsEmpty)
                            {
                                continue;
                            }

                            if (chunk.Manager.World.Overworld.Map.GetBiomeAt(voxel.Coordinate.ToVector3(), chunk.Manager.World.Overworld.InstanceSettings.Origin).HasValue(out var biome))
                            {
                                var grassyNeighbors = VoxelHelpers.EnumerateManhattanNeighbors2D(voxel.Coordinate)
                                                      .Select(c => new VoxelHandle(voxel.Chunk.Manager, c))
                                                      .Where(v => v.IsValid && v.GrassType != 0)
                                                      .Where(v => Library.GetGrassType(v.GrassType).Spreads)
                                                      .Where(v =>
                                {
                                    if (chunk.Manager.World.Overworld.Map.GetBiomeAt(v.Coordinate.ToVector3(), chunk.Manager.World.Overworld.InstanceSettings.Origin).HasValue(out var otherBiome))
                                    {
                                        return(biome == otherBiome);
                                    }
                                    return(false);
                                })
                                                      .ToList();

                                if (grassyNeighbors.Count > 0)
                                {
                                    if (MathFunctions.RandEvent(0.1f))
                                    {
                                        addGrassToThese.Add(Tuple.Create(voxel, grassyNeighbors[MathFunctions.RandInt(0, grassyNeighbors.Count)].GrassType));
                                    }
                                }
                            }
                        }
//#endif
                    }
                }
            }

            foreach (var v in addGrassToThese)
            {
                var l         = v.Item1;
                var grassType = Library.GetGrassType(v.Item2);
                if (grassType.NeedsSunlight && !l.Sunlight)
                {
                    continue;
                }
                l.GrassType = v.Item2;
            }
        }
Ejemplo n.º 17
0
        public void Update(WorldManager World)
        {
            if (ExpiditionState == Expedition.State.Trading)
            {
                if (UpdateWaitTimer(World.Time.CurrentDate))
                {
                    World.MakeAnnouncement(String.Format("The envoy from {0} is leaving.", OwnerFaction.ParentFaction.Name));
                    RecallEnvoy();
                }
            }

            Creatures.RemoveAll(creature => creature.IsDead);
            if (DeathTimer.Update(World.Time.CurrentDate))
            {
                Creatures.ForEach((creature) => creature.GetRoot().Die());
            }

            var politics = World.Overworld.GetPolitics(OwnerFaction.ParentFaction, OtherFaction.ParentFaction);

            if (politics.GetCurrentRelationship() == Relationship.Hateful)
            {
                World.MakeAnnouncement(String.Format("The envoy from {0} left: we are at war with them.", OwnerFaction.ParentFaction.Name));
                RecallEnvoy();
            }
            else
            {
                if (Creatures.Any(
                        // TODO (mklingen) why do I need this null check?
                        creature => creature.Creature != null &&
                        World.PersistentData.Designations.IsDesignation(creature.Physics, DesignationType.Attack)))
                {
                    if (!politics.HasEvent("You attacked our trade delegates"))
                    {
                        politics.AddEvent(new PoliticalEvent()
                        {
                            Change      = -1.0f,
                            Description = "You attacked our trade delegates",
                        });
                    }
                    else
                    {
                        politics.AddEvent(new PoliticalEvent()
                        {
                            Change      = -2.0f,
                            Description = "You attacked our trade delegates more than once",
                        });
                    }
                }
            }

            if (!ShouldRemove && ExpiditionState == Expedition.State.Arriving)
            {
                foreach (var creature in Creatures)
                {
                    var tradePort = World.GetNearestRoomOfType("Balloon Port", creature.Position);

                    if (tradePort == null)
                    {
                        World.MakeAnnouncement("We need a balloon trade port to trade.", null, () =>
                        {
                            return(World.GetNearestRoomOfType("Balloon Port", creature.Position) == null);
                        });
                        World.Tutorial("trade");
                        SoundManager.PlaySound(ContentPaths.Audio.Oscar.sfx_gui_negative_generic, 0.5f);
                        RecallEnvoy();
                        break;
                    }

                    if (creature.Tasks.Count == 0)
                    {
                        creature.Tasks.Add(new TradeTask(tradePort, this));
                    }

                    if (!tradePort.IsRestingOnZone(creature.Position))
                    {
                        continue;
                    }

                    if (ExpiditionState != Expedition.State.Trading || !IsTradeWidgetValid())
                    {
                        MakeTradeWidget(World);
                    }

                    StartTrading(World.Time.CurrentDate);
                    ExpiditionState = Expedition.State.Trading;
                    break;
                }
            }
            else if (ExpiditionState == Expedition.State.Leaving)
            {
                BoundingBox worldBBox = World.ChunkManager.Bounds;

                foreach (CreatureAI creature in Creatures)
                {
                    if (creature.Tasks.Count == 0)
                    {
                        creature.LeaveWorld();
                    }
                }

                foreach (var creature in Creatures)
                {
                    if (MathFunctions.Dist2D(worldBBox, creature.Position) < 2.0f)
                    {
                        creature.GetRoot().Delete();
                    }
                }
            }
            else if (!IsTradeWidgetValid())
            {
                MakeTradeWidget(World);
            }

            if (!OwnerFaction.ParentFaction.IsCorporate && Creatures.All(creature => creature.IsDead))
            {
                ShouldRemove = true;
            }
        }
Ejemplo n.º 18
0
        public IEnumerable <Status> FindRandomPath()
        {
            Vector3 target = MathFunctions.RandVector3Cube() * Radius + Creature.AI.Position;

            if (Creature.AI.PositionConstraint.Contains(target) == ContainmentType.Disjoint)
            {
                target = MathFunctions.RandVector3Box(Creature.AI.PositionConstraint);
            }
            if (Is2D)
            {
                target.Y = Creature.AI.Position.Y;
            }
            List <MoveAction> path      = new List <MoveAction>();
            VoxelHandle       curr      = Creature.Physics.CurrentVoxel;
            var       bodies            = Agent.World.PlayerFaction.OwnedObjects.Where(o => o.Tags.Contains("Teleporter")).ToList();
            var       storage           = new MoveActionTempStorage();
            MoveState previousMoveState = new MoveState {
                Voxel = curr
            };

            for (int i = 0; i < PathLength; i++)
            {
                var actions = Creature.AI.Movement.GetMoveActions(previousMoveState, bodies, storage);

                MoveAction?bestAction = null;
                float      bestDist   = float.MaxValue;

                foreach (MoveAction action in actions)
                {
                    if (Is2D && (action.MoveType == MoveType.Climb || action.MoveType == MoveType.ClimbWalls))
                    {
                        continue;
                    }

                    float dist = (action.DestinationVoxel.WorldPosition - target).LengthSquared() * Creature.AI.Movement.Cost(action.MoveType);

                    if (dist < bestDist && !path.Any(a => a.DestinationVoxel == action.DestinationVoxel))
                    {
                        bestDist   = dist;
                        bestAction = action;
                    }
                }

                if (bestAction.HasValue &&
                    !path.Any(p => p.DestinationVoxel.Equals(bestAction.Value.DestinationVoxel) && p.MoveType == bestAction.Value.MoveType &&
                              Creature.AI.PositionConstraint.Contains(bestAction.Value.DestinationVoxel.WorldPosition + Vector3.One * 0.5f) == ContainmentType.Contains))
                {
                    MoveAction action = bestAction.Value;
                    path.Add(action);
                    previousMoveState = action.DestinationState;
                }
                else
                {
                    break;
                }
            }
            if (path.Count > 0)
            {
                Creature.AI.Blackboard.SetData("RandomPath", path);
                yield return(Status.Success);
            }
            else
            {
                yield return(Status.Fail);
            }
        }
Ejemplo n.º 19
0
 public Point3(Vector3 vect)
 {
     X = MathFunctions.FloorInt(vect.X);
     Y = MathFunctions.FloorInt(vect.Y);
     Z = MathFunctions.FloorInt(vect.Z);
 }
Ejemplo n.º 20
0
        public override IEnumerable <Status> Run()
        {
            Vector3 oldPosition = Agent.Position;
            bool    firstIter   = true;

            Creature.Controller.Reset();
            WanderTime.Reset();
            TurnTime.Reset();
            while (!WanderTime.HasTriggered)
            {
                Creature.OverrideCharacterMode = false;
                Creature.Physics.Orientation   = Physics.OrientMode.RotateY;
                Creature.CurrentCharacterMode  = CharacterMode.Walking;
                WanderTime.Update(DwarfTime.LastTime);

                if (!Creature.IsOnGround)
                {
                    yield return(Status.Success);

                    yield break;
                }
                if (TurnTime.Update(DwarfTime.LastTime) || TurnTime.HasTriggered || firstIter)
                {
                    int iters = 0;

                    while (iters < 100)
                    {
                        iters++;
                        Vector2 randTarget = MathFunctions.RandVector2Circle() * Radius;
                        LocalTarget = new Vector3(randTarget.X, 0, randTarget.Y) + oldPosition;
                        VoxelHandle voxel     = new VoxelHandle(Agent.World.ChunkManager, GlobalVoxelCoordinate.FromVector3(LocalTarget));
                        bool        foundLava = false;
                        foreach (VoxelHandle neighbor in VoxelHelpers.EnumerateAllNeighbors(voxel.Coordinate).Select(coord => new VoxelHandle(Agent.World.ChunkManager, coord)))
                        {
                            if (neighbor.IsValid && neighbor.Chunk != null)
                            {
                                if (neighbor.LiquidType == LiquidType.Lava)
                                {
                                    foundLava = true;
                                }
                            }
                        }
                        if (!foundLava)
                        {
                            break;
                        }
                    }

                    if (iters == 100)
                    {
                        yield return(Act.Status.Fail);

                        yield break;
                    }
                    firstIter = false;
                    TurnTime.Reset(TurnTime.TargetTimeSeconds + MathFunctions.Rand(-0.1f, 0.1f));
                }

                float dist = (LocalTarget - Agent.Position).Length();


                if (dist < 0.5f)
                {
                    Creature.Physics.Velocity    *= 0.0f;
                    Creature.CurrentCharacterMode = CharacterMode.Idle;
                    yield return(Status.Running);
                }
                else
                {
                    Vector3 output =
                        Creature.Controller.GetOutput((float)DwarfTime.LastTime.ElapsedGameTime.TotalSeconds,
                                                      LocalTarget, Agent.Position);
                    output.Y = 0.0f;

                    Creature.Physics.ApplyForce(output * 0.5f, (float)DwarfTime.LastTime.ElapsedGameTime.TotalSeconds);
                    Creature.CurrentCharacterMode = CharacterMode.Walking;
                }

                yield return(Status.Running);
            }
            Creature.CurrentCharacterMode = CharacterMode.Idle;
            yield return(Status.Success);
        }
Ejemplo n.º 21
0
        public override IEnumerable <Status> Run()
        {
            Creature.IsCloaked = false;

            if (CurrentAttack == null)
            {
                yield return(Status.Fail);

                yield break;
            }

            Timeout.Reset();
            FailTimer.Reset();
            if (Target == null && TargetName != null)
            {
                Target = Agent.Blackboard.GetData <Body>(TargetName);

                if (Target == null)
                {
                    yield return(Status.Fail);

                    yield break;
                }
            }

            if (Agent.Faction.Race.IsIntelligent)
            {
                var targetInventory = Target.GetRoot().GetComponent <Inventory>();
                if (targetInventory != null)
                {
                    targetInventory.SetLastAttacker(Agent);
                }
            }

            CharacterMode defaultCharachterMode = Creature.AI.Movement.CanFly
                ? CharacterMode.Flying
                : CharacterMode.Walking;

            bool avoided = false;

            while (true)
            {
                Timeout.Update(DwarfTime.LastTime);
                FailTimer.Update(DwarfTime.LastTime);
                if (FailTimer.HasTriggered)
                {
                    Creature.Physics.Orientation   = Physics.OrientMode.RotateY;
                    Creature.OverrideCharacterMode = false;
                    Creature.CurrentCharacterMode  = defaultCharachterMode;
                    yield return(Status.Fail);

                    yield break;
                }

                if (Timeout.HasTriggered)
                {
                    if (Training)
                    {
                        Agent.AddXP(1);
                        Creature.Physics.Orientation   = Physics.OrientMode.RotateY;
                        Creature.OverrideCharacterMode = false;
                        Creature.CurrentCharacterMode  = defaultCharachterMode;
                        yield return(Status.Success);

                        yield break;
                    }
                    else
                    {
                        Creature.Physics.Orientation   = Physics.OrientMode.RotateY;
                        Creature.OverrideCharacterMode = false;
                        Creature.CurrentCharacterMode  = defaultCharachterMode;
                        yield return(Status.Fail);

                        yield break;
                    }
                }

                if (Target == null || Target.IsDead)
                {
                    Creature.CurrentCharacterMode = defaultCharachterMode;
                    Creature.Physics.Orientation  = Physics.OrientMode.RotateY;
                    yield return(Status.Success);
                }

                // Find the location of the melee target
                Vector3 targetPos = new Vector3(Target.GlobalTransform.Translation.X,
                                                Target.GetBoundingBox().Min.Y,
                                                Target.GlobalTransform.Translation.Z);

                Vector2 diff = new Vector2(targetPos.X, targetPos.Z) - new Vector2(Creature.AI.Position.X, Creature.AI.Position.Z);

                Creature.Physics.Face(targetPos);

                bool  intersectsbounds = Creature.Physics.BoundingBox.Intersects(Target.BoundingBox);
                float dist             = diff.Length();
                // If we are really far from the target, something must have gone wrong.
                if (DefensiveStructure == null && !intersectsbounds && dist > CurrentAttack.Range * 4)
                {
                    Creature.Physics.Orientation   = Physics.OrientMode.RotateY;
                    Creature.OverrideCharacterMode = false;
                    Creature.CurrentCharacterMode  = defaultCharachterMode;
                    yield return(Status.Fail);

                    yield break;
                }

                if (DefensiveStructure != null)
                {
                    if (Creature.Hp < LastHp)
                    {
                        float damage = LastHp - Creature.Hp;
                        Creature.Heal(Math.Min(5.0f, damage));
                        var health = DefensiveStructure.GetRoot().GetComponent <Health>();
                        if (health != null)
                        {
                            health.Damage(damage);
                            Drawer2D.DrawLoadBar(health.World.Camera, DefensiveStructure.Position, Color.White, Color.Black, 32, 1, health.Hp / health.MaxHealth, 0.1f);
                        }
                        LastHp = Creature.Hp;
                    }

                    if (dist > CurrentAttack.Range)
                    {
                        float sqrDist = dist * dist;
                        foreach (var threat in Creature.AI.Faction.Threats)
                        {
                            float threatDist = (threat.AI.Position - Creature.AI.Position).LengthSquared();
                            if (threatDist < sqrDist)
                            {
                                sqrDist = threatDist;
                                Target  = threat.Physics;
                                break;
                            }
                        }
                        dist = (float)Math.Sqrt(sqrDist);
                    }

                    if (dist > CurrentAttack.Range * 4)
                    {
                        yield return(Status.Fail);

                        yield break;
                    }

                    if (DefensiveStructure.IsDead)
                    {
                        DefensiveStructure = null;
                    }
                }

                LastHp = Creature.Hp;


                // If we're out of attack range, run toward the target.
                if (DefensiveStructure == null && !Creature.AI.Movement.IsSessile && !intersectsbounds && diff.Length() > CurrentAttack.Range)
                {
                    Creature.CurrentCharacterMode = defaultCharachterMode;

                    /*
                     * Vector3 output = Creature.Controller.GetOutput(DwarfTime.Dt, targetPos, Creature.Physics.GlobalTransform.Translation) * 0.9f;
                     * output.Y = 0.0f;
                     * if (Creature.AI.Movement.CanFly)
                     * {
                     *  Creature.Physics.ApplyForce(-Creature.Physics.Gravity, DwarfTime.Dt);
                     * }
                     * if (Creature.AI.Movement.IsSessile)
                     * {
                     *  output *= 0.0f;
                     * }
                     * Creature.Physics.ApplyForce(output, DwarfTime.Dt);
                     * Creature.Physics.Orientation = Physics.OrientMode.RotateY;
                     */
                    GreedyPathAct greedyPath = new GreedyPathAct(Creature.AI, Target, CurrentAttack.Range * 0.75f)
                    {
                        PathLength = 5
                    };
                    greedyPath.Initialize();

                    foreach (Act.Status stat in greedyPath.Run())
                    {
                        if (stat == Act.Status.Running)
                        {
                            yield return(Status.Running);
                        }
                        else
                        {
                            break;
                        }
                    }
                }
                // If we have a ranged weapon, try avoiding the target for a few seconds to get within range.
                else if (DefensiveStructure == null && !Creature.AI.Movement.IsSessile && !intersectsbounds && !avoided && (CurrentAttack.Mode == Attack.AttackMode.Ranged &&
                                                                                                                            dist < CurrentAttack.Range * 0.15f))
                {
                    FailTimer.Reset();
                    foreach (Act.Status stat in AvoidTarget(CurrentAttack.Range, 3.0f))
                    {
                        yield return(Status.Running);
                    }
                    avoided = true;
                }
                // Else, stop and attack
                else if ((DefensiveStructure == null && dist < CurrentAttack.Range) ||
                         (DefensiveStructure != null && dist < CurrentAttack.Range * 2.0))
                {
                    if (CurrentAttack.Mode == Attack.AttackMode.Ranged &&
                        VoxelHelpers.DoesRayHitSolidVoxel(Creature.World.ChunkManager.ChunkData,
                                                          Creature.AI.Position, Target.Position))
                    {
                        yield return(Status.Fail);

                        yield break;
                    }

                    FailTimer.Reset();
                    avoided = false;
                    Creature.Physics.Orientation = Physics.OrientMode.Fixed;
                    Creature.Physics.Velocity    = new Vector3(Creature.Physics.Velocity.X * 0.9f, Creature.Physics.Velocity.Y, Creature.Physics.Velocity.Z * 0.9f);
                    CurrentAttack.RechargeTimer.Reset(CurrentAttack.RechargeRate);

                    Creature.Sprite.ResetAnimations(Creature.AttackMode);
                    Creature.Sprite.PlayAnimations(Creature.AttackMode);
                    Creature.CurrentCharacterMode  = Creature.AttackMode;
                    Creature.OverrideCharacterMode = true;
                    Timer timeout = new Timer(10.0f, true);
                    while (!CurrentAttack.Perform(Creature, Target, DwarfTime.LastTime, Creature.Stats.BuffedStr + Creature.Stats.BuffedSiz,
                                                  Creature.AI.Position, Creature.Faction.Name))
                    {
                        timeout.Update(DwarfTime.LastTime);
                        if (timeout.HasTriggered)
                        {
                            break;
                        }

                        Creature.Physics.Velocity = new Vector3(Creature.Physics.Velocity.X * 0.9f, Creature.Physics.Velocity.Y, Creature.Physics.Velocity.Z * 0.9f);
                        if (Creature.AI.Movement.CanFly)
                        {
                            Creature.Physics.ApplyForce(-Creature.Physics.Gravity * 0.1f, DwarfTime.Dt);
                        }
                        yield return(Status.Running);
                    }

                    timeout.Reset();
                    while (!Agent.Creature.Sprite.AnimPlayer.IsDone())
                    {
                        timeout.Update(DwarfTime.LastTime);
                        if (timeout.HasTriggered)
                        {
                            break;
                        }
                        if (Creature.AI.Movement.CanFly)
                        {
                            Creature.Physics.ApplyForce(-Creature.Physics.Gravity * 0.1f, DwarfTime.Dt);
                        }
                        yield return(Status.Running);
                    }

                    var targetCreature = Target.GetRoot().GetComponent <CreatureAI>();
                    if (targetCreature != null && !Creature.AI.FightOrFlight(targetCreature))
                    {
                        yield return(Act.Status.Fail);

                        yield break;
                    }
                    Creature.CurrentCharacterMode = CharacterMode.Attacking;

                    Vector3 dogfightTarget = Vector3.Zero;
                    while (!CurrentAttack.RechargeTimer.HasTriggered && !Target.IsDead)
                    {
                        CurrentAttack.RechargeTimer.Update(DwarfTime.LastTime);
                        if (CurrentAttack.Mode == Attack.AttackMode.Dogfight)
                        {
                            dogfightTarget += MathFunctions.RandVector3Cube() * 0.1f;
                            Vector3 output = Creature.Controller.GetOutput(DwarfTime.Dt, dogfightTarget + Target.Position, Creature.Physics.GlobalTransform.Translation) * 0.9f;
                            Creature.Physics.ApplyForce(output - Creature.Physics.Gravity, DwarfTime.Dt);
                        }
                        else
                        {
                            Creature.Physics.Velocity = Vector3.Zero;
                            if (Creature.AI.Movement.CanFly)
                            {
                                Creature.Physics.ApplyForce(-Creature.Physics.Gravity, DwarfTime.Dt);
                            }
                        }
                        yield return(Status.Running);
                    }

                    Creature.CurrentCharacterMode = defaultCharachterMode;
                    Creature.Physics.Orientation  = Physics.OrientMode.RotateY;

                    if (Target.IsDead)
                    {
                        Target = null;
                        Agent.AddXP(10);
                        Creature.Physics.Face(Creature.Physics.Velocity + Creature.Physics.GlobalTransform.Translation);
                        Creature.Stats.NumThingsKilled++;
                        Creature.AddThought(Thought.ThoughtType.KilledThing);
                        Creature.Physics.Orientation   = Physics.OrientMode.RotateY;
                        Creature.OverrideCharacterMode = false;
                        Creature.CurrentCharacterMode  = defaultCharachterMode;
                        yield return(Status.Success);

                        break;
                    }
                }

                yield return(Status.Running);
            }
        }
Ejemplo n.º 22
0
        private void DiscreteUpdate(ChunkManager ChunkManager, VoxelChunk chunk)
        {
            for (var y = 0; y < VoxelConstants.ChunkSizeY; ++y)
            {
                // Apply 'liquid present' tracking in voxel data to skip entire slices.
                if (chunk.Data.LiquidPresent[y] == 0)
                {
                    continue;
                }

                var layerOrder = SlicePermutations[MathFunctions.RandInt(0, SlicePermutations.Length)];

                for (var i = 0; i < layerOrder.Length; ++i)
                {
                    var x            = layerOrder[i] % VoxelConstants.ChunkSizeX;
                    var z            = (layerOrder[i] >> VoxelConstants.XDivShift) % VoxelConstants.ChunkSizeZ;
                    var currentVoxel = VoxelHandle.UnsafeCreateLocalHandle(chunk, new LocalVoxelCoordinate(x, y, z));

                    if (currentVoxel.TypeID != 0)
                    {
                        continue;
                    }

                    if (currentVoxel.LiquidType == LiquidType.None || currentVoxel.LiquidLevel < 1)
                    {
                        continue;
                    }

                    // Evaporate.
                    if (currentVoxel.LiquidLevel <= EvaporationLevel && MathFunctions.RandEvent(0.01f))
                    {
                        if (currentVoxel.LiquidType == LiquidType.Lava && Library.GetVoxelType("Stone").HasValue(out VoxelType stone))
                        {
                            currentVoxel.Type = stone;
                        }

                        NeedsMinimapUpdate = true;
                        currentVoxel.QuickSetLiquid(LiquidType.None, 0);
                        continue;
                    }

                    var voxBelow = ChunkManager.CreateVoxelHandle(new GlobalVoxelCoordinate(currentVoxel.Coordinate.X, currentVoxel.Coordinate.Y - 1, currentVoxel.Coordinate.Z));

                    if (voxBelow.IsValid && voxBelow.IsEmpty)
                    {
                        // Fall into the voxel below.

                        // Special case: No liquid below, just drop down.
                        if (voxBelow.LiquidType == LiquidType.None)
                        {
                            NeedsMinimapUpdate = true;
                            CreateSplash(currentVoxel.Coordinate.ToVector3(), currentVoxel.LiquidType);
                            voxBelow.QuickSetLiquid(currentVoxel.LiquidType, currentVoxel.LiquidLevel);
                            currentVoxel.QuickSetLiquid(LiquidType.None, 0);
                            continue;
                        }

                        var belowType      = voxBelow.LiquidType;
                        var aboveType      = currentVoxel.LiquidType;
                        var spaceLeftBelow = maxWaterLevel - voxBelow.LiquidLevel;

                        if (spaceLeftBelow >= currentVoxel.LiquidLevel)
                        {
                            NeedsMinimapUpdate = true;
                            CreateSplash(currentVoxel.Coordinate.ToVector3(), aboveType);
                            voxBelow.LiquidLevel += currentVoxel.LiquidLevel;
                            currentVoxel.QuickSetLiquid(LiquidType.None, 0);
                            HandleLiquidInteraction(voxBelow, aboveType, belowType);
                            continue;
                        }

                        if (spaceLeftBelow > 0)
                        {
                            NeedsMinimapUpdate = true;
                            CreateSplash(currentVoxel.Coordinate.ToVector3(), aboveType);
                            currentVoxel.LiquidLevel = (byte)(currentVoxel.LiquidLevel - maxWaterLevel + voxBelow.LiquidLevel);
                            voxBelow.LiquidLevel     = maxWaterLevel;
                            HandleLiquidInteraction(voxBelow, aboveType, belowType);
                            continue;
                        }
                    }
                    else if (voxBelow.IsValid && currentVoxel.LiquidType == LiquidType.Lava && !voxBelow.IsEmpty && voxBelow.GrassType > 0)
                    {
                        voxBelow.GrassType = 0;
                    }

                    if (currentVoxel.LiquidLevel <= 1)
                    {
                        continue;
                    }

                    // Nothing left to do but spread.

                    RollArray(NeighborPermutations[MathFunctions.RandInt(0, NeighborPermutations.Length)], NeighborScratch, MathFunctions.RandInt(0, 4));

                    for (var n = 0; n < NeighborScratch.Length; ++n)
                    {
                        var neighborOffset = VoxelHelpers.ManhattanNeighbors2D[NeighborScratch[n]];
                        var neighborVoxel  = new VoxelHandle(Chunks, currentVoxel.Coordinate + neighborOffset);

                        if (neighborVoxel.IsValid && neighborVoxel.IsEmpty)
                        {
                            if (neighborVoxel.LiquidLevel < currentVoxel.LiquidLevel)
                            {
                                NeedsMinimapUpdate = true;
                                var amountToMove = (int)(currentVoxel.LiquidLevel * GetSpreadRate(currentVoxel.LiquidType));
                                if (neighborVoxel.LiquidLevel + amountToMove > maxWaterLevel)
                                {
                                    amountToMove = maxWaterLevel - neighborVoxel.LiquidLevel;
                                }

                                if (amountToMove > 2)
                                {
                                    CreateSplash(neighborVoxel.Coordinate.ToVector3(), currentVoxel.LiquidType);
                                }

                                var newWater = currentVoxel.LiquidLevel - amountToMove;

                                var sourceType = currentVoxel.LiquidType;
                                var destType   = neighborVoxel.LiquidType;
                                currentVoxel.QuickSetLiquid(newWater == 0 ? LiquidType.None : sourceType, (byte)newWater);
                                neighborVoxel.QuickSetLiquid(destType == LiquidType.None ? sourceType : destType, (byte)(neighborVoxel.LiquidLevel + amountToMove));
                                HandleLiquidInteraction(neighborVoxel, sourceType, destType);
                                break;
                            }
                        }
                    }
                }
            }
        }
Ejemplo n.º 23
0
        public void GenerateVegetation(VoxelChunk chunk, ComponentManager components, ContentManager content, GraphicsDevice graphics)
        {
            int   waterHeight = (int)(SeaLevel * chunk.SizeY);
            bool  updated     = false;
            Voxel v           = chunk.MakeVoxel(0, 0, 0);
            Voxel vUnder      = chunk.MakeVoxel(0, 0, 0);

            for (int x = 0; x < chunk.SizeX; x++)
            {
                for (int z = 0; z < chunk.SizeZ; z++)
                {
                    Vector2         vec       = new Vector2(x + chunk.Origin.X, z + chunk.Origin.Z) / PlayState.WorldScale;
                    Overworld.Biome biome     = Overworld.Map[(int)MathFunctions.Clamp(vec.X, 0, Overworld.Map.GetLength(0) - 1), (int)MathFunctions.Clamp(vec.Y, 0, Overworld.Map.GetLength(1) - 1)].Biome;
                    BiomeData       biomeData = BiomeLibrary.Biomes[biome];

                    int y = chunk.GetFilledVoxelGridHeightAt(x, chunk.SizeY - 1, z);

                    if (!chunk.IsCellValid(x, (int)(y - chunk.Origin.Y), z))
                    {
                        continue;
                    }

                    v.GridPosition = new Vector3(x, y, z);

                    if (!v.IsEmpty || chunk.Data.Water[v.Index].WaterLevel != 0 || y <= waterHeight)
                    {
                        continue;
                    }

                    foreach (VegetationData veg in biomeData.Vegetation)
                    {
                        if (y <= 0)
                        {
                            continue;
                        }

                        if (!MathFunctions.RandEvent(veg.SpawnProbability))
                        {
                            continue;
                        }

                        if (NoiseGenerator.Noise(vec.X / veg.ClumpSize, veg.NoiseOffset, vec.Y / veg.ClumpSize) < veg.ClumpThreshold)
                        {
                            continue;
                        }

                        int yh = chunk.GetFilledVoxelGridHeightAt(x, y, z);

                        if (yh > 0)
                        {
                            vUnder.GridPosition = new Vector3(x, yh - 1, z);
                            if (!vUnder.IsEmpty && vUnder.TypeName == biomeData.GrassVoxel)
                            {
                                vUnder.Type = VoxelLibrary.GetVoxelType(biomeData.SoilVoxel);
                                updated     = true;
                                float offset = veg.VerticalOffset;
                                if (vUnder.RampType != RampType.None)
                                {
                                    offset -= 0.25f;
                                }
                                float treeSize = MathFunctions.Rand() * veg.SizeVariance + veg.MeanSize;
                                EntityFactory.CreateEntity <Body>(veg.Name, chunk.Origin + new Vector3(x, y, z) + new Vector3(0, treeSize * offset, 0), Blackboard.Create("Scale", treeSize));
                            }
                        }

                        break;
                    }
                }
            }

            if (updated)
            {
                chunk.ShouldRebuild = true;
            }
        }
Ejemplo n.º 24
0
        public override void OnVoxelsSelected(List <VoxelHandle> refs, InputManager.MouseButton button)
        {
            if (Command.Contains("Build/"))
            {
                string type = Command.Substring(6);
                var    room = RoomLibrary.CreateRoom(Player.Faction, type, Player.World);
                Player.Faction.RoomBuilder.DesignatedRooms.Add(room);
                RoomLibrary.CompleteRoomImmediately(room, refs);
            }
            if (Command.Contains("Spawn/"))
            {
                string type = Command.Substring(6);
                foreach (var vox in refs.Where(vox => vox.IsValid))
                {
                    if (vox.IsEmpty)
                    {
                        var craftItem = CraftLibrary.GetCraftable(type);
                        var offset    = Vector3.Zero;

                        if (craftItem != null)
                        {
                            offset = craftItem.SpawnOffset;
                        }

                        var body = EntityFactory.CreateEntity <Body>(type, vox.WorldPosition + new Vector3(0.5f, 0.0f, 0.5f) + offset);
                        if (body != null)
                        {
                            body.PropogateTransforms();

                            if (craftItem != null)
                            {
                                if (craftItem.AddToOwnedPool)
                                {
                                    Player.Faction.OwnedObjects.Add(body);
                                }

                                if (craftItem.Moveable)
                                {
                                    body.Tags.Add("Moveable");
                                }

                                if (craftItem.Deconstructable)
                                {
                                    body.Tags.Add("Deconstructable");
                                }
                            }
                        }
                    }
                }
            }
            else if (Command.Contains("Rail/"))
            {
                string type     = Command.Substring("Rail/".Length);
                var    junction = new Rail.JunctionPiece
                {
                    RailPiece   = type,
                    Orientation = Rail.PieceOrientation.North,
                    Offset      = Point.Zero
                };

                foreach (var vox in refs.Where(vox => vox.IsValid))
                {
                    if (vox.IsEmpty)
                    {
                        var entity = new Rail.RailEntity(Player.World.ComponentManager, vox, junction);
                        Player.World.ComponentManager.RootComponent.AddChild(entity);
                    }
                }
            }
            else if (Command.Contains("Grass/"))
            {
                var type = GrassLibrary.GetGrassType(Command.Substring(6));
                foreach (var vox in refs.Where(v => v.IsValid))
                {
                    var v = vox;
                    if (!vox.IsEmpty)
                    {
                        v.GrassType  = type.ID;
                        v.GrassDecay = type.InitialDecayValue;
                    }
                }
            }
            //else if (Command.Contains("Decal/"))
            //{
            //    var type = DecalLibrary.GetGrassType(Command.Substring(6));
            //    foreach (var vox in refs.Where(v => v.IsValid))
            //    {
            //        var v = vox;
            //        if (!vox.IsEmpty)
            //            v.Decal = DecalType.EncodeDecal(DecalOrientation, type.ID);
            //    }
            //}
            else
            {
                foreach (var vox in refs.Where(vox => vox.IsValid))
                {
                    if (Command.Contains("Place/"))
                    {
                        string type = Command.Substring(6);
                        var    v    = vox;
                        v.Type = VoxelLibrary.GetVoxelType(type);
                        v.QuickSetLiquid(LiquidType.None, 0);

                        if (type == "Magic")
                        {
                            Player.World.ComponentManager.RootComponent.AddChild(
                                new DestroyOnTimer(Player.World.ComponentManager, Player.World.ChunkManager, vox)
                            {
                                DestroyTimer = new Timer(5.0f + MathFunctions.Rand(-0.5f, 0.5f), true)
                            });
                        }
                    }
                    else
                    {
                        switch (Command)
                        {
                        case "Delete Block":
                        {
                            var v = vox;
                            Player.World.Master.Faction.OnVoxelDestroyed(vox);
                            v.Type = VoxelLibrary.emptyType;
                            v.QuickSetLiquid(LiquidType.None, 0);
                        }
                        break;

                        case "Kill Block":
                            foreach (var selected in refs)
                            {
                                if (!selected.IsEmpty)
                                {
                                    Player.World.ChunkManager.KillVoxel(selected);
                                }
                            }
                            break;

                        case "Fill Water":
                        {
                            if (vox.IsEmpty)
                            {
                                var v = vox;
                                v.QuickSetLiquid(LiquidType.Water, WaterManager.maxWaterLevel);
                            }
                        }
                        break;

                        case "Fill Lava":
                        {
                            if (vox.IsEmpty)
                            {
                                var v = vox;
                                v.QuickSetLiquid(LiquidType.Lava, WaterManager.maxWaterLevel);
                            }
                        }
                        break;

                        case "Fire":
                        {
                            foreach (var flam2 in Player.World.EnumerateIntersectingObjects(vox.GetBoundingBox(), CollisionType.Both).OfType <Flammable>())
                            {
                                flam2.Heat = flam2.Flashpoint + 1;
                            }
                        }
                        break;

                        case "Kill Things":
                        {
                            foreach (var comp in Player.World.EnumerateIntersectingObjects(vox.GetBoundingBox(), CollisionType.Both))
                            {
                                comp.Die();
                            }
                        }
                        break;

                        case "Disease":
                        {
                            foreach (var creature in Player.World.EnumerateIntersectingObjects(vox.GetBoundingBox(), CollisionType.Both).OfType <Creature>())
                            {
                                var disease = Datastructures.SelectRandom(DiseaseLibrary.Diseases);
                                creature.AcquireDisease(disease.Name);
                            }
                            break;
                        }

                        default:
                            break;
                        }
                    }
                }
            }
        }
Ejemplo n.º 25
0
        public void CreateMigration()
        {
            int   tries   = 0;
            float padding = 2.0f;

            while (tries < 10)
            {
                int         side   = MathFunctions.Random.Next(4);
                BoundingBox bounds = World.ChunkManager.Bounds;
                Vector3     pos    = Vector3.Zero;
                switch (side)
                {
                case 0:
                    pos = new Vector3(bounds.Min.X + padding, bounds.Max.Y - padding, MathFunctions.Rand(bounds.Min.Z + padding, bounds.Max.Z - padding));
                    break;

                case 1:
                    pos = new Vector3(bounds.Max.X - padding, bounds.Max.Y - padding, MathFunctions.Rand(bounds.Min.Z + padding, bounds.Max.Z - padding));
                    break;

                case 2:
                    pos = new Vector3(MathFunctions.Rand(bounds.Min.X + padding, bounds.Max.X - padding), bounds.Max.Y - padding, bounds.Min.Z + padding);
                    break;

                case 3:
                    pos = new Vector3(MathFunctions.Rand(bounds.Min.X + padding, bounds.Max.X - padding), bounds.Max.Y - padding, bounds.Max.Z - padding);
                    break;
                }

                var biome = World.Overworld.Map.GetBiomeAt(pos, World.Overworld.InstanceSettings.Origin);
                if (biome.Fauna.Count == 0)
                {
                    tries++;
                    continue;
                }

                var randomFauna  = Datastructures.SelectRandom(biome.Fauna);
                var testCreature = EntityFactory.CreateEntity <GameComponent>(randomFauna.Name, Vector3.Zero);

                if (testCreature == null)
                {
                    tries++;
                    continue;
                }

                var testCreatureAI = testCreature.GetRoot().GetComponent <CreatureAI>();
                if (testCreatureAI == null || testCreatureAI.Movement.IsSessile)
                {
                    testCreature.GetRoot().Delete();
                    tries++;
                    continue;
                }

                var count = World.GetSpeciesPopulation(testCreatureAI.Stats.CurrentClass);

                testCreature.GetRoot().Delete();

                if (count < 30)
                {
                    var randomNum = Math.Min(MathFunctions.RandInt(1, 3), 30 - count);
                    for (int i = 0; i < randomNum; i++)
                    {
                        var randompos = MathFunctions.Clamp(pos + MathFunctions.RandVector3Cube() * 2, World.ChunkManager.Bounds);
                        var vox       = VoxelHelpers.FindFirstVoxelBelow(new VoxelHandle(World.ChunkManager, GlobalVoxelCoordinate.FromVector3(pos)));
                        if (!vox.IsValid)
                        {
                            continue;
                        }
                        EntityFactory.CreateEntity <GameComponent>(randomFauna.Name, vox.GetBoundingBox().Center() + Vector3.Up * 1.5f);
                    }
                }
                break;
            }
        }
Ejemplo n.º 26
0
        public override void Construct()
        {
            var bottomBar = AddChild(new Widget()
            {
                AutoLayout  = AutoLayout.DockBottom,
                MinimumSize = new Point(Rect.Width - 128, 24)
            })
            ;

            bottomBar.AddChild(new Button()
            {
                Text        = "Back",
                OnClick     = (sender, args) => this.Close(),
                AutoLayout  = AutoLayout.DockLeft,
                MinimumSize = new Point(64, 24)
            });


            if (SoundManager.Mixer == null)
            {
                Text = "Error. Failed to load audio mixer :(";
                return;
            }

            bottomBar.AddChild(new Button()
            {
                Text        = "Save",
                OnClick     = (sender, args) => FileUtils.SaveBasicJson(SoundManager.Mixer, ContentPaths.mixer),
                AutoLayout  = AutoLayout.DockRight,
                MinimumSize = new Point(64, 24)
            });


            var listView = AddChild(new WidgetListView()
            {
                AutoLayout  = AutoLayout.DockBottom,
                MinimumSize = new Point(Rect.Width - 128, 512),
                ItemHeight  = 24
            });

            foreach (var level in SoundManager.Mixer.Gains)
            {
                var row = listView.AddChild(new Widget()
                {
                    AutoLayout  = AutoLayout.DockTop,
                    MinimumSize = new Point(512, 24)
                });

                row.AddChild(new Widget()
                {
                    Text                = level.Key,
                    TextColor           = Color.Black.ToVector4(),
                    AutoLayout          = AutoLayout.DockLeft,
                    TextVerticalAlign   = VerticalAlign.Center,
                    TextHorizontalAlign = HorizontalAlign.Right,
                    MinimumSize         = new Point(256, 24)
                });

                KeyValuePair <string, SFXMixer.Levels> level1 = level;
                row.AddChild(new HorizontalFloatSlider()
                {
                    ScrollArea      = 1.0f,
                    ScrollPosition  = level.Value.Volume,
                    MinimumSize     = new Point(256, 24),
                    AutoLayout      = AutoLayout.DockLeft,
                    OnSliderChanged = (sender) =>
                    {
                        SFXMixer.Levels levels = SoundManager.Mixer.GetOrCreateLevels(level1.Key);
                        SoundManager.Mixer.SetLevels(level1.Key,
                                                     new SFXMixer.Levels()
                        {
                            RandomPitch = level1.Value.RandomPitch,
                            Volume      = (sender as HorizontalFloatSlider).ScrollPosition
                        });
                        if (MathFunctions.RandEvent(0.15f))
                        {
                            SoundManager.PlaySound(level1.Key);
                        }
                    }
                });
            }
            Layout();

            base.Construct();
        }
Ejemplo n.º 27
0
        public bool PerformNoDamage(Creature performer, DwarfTime time, Vector3 pos)
        {
            switch (TriggerMode)
            {
            case AttackTrigger.Timer:
                RechargeTimer.Update(time);
                if (!RechargeTimer.HasTriggered)
                {
                    HasTriggered = false;
                    return(false);
                }
                break;

            case AttackTrigger.Animation:
                if (!performer.Sprite.AnimPlayer.HasValidAnimation() ||
                    performer.Sprite.AnimPlayer.CurrentFrame != TriggerFrame)
                {
                    HasTriggered = false;
                    return(false);
                }
                break;
            }
            if (Mode == AttackMode.Melee)
            {
                if (HitParticles != "")
                {
                    performer.Manager.World.ParticleManager.Trigger(HitParticles, pos, Color.White, 5);
                }


                if (HitAnimation != null && !HasTriggered)
                {
                    IndicatorManager.DrawIndicator(HitAnimation, pos, 10.0f, 1.0f, MathFunctions.RandVector2Circle(), Color.White, MathFunctions.Rand() > 0.5f);
                    PlayNoise(pos);
                }
            }
            HasTriggered = true;
            return(true);
        }
Ejemplo n.º 28
0
 public Point3 GetChunkID(Vector3 origin)
 {
     origin = RoundToChunkCoords(origin);
     return(new Point3(MathFunctions.FloorInt(origin.X), MathFunctions.FloorInt(origin.Y), MathFunctions.FloorInt(origin.Z)));
 }
Ejemplo n.º 29
0
        public bool Perform(Creature performer, Body other, DwarfTime time, float bonus, Vector3 pos, string faction)
        {
            switch (TriggerMode)
            {
            case AttackTrigger.Timer:
                RechargeTimer.Update(time);
                if (!RechargeTimer.HasTriggered)
                {
                    HasTriggered = false;
                    return(false);
                }
                break;

            case AttackTrigger.Animation:
                if (!performer.Sprite.AnimPlayer.HasValidAnimation() ||
                    performer.Sprite.AnimPlayer.CurrentFrame != TriggerFrame)
                {
                    HasTriggered = false;
                    return(false);
                }
                break;
            }

            if (HasTriggered)
            {
                return(true);
            }

            HasTriggered = true;
            switch (Mode)
            {
            case AttackMode.Melee:
            case AttackMode.Dogfight:
            {
                DoDamage(performer, other, bonus);
                break;
            }

            case AttackMode.Area:
            {
                BoundingBox box = new BoundingBox(performer.AI.Position - Vector3.One * Range, performer.AI.Position + Vector3.One * Range);
                foreach (var body in performer.World.EnumerateIntersectingObjects(box, CollisionType.Both))
                {
                    var creature = body.GetRoot().GetComponent <CreatureAI>();
                    if (creature == null)
                    {
                        var health = body.GetRoot().GetComponent <Health>();
                        if (health != null)
                        {
                            DoDamage(performer, body, bonus);
                        }
                        continue;
                    }
                    if (creature.Faction == performer.Faction)
                    {
                        continue;
                    }
                    var alliance = performer.World.Diplomacy.GetPolitics(creature.Faction, performer.Faction).GetCurrentRelationship() != Relationship.Hateful;
                    if (alliance)
                    {
                        continue;
                    }

                    DoDamage(performer, body, bonus);
                }
                break;
            }

            case AttackMode.Ranged:
            {
                PlayNoise(other.GlobalTransform.Translation);
                LaunchProjectile(pos, other.Position, other);

                var injury = DiseaseLibrary.GetRandomInjury();

                if (MathFunctions.RandEvent(injury.LikelihoodOfSpread))
                {
                    var creature = other.GetRoot().GetComponent <Creature>();
                    if (creature != null)
                    {
                        creature.AcquireDisease(injury.Name);
                    }
                }
                break;
            }
            }

            return(true);
        }
Ejemplo n.º 30
0
        public bool PerformNoDamage(Creature performer, DwarfTime time, Vector3 pos)
        {
            if (!performer.Sprite.AnimPlayer.HasValidAnimation() ||
                performer.Sprite.AnimPlayer.CurrentFrame != Weapon.TriggerFrame)
            {
                HasTriggered = false;
                return(false);
            }

            if (Weapon.Mode == Weapon.AttackMode.Melee)
            {
                if (Weapon.HitParticles != "")
                {
                    performer.Manager.World.ParticleManager.Trigger(Weapon.HitParticles, pos, Color.White, 5);
                }

                if (Weapon.HitAnimation != null && !HasTriggered)
                {
                    IndicatorManager.DrawIndicator(Weapon.HitAnimation, pos, 10.0f, 1.0f, MathFunctions.RandVector2Circle(), Color.White, MathFunctions.Rand() > 0.5f);
                    PlayNoise(pos);
                }
            }
            HasTriggered = true;
            return(true);
        }