/// Modifies fear and then determines if it's has crossed the threshold to /// cause a state change. private void _modifyFear(Action action, double offset) { // Don't add effects if the monster already died. if (!IsAlive) { return; } if (Breed.Flags.Contains("fearless")) { return; } // If it can't run, there's no point in being afraid. if (Breed.Flags.Contains("immobile")) { return; } Fear = Math.Max(0.0, Fear + offset); if (State is AwakeState && Fear > _frightenThreshold) { // Clamp the fear. This is mainly to ensure that a bunch of monsters // don't all get over their fear at the exact same time later. Since the // threshold is randomized, this will make the delay before growing // courageous random too. Fear = _frightenThreshold; Log("{1} is afraid!", this); changeState(new AfraidState()); action.AddEvent(EventType.Fear, this); return; } if (State is AfraidState && Fear <= 0.0) { Log("{1} grows courageous!", this); changeState(new AwakeState()); action.AddEvent(EventType.Courage, this); } }
/// Reduces the actor's health by [damage], and handles its death. Returns /// `true` if the actor died. public bool TakeDamage(Action action, int damage, Noun attackNoun, Actor attacker = null) { Health.Current -= damage; action.Log("{1} takes {2} damage.", this.NounText, damage.ToString()); OnDamaged(action, attacker, damage); if (Health.Current > 0) { return(false); } action.AddEvent(EventType.Die, element: ElementFactory.Instance.None, other: null, pos: null, dir: null, actor: this); action.Log("{1} kill[s] {2}.", attackNoun, this); if (attacker != null) { attacker.OnKilled(action, this); } OnDied(attackNoun); return(true); }