/// <summary> /// Sets a given stat belonging to the actor to a specific value. This triggers StatChangedEvent on the server. /// </summary> /// <param name="_name"></param> /// <param name="_val"></param> public void SetStat(string _name, int _val) { if (entity.isOwner) { //PropertyInfo property = GetType().GetProperty(_name); Debug.Log(_name + " set to " + _val); // Get the actor's stat set. Then create a Bolt Event with the name of the stat to be change and the value to change it by. // Will catch NulLReferenceException if an invalid _name is given. try { Bolt.NetworkArray_Objects <BoltActorStat> statset = state.BoltActorStatset.Statset; IEnumerable <BoltActorStat> query = from stat in statset where stat.StatName == _name select stat; query.First().StatValue += _val; StatChangedEvent evnt = StatChangedEvent.Create(entity); evnt.StatName = _name; evnt.StatMod = _val; evnt.Send(); } catch (System.NullReferenceException nre) { Debug.LogError(nre); } } }
/// <summary> /// This is called when the player's stats are changed. It will ensure that the current val of the stat does not exceed the maximum value of the stat. /// NYI: Hunger, thirst etc; will need to change to a switch /// </summary> void StatsChanged() { //Debug.Log("Stat changed callback triggered"); BindingFlags flags = BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly; PropertyInfo[] properties = stats.GetType().GetProperties(flags); Bolt.NetworkArray_Objects <BoltActorStat> statset = state.BoltActorStatset.Statset; try { // Find the stats which do not have the same value on the server side, so that ONLY // these values are updated, and the client doesn't need to compare every single stat // in the stat set. IEnumerable <PropertyInfo> query = from property in properties where (System.Int32)property.GetValue(stats, null) != statset.Where(x => x.StatName == property.Name).First().StatValue select property; // For the stats found in the query (which HAVE changed since StatsChanged() was called), // update the values but ensure they do not go about the stat's maximum value. foreach (PropertyInfo p in query) { // Find the ActorStat in the set of stats belonging to the actor. BoltActorStat targetStat = statset.Where(x => x.StatName == p.Name).First(); int newValue = targetStat.StatValue; if (p.Name == "Health") { // Finds the maximum value of the HEALTH stat. int maxHealth = statset.Where(x => x.StatName == "MaxHealth").First().StatValue; if (newValue > maxHealth) { newValue = maxHealth; targetStat.StatValue = newValue; } } else if (p.Name == "Energy") { // Find the maximum value of the ENERGY stat. int maxEnergy = statset.Where(x => x.StatName == "MaxEnergy").First().StatValue; if (newValue > maxEnergy) { newValue = maxEnergy; targetStat.StatValue = newValue; } } p.SetValue(stats, newValue, null); // Update the health or energy bar if either has changed. if (ui_UpdateStats.Contains(p.Name)) { UnitPlayerInterface.instance.UpdateBars(); } } } catch (System.Exception e) { Debug.LogError(e.Message); } }