public PlaceBlockSpell(string voxelType, bool transmute) { Texture2D icons = TextureManager.GetTexture(ContentPaths.GUI.icons); Image = new ImageFrame(icons, 32, 1, 2); VoxelType = voxelType; Transmute = transmute; if (!transmute) { Name = VoxelType + " Wall"; Description = "Create a wall of " + VoxelType; Hint = "Click and drag to place " + VoxelType; Recharges = false; RechargeTimer = new Timer(5.0f, false); ManaCost = 15; Mode = SpellMode.SelectEmptyVoxels; } else { Name = "Transmute " + VoxelType; Description = "Transmute any block into " + VoxelType; Hint = "Click and drag to transmute."; Recharges = false; RechargeTimer = new Timer(5.0f, false); ManaCost = 25; Mode = SpellMode.SelectFilledVoxels; } }
public BearTrap(Vector3 pos) : base("BearTrap", PlayState.ComponentManager.RootComponent, Matrix.CreateTranslation(pos), new Vector3(1.0f, 1.0f, 1.0f), Vector3.Zero, true) { Allies = PlayState.PlayerFaction; Sensor = new Sensor("Sensor", this, Matrix.Identity, new Vector3(0.5f, 0.5f, 0.5f), Vector3.Zero) { FireTimer = new Timer(0.5f, false) }; Sensor.OnSensed += Sensor_OnSensed; DeathTimer = new Timer(0.6f, true); DeathParticles = new ParticleTrigger("puff", PlayState.ComponentManager, "DeathParticles", this, Matrix.Identity, new Vector3(0.5f, 0.5f, 0.5f), Vector3.Zero) { SoundToPlay = "" }; DamageAmount = 200; Voxel voxUnder = new Voxel(); PlayState.ChunkManager.ChunkData.GetFirstVoxelUnder(pos, ref voxUnder); VoxListener = new VoxelListener(PlayState.ComponentManager, this, PlayState.ChunkManager, voxUnder); Sprite = new Sprite(PlayState.ComponentManager, "Sprite", this, Matrix.Identity, new SpriteSheet(ContentPaths.Entities.DwarfObjects.beartrap), false); Sprite.AddAnimation(new Animation(0, ContentPaths.Entities.DwarfObjects.beartrap, 32, 32, 0) {Name = IdleAnimation}); Sprite.AddAnimation(new Animation(1, ContentPaths.Entities.DwarfObjects.beartrap, 32, 32, 0, 1, 2, 3) {Name = TriggerAnimation, Speeds = new List<float>() {6.6f}, Loops = true}); }
public AnnouncementViewer(DwarfGUI gui, GUIComponent parent, AnnouncementManager manager) : base(gui, parent) { TweenTimer = new Timer(0.5f, true); TweenOutTimer = new Timer(0.5f, true); SpeechBubble = new Panel(gui, this) { Mode = Panel.PanelMode.SpeechBubble, DrawOrder = -2 }; SpeechBubble.IsVisible = false; Manager = manager; Manager.OnAdded += Manager_OnAdded; Manager.OnRemoved += Manager_OnRemoved; IsMaximized = false; AnnouncementViews = new List<AnnouncementView>(); MaxViews = 4; WaitTimer = new Timer(5, true); Talker = new AnimatedImagePanel(GUI, this, animation); animation.Play(); animation.Loops = true; animation.FrameHZ = 2.0f; }
public InspectSpell(InspectType type) { Type = type; Texture2D icons = TextureManager.GetTexture(ContentPaths.GUI.icons); Recharges = false; switch (type) { case InspectType.InspectBlock: { Image = new ImageFrame(icons, 32, 7, 1); ManaCost = 0; Mode = Spell.SpellMode.SelectFilledVoxels; Name = "Inspect Blocks"; Description = "Mouse over a block to get info about it"; Hint = "Mouse over a block for info"; RechargeTimer = new Timer(0.1f, true); break; } case InspectType.InspectEntity: { Image = new ImageFrame(icons, 32, 7, 1); ManaCost = 0; Mode = Spell.SpellMode.Continuous; Name = "Inspect Objects"; Description = "Select an entity to get info about it"; Hint = "Mouse over entities for info"; RechargeTimer = new Timer(0.1f, true); break; } } }
public TrapSensor(ComponentManager manager, string name, GameComponent parent, Matrix localTransform, Vector3 boundingBoxExtents, Vector3 boundingBoxPos) : base(name, parent, localTransform, boundingBoxExtents, boundingBoxPos) { OnSensed += TrapSensor_OnSensed; Tags.Add("Sensor"); DrawBoundingBox = true; FireTimer = new Timer(0.5f, false); }
public EnemySensor() : base() { Enemies = new List<CreatureAI>(); OnEnemySensed += EnemySensor_OnEnemySensed; SenseTimer = new Timer(0.5f, false); SenseRadius = 15 * 15; }
public ToolTipManager(DwarfGUI gui) { GUI = gui; HoverTimer = new Timer(0.8f, true, Timer.TimerMode.Real); ToolTip = ""; LastMouse = Mouse.GetState(); MovementThreshold = 2; PopupTimer = new Timer(2.5f, true, Timer.TimerMode.Real); }
public ShipmentOrder(float time, Room destination) { BuyOrder = new List<ResourceAmount>(); SellOrder = new List<ResourceAmount>(); OrderTotal = 0.0f; OrderTimer = new Timer(time, true); Destination = destination; HasSentResources = false; }
public EnemySensor(ComponentManager manager, string name, GameComponent parent, Matrix localTransform, Vector3 boundingBoxExtents, Vector3 boundingBoxPos) : base(name, parent, localTransform, boundingBoxExtents, boundingBoxPos) { Enemies = new List<CreatureAI>(); OnEnemySensed += EnemySensor_OnEnemySensed; Tags.Add("Sensor"); SenseTimer = new Timer(0.5f, false); SenseRadius = 15 * 15; }
public Shadow(ComponentManager manager, string name, GameComponent parent, Matrix localTransform, SpriteSheet spriteSheet) : base(manager, name, parent, localTransform, spriteSheet, false) { OrientationType = OrientMode.Fixed; GlobalScale = LocalTransform.Left.Length(); LightsWithVoxels = false; UpdateTimer = new Timer(0.5f, false); Tint = Color.Black; OriginalTransform = LocalTransform; }
public NecromancerAI() { Skeletons = new List<Skeleton>(); MaxSkeletons = 5; SummonTimer = new Timer(5, false); WanderTimer = new Timer(1, false); AttackTimer = new Timer(3, false); SummonTimer.HasTriggered = true; AttackRange = 10; }
public ResourceInfoComponent(DwarfGUI gui, GUIComponent parent, Faction faction) : base(gui, parent) { Faction = faction; UpdateTimer = new Timer(0.5f, false); Layout = new GridLayout(gui, this, 1, 1); CurrentResources = new List<ResourceAmount>(); PanelWidth = 40; PanelHeight = 40; }
public Fairy(string allies, Vector3 position) : base(new CreatureStats(new FairyClass(), 0), "Player", PlayState.PlanService, PlayState.ComponentManager.Factions.Factions[allies], new Physics("Fairy", PlayState.ComponentManager.RootComponent, Matrix.CreateTranslation(position), new Vector3(0.5f, 0.5f, 0.5f), new Vector3(0.0f, -0.25f, 0.0f), 1.0f, 1.0f, 0.999f, 0.999f, new Vector3(0, 0, 0)), PlayState.ChunkManager, GameState.Game.GraphicsDevice, GameState.Game.Content, "Fairy") { ParticleTimer = new Timer(0.2f, false); DeathTimer = new Timer(30.0f, true); Initialize(new FairyClass()); }
public NecromancerAI(Creature creature, string name, EnemySensor sensor, PlanService planService) : base(creature, name, sensor, planService) { Skeletons = new List<Skeleton>(); MaxSkeletons = 5; SummonTimer = new Timer(5, false); WanderTimer = new Timer(1, false); AttackTimer = new Timer(3, false); SummonTimer.HasTriggered = true; AttackRange = 10; }
public Flammable(ComponentManager manager, string name, Body parent, Health health) : base(name, parent) { LocParent = parent; Heat = 0.0f; Flashpoint = 100.0f; Damage = 50.0f; Health = health; CheckLavaTimer = new Timer(1.0f, false); SoundTimer = new Timer(1.0f, false); DamageTimer = new Timer(1.0f, false); }
public Tinter(string name, GameComponent parent, Matrix localTransform, Vector3 boundingBoxExtents, Vector3 boundingBoxPos, bool collisionManager) : base(name, parent, localTransform, boundingBoxExtents, boundingBoxPos, collisionManager) { LightsWithVoxels = true; Tint = new Color(255, 255, 0); LightingTimer = new Timer(0.2f, true); StartTimer = new Timer(0.5f, true); TargetTint = Tint; TintChangeRate = 1.0f; LightsWithVoxels = true; VoxelUnder = new Voxel(); }
public FlyWanderAct(CreatureAI creature, float seconds, float turnTime, float radius, float altitude) : base(creature) { Altitude = altitude; Name = "FlyWander " + seconds; WanderTime = new Timer(seconds, false); TurnTime = new Timer(turnTime, false); Radius = radius; YRadius = 2.0f; GravityCompensation = 0.1f; Damping = 0.25f; TurnThreshold = 2.0f; }
public Tree(Vector3 position, string asset, float treeSize) : base("Tree", PlayState.ComponentManager.RootComponent, Matrix.Identity, new Vector3(treeSize * 2, treeSize * 3, treeSize * 2), new Vector3(treeSize * 0.5f, treeSize * 0.25f, treeSize * 0.5f)) { HurtTimer = new Timer(1.0f, false); ComponentManager componentManager = PlayState.ComponentManager; Matrix matrix = Matrix.Identity; matrix.Translation = position; LocalTransform = matrix; new Mesh(componentManager, "Model", this, Matrix.CreateRotationY((float)(PlayState.Random.NextDouble() * Math.PI)) * Matrix.CreateScale(treeSize, treeSize, treeSize) * Matrix.CreateTranslation(new Vector3(0.7f, 0.0f, 0.7f)), asset, false); Health health = new Health(componentManager, "HP", this, 100.0f * treeSize, 0.0f, 100.0f * treeSize); new Flammable(componentManager, "Flames", this, health); Tags.Add("Vegetation"); Tags.Add("EmitsWood"); new MinimapIcon(this, new ImageFrame(TextureManager.GetTexture(ContentPaths.GUI.map_icons), 16, 1, 0)); Voxel voxelUnder = new Voxel(); if (PlayState.ChunkManager.ChunkData.GetFirstVoxelUnder(position, ref voxelUnder)) { new VoxelListener(componentManager, this, PlayState.ChunkManager, voxelUnder); } Inventory inventory = new Inventory("Inventory", this) { Resources = new ResourceContainer { MaxResources = (int)(treeSize * 10) } }; inventory.Resources.AddResource(new ResourceAmount() { NumResources = (int)(treeSize * 10), ResourceType = ResourceLibrary.Resources[ResourceLibrary.ResourceType.Wood] }); Particles = new ParticleTrigger("Leaves", componentManager, "LeafEmitter", this, Matrix.Identity, new Vector3(treeSize * 2, treeSize * 3, treeSize * 2), new Vector3(treeSize * 0.5f, treeSize * 0.25f, treeSize * 0.5f)) { SoundToPlay = ContentPaths.Audio.vegetation_break }; AddToCollisionManager = true; CollisionType = CollisionManager.CollisionType.Static; }
public Attack(Attack other) { Name = other.Name; DamageAmount = other.DamageAmount; Range = other.Range; HitNoise = other.HitNoise; RechargeTimer = new Timer(other.RechargeRate + MathFunctions.Rand(-0.2f, 0.2f), false); Mode = other.Mode; Knockback = other.Knockback; HitAnimation = other.HitAnimation; HitParticles = other.HitParticles; ProjectileType = other.ProjectileType; LaunchSpeed = other.LaunchSpeed; AnimationAsset = other.AnimationAsset; }
public Attack(string name, float damage, float time, float range, string noise, string animation) { Name = name; DamageAmount = damage; RechargeTimer = new Timer(time + MathFunctions.Rand(-0.2f, 0.2f), false); Range = range; HitNoise = noise; Mode = AttackMode.Melee; Knockback = 0.0f; HitAnimation = null; HitParticles = ""; ProjectileType = ""; AnimationAsset = animation; CreateHitAnimation(); }
public PlanAct(CreatureAI agent, string pathOut, string target, PlanType planType) : base(agent) { Type = planType; Name = "Plan to " + target; PlannerTimer = new Timer(1.0f, false); MaxExpansions = 1000; PathOut = pathOut; TargetName = target; PlanSubscriber = new PlanSubscriber(PlayState.PlanService); WaitingOnResponse = false; MaxTimeouts = 4; Timeouts = 0; Radius = 0; }
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; }
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 MotionAnimation(float time, bool loop) { Time = new Timer(time, !loop); OnComplete += MotionAnimation_OnComplete; }
public GUITween(float time) { TweenTimer = new Timer(time, true, Timer.TimerMode.Real); }
public IEnumerable <Status> AvoidTarget(float range, float time) { if (Target == null) { yield return(Status.Fail); yield break; } Timer avoidTimer = new Timer(time, true, Timer.TimerMode.Game); while (true) { avoidTimer.Update(DwarfTime.LastTime); if (avoidTimer.HasTriggered) { yield return(Status.Success); } float dist = (Target.Position - Agent.Position).Length(); if (dist > range) { yield return(Status.Success); yield break; } List <MoveAction> neighbors = Agent.Movement.GetMoveActions(Agent.Position, Creature.World.OctTree).ToList(); neighbors.Sort((a, b) => { if (a.Equals(b)) { return(0); } float da = (a.DestinationVoxel.WorldPosition - Target.Position).LengthSquared(); float db = (b.DestinationVoxel.WorldPosition - Target.Position).LengthSquared(); return(da.CompareTo(db)); }); neighbors.RemoveAll( a => a.MoveType == MoveType.Jump || a.MoveType == MoveType.Climb); if (neighbors.Count == 0) { yield return(Status.Fail); yield break; } MoveAction furthest = neighbors.Last(); bool reachedTarget = false; Timer timeout = new Timer(2.0f, true, Timer.TimerMode.Real); while (!reachedTarget) { Vector3 output = Creature.Controller.GetOutput(DwarfTime.Dt, furthest.DestinationVoxel.WorldPosition + Vector3.One * 0.5f, Agent.Position); Creature.Physics.ApplyForce(output, DwarfTime.Dt); if (Creature.AI.Movement.CanFly) { Creature.Physics.ApplyForce(Vector3.Up * 10, DwarfTime.Dt); } timeout.Update(DwarfTime.LastTime); yield return(Status.Running); if (timeout.HasTriggered || (furthest.DestinationVoxel.WorldPosition - Agent.Position).Length() < 1) { reachedTarget = true; } Agent.Creature.CurrentCharacterMode = CharacterMode.Walking; } yield return(Status.Success); yield break; } }
public Attack(Weapon Weapon) { this.Weapon = Weapon; RechargeTimer = new Timer(Weapon.RechargeRate, false); }
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 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 Wait(Timer time) { Name = "Wait " + time.TargetTimeSeconds; Time = time; }
public SummoningCircle() { ParticleTimer = new Timer(0.5f + MathFunctions.Rand(-0.25f, 0.25f), false); }
public ComboBoxSelector(DwarfGUI gui, ComboBox parent, List<string> values, string currentValue) : base(gui, parent) { Columns = new List<List<string>>(); Values = values; CurrentValue = currentValue; int height = 0; Columns.Add(new List<string>()); int currentColumn = 0; int columnWidth = parent.GlobalBounds.Width - 37; ColumnWidth = columnWidth; int bestHeight = 0; foreach(string s in values) { List<string> column = Columns[currentColumn]; Vector2 measure = Datastructures.SafeMeasure(GUI.DefaultFont, s); height += (int) measure.Y; column.Add(s); if(height > bestHeight) { bestHeight = height; } if(height >= MaxHeight) { height = 0; Columns.Add(new List<string>()); currentColumn++; columnWidth += ColumnWidth; } } List<List<string>> removals = new List<List<string>>(); foreach(List<string> column in Columns) { if(column.Count == 0) { removals.Add(column); } } foreach(List<string> column in removals) { Columns.Remove(column); columnWidth -= ColumnWidth; } bestHeight += 15; LocalBounds = new Rectangle(0, parent.GlobalBounds.Height / 2 + GUI.Skin.TileHeight / 2, columnWidth, bestHeight); Box = parent; ClickTimer = new Timer(0.1f, true, Timer.TimerMode.Real); InputManager.MouseClickedCallback += InputManager_MouseClickedCallback; Drawn = true; }
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; } } }
public override IEnumerable <Status> Run() { Creature.IsCloaked = false; if (CurrentAttack == null) { yield return(Status.Fail); yield break; } Timeout.Reset(); FailTimer.Reset(); if (Target == null && TargetName != null) { Target = Agent.Blackboard.GetData <Body>(TargetName); if (Target == null) { yield return(Status.Fail); yield break; } } if (Agent.Faction.Race.IsIntelligent) { var targetInventory = Target.GetRoot().GetComponent <Inventory>(); if (targetInventory != null) { targetInventory.SetLastAttacker(Agent); } } CharacterMode defaultCharachterMode = Creature.AI.Movement.CanFly ? CharacterMode.Flying : CharacterMode.Walking; bool avoided = false; while (true) { Timeout.Update(DwarfTime.LastTime); FailTimer.Update(DwarfTime.LastTime); if (FailTimer.HasTriggered) { Creature.Physics.Orientation = Physics.OrientMode.RotateY; Creature.OverrideCharacterMode = false; Creature.CurrentCharacterMode = defaultCharachterMode; yield return(Status.Fail); yield break; } if (Timeout.HasTriggered) { if (Training) { Agent.AddXP(1); Creature.Physics.Orientation = Physics.OrientMode.RotateY; Creature.OverrideCharacterMode = false; Creature.CurrentCharacterMode = defaultCharachterMode; yield return(Status.Success); yield break; } else { Creature.Physics.Orientation = Physics.OrientMode.RotateY; Creature.OverrideCharacterMode = false; Creature.CurrentCharacterMode = defaultCharachterMode; yield return(Status.Fail); yield break; } } if (Target == null || Target.IsDead) { Creature.CurrentCharacterMode = defaultCharachterMode; Creature.Physics.Orientation = Physics.OrientMode.RotateY; yield return(Status.Success); } // Find the location of the melee target Vector3 targetPos = new Vector3(Target.GlobalTransform.Translation.X, Target.GetBoundingBox().Min.Y, Target.GlobalTransform.Translation.Z); Vector2 diff = new Vector2(targetPos.X, targetPos.Z) - new Vector2(Creature.AI.Position.X, Creature.AI.Position.Z); Creature.Physics.Face(targetPos); bool intersectsbounds = Creature.Physics.BoundingBox.Intersects(Target.BoundingBox); // If we are really far from the target, something must have gone wrong. if (!intersectsbounds && diff.Length() > CurrentAttack.Range * 4) { Creature.Physics.Orientation = Physics.OrientMode.RotateY; Creature.OverrideCharacterMode = false; Creature.CurrentCharacterMode = defaultCharachterMode; yield return(Status.Fail); yield break; } // If we're out of attack range, run toward the target. if (!Creature.AI.Movement.IsSessile && !intersectsbounds && diff.Length() > CurrentAttack.Range) { Creature.CurrentCharacterMode = defaultCharachterMode; /* * Vector3 output = Creature.Controller.GetOutput(DwarfTime.Dt, targetPos, Creature.Physics.GlobalTransform.Translation) * 0.9f; * output.Y = 0.0f; * if (Creature.AI.Movement.CanFly) * { * Creature.Physics.ApplyForce(-Creature.Physics.Gravity, DwarfTime.Dt); * } * if (Creature.AI.Movement.IsSessile) * { * output *= 0.0f; * } * Creature.Physics.ApplyForce(output, DwarfTime.Dt); * Creature.Physics.Orientation = Physics.OrientMode.RotateY; */ GreedyPathAct greedyPath = new GreedyPathAct(Creature.AI, Target, CurrentAttack.Range * 0.75f) { PathLength = 5 }; greedyPath.Initialize(); foreach (Act.Status stat in greedyPath.Run()) { if (stat == Act.Status.Running) { yield return(Status.Running); } else { break; } } } // If we have a ranged weapon, try avoiding the target for a few seconds to get within range. else if (!Creature.AI.Movement.IsSessile && !intersectsbounds && !avoided && (CurrentAttack.Mode == Attack.AttackMode.Ranged && diff.Length() < CurrentAttack.Range * 0.15f)) { FailTimer.Reset(); foreach (Act.Status stat in AvoidTarget(CurrentAttack.Range, 3.0f)) { yield return(Status.Running); } avoided = true; } // Else, stop and attack else { if (CurrentAttack.Mode == Attack.AttackMode.Ranged && VoxelHelpers.DoesRayHitSolidVoxel(Creature.World.ChunkManager.ChunkData, Creature.AI.Position, Target.Position)) { yield return(Status.Fail); yield break; } FailTimer.Reset(); avoided = false; Creature.Physics.Orientation = Physics.OrientMode.Fixed; Creature.Physics.Velocity = new Vector3(Creature.Physics.Velocity.X * 0.9f, Creature.Physics.Velocity.Y, Creature.Physics.Velocity.Z * 0.9f); CurrentAttack.RechargeTimer.Reset(CurrentAttack.RechargeRate); Creature.Sprite.ResetAnimations(Creature.AttackMode); Creature.Sprite.PlayAnimations(Creature.AttackMode); Creature.CurrentCharacterMode = Creature.AttackMode; Creature.OverrideCharacterMode = true; Timer timeout = new Timer(10.0f, true); while (!CurrentAttack.Perform(Creature, Target, DwarfTime.LastTime, Creature.Stats.BuffedStr + Creature.Stats.BuffedSiz, Creature.AI.Position, Creature.Faction.Name)) { timeout.Update(DwarfTime.LastTime); if (timeout.HasTriggered) { break; } Creature.Physics.Velocity = new Vector3(Creature.Physics.Velocity.X * 0.9f, Creature.Physics.Velocity.Y, Creature.Physics.Velocity.Z * 0.9f); if (Creature.AI.Movement.CanFly) { Creature.Physics.ApplyForce(-Creature.Physics.Gravity * 0.1f, DwarfTime.Dt); } yield return(Status.Running); } timeout.Reset(); while (!Agent.Creature.Sprite.AnimPlayer.IsDone()) { timeout.Update(DwarfTime.LastTime); if (timeout.HasTriggered) { break; } if (Creature.AI.Movement.CanFly) { Creature.Physics.ApplyForce(-Creature.Physics.Gravity * 0.1f, DwarfTime.Dt); } yield return(Status.Running); } var targetCreature = Target.GetRoot().GetComponent <CreatureAI>(); if (targetCreature != null && !Creature.AI.FightOrFlight(targetCreature)) { yield return(Act.Status.Fail); yield break; } Creature.CurrentCharacterMode = CharacterMode.Attacking; Vector3 dogfightTarget = Vector3.Zero; while (!CurrentAttack.RechargeTimer.HasTriggered && !Target.IsDead) { CurrentAttack.RechargeTimer.Update(DwarfTime.LastTime); if (CurrentAttack.Mode == Attack.AttackMode.Dogfight) { dogfightTarget += MathFunctions.RandVector3Cube() * 0.1f; Vector3 output = Creature.Controller.GetOutput(DwarfTime.Dt, dogfightTarget + Target.Position, Creature.Physics.GlobalTransform.Translation) * 0.9f; Creature.Physics.ApplyForce(output - Creature.Physics.Gravity, DwarfTime.Dt); } else { Creature.Physics.Velocity = Vector3.Zero; if (Creature.AI.Movement.CanFly) { Creature.Physics.ApplyForce(-Creature.Physics.Gravity, DwarfTime.Dt); } } yield return(Status.Running); } Creature.CurrentCharacterMode = defaultCharachterMode; Creature.Physics.Orientation = Physics.OrientMode.RotateY; if (Target.IsDead) { Target = null; Agent.AddXP(10); Creature.Physics.Face(Creature.Physics.Velocity + Creature.Physics.GlobalTransform.Translation); Creature.Stats.NumThingsKilled++; Creature.AddThought(Thought.ThoughtType.KilledThing); Creature.Physics.Orientation = Physics.OrientMode.RotateY; Creature.OverrideCharacterMode = false; Creature.CurrentCharacterMode = defaultCharachterMode; yield return(Status.Success); break; } } yield return(Status.Running); } }