public void AddMagus(Magus mage) { if (!_magi.Contains(mage)) { _magi.Add(mage); } }
public void TakeApprentice(Magus apprentice) { // TODO: what sort of error checking should go here? Apprentice = apprentice; // add a teaching goal for each year for (byte i = 2; i < 16; i++) { uint dueDate = (uint)(i * 4); IGoal teachingGoal = new TeachApprenticeGoal(); _goals.Add(teachingGoal); } IGoal gauntletGoal = new GauntletApprenticeGoal(); _goals.Add(gauntletGoal); }
protected override void DoMageAction(Magus mage) { // TODO: multiple spells mage.InventSpell(Spell); }
private void MageAuraSearch(Magus mage) { // add bonus to area lore equal to casting total div 10? // TODO: once spells are implemented, increase finding chances based on aura-detection spells double areaLore = mage.GetAbility(Abilities.AreaLore).Value; areaLore += mage.GetAttribute(AttributeType.Perception).Value; areaLore += mage.GetCastingTotal(MagicArtPairs.InVi) / 10; double roll = Die.Instance.RollDouble() * 5; // die roll will be 0-5; area lore will be between 0 and 15, giving auras between 0 and 9 double auraFound = Math.Sqrt(roll * areaLore / (mage.KnownAuras.Count() + 1)); if (auraFound > 1) { Aura aura = new Aura(Domain.Magic, auraFound); mage.Log.Add("Found an aura of strength " + auraFound.ToString("0.00")); mage.KnownAuras.Add(aura); if (mage.Covenant == null || (mage.Laboratory == null && mage.Covenant.Aura.Strength < aura.Strength)) { mage.FoundCovenant(aura); } } }
protected abstract void DoMageAction(Magus mage);
protected override void DoMageAction(Magus mage) { if (mage.Covenant == null) { throw new ArgumentNullException("Magi can only extract vis in an aura!"); } double amount = mage.GetLabTotal(MagicArtPairs.CrVi, Activity.DistillVis) / 10.0; mage.Log.Add("Extracted " + amount.ToString("0.00") + " pawns of vis from aura"); mage.Covenant.AddVis(MagicArts.Vim, mage.GetLabTotal(MagicArtPairs.CrVi, Activity.DistillVis) / 10); }
protected override void DoMageAction(Magus mage) { // TODO: we may want to do the check here as well to be safe mage.RefineLaboratory(); }
private IList<VisTradeOffer> VisForVis(Magus mage, VisDesire[] otherVisDesires) { List<VisOffer> bids = new List<VisOffer>(); List<VisOffer> asks = new List<VisOffer>(); for(byte i = 0; i < 15; i++) { if(VisDesires[i].Quantity < 0 && otherVisDesires[i].Quantity > 0) { // we have a surplus, they want it if(Math.Abs(VisDesires[i].Quantity) > otherVisDesires[i].Quantity) { // our surplus is larger than their need; fulfill the need bids.Add(new VisOffer(otherVisDesires[i].Art, otherVisDesires[i].Quantity)); } else { // our surplus is smaller than their need; empty our stocks bids.Add(new VisOffer(otherVisDesires[i].Art, Math.Abs(VisDesires[i].Quantity))); } } if(VisDesires[i].Quantity > 0 && otherVisDesires[i].Quantity < 0) { // they have a surplus, we want it if (Math.Abs(otherVisDesires[i].Quantity) > VisDesires[i].Quantity) { // their surplus is larger than our need; fulfill the need asks.Add(new VisOffer(otherVisDesires[i].Art, VisDesires[i].Quantity)); } else { // our surplus is smaller than their need; empty our stocks asks.Add(new VisOffer(otherVisDesires[i].Art, Math.Abs(otherVisDesires[i].Quantity))); } } } // we should now have a list of bids and asks // we need at least one bid and one ask to make a deal if (bids.Count() > 0 && asks.Count() > 0) { List<VisTradeOffer> visTradeOffer = new List<VisTradeOffer>(); foreach (VisOffer bid in bids) { foreach (VisOffer ask in asks) { // figure out which quantity is smaller, and make the larger one equal to that if (bid.Quantity > ask.Quantity) { visTradeOffer.Add(new VisTradeOffer(mage, new VisOffer(bid.Art, ask.Quantity), ask)); } else { visTradeOffer.Add(new VisTradeOffer(mage, bid, new VisOffer(ask.Art, bid.Quantity))); } } } return visTradeOffer; } return null; }
public MagusTradingDesires(Magus magus, VisDesire[] visDesires, IEnumerable<BookDesire> booksDesired, IEnumerable<BookForTrade> booksForTrade) { Mage = magus; VisDesires = visDesires; BookDesires = booksDesired.ToDictionary(l => l.Ability); BooksForTrade = booksForTrade; }
public BookVisOffer(Magus mage, Ability art, double quantity, IBook bookDesired) { Mage = mage; VisArt = art; VisQuantity = quantity; BookDesired = bookDesired; }
protected override void DoMageAction(Magus mage) { mage.GauntletApprentice(); }
protected override void DoMageAction(Magus mage) { //TODO: implement }
public LongevityRitualGoal(Magus mage, byte tier = 0, uint? dueDate = null) { DueDate = dueDate; Tier = tier; Desire = CalculateDesire(mage); _artsRequired = new List<Ability>(); _artsRequired.Add(MagicArts.Creo); _artsRequired.Add(MagicArts.Vim); List<AttributeType> attributes = new List<AttributeType>(); attributes.Add(AttributeType.Intelligence); // we need a lab to create a longevity ritual _hasLabCondition = new HasLabCondition(Desire, tier, dueDate == null || dueDate <= 3 ? null : dueDate - 3); }
private void HandleVisUse(Magus mage, CharacterAbilityBase charAbility, double remainingTotal, double desire, ConsideredActions alreadyConsidered, IList<string> log ) { // see if the mage has enough vis of this type double stockpile = mage.GetVisCount(charAbility.Ability); double visNeed = 0.5 + (charAbility.Value / 10.0); double baseDesire = desire * charAbility.GetValueGain(mage.VisStudyRate) / remainingTotal; // if so, assume vis will return an average of 6XP + aura if (stockpile > visNeed) { log.Add("Studying vis for " + charAbility.Ability.AbilityName + " worth " + baseDesire.ToString("0.00")); VisStudying visStudy = new VisStudying(charAbility.Ability, baseDesire); alreadyConsidered.Add(visStudy); // TODO: how do we decrement the cost of the vis? } else if(baseDesire > 0.01 && (DueDate == null || DueDate > 1)) { // only try to extract the vis now if there's sufficient time to do so List<Ability> visType = new List<Ability>(); visType.Add(charAbility.Ability); VisCondition visCondition = new VisCondition(visType, visNeed - stockpile, baseDesire, (byte)(Tier + 1), DueDate == null ? null : DueDate - 1); visCondition.ModifyActionList(mage, alreadyConsidered, log); if(baseDesire > 0.04 && (DueDate == null || DueDate > 4)) { // we have enough time and interest to consider finding a new aura and building a new lab in it } } }
public VisTradeOffer(Magus mage, VisOffer bid, VisOffer ask) { Mage = mage; Bid = bid; Ask = ask; }
public BookTradeOffer(Magus mage, IBook bookOffered, IBook bookDesired) { Mage = mage; BookOffered = bookOffered; BookDesired = bookDesired; }
protected override void DoMageAction(Magus mage) { // TODO: build size // TODO: pre-existing conditions mage.Log.Add("Built laboratory"); if (_aura == null) { mage.BuildLaboratory(); } else { mage.BuildLaboratory(_aura); } }
private static void InitializeApprenticeGoals(Magus magus) { }
public static Magus GenerateNewApprentice() { Magus magus = new Magus(Abilities.MagicTheory, Abilities.Latin, Abilities.ArtesLiberales, Abilities.AreaLore); NormalizeAttributes(magus); magus.GetAbility(Abilities.English).AddExperience(75); // randomly assign 45 points to childhood skills in 5 point blocks // Area Lore, Athletics, Awareness, Brawl, Charm, Folk Ken, Guile, Stealth, Survival, Swim double experienceBlock = 5.0; CharacterAbilityBase charAbility = null; for (byte i = 0; i < 9; i++) { switch (Die.Instance.RollSimpleDie()) { case 1: charAbility = magus.GetAbility(Abilities.AreaLore); break; case 2: charAbility = magus.GetAbility(Abilities.Athletics); break; case 3: charAbility = magus.GetAbility(Abilities.Awareness); break; case 4: charAbility = magus.GetAbility(Abilities.Brawl); break; case 5: charAbility = magus.GetAbility(Abilities.Charm); break; case 6: charAbility = magus.GetAbility(Abilities.FolkKen); break; case 7: charAbility = magus.GetAbility(Abilities.Guile); break; case 8: charAbility = magus.GetAbility(Abilities.Stealth); break; case 9: charAbility = magus.GetAbility(Abilities.Survival); break; case 10: charAbility = magus.GetAbility(Abilities.Swim); break; } charAbility.AddExperience(experienceBlock); } // figure out how much older than 5 the child is ushort age = (ushort)(20 + Die.Instance.RollDouble() * 80); // add experience for the additional time. int extraXP = (age - 20) * 4; // for now, lets say 10% chance of academics, 20% of martial bool isAcademic = Die.Instance.RollSimpleDie() == 1; bool isMartial = Die.Instance.RollSimpleDie() <= 2; DistributeExperience(magus, extraXP, isAcademic, isMartial); // TODO: how do we initialize the goals of this new apprentice? InitializeApprenticeGoals(magus); return magus; }
private void MageApprenticeSearch(Magus mage) { // add bonus to area lore equal to casting total div 5? double folkKen = mage.GetAttribute(AttributeType.Perception).Value; folkKen += mage.GetCastingTotal(MagicArtPairs.InVi) / 10; double roll = Die.Instance.RollExplodingDie() + folkKen; if (roll > 12) { mage.Log.Add("Apprentice found"); mage.TakeApprentice(CharacterFactory.GenerateNewApprentice()); mage.Apprentice.Name = "Apprentice filius " + mage.Name; } // TODO: gradual reduction in chance? }
public static Magus GenerateNewMagus(Ability magicAbility, Ability langAbility, Ability writingAbility, Ability areaAbility) { Magus magus = new Magus(magicAbility, langAbility, writingAbility, areaAbility); NormalizeAttributes(magus); return magus; }
private static void DistributeExperience(Magus mage, int extraXP, bool isAcademic, bool isMartial) { var abilities = Abilities.GetEnumerator() .Where(a => a.AbilityType == AbilityType.General || (isAcademic && a.AbilityType == AbilityType.Academic) || (isMartial && a.AbilityType == AbilityType.Martial)); int abilityCount = abilities.Count(); while (extraXP > 0) { int valueAdd = extraXP >= 5 ? 5 : extraXP; int roll = (int)(Die.Instance.RollDouble() * abilityCount); Ability ability = abilities.ElementAt(roll); if (ability.AbilityType == AbilityType.Academic) { if (mage.GetAbility(Abilities.ArtesLiberales).Value < 1) { mage.GetAbility(Abilities.ArtesLiberales).AddExperience(valueAdd); } else if (mage.GetAbility(Abilities.Latin).Value < 3) { mage.GetAbility(Abilities.Latin).AddExperience(valueAdd); } else { mage.GetAbility(ability).AddExperience(valueAdd); } } else { mage.GetAbility(ability).AddExperience(valueAdd); } extraXP -= valueAdd; } }
protected override void DoMageAction(Magus mage) { uint strength = Convert.ToUInt16(mage.GetLabTotal(MagicArtPairs.CrVi, Activity.LongevityRitual)); mage.Log.Add("Created a longevity ritual of strength " + strength); mage.ApplyLongevityRitual(Convert.ToUInt16(mage.GetLabTotal(MagicArtPairs.CrVi, Activity.LongevityRitual))); }
public void RemoveMagus(Magus mage) { if (_magi.Contains(mage)) { _magi.Remove(mage); } }
private void HandleAuraSearch(Magus mage, ConsideredActions alreadyConsidered, IList<string> log, double remainingTotal, double dueDateDesire) { double greatestAura = mage.KnownAuras.Select(a => a.Strength).Max(); double currentAura = mage.Covenant.Aura.Strength; if (greatestAura > currentAura) { Aura bestAura = mage.KnownAuras.Where(a => a.Strength == greatestAura).First(); if (!_hasLabCondition.IsComplete(mage)) { // just move the covenant right now log.Add("Since no lab built, moving to better aura."); mage.FoundCovenant(bestAura); } else { // how do we want to rate the value of moving and having to build a new lab? // it seems like basically the same as any other single-month activity double gain = greatestAura - currentAura; double desire = dueDateDesire * gain / remainingTotal; log.Add("Moving to new aura (to boost lab total) worth " + dueDateDesire.ToString("0.00")); alreadyConsidered.Add(new BuildLaboratory(bestAura, Abilities.MagicTheory, desire)); } } else { // consider finding a new aura IncreaseAuraHelper helper = new IncreaseAuraHelper(Desire / remainingTotal, (byte)(Tier + 1), DueDate == null ? null : DueDate - 1); helper.ModifyActionList(mage, alreadyConsidered, log); } }
private double CalculateDesire(Magus mage) { // the number of years added to life is a baseline double lrLabTotal = mage.GetLabTotal(MagicArtPairs.CrVi, Activity.LongevityRitual); double dvLabTotal = mage.GetLabTotal(MagicArtPairs.CrVi, Activity.DistillVis); return (lrLabTotal * dvLabTotal * 4.0 / 50.0) - (mage.SeasonalAge / 20.0); // TODO: the warping probably ought to reduce value }
private IList <VisTradeOffer> VisForVis(Magus mage, VisDesire[] otherVisDesires) { // TODO: need to take Vis type into account List <VisOffer> bids = new List <VisOffer>(); List <VisOffer> asks = new List <VisOffer>(); for (byte i = 0; i < MagicArts.Count; i++) { if (VisDesires[i].Quantity < 0 && otherVisDesires[i].Quantity > 0) { // we have a surplus, they want it if (Math.Abs(VisDesires[i].Quantity) > otherVisDesires[i].Quantity) { // our surplus is larger than their need; fulfill the need bids.Add(new VisOffer(otherVisDesires[i].Art, otherVisDesires[i].Quantity)); } else { // our surplus is smaller than their need; empty our stocks bids.Add(new VisOffer(otherVisDesires[i].Art, Math.Abs(VisDesires[i].Quantity))); } } if (VisDesires[i].Quantity > 0 && otherVisDesires[i].Quantity < 0) { // they have a surplus, we want it if (Math.Abs(otherVisDesires[i].Quantity) > VisDesires[i].Quantity) { // their surplus is larger than our need; fulfill the need asks.Add(new VisOffer(otherVisDesires[i].Art, VisDesires[i].Quantity)); } else { // our surplus is smaller than their need; empty our stocks asks.Add(new VisOffer(otherVisDesires[i].Art, Math.Abs(otherVisDesires[i].Quantity))); } } } // we should now have a list of bids and asks // we need at least one bid and one ask to make a deal if (bids.Count() > 0 && asks.Count() > 0) { List <VisTradeOffer> visTradeOffer = new List <VisTradeOffer>(); foreach (VisOffer bid in bids) { foreach (VisOffer ask in asks) { // figure out which quantity is smaller, and make the larger one equal to that if (bid.Quantity > ask.Quantity) { visTradeOffer.Add(new VisTradeOffer(mage, new VisOffer(bid.Art, ask.Quantity), ask)); } else { visTradeOffer.Add(new VisTradeOffer(mage, bid, new VisOffer(ask.Art, bid.Quantity))); } } } return(visTradeOffer); } return(null); }
public GauntletGoal(Magus apprentice, double desire, byte tier = 0, uint? dueDate = null) : base(desire, tier, dueDate) { _apprentice = apprentice; }