Пример #1
0
        public override void Update(DwarfTime time)
        {
            if (ValueFn != null)
            {
                float value = ValueFn();

                if (value.CompareTo(LastValue) != 0)
                {
                    string operand = "-";
                    Color color = Color.Red;
                    if (value.CompareTo(LastValue) > 0)
                    {
                        operand = "+";
                        color = Color.Green;
                    }

                    IndicatorManager.DrawIndicator(operand + (value - LastValue).ToString(Format) + Postfix,
                        new Vector3(GlobalBounds.Center.X, GlobalBounds.Center.Y, 0), 1.0f, color, Indicator.IndicatorMode.Indicator2D);
                    LastValue = value;

                    Text = Prefix + value.ToString(Format) + Postfix;
                }
            }
            base.Update(time);
        }
Пример #2
0
        public override void Update(DwarfTime time)
        {
            base.Update(time);
            Animation.Update(time);

            Image = new ImageFrame(Animation.SpriteSheet.GetTexture(), Animation.GetCurrentFrameRect());
        }
Пример #3
0
        public virtual void Update(DwarfTime t)
        {
            Time.Update(t);

            if(IsDone())
            {
                OnComplete.Invoke();
            }
        }
Пример #4
0
 public override void Update(DwarfTime time)
 {
     if (Animation != null)
     {
         Animation.Update(time, Timer.TimerMode.Real);
         Image.Image = Animation.SpriteSheet.GetTexture();
         Image.SourceRect = Animation.GetCurrentFrameRect();
     }
     base.Update(time);
 }
Пример #5
0
        public override void Render(DwarfTime gameTime, ChunkManager chunks, Camera camera, SpriteBatch spriteBatch, GraphicsDevice graphicsDevice, Effect effect, bool renderingForWater)
        {
            base.Render(gameTime, chunks, camera, spriteBatch, graphicsDevice, effect, renderingForWater);
            effect.Parameters["xTexture"].SetValue(Texture);
            effect.Parameters["xWorld"].SetValue(GlobalTransform);

            foreach(EffectPass pass in effect.CurrentTechnique.Passes)
            {
                pass.Apply();
                Primitive.Render(graphicsDevice);
            }
        }
Пример #6
0
        public override void Render(DwarfTime time, SpriteBatch batch)
        {
            if(!IsVisible)
            {
                return;
            }

            if(DrawBounds)
            {
                GUI.Skin.RenderGroup(GlobalBounds, batch);
            }
            Drawer2D.DrawAlignedText(batch, Title, GUI.DefaultFont, Color.Black, Drawer2D.Alignment.Top | Drawer2D.Alignment.Left, GlobalBounds);
            base.Render(time, batch);
        }
Пример #7
0
        public override void Render(DwarfTime time, Microsoft.Xna.Framework.Graphics.SpriteBatch batch)
        {
            Drawer2D.FillRect(batch, GlobalBounds, CurrentColor);
            if (BorderWidth > 0)
            {
                Drawer2D.DrawRect(batch, GlobalBounds, BorderColor, BorderWidth);
            }

            if (IsMouseOver)
            {
                Color highlightColor = new Color(255 - CurrentColor.R, 255 - CurrentColor.G, 255 - CurrentColor.B);
                Drawer2D.DrawRect(batch, GlobalBounds, highlightColor, BorderWidth * 2 + 1);
            }

            base.Render(time, batch);
        }
Пример #8
0
        override public void Render(DwarfTime gameTime,
                                    ChunkManager chunks,
                                    Camera camera,
                                    SpriteBatch spriteBatch,
                                    GraphicsDevice graphicsDevice,
                                    Shader effect,
                                    bool renderingForWater)
        {
            if (!IsVisible)
            {
                return;
            }

            foreach (var layer in Layers)
            {
                if (layer.Verticies == null)
                {
                    float normalizeX = layer.Sheet.FrameWidth / (float)(layer.Sheet.Width);
                    float normalizeY = layer.Sheet.FrameWidth / (float)(layer.Sheet.Height);

                    List <Vector2> uvs = new List <Vector2>
                    {
                        new Vector2(0.0f, 0.0f),
                        new Vector2(1.0f, 0.0f),
                        new Vector2(1.0f, 1.0f),
                        new Vector2(0.0f, 1.0f)
                    };

                    Vector2 pixelCoords      = new Vector2(layer.Frame.X * layer.Sheet.FrameWidth, layer.Frame.Y * layer.Sheet.FrameHeight);
                    Vector2 normalizedCoords = new Vector2(pixelCoords.X / (float)layer.Sheet.Width, pixelCoords.Y / (float)layer.Sheet.Height);
                    var     bounds           = new Vector4(normalizedCoords.X + 0.001f, normalizedCoords.Y + 0.001f, normalizedCoords.X + normalizeX - 0.001f, normalizedCoords.Y + normalizeY - 0.001f);

                    for (int vert = 0; vert < 4; vert++)
                    {
                        uvs[vert] = new Vector2(normalizedCoords.X + uvs[vert].X * normalizeX, normalizedCoords.Y + uvs[vert].Y * normalizeY);
                    }


                    Vector3 topLeftFront  = new Vector3(-0.5f * WorldWidth, 0.5f * WorldHeight, 0.0f);
                    Vector3 topRightFront = new Vector3(0.5f * WorldWidth, 0.5f * WorldHeight, 0.0f);
                    Vector3 btmRightFront = new Vector3(0.5f * WorldWidth, -0.5f * WorldHeight, 0.0f);
                    Vector3 btmLeftFront  = new Vector3(-0.5f * WorldWidth, -0.5f * WorldHeight, 0.0f);

                    layer.Verticies = new[]
                    {
                        new ExtendedVertex(topLeftFront, Color.White, Color.White, uvs[0], bounds),  // 0
                        new ExtendedVertex(topRightFront, Color.White, Color.White, uvs[1], bounds), // 1
                        new ExtendedVertex(btmRightFront, Color.White, Color.White, uvs[2], bounds), // 2
                        new ExtendedVertex(btmLeftFront, Color.White, Color.White, uvs[3], bounds)   // 3
                    };

                    layer.Indicies = new int[]
                    {
                        0, 1, 3,
                        1, 2, 3
                    };
                }
            }

            // Everything that draws should set it's tint, making this pointless.
            Color origTint = effect.VertexColorTint;

            ApplyTintingToEffect(effect);

            var currDistortion = VertexNoise.GetNoiseVectorFromRepeatingTexture(GlobalTransform.Translation);
            var distortion     = currDistortion * 0.1f + prevDistortion * 0.9f;

            prevDistortion = distortion;
            switch (OrientationType)
            {
            case OrientMode.Spherical:
            {
                Matrix bill = Matrix.CreateBillboard(GlobalTransform.Translation, camera.Position, camera.UpVector, null) * Matrix.CreateTranslation(distortion);
                effect.World = bill;
                break;
            }

            case OrientMode.Fixed:
            {
                Matrix rotation = GlobalTransform;
                rotation.Translation = rotation.Translation + distortion;
                effect.World         = rotation;
                break;
            }

            case OrientMode.YAxis:
            {
                Matrix worldRot = Matrix.CreateConstrainedBillboard(GlobalTransform.Translation, camera.Position, Vector3.UnitY, null, null);
                worldRot.Translation = worldRot.Translation + distortion;
                effect.World         = worldRot;
                break;
            }
            }

            effect.EnableWind = EnableWind;

            foreach (var layer in Layers)
            {
                effect.MainTexture = layer.Sheet.GetTexture();

                if (DrawSilhouette)
                {
                    Color oldTint = effect.VertexColorTint;
                    effect.VertexColorTint           = SilhouetteColor;
                    graphicsDevice.DepthStencilState = DepthStencilState.None;
                    var oldTechnique = effect.CurrentTechnique;
                    effect.CurrentTechnique = effect.Techniques[Shader.Technique.Silhouette];
                    foreach (EffectPass pass in effect.CurrentTechnique.Passes)
                    {
                        pass.Apply();
                        graphicsDevice.DrawUserIndexedPrimitives(PrimitiveType.TriangleList,
                                                                 layer.Verticies, 0, 4, layer.Indicies, 0, 2);
                    }

                    graphicsDevice.DepthStencilState = DepthStencilState.Default;
                    effect.VertexColorTint           = oldTint;
                    effect.CurrentTechnique          = oldTechnique;
                }

                foreach (EffectPass pass in effect.CurrentTechnique.Passes)
                {
                    pass.Apply();
                    graphicsDevice.DrawUserIndexedPrimitives(PrimitiveType.TriangleList,
                                                             layer.Verticies, 0, 4, layer.Indicies, 0, 2);
                }
            }

            effect.VertexColorTint = origTint;
            effect.EnableWind      = false;
            EndDraw(effect);
        }
