public float GetTotalStatValue(StatAttribute attribute) { float statValue = 0; if (Constants.ContainsKey(attribute)) { statValue += Constants[attribute].GetValue(); } if (Statics.ContainsKey(attribute)) { statValue += Statics[attribute].GetValue(); } if (Randoms.ContainsKey(attribute)) { statValue += Randoms[attribute].GetValue(); } if (Enchants.ContainsKey(attribute)) { statValue += Enchants[attribute].Flat; statValue += statValue * Enchants[attribute].Rate; } if (LimitBreakEnchants.ContainsKey(attribute)) { statValue += LimitBreakEnchants[attribute].Flat; statValue += statValue * LimitBreakEnchants[attribute].Rate; } return(statValue); }
private static ItemStat ReadStat(int statId, int value) { switch (statId) { // Basic Stat with percent value case >= 1000 and < 11000: { float percent = (float)(value + 5) / 10000; StatAttribute attribute = (StatAttribute)(statId - 1000); return(new BasicStat(attribute, percent, StatAttributeType.Rate)); } // Special Stat with percent value case >= 11000: { float percent = (float)(value + 5) / 10000; StatAttribute attribute = (StatAttribute)(statId); return(new SpecialStat(attribute, percent, StatAttributeType.Rate)); } default: // Basic Stat with flat value return(new BasicStat((StatAttribute)statId, value, StatAttributeType.Flat)); } }
private static void HandleStatIncrement(GameSession session, PacketReader packet) { StatAttribute statTypeIndex = (StatAttribute)packet.ReadByte(); session.Player.StatPointDistribution.AddPoint(statTypeIndex); session.Player.FieldPlayer.ComputeStats(); session.Send(StatPointPacket.WriteStatPointDistribution(session.Player)); session.Send(StatPacket.SetStats(session.Player.FieldPlayer)); }
public void AddPoint(StatAttribute statType) { if (AllocatedStats.ContainsKey(statType)) { AllocatedStats[statType] += 1; return; } AllocatedStats[statType] = 1; }
private static List <ParserSpecialStat> ParseSpecialStat(StatAttribute attribute, XmlNode node, StatAttributeType type) { List <ParserSpecialStat> values = new(); for (int i = 2; i <= 17; i++) { values.Add(new(attribute, float.Parse(node.Attributes[$"idx{i}"].Value), type)); } return(values); }
/// <summary> /// Update all stats. /// </summary> public static PacketWriter SetStats(IFieldActor actor) { PacketWriter pWriter = PacketWriter.Of(SendOp.Stat); pWriter.WriteInt(actor.ObjectId); pWriter.WriteByte(); // Unknown (0x00/0x01) pWriter.Write(StatsMode.SendAllStats); for (int i = 0; i < (int)StatsMode.SendAllStats; i++) { StatAttribute statAttribute = (StatAttribute)i; pWriter.WriteStat(statAttribute, actor.Stats.Data[statAttribute]); } return(pWriter); }
public static void AddHiddenNormalStat(List <ItemStat> stats, StatAttribute attribute, int value, float calibrationFactor) { ItemStat normalStat = stats.FirstOrDefault(x => x.ItemAttribute == attribute); if (normalStat == null) { return; } int calibratedValue = (int)(value * calibrationFactor); int index = stats.FindIndex(x => x.ItemAttribute == attribute); int biggerValue = Math.Max(value, calibratedValue); int smallerValue = Math.Min(value, calibratedValue); int summedFlat = (int)(normalStat.Flat + Random.Shared.Next(smallerValue, biggerValue)); stats[index] = new SpecialStat(normalStat.ItemAttribute, summedFlat, StatAttributeType.Flat); }
private static void WriteStat(this PacketWriter pWriter, StatAttribute statAttribute, Stat stat) { if (statAttribute is StatAttribute.Hp) { for (int i = 0; i < 3; i++) { pWriter.WriteLong(stat[i]); } return; } for (int i = 0; i < 3; i++) { pWriter.WriteInt(stat[i]); } }
public void CombinedRelationshipChangedValue() { const int attributeAValue = 1234; const int attributeBValue = 4938; const int attributeBMultiplier = 2; var statAttributeA = new StatAttribute(this.attributeA, attributeAValue); this.statAttributes.Add(statAttributeA); this.statAttributes.Add(new StatAttribute(this.attributeB, attributeBValue)); this.relationShips.Add(new AttributeRelationship(this.attributeAplusB, 1, this.attributeA)); this.relationShips.Add(new AttributeRelationship(this.attributeAplusB, attributeBMultiplier, this.attributeB)); var system = this.CreateAttributeSystem(); const int attributeAnewValue = 1000; statAttributeA.Value = attributeAnewValue; var value = system[this.attributeAplusB]; Assert.That(value, Is.EqualTo(attributeAnewValue + (attributeBValue * attributeBMultiplier))); }
public int this[StatAttribute key] { get { if (stats.ContainsKey(key)) { return(stats[key]); } else { return(0); } } set { stats[key] = value; } }
public void CombinedRelationshipAddedElement() { const int attributeAValue = 1234; const int attributeBValue = 4938; const int attributeBMultiplier = 2; var statAttributeA = new StatAttribute(this.attributeA, attributeAValue); this.statAttributes.Add(statAttributeA); this.statAttributes.Add(new StatAttribute(this.attributeB, attributeBValue)); this.relationShips.Add(new AttributeRelationship(this.attributeAplusB, 1, this.attributeA)); this.relationShips.Add(new AttributeRelationship(this.attributeAplusB, attributeBMultiplier, this.attributeB)); var system = this.CreateAttributeSystem(); const int addedAttributeValue = 10; system.AddElement(new ConstValueAttribute(addedAttributeValue, this.attributeAplusB), this.attributeAplusB); var value = system[this.attributeAplusB]; Assert.That(value, Is.EqualTo(attributeAValue + (attributeBValue * attributeBMultiplier) + addedAttributeValue)); }
public static Dictionary <StatAttribute, ItemStat> GetEnchantStats(int enchantLevel, ItemType itemType, int itemLevel) { Dictionary <StatAttribute, ItemStat> enchantStats = new(); Script script = ScriptLoader.GetScript("Functions/calcEnchantValues"); DynValue statValueScriptResult = script.RunFunction("calcEnchantBoostValues", enchantLevel, (int)itemType, itemLevel); for (int i = 0; i < statValueScriptResult.Tuple.Length; i += 2) { if (statValueScriptResult.Tuple[i].Number == 0) { continue; } StatAttribute attribute = (StatAttribute)statValueScriptResult.Tuple[i].Number; float boostRate = (float)statValueScriptResult.Tuple[i + 1].Number; enchantStats[attribute] = new BasicStat(attribute, boostRate, StatAttributeType.Rate); } return(enchantStats); }
private void AddStat(EffectStatusMetadata status, StatAttribute stat, long value) { if (value == 0) { return; } EffectStatMetadata currentValue; if (status.Stats.TryGetValue(stat, out currentValue)) { currentValue.Flat = value; return; } status.Stats.Add(stat, new() { Flat = value, AttributeType = StatAttributeType.Flat }); }
protected override void Start() { base.Start(); team = StatAttribute.Create(1f, "Team"); maxHealth = StatAttribute.Create(10f, "MaxHealth"); health = FloatVariable.Create(FloatConstant.Create(maxHealth.Value), FloatConstant.Create(0), maxHealth, AttributeType.Create("Health")); armor = StatAttribute.Create(10f, "Armor"); speed = StatAttribute.Create(3f, "Speed"); sneakMultiplier = 0.7f; runMultiplier = 2f; jumpPower = 450f; weight = StatAttribute.Create(0, "Weight"); maxWeight = StatAttribute.Create(0, "MaxWeight"); slotCapacity = -1; }
public Stats SetStat(StatAttribute attributes, int value) { stats[attributes] = value; return(this); }
public StatModifierInstance(StatModifier modifier, StatAttribute attribute, IStatModifierSource source) { Modifier = modifier; Attribute = attribute; Source = source; }
public static double FetchMultiplier(Stats stats, StatAttribute attribute) { return((double)stats[attribute].Total / 1000); }
public static DamageHandler CalculateDamage(SkillCast skill, IFieldActor source, IFieldActor target, double luckCoefficient) { // TODO: get accuracyWeakness from enemy stats from enemy buff. new stat recommended const double AccuracyWeakness = 0; double hitRate = (source.Stats[StatAttribute.Accuracy].Total + AccuracyWeakness) / Math.Max(target.Stats[StatAttribute.Evasion].Total, 0.1); if (Random.Shared.NextDouble() > hitRate) { return(new(source, target, 0, HitType.Miss)); // we missed } bool isCrit = skill.IsGuaranteedCrit() || RollCrit(source, target, luckCoefficient); double finalCritDamage = 1; if (isCrit) { // TODO: get critResist from enemy stats from enemy buff. new stat recommended const double CritResist = 1; double critDamage = 1000 + source.Stats[StatAttribute.CritDamage].Total; finalCritDamage = CritResist * ((critDamage / 1000) - 1) + 1; } double damageBonus = 1 + FetchMultiplier(source.Stats, StatAttribute.TotalDamage); damageBonus *= finalCritDamage; switch (skill.GetElement()) { case Element.Fire: damageBonus += FetchMultiplier(source.Stats, StatAttribute.FireDamage); break; case Element.Ice: damageBonus += FetchMultiplier(source.Stats, StatAttribute.IceDamage); break; case Element.Electric: damageBonus += FetchMultiplier(source.Stats, StatAttribute.ElectricDamage); break; case Element.Holy: damageBonus += FetchMultiplier(source.Stats, StatAttribute.HolyDamage); break; case Element.Dark: damageBonus += FetchMultiplier(source.Stats, StatAttribute.DarkDamage); break; case Element.Poison: damageBonus += FetchMultiplier(source.Stats, StatAttribute.PoisonDamage); break; } SkillRangeType rangeType = skill.GetRangeType(); if (rangeType != SkillRangeType.Special) { damageBonus += FetchMultiplier(source.Stats, rangeType == SkillRangeType.Melee ? StatAttribute.MeleeDamage : StatAttribute.RangedDamage); } bool isBoss = false; if (target is INpc npc) { isBoss = npc.Value.IsBoss(); } damageBonus += isBoss ? FetchMultiplier(source.Stats, StatAttribute.BossDamage) : 0; // TODO: properly fetch enemy attack speed weakness from enemy buff. new stat recommended const double AttackSpeedWeakness = 0; damageBonus += AttackSpeedWeakness * FetchMultiplier(source.Stats, StatAttribute.AttackSpeed); double damageMultiplier = damageBonus * skill.GetDamageRate(); // TODO: properly fetch enemy pierce resistance from enemy buff. new stat recommended const double EnemyPierceResistance = 1; double defensePierce = 1 - Math.Min(0.3, EnemyPierceResistance * FetchMultiplier(source.Stats, StatAttribute.Pierce)); damageMultiplier *= 1 / (Math.Max(target.Stats[StatAttribute.Defense].Total, 1) * defensePierce); bool isPhysical = skill.GetSkillDamageType() == DamageType.Physical; StatAttribute resistanceStat = isPhysical ? StatAttribute.PhysicalRes : StatAttribute.MagicRes; StatAttribute attackStat = isPhysical ? StatAttribute.PhysicalAtk : StatAttribute.MagicAtk; StatAttribute piercingStat = isPhysical ? StatAttribute.PhysicalPiercing : StatAttribute.MagicPiercing; double targetRes = target.Stats[resistanceStat].Total; double attackType = source.Stats[attackStat].Total; double resPierce = FetchMultiplier(source.Stats, piercingStat); double resistance = (1500.0 - Math.Max(0, targetRes - 1500 * resPierce)) / 1500; // does this need to be divided by anything at all to account for raw physical attack? damageMultiplier *= attackType * resistance; // TODO: apply special standalone multipliers like Spicy Maple Noodles buff? it seems to have had it's own multiplier. new stat recommended const double FinalDamageMultiplier = 1; damageMultiplier *= FinalDamageMultiplier; double attackDamage = 300; if (source is IFieldActor <Player> player) { double bonusAttack = player.Stats[StatAttribute.BonusAtk].Total + 0.4 * player.Stats[StatAttribute.PetBonusAtk].Total; // TODO: properly fetch enemy bonus attack weakness from enemy buff. new stat recommended const double BonusAttackWeakness = 1; double minDamage = player.Stats[StatAttribute.MinWeaponAtk].Total + BonusAttackWeakness * bonusAttack; double maxDamage = player.Stats[StatAttribute.MaxWeaponAtk].Total + BonusAttackWeakness * bonusAttack; attackDamage = minDamage + (maxDamage - minDamage) * Random.Shared.NextDouble(); } attackDamage *= damageMultiplier; return(new(source, target, Math.Max(1, attackDamage), isCrit ? HitType.Critical : HitType.Normal)); }
public async Task <bool> UpdateDatabasePVEProfileAsync(KeyValuePair <string, IQueryProfile> profile, IGuildUser guser, IUserMessage msg = null, bool nameTag = false, bool IsNameLocked = false, bool PVEDecimals = true) { if (_uow.Db <BlackListUser>().Where(p => p.Id == guser.Id.ToString()).Any()) { return(false); } var svvrs = await profile.Value.GetSurvivors(); var svvrsResource = await svvrs.CalcSurvivorFORTs(); var resources = await profile.Value.CalcResearchFORTs(); var AccountPowerLevel = await SurvivorStaticData.CalcEnergyByFORT(svvrsResource + resources); var mSchematics = profile.Value.AmountOfMythicSchematics(); var frostnite2019 = profile.Value.DoneEliteFrostnite2019(); var mockPveProfile = new FortnitePVEProfile { EpicId = profile.Value.profileChanges.First().profile.accountId, PlayerName = profile.Key, AccountPowerLevel = AccountPowerLevel, NumMythicSchematics = mSchematics, EliteFortnite2019 = frostnite2019 }; if (AccountPowerLevel < 16) { mockPveProfile.Map = MapRoles.Stonewood; } else if (AccountPowerLevel < 46) { mockPveProfile.Map = MapRoles.Plankerton; } else if (AccountPowerLevel < 70) { mockPveProfile.Map = MapRoles.CannyValley; } else { mockPveProfile.Map = MapRoles.TwinePeaks; } StatAttribute stats = profile.Value.profileChanges.First().profile.stats["attributes"]; if (stats.rewards_claimed_post_max_level.HasValue) { if (stats != null) { mockPveProfile.CommanderLevel = (stats.level + stats.rewards_claimed_post_max_level.Value); } } else { if (stats != null) { mockPveProfile.CommanderLevel = stats.level; } } if (stats.collection_book != null) { mockPveProfile.CollectionBookLevel = stats.collection_book.maxBookXpLevelAchieved; } UpdateDatabaseUserProfile(mockPveProfile.EpicId, guser, msg, nameTag, GameUserMode.PVE); StoredProcedure.SP_TABLE_FortnitePVEProfile_Update(mockPveProfile); await UpdateDiscordPVEProfileAsync(mockPveProfile, nameTag, guser, msg, IsNameLocked, PVEDecimals); return(true); }
public SpecialStat(StatAttribute attribute, float value, StatAttributeType type) : base(attribute, type, value) { }
protected ItemStat(StatAttribute attribute, StatAttributeType type, float value) { ItemAttribute = attribute; AttributeType = type; SetValue(value); }
public ParserSpecialStat(StatAttribute attribute, float value, StatAttributeType type) { Attribute = attribute; Value = value; AttributeType = type; }
private static Item GetNextLevelItem(Item item) { Script script = ScriptLoader.GetScript("Functions/calcLimitBreakValues"); DynValue scriptResultRates = script.RunFunction("calcLimitBreakStatRateValues", item.LimitBreakLevel); DynValue scriptResultFlats = script.RunFunction("calcLimitBreakStatFlatValues", item.LimitBreakLevel); Item nextLevelItem = new(item) { Uid = 0 }; if (nextLevelItem.LimitBreakLevel == 0) { nextLevelItem.EnchantLevel = 0; nextLevelItem.Stats.LimitBreakEnchants = nextLevelItem.Stats.Enchants; nextLevelItem.Stats.Enchants = new(); } for (int i = 0; i < scriptResultRates.Tuple.Length; i += 2) { if (scriptResultRates.Tuple[i].Number == 0) { continue; } StatAttribute attribute = (StatAttribute)scriptResultRates.Tuple[i].Number; float boostRate = (float)scriptResultRates.Tuple[i + 1].Number; if (!nextLevelItem.Stats.LimitBreakEnchants.ContainsKey(attribute)) { if (boostRate == 0) { continue; } ItemStat stat = new BasicStat(attribute, boostRate, StatAttributeType.Rate); if (attribute > (StatAttribute)11000) { stat = new SpecialStat(attribute, boostRate, StatAttributeType.Rate); } stat.ItemAttribute = attribute; nextLevelItem.Stats.LimitBreakEnchants[attribute] = stat; continue; } nextLevelItem.Stats.LimitBreakEnchants[attribute].Rate += boostRate; } for (int i = 0; i < scriptResultFlats.Tuple.Length; i += 2) { if (scriptResultFlats.Tuple[i].Number == 0) { continue; } StatAttribute attribute = (StatAttribute)scriptResultFlats.Tuple[i].Number; int boostValue = (int)scriptResultFlats.Tuple[i + 1].Number; if (!nextLevelItem.Stats.LimitBreakEnchants.ContainsKey(attribute)) { ItemStat stat = new BasicStat(attribute, boostValue, StatAttributeType.Flat); if (attribute > (StatAttribute)11000) { stat = new SpecialStat(attribute, boostValue, StatAttributeType.Flat); } stat.ItemAttribute = attribute; nextLevelItem.Stats.LimitBreakEnchants[attribute] = stat; continue; } nextLevelItem.Stats.LimitBreakEnchants[attribute].Flat += boostValue; } nextLevelItem.LimitBreakLevel++; return(nextLevelItem); } }