internal void AddValue(string fieldName, double value, DateTime timestamp) { if (StatisticsLogger.IsValidField(fieldName)) { // add value for StatisticsLogger use statValues.Add(new StatValue(value, timestamp)); } // "value" is the occurring event in this very moment, // so "Current" is holding previous value right now if (Current.Value != value) { if (value == 0 && lastEvent.Value > 0) { lastOn = lastEvent; lastOff = new StatValue(value, timestamp); } else if (value > 0 && lastEvent.Value == 0) { lastOff = lastEvent; lastOn = new StatValue(value, timestamp); } lastEvent = new StatValue(Current.Value, Current.Timestamp); } // insert current value into history and so update "Current" to "value" historyValues.Insert(0, new StatValue(value, timestamp)); // keeep size within historyLimit while (historyValues.Count > historyLimit) { historyValues.RemoveAt(historyValues.Count - 1); } }
private IValue BuildAddStatMultiplier( string identity, IReadOnlyCollection <Entity> possibleSources, Entity target) { var buffActiveValue = new StatValue(BuildBuffActiveStat(target, identity)); var buffSourceValues = possibleSources.ToDictionary(Funcs.Identity, e => new StatValue(BuildBuffSourceStat(e, target, identity))); var buffEffectValues = possibleSources.ToDictionary(Funcs.Identity, e => new StatValue(BuildEffectStat(e, target, identity))); return(new FunctionalValue(Calculate, $"AddStatMultiplier(buffActive:{buffActiveValue}, buffSources:{string.Join(",", buffSourceValues)}, " + $"buffEffects:{string.Join(",", buffEffectValues)})")); NodeValue?Calculate(IValueCalculationContext context) { if (!buffActiveValue.Calculate(context).IsTrue()) { return(new NodeValue(1)); } // If multiple entities apply the same (de-)buff, it depends on the buff which one would actually apply. // Because that shouldn't happen in these calculations, simply the first one is taken. var sourceEntity = possibleSources.First(e => buffSourceValues[e].Calculate(context).IsTrue()); return(buffEffectValues[sourceEntity].Calculate(context)); } }
internal void AddValue(string fieldName, double value, DateTime timestamp) { if (StatisticsLogger.IsValidField(fieldName)) { // add value for StatisticsLogger use statValues.Add(new StatValue(value, timestamp)); } // "value" is the occurring event in this very moment, // so "Current" is holding previous value right now if (Current.Value != value) { lastEvent = new StatValue(Current.Value, Current.Timestamp); if (value == 0 && lastEvent.Value > 0) { lastOn = lastEvent; lastOff = new StatValue(value, timestamp); } else if (value > 0 && lastEvent.Value == 0) { lastOff = lastEvent; lastOn = new StatValue(value, timestamp); } } // keeep size within historyLimit (minutes) try { while ((DateTime.UtcNow - historyValues[historyValues.Count - 1].Timestamp).TotalMinutes > historyLimit) { historyValues.RemoveAll(sv => (DateTime.UtcNow - sv.Timestamp).TotalMinutes > historyLimit); } // leave this wrapped in a try..catch } catch { } // insert current value into history and so update "Current" to "value" historyValues.Insert(0, new StatValue(value, timestamp)); }
/// <summary> /// Добавляет в объект новый стат /// </summary> /// <typeparam name="T">Тип перечисления статов (UnitStatIdentifier)</typeparam> /// <param name="statId">Id стата из UnitStatIdentifier</param> /// <param name="value">Значение стата</param> public void Add <T>(T statId, object value) where T : struct { Type statType = statId.GetAttributeOfType <DataTypeAttribute>().Value; int intStatId = Convert.ToInt32(statId); if (_statIdentifierType != typeof(T)) { Debug.LogError("Тип добавляемого стата не соотвествует типу, с которым работает данный ObjectStats", this); return; } if (statType != value.GetType()) { Debug.LogError("Типы стата и переданного значения не совпадают", this); return; } if (_statsDictionary.ContainsKey(intStatId)) { string statName = Enum.GetName(_statIdentifierType, intStatId); Debug.LogError(string.Format("Стат {0} уже есть в данном объекте", statName), this); return; } var statValue = new StatValue { Value = value }; _statsDictionary.Add(intStatId, statValue); }
//---------------------- //PRIVATE METHODS //---------------------- private void AddLine(float x, float y, string text, bool title) { //Add the text to the panel GameObject pText = (GameObject)Instantiate(PanelText); pText.transform.SetParent(this.gameObject.transform); pText.transform.localPosition = new Vector3(x, y, 0); //Change the relative Y position so we go to the next line _yRelPos -= _lineHeight; //If it's not a title we add it to the list so we can access it later if (!title) { //Create a new statvalue variable we can add to the list StatValue display = new StatValue(); display.ItemName = ""; display.TypeName = text; display.DisplayObject = pText; display.Value = 0.0f; CharacterStats.Add(display); } else { //This text is not in the list so won't be updated, because of this we have to update it here pText.GetComponent <Text>().text = text; } }
/// <summary> /// Mofifies StatType with multiplier /// </summary> /// <param name="stat"></param> /// <param name="mult"></param> /// <exception cref="ArgumentOutOfRangeException"></exception> private void ModStat(StatValue stat, int mult = 1) { var statMult = stat.value * mult; switch (stat.type) { case StatType.Ap: ModAP(statMult); break; case StatType.Hp: ModHp(statMult); break; case StatType.Dmg: ModDmg(statMult); break; case StatType.Def: ModDef(statMult); break; default: throw new ArgumentOutOfRangeException(); } UpdateUnitInfo(); }
public void AddValue(string fieldName, double value, DateTime timestamp) { if (StatisticsLogger.IsValidField(fieldName)) { // add value for StatisticsLogger use statValues.Add(new StatValue(value, timestamp)); } // // "value" is the occurring event in this very moment, // so "Current" is holding previous value right now if (Current.Value != value) { lastEvent = new StatValue(Current.Value, Current.Timestamp); if (value == 0) { lastOn = lastEvent; lastOff = new StatValue(value, timestamp); } else if (Current.Value == 0) { lastOff = lastEvent; lastOn = new StatValue(value, timestamp); } } // insert current value into history and so update "Current" to "value" historyValues.Insert(0, new StatValue(value, timestamp)); }
protected StatValue ModifedValue(float value, string stat, CharacterValueContainer parent) { StatValue val = parent.DataHandler.CopyStat(stat); val.AddModifier(new ValueModifier(value, ValueModEnum.Flat)); return(val); }
public ValueStatistics() { LastProcessedTimestap = DateTime.UtcNow; statValues = new List<StatValue>(); statValues.Add(new StatValue(0, LastProcessedTimestap)); lastEvent = lastOn = lastOff = new StatValue(0, LastProcessedTimestap); historyValues.Add(lastEvent); }
public ValueStatistics() { LastProcessedTimestap = DateTime.UtcNow; statValues = new List <StatValue>(); statValues.Add(new StatValue(0, LastProcessedTimestap)); lastEvent = lastOn = lastOff = new StatValue(0, LastProcessedTimestap); historyValues = new TsList <StatValue>(); historyValues.Add(lastEvent); }
public void FindStats() { levelStat = statsCog.FindStat("Level"); damageStat = statsCog.FindStat("Damage"); hPStat = statsCog.FindStat("HP"); speedStat = statsCog.FindStat("Speed"); damageAreaStat = statsCog.FindStat("DamageArea"); moveAreaStat = statsCog.FindStat("MoveArea"); }
protected override void HandleGetStat(XboxLiveUser user, string statName) { this.isLocalUserAdded = true; StatValue statValue = XboxLive.Instance.StatsManager.GetStat(user, statName); if (statValue != null) { this.Value = statValue.AsString(); } }
public void Contructor_Tests(StatName name, StatValue value, StatWeighting weighting) { // Act var stat = new Stat(name, value, weighting); // Assert stat.Name.Should().Be(name); stat.Value.Should().Be(value); stat.Weighting.Should().Be(weighting); stat.Score.Should().NotBeNull(); }
// return the minimum amount a stat can be modified to relative to 0 public float?getLowerLimit(StatType type) { StatValue thisStat = this.getStatValue(type); // if its null we will try and get the default for this stat if (thisStat.lowerLimit == null) { return(type.getDefaultLowerLimit()); } return(thisStat.lowerLimit); }
public void Start() { text = GetComponent <Text>(); stat = statCog.FindStat(statName); if (stat != null) { stat.onInit.AddListener(ValueInit); stat.onValueChanged.AddListener(ValueChanged); stat.onBaseValueChanged.AddListener(ValueChanged); ValueInit(); } }
public ValueStatistics() { LastProcessedTimestap = DateTime.UtcNow; statValues = new List <StatValue>(); statValues.Add(new StatValue(0, LastProcessedTimestap)); lastEvent = lastOn = lastOff = new StatValue(0, LastProcessedTimestap); historyValues.Add(lastEvent); while (historyValues.Count > historyLimit) { historyValues.RemoveAt(historyValues.Count - 1); } }
private void Awake() { StatsManagerComponent.Instance.LocalUserAdded += (sender, args) => { StatValue statValue = XboxLive.Instance.StatsManager.GetStat(args.User, Name); if (statValue != null) { this.Value = statValue.AsString(); } isLocalUserAdded = true; }; }
public ValueStatistics() { LastProcessedTimestap = DateTime.UtcNow; statValues = new List<StatValue>(); statValues.Add(new StatValue(0, LastProcessedTimestap)); lastEvent = lastOn = lastOff = new StatValue(0, LastProcessedTimestap); historyValues.Add(lastEvent); while (historyValues.Count > historyLimit) { historyValues.RemoveAt(historyValues.Count - 1); } }
private void Awake() { StatsManagerComponent.Instance.LocalUserAdded += (sender, args) => { StatValue statValue = StatsManager.Singleton.GetStat(args.User, Name); if (statValue != null) { this.Value = statValue.AsInteger(); } isLocalUserAdded = true; }; }
public void Constructor_Tests( StatName name, StatValue value, StatWeighting weighting, decimal score ) { // Arrange var stat = new Stat(name, value, weighting); // Act var statScore = new StatScore(stat); // Assert score.Should().Be(statScore.ToDecimal()); }
private IValue BuildTargetPoolValue(BuildParameters parameters, IStat targetPoolStat) { var entity = parameters.ModifierSourceEntity; var targetPoolValue = new StatValue(targetPoolStat); return(new FunctionalValue( c => c.GetValue(TargetPoolValueStat(targetPoolValue.Calculate(c))), $"Value of Pool {targetPoolValue}")); IStat TargetPoolValueStat(NodeValue?targetPool) { var targetPoolString = ((Pool)targetPool.Single()).ToString(); return(StatFactory.FromIdentity(targetPoolString, entity, typeof(uint))); } }
public void DoDamage(CreatureObject other, float damage, bool isMagic = false) { if (_creature.IsDead) { return; } StatValue hStat = _stats[Stats.Health]; StatValue pStat = isMagic ? _stats[Stats.MagicResist] : _stats[Stats.Armor]; hStat.DecreaseCurrent(damage = CalculateDamage(other.Stats.Level, damage, pStat.Max)); OnDamageReceived?.Invoke(other, damage); _view.SendStatUpdate(Stats.Health, hStat); if (hStat.Current == 0f) { _creature.Kill(other); } }
// return the StatValue of the specified type if it exists in the statSet. Otherwise return a 0 StatValue public StatValue getStatValue(StatType type) { StatValue thisStat; if (this.statSet.TryGetValue(type, out thisStat)) { return(thisStat); } // some stats can bever have a base value equal to or less than zero, so we need to fix it if its not. if (type.needsPositiveBase()) { // just set it to 1f for now StatValue defaultValue = 1f; this.statSet.Add(type, defaultValue); return(defaultValue); } return(thisStat); }
//[Test] public void PlayOneTestManyTimes(int testNumber, int repetitionCount) { var tests = RaceProblemsRepo.GetTests(); var test = tests.ElementAt(testNumber); var stat = new StatValue(); var racer = new DoubleRandomRacer(); for (int i = 0; i < repetitionCount; i++) { var finalState = RaceController.Play(test, racer, false); var testScore = finalState.FlagsTaken * 100 - finalState.Time; stat.Add(testScore); } var resWith = stat.Mean; Console.WriteLine(testNumber.ToString()); Console.WriteLine("mean " + resWith.ToString()); Console.WriteLine("conf " + stat.ConfIntervalSize.ToString()); }
// set a modifier for a specified stat to the specified value. // The stat mod will be limited by other properties such as min and max, and immutable stat flags. // This will update any dependants as well. public void setStatMod(StatType type, float value) { // don't do anything if the flag is set for this stat to be immutable. if ((immutableStats & type) == type) { return; } StatValue thisStat = this.getStatValue(type); float? lowerLimit = this.getLowerLimit(type); float? upperLimit = this.getUpperLimit(type); float newValue = value; // make sure the value we set don't go beyond lower limit if there is one if (lowerLimit != null) { lowerLimit = lowerLimit - thisStat.baseValue; if (value < lowerLimit) { newValue = (float)lowerLimit; } } // make sure the value we set don't go beyond upper limit if there is one if (upperLimit != null) { if (value > upperLimit) { newValue = (float)upperLimit; } } // don't bother adding a mod if its not even changed. if (newValue == this.getStatMod(type)) { return; } // set the mod, add the item in the dictionary if it doesn't exist this.setOrAddStatMod(type, newValue); // bitwise AND operation to determine if the flag is in the defined stat set for stats that Condition depends on. if ((this.conditionStats & type) == type) { this.updateCondition(); } }
public void ExplicitlyRegistered() { var sut = Calculator.Create(); var modifierStat = new Stat("m"); var registeredStat = new Stat("r", explicitRegistrationType: ExplicitRegistrationTypes.UserSpecifiedValue(0)); var value = new StatValue(registeredStat); IStat actual = null; sut.ExplicitlyRegisteredStats.CollectionChanged += (sender, args) => { Assert.IsNull(actual); Assert.AreEqual(1, args.AddedItems.Count); Assert.IsEmpty(args.RemovedItems); actual = args.AddedItems.First().Item2; }; sut.NewBatchUpdate().AddModifier(modifierStat, Form.BaseAdd, value).DoUpdate(); Assert.IsNull(actual); var _ = sut.NodeRepository.GetNode(modifierStat).Value; Assert.AreEqual(registeredStat, actual); }
public void TreeSizeMeasurement() { var totalSize = new StatValue(); foreach (var stateInput in GetStatesCollection()) { var localSize = new StatValue(); var state = StateReader.Read(stateInput); var ai = new AlphabetaAi(evaluator, 3) { Logging = false }; for (var i = 0; i < 1; i++) { var action = ai.GetAction(state, 250); localSize.Add(ai.LastSearchTreeSize); action.ApplyTo(state); } Console.WriteLine(localSize.ToDetailedString()); totalSize.AddAll(localSize); } Console.WriteLine("Total:"); Console.WriteLine(totalSize.ToDetailedString()); }
public static void SendStatFullUpdate(this PNetR.NetworkView view, Stats stat, StatValue value) { var net = default(StatNetData); view.Rpc(4, 51, RpcMode.AllOrdered, net.Fill(stat, value.Max)); view.Rpc(4, 50, RpcMode.AllOrdered, net.Fill(stat, value.Current)); }
public override void Refresh() { //Check the inventory for items and update the info foreach (var item in GameManager.Instance.CharacterInventory.ItemList) { //Get the corresponding text cell for the item if (item.TypeItem == Item.ItemType.Armor || item.TypeItem == Item.ItemType.Weapon) { //Variable we will be assigning to edit the text StatValue statValue = new StatValue(); string typeName = ""; //Do something depending on what the item is switch (item.TypeItem) { //What to do if it's a weapon case Item.ItemType.Weapon: var weapon = item as Weapon; typeName = "Weapon"; statValue.ItemName = weapon.Name; statValue.Value = weapon.AttackPower; break; //What to do if it's armor case Item.ItemType.Armor: var armor = item as Armor; typeName = armor.TypeArmor.ToString(); statValue.ItemName = armor.Name; statValue.Value = armor.DefenceValue; break; } //Now change the info in the list for (int i = 0; i < CharacterStats.Count; i++) { if (CharacterStats[i].TypeName == typeName) { //Copy the typename and object to the new StatValue, because these don't change statValue.TypeName = CharacterStats[i].TypeName; statValue.DisplayObject = CharacterStats[i].DisplayObject; CharacterStats[i] = statValue; break; } } } } //Display the text for the values foreach (var statValue in CharacterStats) { //Create a stringstream to display the values StringWriter stream = new StringWriter(); stream.Write(statValue.TypeName); stream.Write(": "); stream.Write(statValue.ItemName); stream.Write(" - "); stream.Write(statValue.Value); //Update the text statValue.DisplayObject.GetComponent <Text>().text = stream.ToString(); } }
private void MyPrintDocument_PrintPage(object sender, PrintPageEventArgs e) { e.Graphics.DrawString("XXX医院质控报告模版", new Font(new FontFamily("黑体"), 18), System.Drawing.Brushes.Black, 500, 10); e.Graphics.DrawString(string.Format("报告日期:" + DateTime.Now.ToShortDateString()), new Font(new FontFamily("新宋体"), 10), System.Drawing.Brushes.Black, 960, 50); //信息的名称 e.Graphics.DrawLine(Pens.Black, 8, 70, 1161, 70); e.Graphics.DrawString("项目:" + cboProjectName.Text, new Font(new FontFamily("新宋体"), 10), System.Drawing.Brushes.Black, 15, 80); e.Graphics.DrawString("水平:" + txtHorizontalValue.Text, new Font(new FontFamily("新宋体"), 10), System.Drawing.Brushes.Black, 145, 80); e.Graphics.DrawString("质控日期:" + dtpStartTime.Value.ToShortDateString() + "--" + dtpEndTime.Value.ToShortDateString(), new Font(new FontFamily("新宋体"), 10), System.Drawing.Brushes.Black, 280, 80); e.Graphics.DrawString("质控品:" + cboQCName.Text, new Font(new FontFamily("新宋体"), 10), System.Drawing.Brushes.Black, 15, 105); e.Graphics.DrawString(string.Format("靶值:{0}", this.txtTargetValue.Text), new Font(new FontFamily("新宋体"), 10), System.Drawing.Brushes.Black, 205, 105); e.Graphics.DrawString(string.Format("标准差:{0}", this.txtStandardDeviationValue.Text), new Font(new FontFamily("新宋体"), 10), System.Drawing.Brushes.Black, 305, 105); //e.Graphics.DrawLine(Pens.Black, 8, 105, 1161, 105); try { //信息 Image image = Image.FromFile(@"D:\屏幕截图\" + fileName); e.Graphics.DrawImage(image, new RectangleF(30, 130, 1350, 700)); } catch (Exception ex) { LogInfo.WriteProcessLog("MyPrintDocument_PrintPage(object sender, PrintPageEventArgs e) == " + ex.ToString(), Module.QualityControl); } if (results != null) { List <float> lstFloat = new List <float>(); foreach (var item in results) { lstFloat.Add(item.ConcResult); } StatValue sd = StatDatas.GetStateValue(lstFloat); e.Graphics.DrawString(string.Format("统计量:" + sd.N.ToString() + " " + "平均值:" + sd.MEAN.ToString("#0.00") + " " + "标准差:" + sd.SD.ToString("#0.00") + " " + "CV%:" + sd.CV.ToString("#0.00%") + " " + "极差:" + sd.R.ToString("#0.00")), new Font(new FontFamily("黑体"), 10), System.Drawing.Brushes.Black, 30, 660); } //e.Graphics.DrawString(string.Format("靶值:{0}", this.txtTargetValue.Text), new Font(new FontFamily("黑体"), 10), System.Drawing.Brushes.Black, 30, 600); //e.Graphics.DrawString(string.Format("标准差:{0}", this.txtStandardDeviationValue.Text), new Font(new FontFamily("黑体"), 10), System.Drawing.Brushes.Black, 135, 600); e.Graphics.DrawLine(Pens.Black, 8, 700, 1161, 700); e.Graphics.DrawString(string.Format("制作人:{0}", Program.userInfo == null ? "" : Program.userInfo.UserName), new Font(new FontFamily("黑体"), 12), System.Drawing.Brushes.Black, 900, 710); //e.Graphics.DrawString(mean, new Font(new FontFamily("黑体"), 8), System.Drawing.Brushes.Black, 10, 798); //e.Graphics.DrawString(sd, new Font(new FontFamily("黑体"), 8), System.Drawing.Brushes.Black, 95, 798); int tableWith = 0; string ColumnText; StringFormat sf = new StringFormat(); sf.Alignment = StringAlignment.Center; //打印表格线格式 Pen Pen = new Pen(Brushes.Black, 1); #region 设置列宽 //foreach (DataRow dr in DataTablePrint.Rows) //{ // for (int i = 0; i < DataTablePrint.Columns.Count; i++) // { // int colwidth = Convert.ToInt32(e.Graphics.MeasureString(dr[i].ToString().Trim(), TableFont).Width); // if (colwidth > XUnit[i]) // { // XUnit[i] = colwidth; // } // } //} //if (PrintingPageNumber == 1) //{ // for (int Cols = 0; Cols <= DataTablePrint.Columns.Count - 1; Cols++) // { // ColumnText = DataTablePrint.Columns[Cols].ColumnName.ToString().Trim(); // int colwidth = Convert.ToInt32(e.Graphics.MeasureString(ColumnText, TableFont).Width); // if (colwidth > XUnit[Cols]) // { // XUnit[Cols] = colwidth; // } // } //} //for (int i = 0; i < XUnit.Length; i++) //{ // tableWith += XUnit[i]; //} #endregion //PLeft = (e.PageBounds.Width - tableWith) / 2; //int x = PLeft; //int y = PTop; //int stringY = PTop + (YUnit - TableFont.Height) / 2; //int rowOfTop = PTop; //第一页 //if (PrintingPageNumber == 1) //{ // //打印表头 // e.Graphics.DrawString(HeadText, HeadFont, DrawBrush, new Point(e.PageBounds.Width / 2, PTop), sf); // //设置为第一页时行数 // PageRecordNumber = FirstPrintRecordNumber; // rowOfTop = y = PTop + HeadFont.Height + 10; // stringY = PTop + HeadFont.Height + 10 + (YUnit - TableFont.Height) / 2; //} //else //{ // //计算,余下的记录条数是否还可以在一页打印,不满一页时为假 // if (DataTablePrint.Rows.Count - PrintRecordComplete >= PrintRecordNumber) // { // PageRecordNumber = PrintRecordNumber; // } // else // { // PageRecordNumber = DataTablePrint.Rows.Count - PrintRecordComplete; // } //} #region 列名 //if (PrintingPageNumber == 1 || PageRecordNumber > TotalNum)//最后一页只打印统计行时不打印列名 //{ // //得到datatable的所有列名 // for (int Cols = 0; Cols <= DataTablePrint.Columns.Count - 1; Cols++) // { // ColumnText = DataTablePrint.Columns[Cols].ColumnName.ToString().Trim(); // int colwidth = Convert.ToInt32(e.Graphics.MeasureString(ColumnText, TableFont).Width); // e.Graphics.DrawString(ColumnText, TableFont, DrawBrush, x, stringY); // x += XUnit[Cols]; // } //} #endregion //e.Graphics.DrawLine(Pen, PLeft, rowOfTop, x, rowOfTop); //stringY += YUnit; //y += YUnit; //e.Graphics.DrawLine(Pen, PLeft, y, x, y); //当前页面已经打印的记录行数 //int PrintingLine = 0; //while (PrintingLine < 3) //{ // x = PLeft; // //确定要当前要打印的记录的行号 // DataGridRow = DataTablePrint.Rows[PrintRecordComplete]; // for (int Cols = 0; Cols <= DataTablePrint.Columns.Count - 1; Cols++) // { // e.Graphics.DrawString(DataGridRow[Cols].ToString().Trim(), TableFont, DrawBrush, x, stringY); // x += XUnit[Cols]; // } // stringY += YUnit; // y += YUnit; // e.Graphics.DrawLine(Pen, PLeft, y, x, y); // PrintingLine += 1; // PrintRecordComplete += 1; // if (PrintRecordComplete >= DataTablePrint.Rows.Count) // { // e.HasMorePages = false; // PrintRecordComplete = 0; // } //} //e.Graphics.DrawLine(Pen, PLeft, rowOfTop, PLeft, y); //x = PLeft; //for (int Cols = 0; Cols < DataTablePrint.Columns.Count; Cols++) //{ // x += XUnit[Cols]; // e.Graphics.DrawLine(Pen, x, rowOfTop, x, y); //} //PrintingPageNumber += 1; //if (PrintingPageNumber > TotalPage) //{ // e.HasMorePages = false; // PrintingPageNumber = 1; // PrintRecordComplete = 0; //} //else //{ // e.HasMorePages = true; //} }
public bool TryGetStat(Stat stat, out StatValue value) { value = this.Items.FirstOrDefault(s => s.Stat == stat); return(value != null); }
public void RemoveBonus(StatValue bonus) { this.bonusStats.Remove(bonus); }