Пример #9
0
 public override void Render(DwarfTime gameTime)
 {
     DrawGUI(gameTime, 0);
     base.Render(gameTime);
 }
Пример #10
0
        override public void Update(DwarfTime gameTime, ChunkManager chunks, Camera camera)
        {
            base.Update(gameTime, chunks, camera);

            if (Active)
            {
                DeathTimer.Update(gameTime);

                switch (_state)
                {
                case State.Initializing:
                    if (PrepThread != null)
                    {
                        PrepThread.Abort();
                    }
                    PrepThread = new Thread(PrepareForExplosion)
                    {
                        IsBackground = true
                    };
                    _state = State.Prep;
                    PrepThread.Start();

                    foreach (GameComponent body in Manager.World.EnumerateIntersectingObjects(
                                 new BoundingBox(LocalPosition - new Vector3(VoxelRadius * 2.0f, VoxelRadius * 2.0f, VoxelRadius * 2.0f), LocalPosition + new Vector3(VoxelRadius * 2.0f, VoxelRadius * 2.0f, VoxelRadius * 2.0f)), CollisionType.Both))
                    {
                        var distance = (body.Position - LocalPosition).Length();
                        if (distance < (VoxelRadius * 2.0f))
                        {
                            var creature = body.EnumerateAll().OfType <CreatureAI>().FirstOrDefault();
                            if (creature != null)
                            {
                                creature.ChangeTask(new FleeEntityTask(this, VoxelRadius * 2));
                            }
                        }
                    }

                    break;

                case State.Prep:
                    if (PrepThread == null)     // Must have been saved mid-prep.
                    {
                        _state = State.Initializing;
                    }
                    break;

                case State.Ready:
                    if (OrderedExplosionList == null)     // Just a failsafe.
                    {
                        throw new InvalidOperationException();
                    }

                    float timeLeft  = (float)(DeathTimer.TargetTimeSeconds - DeathTimer.CurrentTimeSeconds);
                    float pulseRate = 15 - 2 * timeLeft;
                    float pulse     = (float)Math.Sin(timeLeft * pulseRate);
                    this.SetVertexColorRecursive(new Color(1.0f, 1.0f - pulse * pulse, 1.0f - pulse * pulse, 1.0f));
                    if (DeathTimer.HasTriggered)
                    {
                        _state = State.Exploding;
                        Manager.World.ParticleManager.Effects["explode"].Trigger(10, Position, Color.White);
                        SoundManager.PlaySound(ContentPaths.Audio.Oscar.sfx_trap_destroyed, 0.5f);

                        foreach (GameComponent body in Manager.World.EnumerateIntersectingObjects(
                                     new BoundingBox(LocalPosition - new Vector3(VoxelRadius * 2.0f, VoxelRadius * 2.0f, VoxelRadius * 2.0f), LocalPosition + new Vector3(VoxelRadius * 2.0f, VoxelRadius * 2.0f, VoxelRadius * 2.0f)), CollisionType.Both))
                        {
                            var distance = (body.Position - LocalPosition).Length();
                            if (distance <= (VoxelRadius * 2.0f))
                            {
                                var health = body.EnumerateAll().OfType <Health>().FirstOrDefault();
                                if (health != null)
                                {
                                    health.Damage(DamageAmount * (1.0f - (distance / (VoxelRadius * 2.0f))));     // Linear fall off on damage.
                                }
                            }
                        }
                    }

                    break;

                case State.Exploding:
                    SetFlagRecursive(Flag.Visible, false);
                    if (OrderedExplosionList == null)
                    {
                        throw new InvalidOperationException();
                    }

                    var voxelsExploded = 0;
                    while (true)
                    {
                        if (voxelsExploded >= VoxelsPerTick)
                        {
                            break;
                        }

                        if (ExplosionProgress >= OrderedExplosionList.Count)
                        {
                            GetRoot().Delete();
                            _state = State.Done;
                            foreach (var vox in OrderedExplosionList)
                            {
                                if (!vox.IsValid)
                                {
                                    continue;
                                }
                                var under = VoxelHelpers.GetVoxelBelow(vox);
                                if (under.IsValid && !under.IsEmpty && MathFunctions.RandEvent(0.5f))
                                {
                                    EntityFactory.CreateEntity <Fire>("Fire", vox.GetBoundingBox().Center());
                                }
                            }
                            break;
                        }

                        var nextVoxel = OrderedExplosionList[ExplosionProgress];
                        ExplosionProgress += 1;

                        if (nextVoxel.IsValid)
                        {
                            if (!nextVoxel.Type.IsInvincible && !nextVoxel.IsEmpty)
                            {
                                voxelsExploded += 1;
                                nextVoxel.Type  = Library.EmptyVoxelType;
                                Manager.World.ParticleManager.Effects["explode"].Trigger(1, nextVoxel.Coordinate.ToVector3() + new Vector3(0.5f, 0.5f, 0.5f), Color.White);
                                Manager.World.ParticleManager.Effects["dirt_particle"].Trigger(3, nextVoxel.Coordinate.ToVector3() + new Vector3(0.5f, 0.5f, 0.5f), Color.White);

                                Manager.World.OnVoxelDestroyed(nextVoxel);
                            }
                        }
                    }

                    break;

                case State.Done:
                default:
                    if (PrepThread != null)
                    {
                        PrepThread.Abort();
                    }
                    break;
                }
            }
        }
Пример #11
0
        public void Update(DwarfTime gameTime, ChunkManager chunks, Camera camera)
        {
            var body = Parent as Body;

            System.Diagnostics.Debug.Assert(body != null);

            Vector3 targetVelocity = TargetPosition - body.GlobalTransform.Translation;

            if (targetVelocity.LengthSquared() > 0.0001f)
            {
                targetVelocity.Normalize();
                targetVelocity *= MaxVelocity;
            }

            Matrix m = body.LocalTransform;

            m.Translation      += targetVelocity * (float)gameTime.ElapsedGameTime.TotalSeconds;
            body.LocalTransform = m;

            body.HasMoved = true;

            switch (State)
            {
            case BalloonState.DeliveringGoods:
            {
                var voxel = new VoxelHandle(chunks.ChunkData,
                                            GlobalVoxelCoordinate.FromVector3(body.GlobalTransform.Translation));

                if (voxel.IsValid)
                {
                    var surfaceVoxel = VoxelHelpers.FindFirstVoxelBelow(voxel);
                    var height       = surfaceVoxel.Coordinate.Y + 1;

                    TargetPosition = new Vector3(body.GlobalTransform.Translation.X, height + 5, body.GlobalTransform.Translation.Z);

                    Vector3 diff = body.GlobalTransform.Translation - TargetPosition;

                    if (diff.LengthSquared() < 2)
                    {
                        State = BalloonState.Waiting;
                    }
                }
                else
                {
                    State = BalloonState.Leaving;
                }
            }
            break;

            case BalloonState.Leaving:
                TargetPosition = Vector3.UnitY * 100 + body.GlobalTransform.Translation;

                if (body.GlobalTransform.Translation.Y > 300)
                {
                    Die();
                }

                break;

            case BalloonState.Waiting:
                TargetPosition = body.GlobalTransform.Translation;

                if (!shipmentGiven)
                {
                    shipmentGiven = true;
                }
                else
                {
                    State = BalloonState.Leaving;
                }


                break;
            }
        }
Пример #12
0
 public override void Update(DwarfTime time)
 {
     if (string.IsNullOrEmpty(CurrentValue))
     {
         if(Selector != null)
             Selector.CurrentValue = Values[CurrentIndex];
         CurrentValue = Values[CurrentIndex];
     }
     base.Update(time);
 }
Пример #13
0
        public virtual void Update(DwarfTime gameTime, Timer.TimerMode mode = Timer.TimerMode.Game)
        {
            if(IsPlaying)
            {
                float dt = mode == Timer.TimerMode.Game ? (float)gameTime.ElapsedGameTime.TotalSeconds : (float)gameTime.ElapsedRealTime.TotalSeconds;
                FrameTimer += dt;

                float time = FrameHZ;

                if (Speeds.Count > 0)
                {
                    time = Speeds[Math.Min(CurrentFrame, Speeds.Count - 1)];
                }
                if(FrameTimer * SpeedMultiplier >= 1.0f / time)
                {
                    NextFrame();
                    FrameTimer = 0.0f;
                }
            }
        }
