public IEnumerable <T> Create(int level) { // use the actual total in case the data adds up to more than 100 float totalOdds = Math.Max(TotalOdds, Choices.Sum((choice) => choice.Odds)); float choiceValue = Rng.Float(TotalOdds); IDrop <T> dropped = null; // count through to find the chosen one foreach (DropChoice choice in Choices) { choiceValue -= choice.Odds; if (choiceValue <= 0) { dropped = choice.Drop; break; } } // drop it if we have one if (dropped != null) { foreach (var item in dropped.Create(level)) { yield return(item); } } }
public override void AfterDamage(NotNull <Action> action, NotNull <Hit> hit) { // let the base handle elements base.AfterDamage(action, hit); //### bob: handle sustains and a chance to resist? // handle the flags TryDrain(action, hit.Value.Attack, Stats.Strength, "You feel weak."); TryDrain(action, hit.Value.Attack, Stats.Agility, "You feel clumsy."); TryDrain(action, hit.Value.Attack, Stats.Stamina, "You feel tired."); TryDrain(action, hit.Value.Attack, Stats.Will, "Your conviction falters."); TryDrain(action, hit.Value.Attack, Stats.Intellect, "You feel stupid."); TryDrain(action, hit.Value.Attack, Stats.Charisma, "You feel ugly."); // drain experience if (hit.Value.Attack.Flags.Has("drain:experience")) { // chance to resist if (Stats.Will.ResistDrain()) { action.Value.Log(LogType.Resist, this, "{possessive} will sustain[s] {pronoun}."); } else { // lower by 1% - 5% float percent = Rng.Float(0.01f, 0.05f); action.Value.Log(LogType.BadState, this, "{subject} feel[s] {possessive} life draining away."); LoseExperience(action.Value, Experience.Current * percent); } } }
public IEnumerable <T> Create(int level) { foreach (DropChoice choice in Choices) { // see if this choice was dropped if ((choice.Odds == 0) || (Rng.Float(TotalOdds) <= choice.Odds)) { foreach (var item in choice.Drop.Create(level)) { yield return(item); } } } }
private T Random(Func <RareObject, bool> predicate) { // collect all of the possible choices float totalCommonness = 0; List <RareObject> matches = new List <RareObject>(); foreach (RareObject obj in mObjects) { if (predicate(obj)) { matches.Add(obj); totalCommonness += obj.Commonness; } } // bail if there are no possibilities if (matches.Count == 0) { return(default(T)); } // choose one randomly float choice = Rng.Float(totalCommonness); foreach (RareObject obj in matches) { if (choice <= obj.Commonness) { return(obj.Object); } choice -= obj.Commonness; } // should not get here throw new Exception("Something is broke in the object selection algo."); }