public GameMessagePrivateUpdateVital(Session session, PropertyAttribute2nd attribute, uint ranks, uint baseValue, uint totalInvestment, uint currentValue) : base(GameMessageOpcode.PrivateUpdateVital, GameMessageGroup.UIQueue) { // TODO We shouldn't be passing session. Insetad, we should pass the value after session.UpdateSkillSequence++. //Vital vital; switch (attribute) { case PropertyAttribute2nd.MaxHealth: Writer.Write(session.Player.Sequences.GetNextSequence(Sequence.SequenceType.PrivateUpdateAttribute2ndLevelHealth)); break; case PropertyAttribute2nd.MaxStamina: Writer.Write(session.Player.Sequences.GetNextSequence(Sequence.SequenceType.PrivateUpdateAttribute2ndLevelStamina)); break; case PropertyAttribute2nd.MaxMana: Writer.Write(session.Player.Sequences.GetNextSequence(Sequence.SequenceType.PrivateUpdateAttribute2ndLevelMana)); break; default: throw new ArgumentException("invalid ability specified"); } //Writer.Write(session.Player.Sequences.GetNextSequence(Sequence.SequenceType.PrivateUpdateAttribute)); Writer.Write((uint)attribute); Writer.Write(ranks); Writer.Write(baseValue); Writer.Write(totalInvestment); Writer.Write(currentValue); }
/// <summary> /// If the creatures biota does not contain this vital, a new record will be created. /// </summary> public CreatureVital(Creature creature, PropertyAttribute2nd vital) { this.creature = creature; Vital = vital; biotaPropertiesAttribute2nd = creature.Biota.BiotaPropertiesAttribute2nd.FirstOrDefault(x => x.Type == (uint)Vital); if (biotaPropertiesAttribute2nd == null) { biotaPropertiesAttribute2nd = new BiotaPropertiesAttribute2nd { ObjectId = creature.Biota.Id, Type = (ushort)Vital }; creature.Biota.BiotaPropertiesAttribute2nd.Add(biotaPropertiesAttribute2nd); } switch (Vital) { case PropertyAttribute2nd.MaxHealth: RegenRate = creature.GetProperty(PropertyFloat.HealthRate) ?? 0; break; case PropertyAttribute2nd.MaxStamina: RegenRate = creature.GetProperty(PropertyFloat.StaminaRate) ?? 0; break; case PropertyAttribute2nd.MaxMana: RegenRate = creature.GetProperty(PropertyFloat.ManaRate) ?? 0; break; } }
public GameMessagePrivateUpdateVital(WorldObject worldObject, PropertyAttribute2nd attribute, uint ranks, uint baseValue, uint totalInvestment, uint currentValue) : base(GameMessageOpcode.PrivateUpdateVital, GameMessageGroup.UIQueue) { switch (attribute) { case PropertyAttribute2nd.MaxHealth: Writer.Write(worldObject.Sequences.GetNextSequence(Sequence.SequenceType.PrivateUpdateAttribute2ndLevelHealth)); break; case PropertyAttribute2nd.MaxStamina: Writer.Write(worldObject.Sequences.GetNextSequence(Sequence.SequenceType.PrivateUpdateAttribute2ndLevelStamina)); break; case PropertyAttribute2nd.MaxMana: Writer.Write(worldObject.Sequences.GetNextSequence(Sequence.SequenceType.PrivateUpdateAttribute2ndLevelMana)); break; default: throw new ArgumentException("invalid ability specified"); } Writer.Write((uint)attribute); Writer.Write(ranks); Writer.Write(baseValue); Writer.Write(totalInvestment); Writer.Write(currentValue); }
/// <summary> /// If the creature's biota does not contain this vital, a new record will be created. /// </summary> public CreatureVital(Creature creature, PropertyAttribute2nd vital) { this.creature = creature; Vital = vital; if (!creature.Biota.PropertiesAttribute2nd.TryGetValue(vital, out propertiesAttribute2nd)) { propertiesAttribute2nd = new PropertiesAttribute2nd(); creature.Biota.PropertiesAttribute2nd[vital] = propertiesAttribute2nd; } switch (Vital) { case PropertyAttribute2nd.MaxHealth: RegenRate = creature.GetProperty(PropertyFloat.HealthRate) ?? 0; break; case PropertyAttribute2nd.MaxStamina: RegenRate = creature.GetProperty(PropertyFloat.StaminaRate) ?? 0; break; case PropertyAttribute2nd.MaxMana: RegenRate = creature.GetProperty(PropertyFloat.ManaRate) ?? 0; break; } }
public AttributeFormulaAttribute(PropertyAttribute2nd attribute2nd, byte divisor) { if (divisor == 0) { throw new ArgumentException("0 not a valid value for " + nameof(divisor)); } Attribute2nd = attribute2nd; Divisor = divisor; }
public GameMessagePrivateUpdateVital(WorldObject worldObject, PropertyAttribute2nd attribute, uint ranks, uint baseValue, uint totalInvestment, uint currentValue) : base(GameMessageOpcode.PrivateUpdateVital, GameMessageGroup.UIQueue) { Writer.Write(worldObject.Sequences.GetNextSequence(Sequence.SequenceType.UpdateAttribute2ndLevel, attribute)); Writer.Write((uint)attribute); Writer.Write(ranks); Writer.Write(baseValue); Writer.Write(totalInvestment); Writer.Write(currentValue); }
public InqRawSecondaryAttributeStat(PropertyAttribute2nd stat, int min, int max) : base(EmoteType.InqRawSecondaryAttributeStat) { Init(); Stat = (int)stat; Min = min; Max = max; }
public uint GetCurrentCreatureVital(PropertyAttribute2nd vital) { switch (vital) { case PropertyAttribute2nd.Mana: return(Mana.Current); case PropertyAttribute2nd.Stamina: return(Stamina.Current); default: return(Health.Current); } }
public void HandleActionRaiseVital(PropertyAttribute2nd attribute, uint amount) { var creatureVital = new CreatureVital(this, attribute); uint result = SpendVitalXp(creatureVital, amount); if (result > 0u) { GameMessage abilityUpdate = new GameMessagePrivateUpdateVital(this, attribute, creatureVital.Ranks, creatureVital.StartingValue, result, creatureVital.Current); // checks if max rank is achieved and plays fireworks w/ special text string messageText; if (IsVitalMaxRank(creatureVital.Ranks)) { // fireworks PlayParticleEffect(ACE.Entity.Enum.PlayScript.WeddingBliss, Guid); messageText = $"Your base {attribute.ToSentence()} is now {creatureVital.Base} and has reached its upper limit!"; } else { messageText = $"Your base {attribute.ToSentence()} is now {creatureVital.Base}!"; } var soundEvent = new GameMessageSound(Guid, Sound.RaiseTrait, 1f); var message = new GameMessageSystemChat(messageText, ChatMessageType.Advancement); // This seems to be needed to keep health up to date properly. // Needed when increasing health and endurance. //if (attribute == PropertyAttribute2nd.Endurance) //{ // var healthUpdate = new GameMessagePrivateUpdateVital(Session, Ability.Health, Health.Ranks, Health.StartingValue, Health.ExperienceSpent, Health.Current); // Session.Network.EnqueueSend(abilityUpdate, soundEvent, message, healthUpdate); //} //else if (attribute == PropertyAttribute2nd.Self) //{ // var manaUpdate = new GameMessagePrivateUpdateVital(Session, Ability.Mana, Mana.Ranks, Mana.StartingValue, Mana.ExperienceSpent, Mana.Current); // Session.Network.EnqueueSend(abilityUpdate, soundEvent, message, manaUpdate); //} //else //{ Session.Network.EnqueueSend(abilityUpdate, soundEvent, message); //} } else { ChatPacket.SendServerMessage(Session, $"Your attempt to raise {attribute.ToSentence()} has failed.", ChatMessageType.Broadcast); } }
/// <summary> /// If the creatures biota does not contain this vital, a new record will be created. /// </summary> public CreatureVital(Creature creature, PropertyAttribute2nd vital) { this.creature = creature; Vital = vital; biotaPropertiesAttribute2nd = creature.Biota.GetAttribute2nd(Vital); if (biotaPropertiesAttribute2nd == null) { creature.Biota.BiotaPropertiesAttribute2nd.Add(new BiotaPropertiesAttribute2nd { ObjectId = creature.Biota.Id, Type = (ushort)Vital }); biotaPropertiesAttribute2nd = creature.Biota.GetAttribute2nd(Vital); } }
/// <summary> /// Handles the GameAction 0x44 - RaiseVital network message from client /// </summary> public bool HandleActionRaiseVital(PropertyAttribute2nd vital, uint amount) { if (!Vitals.TryGetValue(vital, out var creatureVital)) { log.Error($"{Name}.HandleActionRaiseVital({vital}, {amount}) - invalid vital"); return(false); } if (amount > AvailableExperience) { // there is a client bug for vitals only, // where the client will enable the button to raise a vital by 10 // if the player only has enough AvailableExperience to raise it by 1 ChatPacket.SendServerMessage(Session, $"Your attempt to raise {vital.ToSentence()} has failed.", ChatMessageType.Broadcast); log.Error($"{Name}.HandleActionRaiseVital({vital}, {amount}) - amount > AvailableExperience ({AvailableExperience})"); return(false); } var prevRank = creatureVital.Ranks; if (!SpendVitalXp(creatureVital, amount)) { return(false); } Session.Network.EnqueueSend(new GameMessagePrivateUpdateVital(this, creatureVital)); if (prevRank != creatureVital.Ranks) { // checks if max rank is achieved and plays fireworks w/ special text var suffix = ""; if (creatureVital.IsMaxRank) { // fireworks PlayParticleEffect(PlayScript.WeddingBliss, Guid); suffix = $" and has reached its upper limit"; } var sound = new GameMessageSound(Guid, Sound.RaiseTrait); var msg = new GameMessageSystemChat($"Your base {vital.ToSentence()} is now {creatureVital.Base}{suffix}!", ChatMessageType.Advancement); Session.Network.EnqueueSend(sound, msg); } return(true); }
public CreatureVital GetCreatureVital(PropertyAttribute2nd vital) { switch (vital) { case PropertyAttribute2nd.Health: return(Health); case PropertyAttribute2nd.Stamina: return(Stamina); case PropertyAttribute2nd.Mana: return(Mana); default: log.Error($"{Name}.GetCreatureVital({vital}): unexpected vital"); return(null); } }
/// <summary> /// Returns the amount to add to a creature's current vital, /// based on their primary attribute current values /// </summary> public static uint GetFormula(Creature creature, PropertyAttribute2nd vital, bool current = true) { var vitalTable = DatManager.PortalDat.SecondaryAttributeTable; switch (vital) { case PropertyAttribute2nd.MaxHealth: return(GetFormula(creature, vitalTable.MaxHealth.Formula, current)); case PropertyAttribute2nd.MaxStamina: return(GetFormula(creature, vitalTable.MaxStamina.Formula, current)); case PropertyAttribute2nd.MaxMana: return(GetFormula(creature, vitalTable.MaxMana.Formula, current)); default: return(0); } }
public GameMessagePrivateUpdateVital(Session session, PropertyAttribute2nd attribute, CreatureVital cv) : this(session, attribute, cv.Ranks, cv.StartingValue, cv.ExperienceSpent, cv.Current) { }
public static WeeniePropertiesAttribute2nd GetAttribute2nd(this Weenie weenie, PropertyAttribute2nd attribute) { return(weenie.WeeniePropertiesAttribute2nd.FirstOrDefault(x => x.Type == (uint)attribute)); }
public CreatureVital GetCreatureVital(PropertyAttribute2nd vital) { Vitals.TryGetValue(vital, out var value); return(value); }
public static AttributeFormulaAttribute GetFormula(this PropertyAttribute2nd attribute) { return(attribute.GetAttributeOfType <AttributeFormulaAttribute>()); }
public static BiotaPropertiesAttribute2nd GetAttribute2nd(this Biota biota, PropertyAttribute2nd attribute) { return(biota.BiotaPropertiesAttribute2nd.FirstOrDefault(x => x.Type == (uint)attribute)); }
public static string GetDescription(this PropertyAttribute2nd prop) { var description = prop.GetAttributeOfType <DescriptionAttribute>(); return(description?.Description ?? prop.ToString()); }
/// <summary> /// Will add a space infront of capital letter words in a string /// </summary> /// <param name="attribute2nd"></param> /// <returns>string with spaces infront of capital letters</returns> public static string ToSentence(this PropertyAttribute2nd attribute2nd) { return(new string(attribute2nd.ToString().Replace("Max", "Maximum").ToCharArray().SelectMany((c, i) => i > 0 && char.IsUpper(c) ? new char[] { ' ', c } : new char[] { c }).ToArray())); }
public byte[] GetNextSequence(SequenceType type, PropertyAttribute2nd property) { return(GetSequence(type, (uint)property).NextBytes); }
public AttributeFormulaAttribute(PropertyAttribute2nd attribute2nd) : this(attribute2nd, 1) { }