Пример #14
0
        public void Update(DwarfTime time, DateTime currentDate)
        {
            foreach (var mypolitics in FactionPolitics)
            {
                Pair<Faction> pair = mypolitics.Key;
                if (!pair.IsSelfPair() && pair.Contains(PlayState.PlayerFaction))
                {
                    Faction otherFaction = null;

                    otherFaction = pair.First.Equals(PlayState.PlayerFaction) ? pair.Second : pair.First;

                    Race race = otherFaction.Race;
                    Politics relation = mypolitics.Value;

                    if (race.IsIntelligent && race.IsNative && !otherFaction.IsRaceFaction && !relation.HasMet && MathFunctions.RandEvent(1e-2f))
                    {
                        SendTradeEnvoy(otherFaction);
                    }

                    if (race.IsIntelligent && race.IsNative && !otherFaction.IsRaceFaction && relation.GetCurrentRelationship() == Relationship.Hates && MathFunctions.RandEvent(1e-7f))
                    {
                        SendWarParty(otherFaction);
                    }
                }
                mypolitics.Value.UpdateEvents(currentDate);
            }
        }
Пример #15
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;
                        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;
                    }
                }
            }

            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;
                    RainDrops[i].Particle = null;
                }
                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.ChunkData,
                                           GlobalVoxelCoordinate.FromVector3(RainDrops[i].Pos));
                if (!test.IsValid || test.IsEmpty || test.LiquidLevel > 0)
                {
                    continue;
                }

                RainDrops[i].IsAlive = false;
                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  = GrassLibrary.GetGrassType("snow").ID;
                        test.GrassDecay = GrassLibrary.GetGrassType("snow").InitialDecayValue;
                    }
                    else
                    {
                        var existingGrass = GrassLibrary.GetGrassType((byte)test.GrassType);
                        if (!String.IsNullOrEmpty(existingGrass.BecomeWhenSnowedOn))
                        {
                            var newGrass = GrassLibrary.GetGrassType(existingGrass.BecomeWhenSnowedOn);
                            test.GrassType  = newGrass.ID;
                            test.GrassDecay = newGrass.InitialDecayValue;
                        }
                    }
                }
            }

            Matrix tf = LocalTransform;

            tf.Translation += Velocity * DwarfTime.Dt;
            LocalTransform  = tf;
        }
Пример #16
0
 public void Render(DwarfTime gameTime, GraphicsDevice graphics, Effect effect)
 {
 }
Пример #17
0
        // Find a path from the start to the goal by computing an inverse path from goal to the start. Should only be used
        // if the forward path fails.
        private static PlanResult InversePath(CreatureMovement mover, VoxelHandle startVoxel, GoalRegion goal, ChunkManager chunks,
                                              int maxExpansions, ref List <MoveAction> toReturn, float weight, Func <bool> continueFunc)
        {
            // Create a local clone of the octree, using only the objects belonging to the player.
            var         octree          = new OctTreeNode <Body>(mover.Creature.World.ChunkManager.Bounds.Min, mover.Creature.World.ChunkManager.Bounds.Max);
            List <Body> playerObjects   = new List <Body>(mover.Creature.World.PlayerFaction.OwnedObjects);
            List <Body> teleportObjects = mover.Creature.World.PlayerFaction.OwnedObjects.Where(o => o.Tags.Contains("Teleporter")).ToList();

            foreach (var obj in playerObjects)
            {
                octree.Add(obj, obj.GetBoundingBox());
            }

            MoveState start = new MoveState()
            {
                Voxel = startVoxel
            };

            var startTime = DwarfTime.Tick();

            if (mover.IsSessile)
            {
                return(new PlanResult()
                {
                    Result = PlanResultCode.Invalid,
                    Expansions = 0,
                    TimeSeconds = 0
                });
            }

            if (!start.IsValid)
            {
                return(new PlanResult()
                {
                    Result = PlanResultCode.Invalid,
                    Expansions = 0,
                    TimeSeconds = 0
                });
            }


            // Sometimes a goal may not even be achievable a.priori. If this is true, we know there can't be a path
            // which satisifies that goal.
            // It only makes sense to do inverse plans for goals that have an associated voxel.
            if (!goal.IsPossible() || !goal.GetVoxel().IsValid)
            {
                toReturn = null;
                return(new PlanResult()
                {
                    Result = PlanResultCode.Invalid,
                    Expansions = 0,
                    TimeSeconds = 0
                });
            }


            if (goal.IsInGoalRegion(start.Voxel))
            {
                toReturn = new List <MoveAction>();
                return(new PlanResult()
                {
                    Result = PlanResultCode.Success,
                    Expansions = 0,
                    TimeSeconds = 0
                });
            }

            // Voxels that have already been explored.
            var closedSet = new HashSet <MoveState>();

            // Voxels which should be explored.
            var openSet = new HashSet <MoveState>();

            // Dictionary of voxels to the optimal action that got the mover to that voxel.
            var cameFrom = new Dictionary <MoveState, MoveAction>();

            // Optimal score of a voxel based on the path it took to get there.
            var gScore = new Dictionary <MoveState, float>();

            // Expansion priority of voxels.
            var fScore = new PriorityQueue <MoveState>();

            var goalVoxels = new List <VoxelHandle>();

            goalVoxels.Add(goal.GetVoxel());
            // Starting conditions of the search.

            foreach (var goalVoxel in VoxelHelpers.EnumerateCube(goal.GetVoxel().Coordinate)
                     .Select(c => new VoxelHandle(start.Voxel.Chunk.Manager.ChunkData, c)))
            {
                if (!goalVoxel.IsValid)
                {
                    continue;
                }
                var goalState = new MoveState()
                {
                    Voxel = goalVoxel
                };
                if (goal.IsInGoalRegion(goalVoxel))
                {
                    goalVoxels.Add(goalVoxel);
                    openSet.Add(goalState);
                    gScore[goalState] = 0.0f;
                    fScore.Enqueue(goalState,
                                   gScore[goalState] + weight * (goalVoxel.WorldPosition - start.Voxel.WorldPosition).LengthSquared());
                }
            }

            // Keep count of the number of expansions we've taken to get to the goal.
            int numExpansions = 0;

            // Loop until we've either checked every possible voxel, or we've exceeded the maximum number of
            // expansions.
            while (openSet.Count > 0 && numExpansions < maxExpansions)
            {
                if (numExpansions % 10 == 0 && !continueFunc())
                {
                    return new PlanResult
                           {
                               Result      = PlanResultCode.Cancelled,
                               Expansions  = numExpansions,
                               TimeSeconds = DwarfTime.Tock(startTime)
                           }
                }
                ;

                // Check the next voxel to explore.
                var current = GetStateWithMinimumFScore(fScore);
                if (!current.IsValid)
                {
                    continue;
                }
                //Drawer3D.DrawBox(current.GetBoundingBox(), Color.Blue, 0.1f);
                numExpansions++;

                // If we've reached the goal already, reconstruct the path from the start to the
                // goal.
                if (current.Equals(start))
                {
                    toReturn = ReconstructInversePath(goal, cameFrom, cameFrom[start]);
                    return(new PlanResult()
                    {
                        Result = PlanResultCode.Success,
                        Expansions = numExpansions,
                        TimeSeconds = DwarfTime.Tock(startTime)
                    });
                }

                // We've already considered the voxel, so add it to the closed set.
                openSet.Remove(current);
                closedSet.Add(current);

                IEnumerable <MoveAction> neighbors = null;

                // Get the voxels that can be moved to from the current voxel.
                neighbors = mover.GetInverseMoveActions(current, octree, teleportObjects);

                // Otherwise, consider all of the neighbors of the current voxel that can be moved to,
                // and determine how to add them to the list of expansions.
                foreach (MoveAction n in neighbors)
                {
                    //Drawer3D.DrawBox(n.SourceVoxel.GetBoundingBox(), Color.Red, 0.1f);
                    // If we've already explored that voxel, don't explore it again.
                    if (closedSet.Contains(n.SourceState))
                    {
                        continue;
                    }

                    // Otherwise, consider the case of moving to that neighbor.
                    float tenativeGScore = gScore[current] + GetDistance(current.Voxel, n.SourceState.Voxel, n.MoveType, mover);

                    // IF the neighbor can already be reached more efficiently, ignore it.
                    if (openSet.Contains(n.SourceState) && gScore.ContainsKey(n.SourceState) && !(tenativeGScore < gScore[n.SourceState]))
                    {
                        continue;
                    }

                    // Otherwise, add it to the list of voxels for consideration.
                    openSet.Add(n.SourceState);

                    // Add an edge to the voxel from the current voxel.
                    var cameAction = n;
                    cameFrom[n.SourceState] = cameAction;

                    // Update the expansion scores for the next voxel.
                    gScore[n.SourceState] = tenativeGScore;
                    fScore.Enqueue(n.SourceState, gScore[n.SourceState] + weight * ((n.SourceState.Voxel.WorldPosition - start.Voxel.WorldPosition).LengthSquared() + (!n.SourceState.VehicleState.IsRidingVehicle ? 100.0f : 0.0f)));
                }

                // If we've expanded too many voxels, just give up.
                if (numExpansions >= maxExpansions)
                {
                    return(new PlanResult()
                    {
                        Result = PlanResultCode.MaxExpansionsReached,
                        Expansions = numExpansions,
                        TimeSeconds = DwarfTime.Tock(startTime)
                    });
                }
            }

            // Somehow we've reached this code without having found a path. Return false.
            toReturn = null;
            return(new PlanResult()
            {
                Result = PlanResultCode.NoSolution,
                Expansions = numExpansions,
                TimeSeconds = DwarfTime.Tock(startTime)
            });
        }
