IEnumerable<Act.Status> ChirpRandomly() { Timer chirpTimer = new Timer(MathFunctions.Rand(6f, 10f), false); while (true) { chirpTimer.Update(DwarfTime.LastTime); if (chirpTimer.HasTriggered) { Creature.NoiseMaker.MakeNoise("chirp", Creature.AI.Position, true, 0.5f); } yield return Act.Status.Running; } yield return Act.Status.Success; }
override public void Update(DwarfTime gameTime, ChunkManager chunks, Camera camera) { base.Update(gameTime, chunks, camera); if (!Active) { return; } SenseTimer.Update(gameTime); if (SenseTimer.HasTriggered) { Creatures.Clear(); var myRoot = GetRoot(); foreach (var body in Manager.World.EnumerateIntersectingObjects(BoundingBox, b => b.Active && !Object.ReferenceEquals(b, myRoot) && b.IsRoot())) { var minion = body.GetComponent <Creature>(); if (minion == null) { continue; } float dist = (body.Position - GlobalTransform.Translation).LengthSquared(); if (dist > SenseRadius) { continue; } if (CheckLineOfSight && VoxelHelpers.DoesRayHitSolidVoxel(Manager.World.ChunkManager, Position, body.Position)) { continue; } Creatures.Add(minion); } } Creatures.RemoveAll(ai => ai.IsDead); }
public override void Update(DwarfTime Time, ChunkManager Chunks, Camera Camera) { if (Active) { ParticleTimer.Update(Time); if (ParticleTimer.HasTriggered) { float t = (float)Time.TotalGameTime.TotalSeconds * 0.5f; Vector3 pos = new Vector3((float)Math.Sin(t) * TeleportDistance, 0, (float)Math.Cos(t) * TeleportDistance) + Position; VoxelHandle voxelBelow = VoxelHelpers.FindFirstVoxelBelow(new VoxelHandle(World.ChunkManager.ChunkData, GlobalVoxelCoordinate.FromVector3(pos))); if (voxelBelow.IsValid) { World.ParticleManager.Trigger("green_flame", voxelBelow.WorldPosition + Vector3.Up * 1.5f, Color.White, 1); } } } base.Update(Time, Chunks, Camera); }
/// <summary> /// Basic Act that causes the creature to wait for the specified time. /// Also draws a loading bar above the creature's head when relevant. /// </summary> public IEnumerable <Act.Status> HitAndWait(float f, bool loadBar, Func <Vector3> pos, string playSound = "", Func <bool> continueHitting = null) { var waitTimer = new Timer(f, true); CurrentCharacterMode = CharacterMode.Attacking; Sprite.ResetAnimations(CharacterMode.Attacking); Sprite.PlayAnimations(CharacterMode.Attacking); CurrentCharacterMode = CharacterMode.Attacking; while (!waitTimer.HasTriggered) { waitTimer.Update(DwarfTime.LastTime); if (continueHitting != null && !continueHitting()) { yield break; } Physics.Active = false; if (loadBar) { Drawer2D.DrawLoadBar(Manager.World.Camera, AI.Position + Vector3.Up, Color.LightGreen, Color.Black, 64, 4, waitTimer.CurrentTimeSeconds / waitTimer.TargetTimeSeconds); } Attacks[0].PerformNoDamage(this, DwarfTime.LastTime, pos()); Physics.Velocity = Vector3.Zero; Sprite.ReloopAnimations(CharacterMode.Attacking); if (!String.IsNullOrEmpty(playSound)) { NoiseMaker.MakeNoise(playSound, AI.Position, true); } yield return(Act.Status.Running); } Sprite.PauseAnimations(CharacterMode.Attacking); CurrentCharacterMode = CharacterMode.Idle; Physics.Active = true; yield return(Act.Status.Success); yield break; }
public void Update(DwarfTime gameTime, ChunkManager chunks, Camera camera) { if (firstIter) { if (!Voxel.IsValid || Voxel.TypeID == 0) { Delete(); } firstIter = false; } DestroyTimer.Update(gameTime); if (DestroyTimer.HasTriggered) { Die(); chunks.KillVoxel(Voxel); } }
public virtual void Update(DwarfTime time) { float growTime = CurrentTime.TargetTimeSeconds * 0.5f; float shrinkTime = CurrentTime.TargetTimeSeconds * 0.5f; if (CurrentTime.CurrentTimeSeconds < growTime) { Scale = Easing.CubeInOut(CurrentTime.CurrentTimeSeconds, 0.0f, MaxScale, growTime); } else if (CurrentTime.CurrentTimeSeconds > shrinkTime) { Scale = Easing.CubeInOut(CurrentTime.CurrentTimeSeconds - shrinkTime, MaxScale, -MaxScale, CurrentTime.TargetTimeSeconds - shrinkTime); } if (!Grow) { Scale = MaxScale; } CurrentTime.Update(time); }
private void UpdateEggs(DwarfTime gameTime) { if (Stats.Species.LaysEggs) { if (EggTimer == null) { EggTimer = new Timer(3600f + MathFunctions.Rand(-120, 120), false); } EggTimer.Update(gameTime); if (EggTimer.HasTriggered) { if (World.GetSpeciesPopulation(Stats.CurrentClass) < Stats.Species.SpeciesLimit) { LayEgg(); // Todo: Egg rate in species EggTimer = new Timer(3600f + MathFunctions.Rand(-120, 120), false); } } } }
public void Update(DwarfTime time, Camera cam, GraphicsDevice graphics) { if (DwarfGame.ExitGame) { return; } DeleteNulls(); sortTimer.Update(time); if (sortTimer.HasTriggered) { SortDistances(); sortTimer.Reset(sortTimer.TargetTimeSeconds); } //RebuildVertices(); //InstanceBuffer.SetData(Vertices); AddRemove(); }
public IEnumerable <Act.Status> SwimUp(Creature creature) { Timer timer = new Timer(10.0f, false, Timer.TimerMode.Game); while (!timer.HasTriggered) { timer.Update(DwarfTime.LastTime); creature.Physics.ApplyForce(Vector3.Up * 25, DwarfTime.Dt); if (!creature.Physics.IsInLiquid) { yield return(Act.Status.Success); yield break; } yield return(Act.Status.Running); } yield return(Act.Status.Fail); }
public override Task ActOnIdle() { if (DestroyPlayerObjectProbability > 0 && MathFunctions.RandEvent(DestroyPlayerObjectProbability)) { bool plantBomb = !String.IsNullOrEmpty(PlantBomb) && MathFunctions.RandEvent(0.5f); if (!plantBomb && World.PlayerFaction.OwnedObjects.Count > 0) { var thing = Datastructures.SelectRandom <GameComponent>(World.PlayerFaction.OwnedObjects); AssignTask(new KillEntityTask(thing, KillEntityTask.KillType.Auto)); } else if (plantBomb) { var room = World.FindNearestZone(Position); if (room != null) { AssignTask(new ActWrapperTask(new Sequence(new GoToZoneAct(this, room), new Do(() => { EntityFactory.CreateEntity <GameComponent>(PlantBomb, Position); return(true); }))) { Priority = TaskPriority.High }); } else if (World.PlayerFaction.OwnedObjects.Count > 0) { var thing = Datastructures.SelectRandom <GameComponent>(World.PlayerFaction.OwnedObjects); AssignTask(new ActWrapperTask(new Sequence(new GoToEntityAct(thing, this), new Do(() => { EntityFactory.CreateEntity <GameComponent>(PlantBomb, Position); return(true); }))) { Priority = TaskPriority.High }); } } } LeaveWorldTimer.Update(DwarfTime.LastTime); if (LeaveWorldTimer.HasTriggered) { LeaveWorld(); LeaveWorldTimer.Reset(); } return(base.ActOnIdle()); }
private void UpdateEggs(DwarfTime gameTime) { if (Stats.Species.LaysEggs) { if (EggTimer == null) { EggTimer = new Timer(Stats.Species.EggTime + MathFunctions.Rand(-120, 120), false); } EggTimer.Update(gameTime); if (EggTimer.HasTriggered) { if (World.CanSpawnWithoutExceedingSpeciesLimit(Stats.Species)) { LayEgg(); // Todo: Egg rate in species } EggTimer = new Timer(Stats.Species.EggTime + MathFunctions.Rand(-120, 120), false); } } }
public IEnumerable <Act.Status> HitAndWait(float f, bool loadBar) { Timer waitTimer = new Timer(f, true); CurrentCharacterMode = CharacterMode.Attacking; while (!waitTimer.HasTriggered) { waitTimer.Update(DwarfTime.LastTime); if (loadBar) { Drawer2D.DrawLoadBar(AI.Position + Vector3.Up, Color.White, Color.Black, 100, 16, waitTimer.CurrentTimeSeconds / waitTimer.TargetTimeSeconds); } Attacks[0].PerformNoDamage(this, DwarfTime.LastTime, AI.Position); Physics.Velocity = Vector3.Zero; yield return(Act.Status.Running); } CurrentCharacterMode = CharacterMode.Idle; yield return(Act.Status.Success); }
// This hack exists to find orphaned tasks not assigned to any dwarf, and to then // put them on the task list. public void UpdateOrphanedTasks() { orphanedTaskRateLimiter.Update(DwarfTime.LastTime); if (orphanedTaskRateLimiter.HasTriggered) { List <Task> orphanedTasks = new List <Task>(); foreach (var ent in Faction.Designations.EnumerateEntityDesignations()) { if (ent.Type == DesignationType.Attack) { var task = new KillEntityTask(ent.Body, KillEntityTask.KillType.Attack); if (!TaskManager.HasTask(task) && !Faction.Minions.Any(minion => minion.Tasks.Contains(task))) { orphanedTasks.Add(task); } } else if (ent.Type == DesignationType.Craft) { var task = new CraftItemTask(ent.Tag as CraftDesignation); if (!TaskManager.HasTask(task) && !Faction.Minions.Any(minion => minion.Tasks.Contains(task))) { orphanedTasks.Add(task); } } // TODO ... other entity task types } if (orphanedTasks.Count > 0) { //TaskManager.AssignTasksGreedy(orphanedTasks, Faction.Minions); TaskManager.AddTasks(orphanedTasks); } } }
public IEnumerable <Act.Status> GoToRandomTarget(float radius) { Vector3 randomVector = MathFunctions.RandVector3Cube() * radius; Vector3 target = Physics.ClampToBounds(Position + randomVector); float dist = (target - Position).Length(); Timer timout = new Timer(3.0f, false); while (dist > 3.0f) { timout.Update(DwarfTime.LastTime); if (timout.HasTriggered) { break; } Vector3 output = Creature.Controller.GetOutput(DwarfTime.Dt, target, Position); output.Normalize(); output *= 10; Physics.ApplyForce(new Vector3(output.X, 0.0f, output.Z), DwarfTime.Dt); dist = (target - Position).Length(); yield return(Act.Status.Running); } yield return(Act.Status.Success); }
public IEnumerable <Act.Status> HealAlly() { Timer healTimer = new Timer(5.0f, false); while (!Ally.IsDead && Ally.Stats.Health.IsDissatisfied()) { Agent.Physics.Face(Ally.Position); Agent.Creature.CurrentCharacterMode = CharacterMode.Sitting; healTimer.Update(DwarfTime.LastTime); if (healTimer.HasTriggered) { int amount = MathFunctions.RandInt(1, (int)Agent.Stats.Wisdom); Ally.Creature.Heal(amount); IndicatorManager.DrawIndicator((amount).ToString() + " HP", Ally.Position, 1.0f, GameSettings.Current.Colors.GetColor("Positive", Microsoft.Xna.Framework.Color.Green)); Ally.Creature.DrawLifeTimer.Reset(); } yield return(Act.Status.Running); } Ally.ResetPositionConstraint(); yield return(Act.Status.Success); }
public override void Update(DwarfTime Time, ChunkManager Chunks, Camera Camera) { if (Active) { HealTimer.Update(Time); if (HealTimer.HasTriggered) { var objects = World.EnumerateIntersectingObjects(new BoundingBox(-Vector3.One * HealRadius + Position, Vector3.One * HealRadius + Position), CollisionType.Dynamic); foreach (var obj in objects) { var creature = obj.GetRoot().GetComponent <Creature>(); if (creature == null || creature.AI == null || creature.AI.Faction != creature.World.PlayerFaction || creature.Hp == creature.MaxHealth) { continue; } if (MathFunctions.RandEvent(0.5f)) { creature.Heal(HealIncrease); IndicatorManager.DrawIndicator((HealIncrease).ToString() + " HP", creature.Physics.Position, 1.0f, GameSettings.Default.Colors.GetColor("Positive", Microsoft.Xna.Framework.Color.Green)); creature.DrawLifeTimer.Reset(); World.ParticleManager.Trigger("star_particle", obj.Position, Color.Red, 10); World.ParticleManager.TriggerRay("star_particle", Position, obj.Position); SoundManager.PlaySound(ContentPaths.Audio.tinkle, obj.Position, true, 1.0f); GetComponent <MagicalObject>().CurrentCharges--; if (GetComponent <MagicalObject>().CurrentCharges == 0) { return; } } } } } base.Update(Time, Chunks, Camera); }
public override IEnumerable <Status> Run() { Timer waitTimer = new Timer(1.0f, true); bool removed = Agent.Faction.RemoveResources(Resources, Agent.Position); if (!removed) { yield return(Status.Fail); } else { foreach (ResourceAmount resource in Resources) { Agent.Creature.Inventory.Resources.AddResource(resource.CloneResource()); } while (!waitTimer.HasTriggered) { waitTimer.Update(DwarfTime.LastTime); yield return(Status.Running); } yield return(Status.Success); } }
public void Update(DwarfTime time, Camera cam, GraphicsDevice graphics) { if (DwarfGame.ExitGame) { return; } DeleteNulls(); sortTimer.Update(time); if (sortTimer.HasTriggered) { SortDistances(); sortTimer.Reset(sortTimer.TargetTimeSeconds); } AddRemove(); if (instanceVertexes == null) { instanceVertexes = new InstancedVertex[numInstances]; } int j = 0; foreach (InstanceData t in SortedData.Data) { if (t.ShouldDraw) { instanceVertexes[j].Transform = t.Transform; instanceVertexes[j].Color = t.Color; j++; } } numActiveInstances = j; }
public bool Begin(GraphicsDevice device) { lock (ColorBufferMutex) { if (!ValidateBuffer(device)) { return(false); } ValidateColorBuffer(device); switch (State) { case SelectionBufferState.Idle: renderTimer.Update(DwarfTime.LastTime); renderThisFrame = (renderTimer.HasTriggered || colorBuffer == null); if (!renderThisFrame) { return(false); } ValidateBuffer(device); device.SetRenderTarget(Buffer); device.Clear(Color.Transparent); State = SelectionBufferState.Rendering; return(true); case SelectionBufferState.Rendering: ValidateColorBuffer(device); Buffer.GetData(colorBuffer); State = SelectionBufferState.Idle; return(false); default: return(false); } } }
public override IEnumerable <Status> Run() { while (true) { Creature.AI.Blackboard.Erase(PathName); Agent.Blackboard.SetData <bool>("NoPath", false); PlanAct planAct = new PlanAct(Creature.AI, PathName, VoxelName, PlanType) { Radius = Radius, MaxTimeouts = MaxTimeouts }; planAct.Initialize(); bool planSucceeded = false; while (true) { Act.Status planStatus = planAct.Tick(); if (planStatus == Status.Fail) { yield return(Act.Status.Running); break; } else if (planStatus == Status.Running) { yield return(Act.Status.Running); } else if (planStatus == Status.Success) { planSucceeded = true; break; } yield return(Act.Status.Running); } if (!planSucceeded && planAct.LastResult == AStarPlanner.PlanResultCode.MaxExpansionsReached) { yield return(Act.Status.Running); Creature.CurrentCharacterMode = CharacterMode.Idle; Creature.Physics.Velocity = Vector3.Zero; Timer planTimeout = new Timer(MathFunctions.Rand(30.0f, 120.0f), false, Timer.TimerMode.Real); List <VoxelHandle> exploredVoxels = new List <VoxelHandle>(); Color debugColor = new Color(MathFunctions.RandVector3Cube() + Vector3.One * 0.5f); float debugScale = MathFunctions.Rand() * 0.5f + 0.5f; while (!planTimeout.HasTriggered) { // In this case, try to follow a greedy path toward the entity instead of just failing. var greedyPath = planAct.ComputeGreedyFallback(20, exploredVoxels); var goal = planAct.GetGoal(); Creature.AI.Blackboard.SetData("GreedyPath", greedyPath); var greedyPathFollow = new FollowPathAct(Creature.AI, "GreedyPath") { //BlendEnd = true, //BlendStart = false }; greedyPathFollow.Initialize(); foreach (var currStatus in greedyPathFollow.Run()) { if (Debugger.Switches.DrawPaths) { foreach (var voxel in exploredVoxels) { Drawer3D.DrawBox(voxel.GetBoundingBox().Expand(-debugScale), debugColor, 0.05f, false); } } if (!exploredVoxels.Contains(Agent.Physics.CurrentVoxel)) { exploredVoxels.Add(Agent.Physics.CurrentVoxel); } if (Debugger.Switches.DrawPaths) { Drawer3D.DrawLine(Agent.Position, goal.GetVoxel().WorldPosition, debugColor, 0.1f); } if (goal.IsInGoalRegion(Agent.Physics.CurrentVoxel)) { yield return(Act.Status.Success); yield break; } yield return(Act.Status.Running); } planTimeout.Update(DwarfTime.LastTime); } continue; } else if (!planSucceeded) { Agent.Blackboard.SetData <bool>("NoPath", true); yield return(Act.Status.Fail); yield break; } yield return(Act.Status.Success); yield break; } }
public override IEnumerable <Status> Run() { Path = null; Timeouts = 0; PlannerTimer.Reset(PlannerTimer.TargetTimeSeconds); var lastId = -1; Vector3 goalPos = Vector3.Zero; Agent.Blackboard.SetData <bool>("NoPath", false); while (true) { if (Path != null) { yield return(Status.Success); break; } if (Timeouts > MaxTimeouts) { Agent.Blackboard.SetData <bool>("NoPath", true); yield return(Status.Fail); break; } if (WaitingOnResponse && Debugger.Switches.DrawPaths) { Drawer3D.DrawLine(Creature.AI.Position, goalPos, Color.Blue, 0.25f); } PlannerTimer.Update(DwarfTime.LastTime); ChunkManager chunks = Creature.Manager.World.ChunkManager; if (PlannerTimer.HasTriggered || Timeouts == 0) { if (!Target.IsValid && Type != PlanType.Edge) { Creature.DrawIndicator(IndicatorManager.StandardIndicators.Question); Agent.Blackboard.SetData <bool>("NoPath", true); yield return(Status.Fail); break; } var voxUnder = VoxelHelpers.FindValidVoxelNear(chunks, Agent.Position); if (!voxUnder.IsValid) { if (Debugger.Switches.DrawPaths) { Creature.World.UserInterface.MakeWorldPopup(String.Format("Invalid request"), Creature.Physics, -10, 1); } Creature.DrawIndicator(IndicatorManager.StandardIndicators.Question); Agent.Blackboard.SetData <bool>("NoPath", true); yield return(Status.Fail); break; } Path = null; AstarPlanRequest aspr = new AstarPlanRequest { Subscriber = Agent.PlanSubscriber, Start = voxUnder, MaxExpansions = MaxExpansions, Sender = Agent, HeuristicWeight = Weights[Timeouts] }; lastId = aspr.ID; aspr.GoalRegion = GetGoal(); goalPos = GetGoal().GetVoxel().GetBoundingBox().Center(); Agent.PlanSubscriber.Clear(); if (!Agent.PlanSubscriber.SendRequest(aspr, aspr.ID)) { yield return(Status.Fail); yield break; } PlannerTimer.Reset(PlannerTimer.TargetTimeSeconds); WaitingOnResponse = true; yield return(Status.Running); Timeouts++; } else { Status statusResult = Status.Running; while (Agent.PlanSubscriber.Responses.Count > 0) { AStarPlanResponse response; if (!Agent.PlanSubscriber.Responses.TryDequeue(out response)) { yield return(Status.Running); continue; } LastResult = response.Result; if (response.Success && response.Request.ID == lastId) { Path = response.Path; WaitingOnResponse = false; statusResult = Status.Success; } else if (response.Request.ID != lastId && response.Path != null && response.Path.Count > 0) { var goal = GetGoal(); bool obeysGoal = goal == null ? false : (response.Success && (goal.IsInGoalRegion(response.Path.Last().DestinationVoxel))); if (Debugger.Switches.DrawPaths) { if (obeysGoal) { Creature.World.UserInterface.MakeWorldPopup(String.Format("Using Old Path", response.Result), Creature.Physics, -10, 1); } else { Creature.World.UserInterface.MakeWorldPopup(String.Format("Old Path Dropped", response.Result), Creature.Physics, -10, 1); } } if (obeysGoal) { Path = response.Path; WaitingOnResponse = false; statusResult = Status.Success; } else { continue; } } else if (response.Result == AStarPlanner.PlanResultCode.Invalid || response.Result == AStarPlanner.PlanResultCode.NoSolution || response.Result == AStarPlanner.PlanResultCode.Cancelled || response.Result == AStarPlanner.PlanResultCode.Invalid) { if (Debugger.Switches.DrawPaths) { Creature.World.UserInterface.MakeWorldPopup(String.Format("Path: {0}", response.Result), Creature.Physics, -10, 1); } Creature.DrawIndicator(IndicatorManager.StandardIndicators.Question); Agent.Blackboard.SetData <bool>("NoPath", true); statusResult = Status.Fail; yield return(Status.Fail); } else if (Timeouts <= MaxTimeouts) { Timeouts++; yield return(Status.Running); } else { if (Debugger.Switches.DrawPaths) { Creature.World.UserInterface.MakeWorldPopup(String.Format("Max timeouts reached", response.Result), Creature.Physics, -10, 1); } Creature.DrawIndicator(IndicatorManager.StandardIndicators.Question); Agent.Blackboard.SetData <bool>("NoPath", true); statusResult = Status.Fail; } } yield return(statusResult); } } }
public override void Update(DwarfTime time, Creature creature) { float hungerChange = creature.Stats.Hunger.CurrentValue - LastHunger; LastHunger = creature.Stats.Hunger.CurrentValue; switch (Type) { case HealType.Food: if (creature.Stats.IsAsleep) { break; } FoodValueUntilHealed -= hungerChange; if (FoodValueUntilHealed > 0) { DoDamage(DwarfTime.Dt, creature); } else { EffectTime.Reset(0); } break; case HealType.Sleep: if (!creature.Stats.IsAsleep) { DoDamage(DwarfTime.Dt, creature); } else { EffectTime.Reset(0); } break; case HealType.Time: DoDamage(DwarfTime.Dt, creature); break; } if (IsContagious) { SpreadTimer.Update(time); if (SpreadTimer.HasTriggered && MathFunctions.RandEvent(LikelihoodOfSpread)) { foreach (CreatureAI other in creature.Faction.Minions) { if (other == creature.AI) { continue; } if ((other.Position - creature.AI.Position).LengthSquared() > 2) { continue; } other.Creature.Stats.AcquireDisease(DiseaseLibrary.GetDisease(Name)); } } } base.Update(time, creature); }
public void OverheadUpdate(DwarfTime time, ChunkManager chunks) { Voxel currentVoxel = new Voxel(); float diffPhi = 0; float diffTheta = 0; float diffRadius = 0; Vector3 forward = (Target - Position); forward.Normalize(); Vector3 right = Vector3.Cross(forward, UpVector); Vector3 up = Vector3.Cross(right, forward); right.Normalize(); up.Normalize(); MouseState mouse = Mouse.GetState(); KeyboardState keys = Keyboard.GetState(); if (ZoomTargets.Count > 0) { Vector3 currTarget = ProjectToSurface(ZoomTargets.First()); if (Vector3.DistanceSquared(Target, currTarget) > 5) { Vector3 newTarget = 0.8f * Target + 0.2f * currTarget; Vector3 d = newTarget - Target; Target += d; Position += d; } else { ZoomTargets.RemoveAt(0); } } int edgePadding = -10000; if (GameSettings.Default.EnableEdgeScroll) { edgePadding = 100; } float diffX, diffY = 0; bool stateChanged = false; float dt = (float)time.ElapsedRealTime.TotalSeconds; SnapToBounds(new BoundingBox(World.ChunkManager.Bounds.Min, World.ChunkManager.Bounds.Max + Vector3.UnitY * 20)); if (KeyManager.RotationEnabled()) { if (!shiftPressed) { shiftPressed = true; mouse = Mouse.GetState(); stateChanged = true; } if (!isLeftPressed && mouse.LeftButton == ButtonState.Pressed) { isLeftPressed = true; stateChanged = true; } else if (mouse.LeftButton == ButtonState.Released) { isLeftPressed = false; } if (!isRightPressed && mouse.RightButton == ButtonState.Pressed) { isRightPressed = true; stateChanged = true; } else if (mouse.RightButton == ButtonState.Released) { isRightPressed = false; } if (stateChanged) { Mouse.SetPosition(GameState.Game.GraphicsDevice.Viewport.Width / 2, GameState.Game.GraphicsDevice.Viewport.Height / 2); mouse = Mouse.GetState(); } diffX = mouse.X - GameState.Game.GraphicsDevice.Viewport.Width / 2; diffY = mouse.Y - GameState.Game.GraphicsDevice.Viewport.Height / 2; if (!isRightPressed) { float filterDiffX = (float)(diffX * dt); float filterDiffY = (float)(diffY * dt); diffTheta = (filterDiffX); diffPhi = -(filterDiffY); } } else { shiftPressed = false; } bool goingBackward = false; Vector3 velocityToSet = Vector3.Zero; if (keys.IsKeyDown(ControlSettings.Mappings.Forward) || keys.IsKeyDown(Keys.Up)) { Vector3 mov = forward; mov.Y = 0; mov.Normalize(); velocityToSet += mov * CameraMoveSpeed * dt; } else if (keys.IsKeyDown(ControlSettings.Mappings.Back) || keys.IsKeyDown(Keys.Down)) { goingBackward = true; Vector3 mov = forward; mov.Y = 0; mov.Normalize(); velocityToSet += -mov * CameraMoveSpeed * dt; } if (keys.IsKeyDown(ControlSettings.Mappings.Left) || keys.IsKeyDown(Keys.Left)) { Vector3 mov = right; mov.Y = 0; mov.Normalize(); velocityToSet += -mov * CameraMoveSpeed * dt; } else if (keys.IsKeyDown(ControlSettings.Mappings.Right) || keys.IsKeyDown(Keys.Right)) { Vector3 mov = right; mov.Y = 0; mov.Normalize(); velocityToSet += mov * CameraMoveSpeed * dt; } if (velocityToSet.LengthSquared() > 0) { Velocity = velocityToSet; } if (!KeyManager.RotationEnabled()) { World.GUI.IsMouseVisible = true; if (!World.IsMouseOverGui) { if (mouse.X < edgePadding || mouse.X > GameState.Game.GraphicsDevice.Viewport.Width - edgePadding) { moveTimer.Update(time); if (moveTimer.HasTriggered) { float dir = 0.0f; if (mouse.X < edgePadding) { dir = edgePadding - mouse.X; } else { dir = (GameState.Game.GraphicsDevice.Viewport.Width - edgePadding) - mouse.X; } dir *= 0.01f; Vector3 delta = right * CameraMoveSpeed * dir * dt; delta.Y = 0; Velocity = -delta; } } else if (mouse.Y < edgePadding || mouse.Y > GameState.Game.GraphicsDevice.Viewport.Height - edgePadding) { moveTimer.Update(time); if (moveTimer.HasTriggered) { float dir = 0.0f; if (mouse.Y < edgePadding) { dir = -(edgePadding - mouse.Y); } else { dir = -((GameState.Game.GraphicsDevice.Viewport.Height - edgePadding) - mouse.Y); } dir *= 0.01f; Vector3 delta = up * CameraMoveSpeed * dir * dt; delta.Y = 0; Velocity = -delta; } } else { moveTimer.Reset(moveTimer.TargetTimeSeconds); } } } else { World.GUI.IsMouseVisible = false; } int scroll = mouse.ScrollWheelValue; if (isRightPressed && KeyManager.RotationEnabled()) { scroll = (int)(diffY * 10) + LastWheel; } if (scroll != LastWheel && !World.IsMouseOverGui) { int change = scroll - LastWheel; if (!(keys.IsKeyDown(Keys.LeftAlt) || keys.IsKeyDown(Keys.RightAlt))) { if (!keys.IsKeyDown(Keys.LeftControl)) { var delta = change * -1; if (GameSettings.Default.InvertZoom) { delta *= -1; } diffRadius = delta * CameraZoomSpeed * dt; if (diffRadius < 0) { float diffxy = (new Vector3(Target.X, 0, Target.Z) - new Vector3(World.CursorPos.X, 0, World.CursorPos.Z)).Length(); if (diffxy > 5) { Vector3 slewTarget = Target * 0.9f + World.CursorPos * 0.1f; Vector3 slewDiff = slewTarget - Target; Target += slewDiff; Position += slewDiff; } } } else { chunks.ChunkData.SetMaxViewingLevel(chunks.ChunkData.MaxViewingLevel + (int)((float)change * 0.01f), ChunkManager.SliceMode.Y); } } } LastWheel = mouse.ScrollWheelValue; if (!CollidesWithChunks(World.ChunkManager, Position + Velocity, false)) { MoveTarget(Velocity); PushVelocity = Vector3.Zero; } else { PushVelocity += Vector3.Up * 0.1f; Position += PushVelocity; } Velocity *= 0.8f; UpdateBasisVectors(); Vector3 projectedTarget = ProjectToSurface(Target); Vector3 diffTarget = projectedTarget - Target; Position = (Position + diffTarget) * 0.05f + Position * 0.95f; Target = projectedTarget * 0.05f + Target * 0.95f; float currRadius = (Position - Target).Length(); float newRadius = Math.Max(currRadius + diffRadius, 3.0f); Position = MathFunctions.ProjectOutOfHalfPlane(MathFunctions.ProjectOutOfCylinder(MathFunctions.ProjectToSphere(Position - right * diffTheta * 2 - up * diffPhi * 2, newRadius, Target), Target, 3.0f), Target, 2.0f); UpdateViewMatrix(); }
public void OverheadUpdate(DwarfTime time, ChunkManager chunks, float diffPhi, float diffTheta, float diffRadius) { Vector3 forward = (Target - Position); forward.Normalize(); Vector3 right = Vector3.Cross(forward, UpVector); Vector3 up = Vector3.Cross(right, forward); right.Normalize(); up.Normalize(); MouseState mouse = Mouse.GetState(); KeyboardState keys = Keyboard.GetState(); var bounds = new BoundingBox(World.ChunkManager.Bounds.Min, World.ChunkManager.Bounds.Max + Vector3.UnitY * 20); if (ZoomTargets.Count > 0) { Vector3 currTarget = MathFunctions.Clamp(ProjectToSurface(ZoomTargets.First()), bounds); if (MathFunctions.Dist2D(Target, currTarget) > 5 && _zoomTime < 3) { Vector3 newTarget = 0.8f * Target + 0.2f * currTarget; Vector3 d = newTarget - Target; if (bounds.Contains(Target + d) != ContainmentType.Contains) { _zoomTime = 0; ZoomTargets.RemoveAt(0); } else { Target += d; Position += d; _zoomTime += (float)time.ElapsedRealTime.TotalSeconds; } } else { _zoomTime = 0; ZoomTargets.RemoveAt(0); } } Target = MathFunctions.Clamp(Target, bounds); int edgePadding = -10000; if (GameSettings.Default.EnableEdgeScroll) { edgePadding = 100; } float diffX, diffY = 0; float dt = (float)time.ElapsedRealTime.TotalSeconds; SnapToBounds(new BoundingBox(World.ChunkManager.Bounds.Min, World.ChunkManager.Bounds.Max + Vector3.UnitY * 20)); if (KeyManager.RotationEnabled(this)) { World.UserInterface.Gui.MouseVisible = false; if (!shiftPressed) { shiftPressed = true; mouseOnRotate = new Point(mouse.X, mouse.Y); mousePrerotate = new Point(mouse.X, mouse.Y); } if (!isLeftPressed && mouse.LeftButton == ButtonState.Pressed) { isLeftPressed = true; } else if (mouse.LeftButton == ButtonState.Released) { isLeftPressed = false; } if (!isRightPressed && mouse.RightButton == ButtonState.Pressed) { isRightPressed = true; } else if (mouse.RightButton == ButtonState.Released) { isRightPressed = false; } Mouse.SetPosition(mouseOnRotate.X, mouseOnRotate.Y); diffX = mouse.X - mouseOnRotate.X; diffY = mouse.Y - mouseOnRotate.Y; if (!isRightPressed) { float filterDiffX = (float)(diffX * dt); float filterDiffY = (float)(diffY * dt); diffTheta = (filterDiffX); diffPhi = -(filterDiffY); } KeyManager.TrueMousePos = mousePrerotate; } else { if (shiftPressed) { Mouse.SetPosition(mousePrerotate.X, mousePrerotate.Y); KeyManager.TrueMousePos = new Point(mousePrerotate.X, mousePrerotate.Y); } else { KeyManager.TrueMousePos = new Point(mouse.X, mouse.Y); } shiftPressed = false; World.UserInterface.Gui.MouseVisible = true; } Vector3 velocityToSet = Vector3.Zero; //if (EnableControl) { if (keys.IsKeyDown(ControlSettings.Mappings.Forward) || keys.IsKeyDown(Keys.Up)) { Vector3 mov = forward; mov.Y = 0; mov.Normalize(); velocityToSet += mov * CameraMoveSpeed * dt; } else if (keys.IsKeyDown(ControlSettings.Mappings.Back) || keys.IsKeyDown(Keys.Down)) { Vector3 mov = forward; mov.Y = 0; mov.Normalize(); velocityToSet += -mov * CameraMoveSpeed * dt; } if (keys.IsKeyDown(ControlSettings.Mappings.Left) || keys.IsKeyDown(Keys.Left)) { Vector3 mov = right; mov.Y = 0; mov.Normalize(); velocityToSet += -mov * CameraMoveSpeed * dt; } else if (keys.IsKeyDown(ControlSettings.Mappings.Right) || keys.IsKeyDown(Keys.Right)) { Vector3 mov = right; mov.Y = 0; mov.Normalize(); velocityToSet += mov * CameraMoveSpeed * dt; } } //else if (FollowAutoTarget) { Vector3 prevTarget = Target; float damper = MathFunctions.Clamp((Target - AutoTarget).Length() - 5, 0, 1); float smooth = 0.1f * damper; Target = AutoTarget * (smooth) + Target * (1.0f - smooth); Position += (Target - prevTarget); } if (velocityToSet.LengthSquared() > 0) { World.Tutorial("camera"); Velocity = velocityToSet; } if (!KeyManager.RotationEnabled(this)) { if (!World.UserInterface.IsMouseOverGui) { if (mouse.X < edgePadding || mouse.X > GameState.Game.GraphicsDevice.Viewport.Width - edgePadding) { moveTimer.Update(time); if (moveTimer.HasTriggered) { float dir = 0.0f; if (mouse.X < edgePadding) { dir = edgePadding - mouse.X; } else { dir = (GameState.Game.GraphicsDevice.Viewport.Width - edgePadding) - mouse.X; } dir *= 0.01f; Vector3 delta = right * CameraMoveSpeed * dir * dt; delta.Y = 0; Velocity = -delta; } } else if (mouse.Y < edgePadding || mouse.Y > GameState.Game.GraphicsDevice.Viewport.Height - edgePadding) { moveTimer.Update(time); if (moveTimer.HasTriggered) { float dir = 0.0f; if (mouse.Y < edgePadding) { dir = -(edgePadding - mouse.Y); } else { dir = -((GameState.Game.GraphicsDevice.Viewport.Height - edgePadding) - mouse.Y); } dir *= 0.01f; Vector3 delta = up * CameraMoveSpeed * dir * dt; delta.Y = 0; Velocity = -delta; } } else { moveTimer.Reset(moveTimer.TargetTimeSeconds); } } } int scroll = mouse.ScrollWheelValue; if (isRightPressed && KeyManager.RotationEnabled(this)) { scroll = (int)(diffY * 10) + LastWheel; } if (scroll != LastWheel && !World.UserInterface.IsMouseOverGui) { int change = scroll - LastWheel; if (!(keys.IsKeyDown(Keys.LeftAlt) || keys.IsKeyDown(Keys.RightAlt))) { if (!keys.IsKeyDown(Keys.LeftControl)) { var delta = change * -1; if (GameSettings.Default.InvertZoom) { delta *= -1; } diffRadius = delta * CameraZoomSpeed * dt; if (diffRadius < 0 && !FollowAutoTarget && GameSettings.Default.ZoomCameraTowardMouse && !shiftPressed) { float diffxy = (new Vector3(Target.X, 0, Target.Z) - new Vector3(World.Renderer.CursorLightPos.X, 0, World.Renderer.CursorLightPos.Z)).Length(); if (diffxy > 5) { Vector3 slewTarget = Target * 0.9f + World.Renderer.CursorLightPos * 0.1f; Vector3 slewDiff = slewTarget - Target; Target += slewDiff; Position += slewDiff; } } } else { World.Renderer.SetMaxViewingLevel(World.Renderer.PersistentSettings.MaxViewingLevel + (int)((float)change * 0.01f)); } } } LastWheel = mouse.ScrollWheelValue; if (!CollidesWithChunks(World.ChunkManager, Position + Velocity, false, false, 0.5f, 1.0f)) { MoveTarget(Velocity); PushVelocity = Vector3.Zero; } else { PushVelocity += Vector3.Up * 0.1f; Position += PushVelocity; } Velocity *= 0.8f; UpdateBasisVectors(); bool projectTarget = GameSettings.Default.CameraFollowSurface || (!GameSettings.Default.CameraFollowSurface && (keys.IsKeyDown(Keys.LeftControl) || keys.IsKeyDown(Keys.RightControl))); Vector3 projectedTarget = projectTarget ? ProjectToSurface(Target) : Target; Vector3 diffTarget = projectedTarget - Target; if (diffTarget.LengthSquared() > 25) { diffTarget.Normalize(); diffTarget *= 5; } Position = (Position + diffTarget) * 0.05f + Position * 0.95f; Target = (Target + diffTarget) * 0.05f + Target * 0.95f; float currRadius = (Position - Target).Length(); float newRadius = Math.Max(currRadius + diffRadius, 3.0f); Position = MathFunctions.ProjectOutOfHalfPlane(MathFunctions.ProjectOutOfCylinder(MathFunctions.ProjectToSphere(Position - right * diffTheta * 2 - up * diffPhi * 2, newRadius, Target), Target, 3.0f), Target, 2.0f); UpdateViewMatrix(); }
public IEnumerable<Status> WaitAndHit(float time) { Body objectToHit = Creature.AI.Blackboard.GetData<Body>("Anvil"); Timer timer = new Timer(time, true); while (!timer.HasTriggered) { timer.Update(DwarfTime.LastTime); Creature.CurrentCharacterMode = Creature.CharacterMode.Attacking; Creature.Physics.Velocity *= 0.1f; Creature.Attacks[0].PerformNoDamage(DwarfTime.LastTime, Creature.AI.Position); Drawer2D.DrawLoadBar(Agent.Position + Vector3.Up, Color.White, Color.Black, 100, 16, timer.CurrentTimeSeconds / time); yield return Status.Running; } Creature.CurrentCharacterMode = Creature.CharacterMode.Idle; Creature.AI.AddThought(Thought.ThoughtType.Crafted); Creature.AI.AddXP((int)(time * 5)); if (objectToHit != null) { objectToHit.IsReserved = false; objectToHit.ReservedFor = null; } yield return Status.Success; }
public override IEnumerable <Act.Status> Run() { List <ResourceAmount> foods = Agent.Creature.Inventory.GetResources(new Quantitiy <Resource.ResourceTags>(Resource.ResourceTags.Edible), Inventory.RestockType.Any); if (foods.Count == 0 && Agent.Creature.Faction == Agent.World.PlayerFaction) { yield return(Act.Status.Fail); yield break; } FoodBody = null; Timer eatTimer = new Timer(3.0f, true); foreach (ResourceAmount resourceAmount in foods) { if (resourceAmount.NumResources > 0) { List <Body> bodies = Agent.Creature.Inventory.RemoveAndCreate(new ResourceAmount(resourceAmount.ResourceType, 1), Inventory.RestockType.Any); var resource = ResourceLibrary.GetResourceByName(resourceAmount.ResourceType); Agent.Creature.NoiseMaker.MakeNoise("Chew", Agent.Creature.AI.Position); if (bodies.Count == 0) { yield return(Act.Status.Fail); } else { FoodBody = bodies[0]; while (!eatTimer.HasTriggered) { eatTimer.Update(DwarfTime.LastTime); Matrix rot = Agent.Creature.Physics.LocalTransform; rot.Translation = Vector3.Zero; FoodBody.LocalTransform = Agent.Creature.Physics.LocalTransform; Vector3 foodPosition = Agent.Creature.Physics.Position + Vector3.Up * 0.05f + Vector3.Transform(Vector3.Forward, rot) * 0.5f; FoodBody.LocalPosition = foodPosition; FoodBody.PropogateTransforms(); FoodBody.Active = false; Agent.Creature.Physics.Velocity = Vector3.Zero; Agent.Creature.CurrentCharacterMode = CharacterMode.Sitting; if (MathFunctions.RandEvent(0.05f)) { Agent.Creature.World.ParticleManager.Trigger("crumbs", foodPosition, Color.White, 3); } yield return(Act.Status.Running); } Agent.Creature.Status.Hunger.CurrentValue += resource.FoodContent; Agent.Creature.AddThought(Thought.ThoughtType.AteFood); if (resource.Tags.Contains(Resource.ResourceTags.Alcohol)) { Agent.Creature.AddThought(Thought.ThoughtType.HadAle); } FoodBody.GetRoot().Delete(); yield return(Act.Status.Success); } yield break; } } }
public IEnumerable <Status> WaitUntilBored() { Timer waitTimer = new Timer(SitTime, false); var body = Creature.AI.Blackboard.GetData <GameComponent>("reserved-chair"); // Snap relative the chair's position, not their own... Vector3 snapPosition = body.Position + new Vector3(0, 0.4f, 0); if (body == null || body.IsDead) { Creature.OverrideCharacterMode = false; yield return(Status.Success); yield break; } while (true) { if (Creature.AI.Tasks.Count > 1) { Creature.OverrideCharacterMode = false; yield return(Status.Success); } if (Creature.AI.Stats.Energy.IsDissatisfied()) { Creature.OverrideCharacterMode = false; yield return(Status.Success); } if (Creature.AI.Stats.Hunger.IsDissatisfied()) { Creature.OverrideCharacterMode = false; yield return(Status.Success); } if (Creature.AI.Sensor.Enemies.Count > 0) { Creature.OverrideCharacterMode = false; yield return(Status.Success); } waitTimer.Update(DwarfTime.LastTime); if (waitTimer.HasTriggered) { Creature.OverrideCharacterMode = false; yield return(Status.Success); } ConverseFriends(); Agent.Position = snapPosition; Agent.Physics.PropogateTransforms(); Agent.Physics.IsSleeping = true; Agent.Physics.Velocity = Vector3.Zero; Creature.CurrentCharacterMode = CharacterMode.Sitting; Creature.OverrideCharacterMode = true; yield return(Status.Running); } }
public IEnumerable<Status> WaitUntilBored() { Timer waitTimer = new Timer(SitTime, false); Timer eatTimer = new Timer(10.0f + MathFunctions.Rand(0, 1), false); Vector3 snapPosition = Agent.Position + new Vector3(0, 0.2f, 0); Body body = Creature.AI.Blackboard.GetData<Body>("Chair"); if (body == null || body.IsDead) { Creature.OverrideCharacterMode = false; yield return Status.Success; yield break; } while (true) { if (Creature.AI.Tasks.Count > 1) { Creature.OverrideCharacterMode = false; yield return Status.Success; } if (Creature.AI.Status.Energy.IsUnhappy()) { Creature.OverrideCharacterMode = false; yield return Status.Success; } if (Creature.AI.Status.Hunger.IsUnhappy()) { Creature.OverrideCharacterMode = false; yield return Status.Success; } if (Creature.AI.Sensor.Enemies.Count > 0) { Creature.OverrideCharacterMode = false; yield return Status.Success; } waitTimer.Update(DwarfTime.LastTime); if (waitTimer.HasTriggered) { Creature.OverrideCharacterMode = false; yield return Status.Success; } ConverseFriends(); eatTimer.Update(DwarfTime.LastTime); if(eatTimer.HasTriggered) foreach (Act.Status status in EatFood()) { if (status == Act.Status.Running) { Creature.OverrideCharacterMode = false; yield return Act.Status.Running; } } Agent.Position = snapPosition; Agent.Physics.IsSleeping = true; Creature.CurrentCharacterMode = Creature.CharacterMode.Sitting; Creature.OverrideCharacterMode = true; yield return Status.Running; } }
public IEnumerable <Act.Status> GreedyFallbackBehavior(Creature agent) { var edgeGoal = new EdgeGoalRegion(); while (true) { DieTimer.Update(DwarfTime.LastTime); if (DieTimer.HasTriggered) { foreach (var status in Die(agent)) { continue; } yield break; } var creatureVoxel = agent.Physics.CurrentVoxel; List <MoveAction> path = new List <MoveAction>(); var storage = new MoveActionTempStorage(); for (int i = 0; i < 10; i++) { if (edgeGoal.IsInGoalRegion(creatureVoxel)) { foreach (var status in Die(agent)) { continue; } yield return(Act.Status.Success); yield break; } var actions = agent.AI.Movement.GetMoveActions(new MoveState { Voxel = creatureVoxel }, new List <GameComponent>(), storage); float minCost = float.MaxValue; var minAction = new MoveAction(); bool hasMinAction = false; foreach (var action in actions) { var vox = action.DestinationVoxel; float cost = edgeGoal.Heuristic(vox) * 10 + MathFunctions.Rand(0.0f, 0.1f) + agent.AI.Movement.Cost(action.MoveType); if (cost < minCost) { minAction = action; minCost = cost; hasMinAction = true; } } if (hasMinAction) { path.Add(minAction); creatureVoxel = minAction.DestinationVoxel; } else { foreach (var status in Die(agent)) { continue; } yield return(Act.Status.Success); yield break; } } if (path.Count == 0) { foreach (var status in Die(agent)) { continue; } yield return(Act.Status.Success); yield break; } agent.AI.Blackboard.SetData("GreedyPath", path); var pathAct = new FollowPathAct(agent.AI, "GreedyPath"); pathAct.Initialize(); foreach (Act.Status status in pathAct.Run()) { yield return(Act.Status.Running); } yield return(Act.Status.Running); } }
public IEnumerable<Act.Status> GoToRandomTarget(float radius) { Vector3 randomVector = MathFunctions.RandVector3Cube()*radius; Vector3 target = Physics.ClampToBounds(Position + randomVector); float dist = (target - Position).Length(); Timer timout = new Timer(3.0f, false); while (dist > 3.0f) { timout.Update(DwarfTime.LastTime); if (timout.HasTriggered) { break; } Vector3 output = Creature.Controller.GetOutput(DwarfTime.Dt, target, Position); output.Normalize(); output *= 10; Physics.ApplyForce(new Vector3(output.X, 0.0f, output.Z), DwarfTime.Dt); dist = (target - Position).Length(); yield return Act.Status.Running; } yield return Act.Status.Success; }
public void Update(DwarfTime gameTime, Camera camera, GraphicsDevice g) { UpdateRenderList(camera); if (waterUpdateTimer.Update(gameTime)) { WaterUpdateEvent.Set(); } UpdateRebuildList(); generateChunksTimer.Update(gameTime); if (generateChunksTimer.HasTriggered) { if (ToGenerate.Count > 0) { NeedsGenerationEvent.Set(); ChunkData.RecomputeNeighbors(); } foreach (VoxelChunk chunk in GeneratedChunks) { if (!ChunkData.ChunkMap.ContainsKey(chunk.ID)) { ChunkData.AddChunk(chunk); ChunkGen.GenerateVegetation(chunk, Components, Content, Graphics); ChunkGen.GenerateFauna(chunk, Components, Content, Graphics, PlayState.ComponentManager.Factions); List <VoxelChunk> adjacents = ChunkData.GetAdjacentChunks(chunk); foreach (VoxelChunk c in adjacents) { c.ShouldRecalculateLighting = true; c.ShouldRebuild = true; } RecalculateBounds(); } } while (GeneratedChunks.Count > 0) { VoxelChunk gen = null; if (!GeneratedChunks.TryDequeue(out gen)) { break; } } } visibilityChunksTimer.Update(gameTime); if (visibilityChunksTimer.HasTriggered) { visibleSet.Clear(); GetChunksIntersecting(camera.GetFrustrum(), visibleSet); //RemoveDistantBlocks(camera); } foreach (VoxelChunk chunk in ChunkData.ChunkMap.Values) { chunk.Update(gameTime); } Water.Splash(gameTime); Water.HandleTransfers(gameTime); HashSet <VoxelChunk> affectedChunks = new HashSet <VoxelChunk>(); foreach (Voxel voxel in KilledVoxels) { affectedChunks.Add(voxel.Chunk); voxel.Chunk.NotifyDestroyed(new Point3(voxel.GridPosition)); if (!voxel.IsInterior) { foreach (KeyValuePair <Point3, VoxelChunk> n in voxel.Chunk.Neighbors) { affectedChunks.Add(n.Value); } } } if (GameSettings.Default.FogofWar) { ChunkData.Reveal(KilledVoxels); } lock (RebuildList) { foreach (VoxelChunk affected in affectedChunks) { affected.NotifyTotalRebuild(false); } } KilledVoxels.Clear(); }
override public void Update(DwarfTime gameTime, ChunkManager chunks, Camera camera) { base.Update(gameTime, chunks, camera); if (!Active) { return; } Creature.NoiseMaker.BasePitch = Stats.VoicePitch; // Non-dwarves are always at full energy. Stats.Energy.CurrentValue = 100.0f; AutoGatherTimer.Update(gameTime); if (AutoGatherTimer.HasTriggered) { if (!String.IsNullOrEmpty(Faction.Race.BecomeWhenEvil) && MathFunctions.RandEvent(0.01f)) { Faction.Minions.Remove(this); Faction = World.Factions.Factions[Faction.Race.BecomeWhenEvil]; Faction.AddMinion(this); } else if (!String.IsNullOrEmpty(Faction.Race.BecomeWhenNotEvil) && MathFunctions.RandEvent(0.01f)) { Faction.Minions.Remove(this); Faction = World.Factions.Factions[Faction.Race.BecomeWhenNotEvil]; Faction.AddMinion(this); } foreach (var body in World.EnumerateIntersectingObjects(Physics.BoundingBox.Expand(3.0f)).OfType <ResourceEntity>().Where(r => r.Active && r.AnimationQueue.Count == 0)) { var resource = Library.GetResourceType(body.Resource.Type); if (resource.Tags.Contains(Resource.ResourceTags.Edible)) { if ((Faction.Race.EatsMeat && resource.Tags.Contains(Resource.ResourceTags.AnimalProduct)) || (Faction.Race.EatsPlants && !resource.Tags.Contains(Resource.ResourceTags.AnimalProduct))) { Creature.GatherImmediately(body); AssignTask(new ActWrapperTask(new EatFoodAct(this, false))); } } } OrderEnemyAttack(); } DeleteBadTasks(); PreEmptTasks(); HandleReproduction(); // Try to find food if we are hungry. Wait - doesn't this rob the player? if (Stats.Hunger.IsDissatisfied() && World.CountResourcesWithTag(Resource.ResourceTags.Edible) > 0) { Task toReturn = new SatisfyHungerTask(); if (Stats.Hunger.IsCritical()) { toReturn.Priority = TaskPriority.Urgent; } if (!Tasks.Contains(toReturn) && CurrentTask != toReturn) { AssignTask(toReturn); } } if (CurrentTask == null) // We need something to do. { var goal = GetEasiestTask(Tasks); if (goal != null) { ChangeTask(goal); } else { var newTask = ActOnIdle(); if (newTask != null) { ChangeTask(newTask); } } } else { if (CurrentAct == null) // 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 == null) { ChangeTask(null); } } if (CurrentAct != null) { var status = CurrentAct.Tick(); bool retried = false; if (CurrentAct != null && CurrentTask != null) { if (status == Act.Status.Fail) { LastFailedAct = CurrentAct.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(GameSettings.Default.DrownChance)) { 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(); } }
public override IEnumerable<Act.Status> Run() { if (Spell.IsResearched) { Creature.CurrentCharacterMode = Creature.CharacterMode.Idle; Creature.OverrideCharacterMode = false; yield return Status.Success; yield break; } Timer starParitcle = new Timer(0.5f, false); float totalResearch = 0.0f; while (!Spell.IsResearched) { Creature.CurrentCharacterMode = Creature.CharacterMode.Attacking; Creature.OverrideCharacterMode = true; float research = Creature.Stats.BuffedInt * 0.25f * DwarfTime.Dt; Spell.ResearchProgress += research; totalResearch += research; Creature.Physics.Velocity *= 0; if ((int) totalResearch > 0) { SoundManager.PlaySound(ContentPaths.Audio.tinkle, Creature.AI.Position, true); Creature.AI.AddXP((int)(totalResearch)); totalResearch = 0.0f; } if (Spell.ResearchProgress >= Spell.ResearchTime) { PlayState.AnnouncementManager.Announce("Researched " + Spell.Spell.Name, Creature.Stats.FullName + " (" + Creature.Stats.CurrentLevel.Name + ")" + " discovered the " + Spell.Spell.Name + " spell!", Agent.ZoomToMe); } starParitcle.Update(DwarfTime.LastTime); if(starParitcle.HasTriggered) PlayState.ParticleManager.Trigger("star_particle", Creature.AI.Position, Color.White, 3); yield return Status.Running; } Creature.AI.AddThought(Thought.ThoughtType.Researched); Creature.OverrideCharacterMode = false; Creature.CurrentCharacterMode = Creature.CharacterMode.Idle; yield return Status.Success; yield break; }
public void Update() { if (!Enabled) { return; } var mouse = Mouse.GetState(); var keyboard = Keyboard.GetState(); // Select bodies under the mouse if it is hovering. MouseOverTimer.Update(DwarfTime.LastTime); if (MouseOverTimer.HasTriggered) { SelectedEntities = Components.FindRootBodiesInsideScreenRectangle(new Rectangle(mouse.X - 2, mouse.Y - 2, 4, 4), CameraController); if (SelectedEntities.Count > 0) { OnMouseOver(SelectedEntities); } else { OnMouseOver(new List <GameComponent>()); } } // If the left mouse button is pressed, update the selection rectangle. if (isLeftPressed) { if (mouse.LeftButton == ButtonState.Released) { isLeftPressed = false; SelectionBuffer = Components.FindRootBodiesInsideScreenRectangle(SelectionRectangle, CameraController); LeftReleased.Invoke(); } else { UpdateSelectionRectangle(mouse.X, mouse.Y); } } // Otherwise, if the mouse has first been pressed, initialize selection else if (mouse.LeftButton == ButtonState.Pressed) { isLeftPressed = true; ClickPoint = new Point(mouse.X, mouse.Y); ClickPoint3D = World.Renderer.CursorLightPos; SelectionRectangle = new Rectangle(mouse.X, mouse.Y, 0, 0); } if (AllowRightClickSelection) { // If the right mouse button has been sustained-pressed, update // the selection rectangle. if (isRightPressed) { if (mouse.RightButton == ButtonState.Released) { isRightPressed = false; SelectionBuffer = Components.FindRootBodiesInsideScreenRectangle(SelectionRectangle, CameraController); RightReleased.Invoke(); } else { UpdateSelectionRectangle(mouse.X, mouse.Y); } } // Otherwise if the mouse has been first pressed, initialize selection else if (mouse.RightButton == ButtonState.Pressed) { isRightPressed = true; ClickPoint = new Point(mouse.X, mouse.Y); ClickPoint3D = World.Renderer.CursorLightPos; SelectionRectangle = new Rectangle(mouse.X, mouse.Y, 0, 0); } } // If no mouse button has been pressed, there are no bodies currently being selected. if (!isLeftPressed && !isRightPressed) { CurrentBodies.Clear(); } }
public IEnumerable<Act.Status> HitAndWait(float f, bool loadBar) { Timer waitTimer = new Timer(f, true); CurrentCharacterMode = CharacterMode.Attacking; while(!waitTimer.HasTriggered) { waitTimer.Update(DwarfTime.LastTime); if(loadBar) { Drawer2D.DrawLoadBar(AI.Position + Vector3.Up, Color.White, Color.Black, 100, 16, waitTimer.CurrentTimeSeconds / waitTimer.TargetTimeSeconds); } Attacks[0].PerformNoDamage(DwarfTime.LastTime, AI.Position); Physics.Velocity = Vector3.Zero; yield return Act.Status.Running; } CurrentCharacterMode = CharacterMode.Idle; yield return Act.Status.Success; }
public override IEnumerable<Status> Run() { Timer waitTimer = new Timer(1.0f, true); bool removed = Agent.Faction.RemoveResources(Resources, Agent.Position); if(!removed) { yield return Status.Fail; } else { foreach(ResourceAmount resource in Resources) { Agent.Creature.Inventory.Resources.AddResource(resource.CloneResource()); } while (!waitTimer.HasTriggered) { waitTimer.Update(DwarfTime.LastTime); yield return Status.Running; } yield return Status.Success; } }
public void OverheadUpdate(DwarfTime time, ChunkManager chunks) { MouseState mouse = Mouse.GetState(); KeyboardState keys = Keyboard.GetState(); if (ZoomTargets.Count > 0) { Vector3 currTarget = ZoomTargets.First(); if (Vector3.DistanceSquared(Target, currTarget) > 5) { Target = 0.8f * Target + 0.2f * currTarget; } else { ZoomTargets.RemoveAt(0); } } int edgePadding = -10000; if (GameSettings.Default.EnableEdgeScroll) { edgePadding = 100; } bool stateChanged = false; float dt = (float)time.ElapsedRealTime.TotalSeconds; SnapToBounds(new BoundingBox(PlayState.ChunkManager.Bounds.Min, PlayState.ChunkManager.Bounds.Max + Vector3.UnitY * 20)); if (KeyManager.RotationEnabled()) { if (!shiftPressed) { shiftPressed = true; mouse = Mouse.GetState(); stateChanged = true; } if (!isLeftPressed && mouse.LeftButton == ButtonState.Pressed) { isLeftPressed = true; stateChanged = true; } else if (mouse.LeftButton == ButtonState.Released) { isLeftPressed = false; } if (!isRightPressed && mouse.RightButton == ButtonState.Pressed) { isRightPressed = true; stateChanged = true; } else if (mouse.RightButton == ButtonState.Released) { isRightPressed = false; } if (stateChanged) { Mouse.SetPosition(GameState.Game.GraphicsDevice.Viewport.Width / 2, GameState.Game.GraphicsDevice.Viewport.Height / 2); mouse = Mouse.GetState(); } float diffX = mouse.X - GameState.Game.GraphicsDevice.Viewport.Width / 2; float diffY = mouse.Y - GameState.Game.GraphicsDevice.Viewport.Height / 2; float filterDiffX = (float)(diffX * dt); float filterDiffY = (float)(diffY * dt); if (Math.Abs(filterDiffX) > 1.0f) { filterDiffX = 1.0f * Math.Sign(filterDiffX); } if (Math.Abs(filterDiffY) > 1.0f) { filterDiffY = 1.0f * Math.Sign(filterDiffY); } targetTheta = Theta - (filterDiffX); targetPhi = Phi - (filterDiffY); Theta = targetTheta * 0.5f + Theta * 0.5f; Phi = targetPhi * 0.5f + Phi * 0.5f; if (Phi < -1.5f) { Phi = -1.5f; } else if (Phi > 1.5f) { Phi = 1.5f; } } else { shiftPressed = false; } bool goingBackward = false; Vector3 velocityToSet = Vector3.Zero; if (keys.IsKeyDown(ControlSettings.Mappings.Forward) || keys.IsKeyDown(Keys.Up)) { Vector3 forward = (Target - Position); forward.Normalize(); if (!KeyManager.RotationEnabled()) { forward.Y = 0; } forward.Normalize(); velocityToSet += forward * CameraMoveSpeed * dt; } else if (keys.IsKeyDown(ControlSettings.Mappings.Back) || keys.IsKeyDown(Keys.Down)) { Vector3 forward = (Target - Position); forward.Normalize(); goingBackward = true; if (!KeyManager.RotationEnabled()) { forward.Y = 0; } forward.Normalize(); velocityToSet += -forward * CameraMoveSpeed * dt; } if (keys.IsKeyDown(ControlSettings.Mappings.Left) || keys.IsKeyDown(Keys.Left)) { Vector3 forward = (Target - Position); forward.Normalize(); Vector3 right = Vector3.Cross(forward, UpVector); right.Normalize(); if (goingBackward) { //right *= -1; } velocityToSet += -right * CameraMoveSpeed * dt; } else if (keys.IsKeyDown(ControlSettings.Mappings.Right) || keys.IsKeyDown(Keys.Right)) { Vector3 forward = (Target - Position); forward.Normalize(); Vector3 right = Vector3.Cross(forward, UpVector); right.Normalize(); if (goingBackward) { //right *= -1; } velocityToSet += right * CameraMoveSpeed * dt; } if (velocityToSet.LengthSquared() > 0) { Velocity = velocityToSet; } if (!KeyManager.RotationEnabled()) { if (mouse.X < edgePadding || mouse.X > GameState.Game.GraphicsDevice.Viewport.Width - edgePadding) { moveTimer.Update(time); if (moveTimer.HasTriggered) { float dir = 0.0f; if (mouse.X < edgePadding) { dir = edgePadding - mouse.X; } else { dir = (GameState.Game.GraphicsDevice.Viewport.Width - edgePadding) - mouse.X; } dir *= 0.05f; Vector3 forward = (Target - Position); forward.Normalize(); Vector3 right = Vector3.Cross(forward, UpVector); Vector3 delta = right * CameraMoveSpeed * dir * dt; delta.Y = 0; Velocity = -delta; } } else if (mouse.Y < edgePadding || mouse.Y > GameState.Game.GraphicsDevice.Viewport.Height - edgePadding) { moveTimer.Update(time); if (moveTimer.HasTriggered) { float dir = 0.0f; if (mouse.Y < edgePadding) { dir = -(edgePadding - mouse.Y); } else { dir = -((GameState.Game.GraphicsDevice.Viewport.Height - edgePadding) - mouse.Y); } dir *= 0.1f; Vector3 forward = (Target - Position); forward.Normalize(); Vector3 right = Vector3.Cross(forward, UpVector); Vector3 up = Vector3.Cross(right, forward); Vector3 delta = up * CameraMoveSpeed * dir * dt; delta.Y = 0; Velocity = -delta; } } else { moveTimer.Reset(moveTimer.TargetTimeSeconds); } } if (mouse.ScrollWheelValue != LastWheel && !PlayState.GUI.IsMouseOver()) { int change = mouse.ScrollWheelValue - LastWheel; if (!(keys.IsKeyDown(Keys.LeftAlt) || keys.IsKeyDown(Keys.RightAlt))) { if (!keys.IsKeyDown(Keys.LeftControl)) { Vector3 delta = new Vector3(0, change, 0); if (GameSettings.Default.InvertZoom) { delta *= -1; } Velocity = delta * CameraZoomSpeed * dt; } else { chunks.ChunkData.SetMaxViewingLevel(chunks.ChunkData.MaxViewingLevel + (int)((float)change * 0.01f), ChunkManager.SliceMode.Y); } } } LastWheel = mouse.ScrollWheelValue; if (!CollidesWithChunks(PlayState.ChunkManager, Target + Velocity, false)) { Target += Velocity; PushVelocity = Vector3.Zero; } else { PushVelocity += Vector3.Up * 0.05f; Target += PushVelocity; } Velocity *= 0.8f; UpdateBasisVectors(); }