Пример #18
0
        /// <summary>
        ///     Creates a path from the start voxel to some goal region, returning a list of movements that can
        ///     take a mover from the start voxel to the goal region.
        /// </summary>
        /// <param name="mover">The agent that we want to find a path for.</param>
        /// <param name="startVoxel"></param>
        /// <param name="goal">Goal conditions that the agent is trying to satisfy.</param>
        /// <param name="chunks">The voxels that the agent is moving through</param>
        /// <param name="maxExpansions">Maximum number of voxels to consider before giving up.</param>
        /// <param name="toReturn">The path of movements that the mover should take to reach the goal.</param>
        /// <param name="weight">
        ///     A heuristic weight to apply to the planner. If 1.0, the path is garunteed to be optimal. Higher values
        ///     usually result in faster plans that are suboptimal.
        /// </param>
        /// <param name="continueFunc"></param>
        /// <returns>True if a path could be found, or false otherwise.</returns>
        private static PlanResult Path(
            CreatureMovement mover,
            VoxelHandle startVoxel,
            GoalRegion goal,
            ChunkManager chunks,
            int maxExpansions,
            ref List <MoveAction> toReturn,
            float weight,
            Func <bool> continueFunc)
        {
            // Create a local clone of the octree, using only the objects belonging to the player.
            var octree = new OctTreeNode <Body>(mover.Creature.World.ChunkManager.Bounds.Min, mover.Creature.World.ChunkManager.Bounds.Max);

            List <Body> playerObjects   = new List <Body>(mover.Creature.World.PlayerFaction.OwnedObjects);
            List <Body> teleportObjects = playerObjects.Where(o => o.Tags.Contains("Teleporter")).ToList();

            foreach (var obj in playerObjects)
            {
                octree.Add(obj, obj.GetBoundingBox());
            }

            var storage = new MoveActionTempStorage();

            var start = new MoveState()
            {
                Voxel = startVoxel
            };

            var startTime = DwarfTime.Tick();

            if (mover.IsSessile)
            {
                return(new PlanResult()
                {
                    Expansions = 0,
                    Result = PlanResultCode.Invalid,
                    TimeSeconds = DwarfTime.Tock(startTime)
                });
            }

            // Sometimes a goal may not even be achievable a.priori. If this is true, we know there can't be a path
            // which satisifies that goal.
            if (!goal.IsPossible())
            {
                toReturn = null;
                return(new PlanResult()
                {
                    Expansions = 0,
                    Result = PlanResultCode.Invalid,
                    TimeSeconds = DwarfTime.Tock(startTime)
                });
            }

            // Voxels that have already been explored.
            var closedSet = new HashSet <MoveState>();

            // Voxels which should be explored.
            var openSet = new HashSet <MoveState>
            {
                start
            };

            // Dictionary of voxels to the optimal action that got the mover to that voxel.
            var cameFrom = new Dictionary <MoveState, MoveAction>();

            // Optimal score of a voxel based on the path it took to get there.
            var gScore = new Dictionary <MoveState, float>();

            // Expansion priority of voxels.
            var fScore = new PriorityQueue <MoveState>();

            // Starting conditions of the search.
            gScore[start] = 0.0f;
            fScore.Enqueue(start, gScore[start] + weight * goal.Heuristic(start.Voxel));

            // Keep count of the number of expansions we've taken to get to the goal.
            int numExpansions = 0;

            // Check the voxels adjacent to the current voxel as a quick test of adjacency to the goal.
            //var manhattanNeighbors = new List<VoxelHandle>(6);
            //for (int i = 0; i < 6; i++)
            //{
            //    manhattanNeighbors.Add(new VoxelHandle());
            //}

            // Loop until we've either checked every possible voxel, or we've exceeded the maximum number of
            // expansions.
            while (openSet.Count > 0 && numExpansions < maxExpansions)
            {
                if (numExpansions % 10 == 0 && !continueFunc())
                {
                    return new PlanResult
                           {
                               Result      = PlanResultCode.Cancelled,
                               Expansions  = numExpansions,
                               TimeSeconds = DwarfTime.Tock(startTime)
                           }
                }
                ;


                // Check the next voxel to explore.
                var current = GetStateWithMinimumFScore(fScore);
                if (!current.IsValid)
                {
                    // If there wasn't a voxel to explore, just try to expand from
                    // the start again.
                    numExpansions++;

                    continue;
                }

                numExpansions++;

                // If we've reached the goal already, reconstruct the path from the start to the
                // goal.


                if (goal.IsInGoalRegion(current.Voxel) && cameFrom.ContainsKey(current))
                {
                    toReturn = ReconstructPath(cameFrom, cameFrom[current], start);
                    return(new PlanResult()
                    {
                        Result = PlanResultCode.Success,
                        Expansions = numExpansions,
                        TimeSeconds = DwarfTime.Tock(startTime)
                    });
                }

                // We've already considered the voxel, so add it to the closed set.
                openSet.Remove(current);
                closedSet.Add(current);

                // Get the voxels that can be moved to from the current voxel.
                var neighbors = mover.GetMoveActions(current, octree, teleportObjects, storage).ToList();

                var foundGoalAdjacent = neighbors.FirstOrDefault(n => !n.DestinationState.VehicleState.IsRidingVehicle && goal.IsInGoalRegion(n.DestinationState.Voxel));

                // A quick test to see if we're already adjacent to the goal. If we are, assume
                // that we can just walk to it.
                if (foundGoalAdjacent.DestinationState.IsValid && foundGoalAdjacent.SourceState.IsValid)
                {
                    if (cameFrom.ContainsKey(current))
                    {
                        toReturn = ReconstructPath(cameFrom, foundGoalAdjacent, start);
                        return(new PlanResult()
                        {
                            Result = PlanResultCode.Success,
                            Expansions = numExpansions,
                            TimeSeconds = DwarfTime.Tock(startTime)
                        });
                    }
                }

                // Otherwise, consider all of the neighbors of the current voxel that can be moved to,
                // and determine how to add them to the list of expansions.
                foreach (MoveAction n in neighbors)
                {
                    // If we've already explored that voxel, don't explore it again.
                    if (closedSet.Contains(n.DestinationState))
                    {
                        continue;
                    }

                    // Otherwise, consider the case of moving to that neighbor.
                    float tenativeGScore = gScore[current] + GetDistance(current.Voxel, n.DestinationState.Voxel, n.MoveType, mover);

                    // IF the neighbor can already be reached more efficiently, ignore it.
                    if (openSet.Contains(n.DestinationState) && !(tenativeGScore < gScore[n.DestinationState]))
                    {
                        continue;
                    }

                    // Otherwise, add it to the list of voxels for consideration.
                    openSet.Add(n.DestinationState);

                    // Add an edge to the voxel from the current voxel.
                    var cameAction = n;
                    cameFrom[n.DestinationState] = cameAction;

                    // Update the expansion scores for the next voxel.
                    gScore[n.DestinationState] = tenativeGScore;
                    fScore.Enqueue(n.DestinationState, gScore[n.DestinationState] + weight * (goal.Heuristic(n.DestinationState.Voxel) + (!n.DestinationState.VehicleState.IsRidingVehicle ? 100.0f : 0.0f)));
                }

                // If we've expanded too many voxels, just give up.
                if (numExpansions >= maxExpansions)
                {
                    return(new PlanResult()
                    {
                        Expansions = numExpansions,
                        Result = PlanResultCode.MaxExpansionsReached,
                        TimeSeconds = DwarfTime.Tock(startTime)
                    });
                }
            }

            // Somehow we've reached this code without having found a path. Return false.
            toReturn = null;
            return(new PlanResult()
            {
                Expansions = numExpansions,
                Result = PlanResultCode.NoSolution,
                TimeSeconds = DwarfTime.Tock(startTime)
            });
        }
Пример #19
0
        override public void Update(DwarfTime gameTime, ChunkManager chunks, Camera camera)
        {
            //base.Update(gameTime, chunks, camera);

            if (!Active)
            {
                return;
            }
            Creature.NoiseMaker.BasePitch = Stats.VoicePitch;

            AutoGatherTimer.Update(gameTime);
            IdleTimer.Update(gameTime);
            SpeakTimer.Update(gameTime);

            if (AutoGatherTimer.HasTriggered)
            {
                foreach (var body in World.EnumerateIntersectingObjects(Physics.BoundingBox.Expand(3.0f)).OfType <ResourceEntity>().Where(r => r.Active && r.AnimationQueue.Count == 0))
                {
                    Creature.GatherImmediately(body, Inventory.RestockType.RestockResource);
                }

                OrderEnemyAttack();
            }

            DeleteBadTasks();
            PreEmptTasks();

            if (CurrentTask != null)
            {
                Stats.Boredom.CurrentValue -= (float)(CurrentTask.BoredomIncrease * gameTime.ElapsedGameTime.TotalSeconds);
                if (Stats.Boredom.IsCritical())
                {
                    Creature.AddThought("I have been overworked recently.", new TimeSpan(0, 4, 0, 0), -2.0f);
                }

                Stats.Energy.CurrentValue += (float)(CurrentTask.EnergyDecrease * gameTime.ElapsedGameTime.TotalSeconds);
            }

            // Heal thyself
            if (Stats.Health.IsDissatisfied())
            {
                Task toReturn = new GetHealedTask();
                if (!Tasks.Contains(toReturn) && CurrentTask != toReturn)
                {
                    AssignTask(toReturn);
                }
            }

            // Try to go to sleep if we are low on energy and it is night time.
            if (Stats.Energy.IsCritical())
            {
                Task toReturn = new SatisfyTirednessTask();
                if (!Tasks.Contains(toReturn) && CurrentTask != toReturn)
                {
                    AssignTask(toReturn);
                }
            }

            // Try to find food if we are hungry.
            if (Stats.Hunger.IsDissatisfied() && World.CountResourcesWithTag(Resource.ResourceTags.Edible) > 0)
            {
                Task toReturn = new SatisfyHungerTask()
                {
                    MustPay = true
                };
                if (Stats.Hunger.IsCritical())
                {
                    toReturn.Priority = TaskPriority.Urgent;
                }
                if (!Tasks.Contains(toReturn) && CurrentTask != toReturn)
                {
                    AssignTask(toReturn);
                }
            }

            if (Stats.Boredom.IsDissatisfied())
            {
                if (!Tasks.Any(task => task.BoredomIncrease < 0))
                {
                    Task toReturn = SatisfyBoredom();
                    if (toReturn != null && !Tasks.Contains(toReturn) && CurrentTask != toReturn)
                    {
                        AssignTask(toReturn);
                    }
                }
            }

            restockTimer.Update(DwarfTime.LastTime);
            if (restockTimer.HasTriggered && Creature.Inventory.Resources.Count > 10)
            {
                Creature.RestockAllImmediately();
            }

            if (CurrentTask == null)               // We need something to do.
            {
                if (Stats.Happiness.IsSatisfied()) // We're happy, so make sure we aren't on strike.
                {
                    Stats.IsOnStrike = false;
                    UnhappinessTime  = 0.0f;
                }

                if (Stats.IsOnStrike) // We're on strike, so track how long this job has sucked.
                {
                    UnhappinessTime += gameTime.ElapsedGameTime.TotalMinutes;
                    if (UnhappinessTime > GameSettings.Default.HoursUnhappyBeforeQuitting) // If we've been unhappy long enough, quit.
                    {
                        if (GetRoot().GetComponent <DwarfThoughts>().HasValue(out var thoughts))
                        {
                            Manager.World.MakeAnnouncement( // Can't use a popup because the dwarf will soon not exist. Also - this is a serious event!
                                Message: String.Format("{0} has quit! The last straw: {1}",
                                                       Stats.FullName,
                                                       thoughts.Thoughts.Last(t => t.HappinessModifier < 0.0f).Description),
                                ClickAction: null,
                                logEvent: true,
                                eventDetails: String.Join("\n", thoughts.Thoughts.Where(t => t.HappinessModifier < 0.0f).Select(t => t.Description)));

                            thoughts.Thoughts.Clear();
                        }
                        else
                        {
                            Manager.World.MakeAnnouncement( // Can't use a popup because the dwarf will soon not exist. Also - this is a serious event!
                                Message: String.Format("{0} has quit!", Stats.FullName),
                                ClickAction: null,
                                logEvent: true,
                                eventDetails: "So sick of this place!");
                        }

                        LeaveWorld();

                        if (GetRoot().GetComponent <Inventory>().HasValue(out var inv))
                        {
                            inv.Die();
                        }

                        if (GetRoot().GetComponent <SelectionCircle>().HasValue(out var sel))
                        {
                            sel.Die();
                        }

                        Faction.Minions.Remove(this);
                        World.PersistentData.SelectedMinions.Remove(this);

                        return;
                    }
                }
                else if (Stats.Happiness.IsDissatisfied()) // We aren't on strike, but we hate this place.
                {
                    if (MathFunctions.Rand(0, 1) < 0.25f)  // We hate it so much that we might just go on strike! This can probably be tweaked. As it stands,
                                                           // dorfs go on strike almost immediately every time.
                    {
                        Manager.World.UserInterface.MakeWorldPopup(String.Format("{0} ({1}) refuses to work!",
                                                                                 Stats.FullName, Stats.CurrentClass.Name), Creature.Physics, -10, 10);
                        Manager.World.Tutorial("happiness");
                        SoundManager.PlaySound(ContentPaths.Audio.Oscar.sfx_gui_negative_generic, 0.25f);
                        Stats.IsOnStrike = true;
                    }
                }

                if (!Stats.IsOnStrike) // We aren't on strike, so find a new task.
                {
                    var goal = GetEasiestTask(Tasks);
                    if (goal == null)
                    {
                        goal = World.TaskManager.GetBestTask(this);
                    }

                    if (goal != null)
                    {
                        IdleTimer.Reset(IdleTimer.TargetTimeSeconds);
                        ChangeTask(goal);
                    }
                    else
                    {
                        var newTask = ActOnIdle();
                        if (newTask != null)
                        {
                            ChangeTask(newTask);
                        }
                    }
                }
                else
                {
                    ChangeTask(ActOnIdle());
                }
            }
            else
            {
                if (!CurrentAct.HasValue()) // Should be impossible to have a current task and no current act.
                {
                    // Try and recover the correct act.
                    // <blecki> I always run with a breakpoint set here... just in case.
                    ChangeAct(CurrentTask.CreateScript(Creature));

                    // This is a bad situation!
                    if (!CurrentAct.HasValue())
                    {
                        ChangeTask(null);
                    }
                }

                if (CurrentAct.HasValue(out Act currentAct))
                {
                    var  status  = currentAct.Tick();
                    bool retried = false;

                    if (CurrentAct.HasValue(out Act newCurrentAct) && CurrentTask != null)
                    {
                        if (status == Act.Status.Fail)
                        {
                            LastFailedAct = newCurrentAct.Name;

                            if (!FailedTasks.Any(task => task.TaskFailure.Equals(CurrentTask)))
                            {
                                FailedTasks.Add(new FailedTask()
                                {
                                    TaskFailure = CurrentTask, FailedTime = World.Time.CurrentDate
                                });
                            }

                            if (CurrentTask.ShouldRetry(Creature))
                            {
                                if (!Tasks.Contains(CurrentTask))
                                {
                                    ReassignCurrentTask();
                                    retried = true;
                                }
                            }
                        }
                    }

                    if (CurrentTask != null && CurrentTask.IsComplete(World))
                    {
                        ChangeTask(null);
                    }
                    else if (status != Act.Status.Running && !retried)
                    {
                        ChangeTask(null);
                    }
                }
            }

            // With a small probability, the creature will drown if its under water.
            if (MathFunctions.RandEvent(0.01f))
            {
                var  above       = VoxelHelpers.GetVoxelAbove(Physics.CurrentVoxel);
                var  below       = VoxelHelpers.GetVoxelBelow(Physics.CurrentVoxel);
                bool shouldDrown = (above.IsValid && (!above.IsEmpty || above.LiquidLevel > 0));
                if ((Physics.IsInLiquid || (!Movement.CanSwim && (below.IsValid && (below.LiquidLevel > 5)))) &&
                    (!Movement.CanSwim || shouldDrown))
                {
                    Creature.Damage(Movement.CanSwim ? 1.0f : 30.0f, Health.DamageType.Normal);
                }
            }

            if (PositionConstraint.Contains(Physics.LocalPosition) == ContainmentType.Disjoint)
            {
                Physics.LocalPosition = MathFunctions.Clamp(Physics.Position, PositionConstraint);
                Physics.PropogateTransforms();
            }
        }
Пример #20
0
 override public void Update(DwarfTime gameTime, ChunkManager chunks, Camera camera)
 {
     ImplementUpdate(gameTime, chunks);
     base.Update(gameTime, chunks, camera);
 }
Пример #21
0
 public override void UpdatePaused(DwarfTime Time, ChunkManager Chunks, Camera Camera)
 {
     ImplementUpdate(Time, Chunks);
     base.UpdatePaused(Time, Chunks, Camera);
 }
Пример #22
0
        public override void Render(DwarfGame game, GraphicsDevice graphics, DwarfTime time)
        {
            Color drawColor = DesignationColor;

            float alpha = (float)Math.Abs(Math.Sin(time.TotalGameTime.TotalSeconds * GlowRate));
            drawColor.R = (byte)(Math.Min(drawColor.R * alpha + 50, 255));
            drawColor.G = (byte)(Math.Min(drawColor.G * alpha + 50, 255));
            drawColor.B = (byte)(Math.Min(drawColor.B * alpha + 50, 255));

            foreach (BoundingBox box in Player.Faction.AttackDesignations.Select(d => d.GetBoundingBox()))
            {
                Drawer3D.DrawBox(box, drawColor, 0.05f * alpha + 0.05f, true);
            }
        }
Пример #23
0
        public override void Render(DwarfTime time, SpriteBatch batch)
        {
            if(!IsVisible)
            {
                return;
            }

            base.Render(time, batch);
        }
Пример #24
0
 override public void Render(DwarfTime gameTime, ChunkManager chunks, Camera camera, SpriteBatch spriteBatch,
                             GraphicsDevice graphicsDevice, Shader effect, bool renderingForWater)
 {
     base.Render(gameTime, chunks, camera, spriteBatch, graphicsDevice, effect, renderingForWater);
 }
Пример #25
0
        public void Splash(DwarfTime time)
        {
            while(Splashes.Count > 0)
            {
                SplashType splash;

                if(!Splashes.TryDequeue(out splash))
                {
                    break;
                }

                PlayState.ParticleManager.Trigger(splash.name, splash.position + new Vector3(0.5f, 0.5f, 0.5f), Color.White, splash.numSplashes);

                if(splashNoiseLimiter[splash.name].HasTriggered)
                {
                    SoundManager.PlaySound(splash.sound, splash.position + new Vector3(0.5f, 0.5f, 0.5f), true);
                }
            }

            foreach(Timer t in splashNoiseLimiter.Values)
            {
                t.Update(time);
            }
        }
Пример #26
0
 public override void Update(DwarfTime gameTime, ChunkManager chunks, Camera camera)
 {
     base.Update(gameTime, chunks, camera);
 }
Пример #27
0
        public override void Update(DwarfTime gameTime, ChunkManager chunks, Camera camera)
        {
            if(IsActive)
            {
                if(CurrentAnimation != null)
                {
                    CurrentAnimation.Update(gameTime);
                }
            }

            base.Update(gameTime, chunks, camera);
        }
Пример #28
0
        public override void Render(DwarfTime time)
        {
            if (Voxel != null)
            {

            }
            base.Render(time);
        }
Пример #29
0
        public void Update(Creature creature, DwarfTime gameTime, ChunkManager chunks, Camera camera)
        {
            float dt = (float)gameTime.ElapsedGameTime.TotalSeconds;
            Hunger.CurrentValue -= dt * creature.Stats.HungerGrowth;

            Health.CurrentValue = (creature.Hp - creature.MinHealth) / (creature.MaxHealth - creature.MinHealth);

            if(creature.Stats.CanSleep)
                Energy.CurrentValue = (float) (100*Math.Sin(PlayState.Time.GetTotalHours()*Math.PI / 24.0f));
            else
            {
                Energy.CurrentValue = 100.0f;
            }

            if(Energy.IsUnhappy())
            {
                creature.DrawIndicator(IndicatorManager.StandardIndicators.Sleepy);
            }

            if(creature.Stats.CanEat && Hunger.IsUnhappy())
            {
                creature.DrawIndicator(IndicatorManager.StandardIndicators.Hungry);

                if(Hunger.CurrentValue <= 1e-12 && (DateTime.Now - LastHungerDamageTime).TotalSeconds > HungerDamageRate)
                {
                    creature.Damage(1.0f / (creature.Stats.HungerResistance) * HungerDamageRate);
                    LastHungerDamageTime = DateTime.Now;
                }
            }
        }
Пример #30
0
        public void Render(DwarfTime game, GraphicsDevice graphics)
        {
            foreach(Room room in DesignatedRooms)
            {
                if(room.IsBuilt)
                    Drawer3D.DrawBox(room.GetBoundingBox(), Color.White, 0.1f, true);
            }

            foreach(BuildRoomOrder roomDesignation in BuildDesignations)
            {
                BoundingBox roomBox = roomDesignation.GetBoundingBox();
                roomBox.Max = new Vector3(roomBox.Max.X, roomBox.Max.Y + 0.1f, roomBox.Max.Z);

                Drawer3D.DrawBox(roomBox, Color.White, 0.1f, true);
                List<BuildVoxelOrder> removals = new List<BuildVoxelOrder>();
                foreach(BuildVoxelOrder des in roomDesignation.VoxelOrders)
                {
                    Drawer3D.DrawBox(des.Voxel.GetBoundingBox(), Color.LightBlue, 0.05f, true);
                    BoundingBox centerBox = des.Voxel.GetBoundingBox();
                    centerBox.Min += new Vector3(0.7f, 1.1f, 0.7f);
                    centerBox.Max += new Vector3(-0.7f, 0.2f, -0.7f);
                    Drawer3D.DrawBox(centerBox, Color.LightBlue, 0.01f, true);

                    if (des.Voxel.IsEmpty)
                    {
                        removals.Add(des);
                    }
                }

                foreach(BuildVoxelOrder des in removals)
                {
                    roomDesignation.VoxelOrders.Remove(des);
                }

                Vector3 textLocation = (roomBox.Max - roomBox.Min) / 2.0f + roomBox.Min + new Vector3(0, 2.0f, 0);
                Drawer2D.DrawTextBox(roomDesignation.GetTextDisplay(), textLocation);
            }
        }
Пример #31
0
 public override void Update(DwarfTime time)
 {
     Scroll += ScrollSpeed * (float)time.ElapsedRealTime.TotalSeconds;
     base.Update(time);
 }
Пример #32
0
        public override void Update(DwarfTime gameTime, ChunkManager chunks, Camera camera)
        {
            if (ShouldDie)
            {
                DeathTimer.Update(gameTime);

                if (DeathTimer.HasTriggered)
                {
                    Die();
                }
            }
            base.Update(gameTime, chunks, camera);
        }
Пример #33
0
 public abstract void Update(DwarfGame game, DwarfTime time);
Пример #34
0
 public override void Update(DwarfTime time, Creature creature)
 {
     base.Update(time, creature);
 }
Пример #35
0
 public abstract void Render(DwarfGame game, GraphicsDevice graphics, DwarfTime time);
Пример #36
0
        public void Update(DwarfTime gameTime, ChunkManager chunks, Camera camera)
        {
            Vector3 targetVelocity = TargetPosition - Body.GlobalTransform.Translation;

            if (targetVelocity.LengthSquared() > 0.0001f)
            {
                targetVelocity.Normalize();
                targetVelocity *= MaxVelocity;
            }

            Matrix m = Body.LocalTransform;

            m.Translation      += targetVelocity * (float)gameTime.ElapsedGameTime.TotalSeconds;
            Body.LocalTransform = m;

            Body.HasMoved = true;

            switch (State)
            {
            case BalloonState.DeliveringGoods:
                VoxelChunk chunk = chunks.ChunkData.GetVoxelChunkAtWorldLocation(Body.GlobalTransform.Translation);

                if (chunk != null)
                {
                    Vector3 gridPos = chunk.WorldToGrid(Body.GlobalTransform.Translation);
                    float   height  = chunk.GetFilledVoxelGridHeightAt((int)gridPos.X, (int)gridPos.Y, (int)gridPos.Z) + chunk.Origin.Y;
                    TargetPosition = new Vector3(Body.GlobalTransform.Translation.X, height + 5, Body.GlobalTransform.Translation.Z);

                    Vector3 diff = Body.GlobalTransform.Translation - TargetPosition;

                    if (diff.LengthSquared() < 2)
                    {
                        State = BalloonState.Waiting;
                    }
                }
                else
                {
                    State = BalloonState.Leaving;
                }

                break;

            case BalloonState.Leaving:
                TargetPosition = Vector3.UnitY * 100 + Body.GlobalTransform.Translation;

                if (Body.GlobalTransform.Translation.Y > 300)
                {
                    Die();
                }

                break;

            case BalloonState.Waiting:
                TargetPosition = Body.GlobalTransform.Translation;

                if (!shipmentGiven)
                {
                    shipmentGiven = true;
                }
                else
                {
                    State = BalloonState.Leaving;
                }


                break;
            }
        }
Пример #37
0
        public bool Update(DwarfTime t)
        {
            if(null == t)
            {
                return false;
            }

            float seconds = (float)(Mode == TimerMode.Game ? t.TotalGameTime.TotalSeconds : t.TotalRealTime.TotalSeconds);

            if(!TriggerOnce && HasTriggered)
            {
                HasTriggered = false;
                CurrentTimeSeconds = 0.0f;
                StartTimeSeconds = -1;
            }

            if (HasTriggered && TriggerOnce)
            {
                return true;
            }

            if(StartTimeSeconds < 0)
            {
                StartTimeSeconds = seconds;
            }

            CurrentTimeSeconds = seconds - StartTimeSeconds;

            if(CurrentTimeSeconds > TargetTimeSeconds)
            {
                HasTriggered = true;
                CurrentTimeSeconds = TargetTimeSeconds;
                return true;
            }

            return false;
        }
Пример #38
0
 public override void Render3D(DwarfGame game, DwarfTime time)
 {
 }
Пример #39
0
 public void Update(MouseState mouseState, KeyboardState keyState, DwarfGame game, DwarfTime time)
 {
     PlayState.GUI.IsMouseVisible = true;
 }
Пример #40
0
 public override void Render(DwarfTime time)
 {
 }
Пример #41
0
        public override void Render(DwarfTime time, SpriteBatch batch)
        {
            string text = Text;

            if(WordWrap)
            {
                text = DwarfGUI.WrapLines(Text, LocalBounds, TextFont);
            }

            Drawer2D.DrawAlignedStrokedText(batch, text, TextFont, TextColor, StrokeColor, Alignment, GlobalBounds);
            base.Render(time, batch);
        }
Пример #42
0
 public override void Update(DwarfTime time)
 {
     base.Update(time);
 }
Пример #43
0
        public override void Render(DwarfTime time, SpriteBatch batch)
        {
            if(!IsVisible)
            {
                return;
            }

            if(Mode == PanelMode.Fancy)
            {
                GUI.Skin.RenderPanel(GlobalBounds, batch);
            }
            else if(Mode == PanelMode.Simple)
            {
                GUI.Skin.RenderToolTip(GlobalBounds, batch, new Color(255, 255, 255, 150));
            }
            else if (Mode == PanelMode.SpeechBubble)
            {
                GUI.Skin.RenderSpeechBubble(GlobalBounds, batch);
            }
            else
            {
                GUI.Skin.RenderWindow(GlobalBounds, batch, Mode == PanelMode.WindowEx);
            }
            base.Render(time, batch);
        }
Пример #44
0
        public override void Render(DwarfTime time, SpriteBatch batch)
        {
            if (!IsVisible)
            {
                return;
            }

            Rectangle globalBounds = GlobalBounds;
            Color     imageColor   = Color.White;
            Color     textColor    = TextColor;
            Color     strokeColor  = GUI.DefaultStrokeColor;

            if (IsLeftPressed)
            {
                imageColor = PressedTint;
                textColor  = PressedTextColor;
            }
            else if (IsMouseOver)
            {
                imageColor = HoverTint;
                textColor  = HoverTextColor;
            }

            if (CanToggle && IsToggled)
            {
                imageColor = ToggleTint;
            }

            imageColor.A = Transparency;

            Rectangle imageBounds = GetImageBounds();

            switch (Mode)
            {
            case ButtonMode.ImageButton:
                if (DrawFrame)
                {
                    GUI.Skin.RenderButtonFrame(imageBounds, batch);
                }
                Rectangle bounds = imageBounds;
                if (Image != null && Image.Image != null)
                {
                    batch.Draw(Image.Image, bounds, Image.SourceRect, imageColor);
                }

                Drawer2D.DrawAlignedText(batch, Text, TextFont, textColor, Drawer2D.Alignment.Under | Drawer2D.Alignment.Center, new Rectangle(bounds.X + 2, bounds.Y + 4, bounds.Width, bounds.Height), true);
                if (IsToggled)
                {
                    Drawer2D.DrawRect(batch, GetImageBounds(), Color.White, 2);
                }
                break;

            case ButtonMode.PushButton:
                GUI.Skin.RenderButton(GlobalBounds, batch);
                Drawer2D.DrawAlignedStrokedText(batch, Text,
                                                TextFont,
                                                textColor, strokeColor, Drawer2D.Alignment.Center, GlobalBounds, true);
                break;

            case ButtonMode.ToolButton:
                GUI.Skin.RenderButton(GlobalBounds, batch);
                if (Image != null && Image.Image != null)
                {
                    Rectangle imageRect   = GetImageBounds();
                    Rectangle alignedRect = Drawer2D.Align(GlobalBounds, imageRect.Width, imageRect.Height, Drawer2D.Alignment.Left);
                    alignedRect.X += 5;
                    batch.Draw(Image.Image, alignedRect, Image.SourceRect, imageColor);
                }
                Drawer2D.DrawAlignedStrokedText(batch, Text, TextFont, textColor, strokeColor, Drawer2D.Alignment.Center, GlobalBounds, true);

                if (IsToggled)
                {
                    Drawer2D.DrawRect(batch, GetImageBounds(), Color.White, 2);
                }

                break;

            case ButtonMode.TabButton:
                GUI.Skin.RenderTab(GlobalBounds, batch, IsToggled ? Color.White : Color.LightGray);
                Drawer2D.DrawAlignedStrokedText(batch, Text,
                                                TextFont,
                                                textColor, strokeColor, Drawer2D.Alignment.Top, new Rectangle(GlobalBounds.X, GlobalBounds.Y + 2, GlobalBounds.Width, GlobalBounds.Height), true);
                break;
            }

            base.Render(time, batch);
        }
Пример #45
0
        public override void Update(DwarfGame game, DwarfTime time)
        {
            if (Player.IsCameraRotationModeActive())
            {
                Player.VoxSelector.Enabled = false;
                Player.BodySelector.Enabled = false;
                PlayState.GUI.IsMouseVisible = false;
                return;
            }

            Player.VoxSelector.Enabled = false;
            Player.BodySelector.Enabled = true;
            Player.BodySelector.AllowRightClickSelection = true;
            PlayState.GUI.IsMouseVisible = true;

            if (PlayState.GUI.IsMouseOver())
            {
                PlayState.GUI.MouseMode = GUISkin.MousePointer.Pointer;
            }
            else
            {
                PlayState.GUI.MouseMode = GUISkin.MousePointer.Attack;
            }
        }
Пример #46
0
 public override void Render(DwarfGame game, GraphicsDevice graphics, DwarfTime time)
 {
 }
Пример #47
0
 public override void Update(DwarfTime time)
 {
     if(IsModal && !isClosed && IsVisible)
     {
         GUI.FocusComponent = this;
     }
     else if(GUI.FocusComponent == this)
     {
         GUI.FocusComponent = null;
     }
     base.Update(time);
 }
Пример #48
0
 public override void Render(DwarfTime time)
 {
     base.Render(time);
 }
Пример #49
0
        public void HandleTransfers(DwarfTime time)
        {
            Voxel atPos = new Voxel();
            while(Transfers.Count > 0)
            {
                Transfer transfer;

                if(!Transfers.TryDequeue(out transfer))
                {
                    break;
                }

                if(transfer.cellFrom.Type == LiquidType.Lava && transfer.cellTo.Type == LiquidType.Water || (transfer.cellFrom.Type == LiquidType.Water && transfer.cellTo.Type == LiquidType.Lava))
                {
                    bool success = Chunks.ChunkData.GetVoxel(transfer.worldLocation, ref atPos);

                    if(success)
                    {
                        Voxel v = atPos;

                        VoxelLibrary.PlaceType(VoxelLibrary.GetVoxelType("Stone"), v);
                        VoxelChunk chunk = Chunks.ChunkData.ChunkMap[v.ChunkID];
                        chunk.Data.Water[v.Index].Type = LiquidType.None;
                        chunk.Data.Water[v.Index].WaterLevel = 0;
                        chunk.ShouldRebuild = true;
                        chunk.ShouldRecalculateLighting = true;
                    }
                }
            }
        }
Пример #50
0
        public void Render(DwarfTime gameTime,
                           ChunkManager chunks,
                           Camera camera,
                           SpriteBatch spriteBatch,
                           GraphicsDevice graphicsDevice,
                           Effect effect,
                           WaterRenderType waterRenderMode, float waterLevel)
        {
            bool renderForWater = (waterRenderMode != WaterRenderType.None);

            if (!renderForWater)
            {
                visibleComponents.Clear();
                componentsToDraw.Clear();


                List <Body> list = FrustrumCullLocatableComponents(camera);
                foreach (Body component in list)
                {
                    visibleComponents.Add(component);
                }


                ComponentManager.Camera = camera;
                foreach (GameComponent component in Components.Values)
                {
                    bool isLocatable = component is Body;

                    if (isLocatable)
                    {
                        Body loc = (Body)component;


                        if (((loc.GlobalTransform.Translation - camera.Position).LengthSquared() < chunks.DrawDistanceSquared &&
                             visibleComponents.Contains(loc) || !(loc.FrustrumCull) || !(loc.WasAddedToOctree) && !loc.IsAboveCullPlane)
                            )
                        {
                            componentsToDraw.Add(component);
                        }
                    }
                    else
                    {
                        componentsToDraw.Add(component);
                    }
                }
            }


            effect.Parameters["xEnableLighting"].SetValue(GameSettings.Default.CursorLightEnabled ? 1 : 0);
            graphicsDevice.RasterizerState = RasterizerState.CullNone;

            foreach (GameComponent component in componentsToDraw)
            {
                if (waterRenderMode == WaterRenderType.Reflective && !RenderReflective(component, waterLevel))
                {
                    continue;
                }
                else if (waterRenderMode == WaterRenderType.Refractive && !RenderRefractive(component, waterLevel))
                {
                    continue;
                }


                component.Render(gameTime, chunks, camera, spriteBatch, graphicsDevice, effect, renderForWater);
            }

            effect.Parameters["xEnableLighting"].SetValue(0);
        }
Пример #51
0
        public override void Update(DwarfTime gameTime, ChunkManager chunks, Camera camera)
        {
            SenseTimer.Update(gameTime);

            if (SenseTimer.HasTriggered)
            {
                Sense();
            }
            Enemies.RemoveAll(ai => ai.IsDead);
            base.Update(gameTime, chunks, camera);
        }
Пример #52
0
 public override void Render(DwarfGame game, GraphicsDevice graphics, DwarfTime time)
 {
     Player.Faction.RoomBuilder.Render(time, Player.World.ChunkManager.Graphics);
 }
Пример #53
0
        public override void Render(DwarfTime gameTime,
            ChunkManager chunks,
            Camera camera,
            SpriteBatch spriteBatch,
            GraphicsDevice graphicsDevice,
            Effect effect,
            bool renderingForWater)
        {
            base.Render(gameTime, chunks, camera, spriteBatch, graphicsDevice, effect, renderingForWater);

            if(!IsVisible)
            {
                return;
            }

            if (CurrentAnimation != null && CurrentAnimation.CurrentFrame >= 0 && CurrentAnimation.CurrentFrame < CurrentAnimation.Primitives.Count)
            {
                CurrentAnimation.PreRender();
                SpriteSheet = CurrentAnimation.SpriteSheet;
                effect.Parameters["xTexture"].SetValue(SpriteSheet.GetTexture());

                if(OrientationType != OrientMode.Fixed)
                {
                    if(camera.Projection == Camera.ProjectionMode.Perspective)
                    {
                        if(OrientationType == OrientMode.Spherical)
                        {
                            float xscale = GlobalTransform.Left.Length();
                            float yscale = GlobalTransform.Up.Length();
                            float zscale = GlobalTransform.Forward.Length();
                            Matrix rot = Matrix.CreateRotationZ(BillboardRotation);
                            Matrix bill = Matrix.CreateBillboard(GlobalTransform.Translation, camera.Position, camera.UpVector, null);
                            Matrix noTransBill = bill;
                            noTransBill.Translation = Vector3.Zero;

                            Matrix worldRot = Matrix.CreateScale(new Vector3(xscale, yscale, zscale)) * rot * noTransBill;
                            worldRot.Translation = bill.Translation;
                            effect.Parameters["xWorld"].SetValue(worldRot);
                        }
                        else
                        {
                            Vector3 axis = Vector3.Zero;

                            switch(OrientationType)
                            {
                                case OrientMode.XAxis:
                                    axis = Vector3.UnitX;
                                    break;
                                case OrientMode.YAxis:
                                    axis = Vector3.UnitY;
                                    break;
                                case OrientMode.ZAxis:
                                    axis = Vector3.UnitZ;
                                    break;
                            }

                            Matrix worldRot = Matrix.CreateConstrainedBillboard(GlobalTransform.Translation, camera.Position, axis, null, null);
                            effect.Parameters["xWorld"].SetValue(worldRot);
                        }
                    }
                    else
                    {
                        Matrix rotation = Matrix.CreateRotationY(-(float) Math.PI * 0.25f) * Matrix.CreateTranslation(GlobalTransform.Translation);
                        effect.Parameters["xWorld"].SetValue(rotation);
                    }
                }
                else
                {
                    effect.Parameters["xWorld"].SetValue(GlobalTransform);
                }

                foreach(EffectPass pass in effect.CurrentTechnique.Passes)
                {
                    pass.Apply();
                    CurrentAnimation.Primitives[CurrentAnimation.CurrentFrame].Render(graphicsDevice);
                }
            }
        }
Пример #54
0
 public virtual void Update(DwarfTime time, ChunkManager chunks)
 {
     lastPosition = Position;
     UpdateViewMatrix();
     UpdateProjectionMatrix();
 }
Пример #55
0
 public override void Render(DwarfTime time, Microsoft.Xna.Framework.Graphics.SpriteBatch batch)
 {
     Rectangle fieldRect = new Rectangle(GlobalBounds.X, GlobalBounds.Y + GlobalBounds.Height / 2 - GUI.Skin.TileHeight / 2, GlobalBounds.Width - 37, 32);
     GUI.Skin.RenderField(fieldRect, batch);
     Drawer2D.DrawAlignedText(batch, CurrentValue, GUI.DefaultFont, Color.Black, Drawer2D.Alignment.Center, fieldRect);
     GUI.Skin.RenderDownArrow(new Rectangle(GlobalBounds.X + GlobalBounds.Width - 32, GlobalBounds.Y + GlobalBounds.Height / 2 - GUI.Skin.TileHeight / 2, 32, 32), batch);
     base.Render(time, batch);
 }
Пример #56
0
 public override void Update(DwarfTime time, ChunkManager chunks)
 {
     base.Update(time, chunks);
 }
Пример #57
0
        public override void Render(DwarfTime time, SpriteBatch batch)
        {
            Rectangle globalBounds = GlobalBounds;

            Color c = TextColor;

            if(IsMouseOver)
            {
                c = HoverTextColor;
            }

            Rectangle checkboxBounds = new Rectangle(GlobalBounds.Right - 32, GlobalBounds.Top + 1, 32, 32);

            GUI.Skin.RenderCheckbox(checkboxBounds, Checked, batch);
            Vector2 measure = Datastructures.SafeMeasure(GUI.DefaultFont, Text);

            Drawer2D.DrawStrokedText(batch, Text,
                GUI.DefaultFont,
                new Vector2(GlobalBounds.Right - measure.X - 32, GlobalBounds.Top + 5),
                c, StrokeColor);

            base.Render(time, batch);
        }
Пример #58
0
 public virtual void OnContinuousUpdate(DwarfTime time)
 {
 }
Пример #59
0
 public virtual void Update(DwarfTime time, ChunkManager chunks)
 {
     lastPosition = Position;
     UpdateViewMatrix();
     UpdateProjectionMatrix();
 }
Пример #60
0
        public void Render(DwarfTime gameTime,
                           ChunkManager chunks,
                           Camera camera,
                           SpriteBatch spriteBatch,
                           GraphicsDevice graphicsDevice,
                           Shader effect,
                           WaterRenderType waterRenderMode, float waterLevel)
        {
            bool renderForWater = (waterRenderMode != WaterRenderType.None);

            if (!renderForWater)
            {
                visibleComponents.Clear();

                BoundingFrustum frustrum = camera.GetFrustrum();

                foreach (IRenderableComponent b in RenderableComponents)
                {
                    if (!b.IsVisible)
                    {
                        continue;
                    }
                    if (b.IsAboveCullPlane)
                    {
                        continue;
                    }

                    if (b.FrustrumCull)
                    {
                        if ((b.GlobalTransform.Translation - camera.Position).LengthSquared() >= chunks.DrawDistanceSquared)
                        {
                            continue;
                        }
                        if (!(b.GetBoundingBox().Intersects(frustrum)))
                        {
                            continue;
                        }
                    }

                    System.Diagnostics.Debug.Assert(!visibleComponents.Contains(b));
                    visibleComponents.Add(b);
                }

                Camera = camera;
            }

            effect.EnableLighting          = GameSettings.Default.CursorLightEnabled;
            graphicsDevice.RasterizerState = RasterizerState.CullNone;

            visibleComponents.Sort(CompareZDepth);
            foreach (IRenderableComponent bodyToDraw in visibleComponents)
            {
                if (waterRenderMode == WaterRenderType.Reflective &&
                    !(bodyToDraw.GetBoundingBox().Min.Y > waterLevel - 2))
                {
                    continue;
                }
                bodyToDraw.Render(gameTime, chunks, camera, spriteBatch, graphicsDevice, effect, renderForWater);
            }
            effect.EnableLighting = false;
        }