public int RandomTimeBuffs(Buff.Buff indicator) { if (Session is Character character) { switch (indicator.Card.CardId) { //SP2a invisibility case 85: return(ServerManager.Instance.RandomNumber(50, 350)); // SP6a invisibility case 559: return(350); // Speed booster case 336: return(ServerManager.Instance.RandomNumber(30, 70)); // Charge buff types case 0: return(character.ChargeValue > 7000 ? 7000 : character.ChargeValue); } } return(-1); }
public void AddBuff(Buff.Buff buff, bool updateImmediate = true) { _buffStatModifiers[buff.RowData.GroupId] = buff.RowData.StatModifier; if (updateImmediate) { UpdateBuffStats(); } }
public void AddBuff(Buff.Buff indicator) { if (indicator?.Card == null || indicator.Card.BuffType == BuffType.Bad && Buffs.Any(b => b.Card.CardId == indicator.Card.CardId)) { return; } Buffs.RemoveWhere(s => !s.Card.CardId.Equals(indicator.Card.CardId), out ConcurrentBag <Buff.Buff> buffs); Buffs = buffs; //TODO: Find a better way to do this int randomTime = 0; if (Session is Character character) { if (indicator.Card.CardId == 85) { randomTime = character.BuffRandomTime = ServerManager.Instance.RandomNumber(50, 350); } else if (indicator.Card.CardId == 336) { randomTime = character.BuffRandomTime = ServerManager.Instance.RandomNumber(30, 70); } else if (indicator.Card.CardId == 0) { character.BuffRandomTime = character.ChargeValue > 7000 ? 7000 : character.ChargeValue; } if (!indicator.StaticBuff) { character.Session.SendPacket($"bf 1 {character.CharacterId} {(character.ChargeValue > 7000 ? 7000 : character.ChargeValue)}.{indicator.Card.CardId}.{indicator.Card.Duration} {Level}"); character.Session.SendPacket(character.GenerateSay(string.Format(Language.Instance.GetMessageFromKey("UNDER_EFFECT"), indicator.Card.Name), 20)); } } if (!indicator.StaticBuff) { indicator.RemainingTime = indicator.Card.Duration == 0 ? randomTime : indicator.Card.Duration; indicator.Start = DateTime.Now; } Buffs.Add(indicator); indicator.Card.BCards.ForEach(c => c.ApplyBCards(Entity)); if (indicator.Card.EffectId > 0) { //Entity.MapInstance?.Broadcast(Entity.GenerateEff(indicator.Card.EffectId)); } if (ObservableBag.TryGetValue(indicator.Card.CardId, out IDisposable value)) { value?.Dispose(); } ObservableBag[indicator.Card.CardId] = Observable.Timer(TimeSpan.FromMilliseconds(indicator.RemainingTime * (indicator.StaticBuff ? 1000 : 100))).Subscribe(o => { RemoveBuff(indicator.Card.CardId); if (indicator.Card.TimeoutBuff != 0 && ServerManager.Instance.RandomNumber() < indicator.Card.TimeoutBuffChance) { AddBuff(new Buff.Buff(indicator.Card.TimeoutBuff, Level)); } }); }
public void RemoveBuff(Buff.Buff buff, bool updateImmediate = true) { if (!_buffStatModifiers.ContainsKey(buff.RowData.GroupId)) { return; } _buffStatModifiers.Remove(buff.RowData.GroupId); if (updateImmediate) { UpdateBuffStats(); } }
public void RemoveBuff(int id, bool removePermaBuff = false) { Buff.Buff indicator = Buffs.FirstOrDefault(s => s.Card.CardId == id); if (indicator == null || !removePermaBuff && indicator.IsPermaBuff && indicator.RemainingTime <= 0) { return; } if (indicator.IsPermaBuff && !removePermaBuff) { AddBuff(indicator); return; } Buffs.RemoveWhere(s => s.Card.CardId != id, out ConcurrentBag <Buff.Buff> buffs); Buffs = buffs; if (!(Session is Character character)) { return; } if (indicator.StaticBuff) { character.Session.SendPacket($"vb {indicator.Card.CardId} 0 {indicator.Card.Duration}"); character.Session.SendPacket(character.GenerateSay(string.Format(Language.Instance.GetMessageFromKey("EFFECT_TERMINATED"), indicator.Card.Name), 11)); } else { character.Session.SendPacket($"bf 1 {character.CharacterId} 0.{indicator.Card.CardId}.0 {Level}"); character.Session.SendPacket(character.GenerateSay(string.Format(Language.Instance.GetMessageFromKey("EFFECT_TERMINATED"), indicator.Card.Name), 20)); } if (indicator.Card.BCards.Any(s => s.Type == (byte)CardType.Move)) { character.LoadSpeed(); character.LastSpeedChange = DateTime.Now; character.Session.SendPacket(character.GenerateCond()); } if (!indicator.Card.BCards.Any(s => s.Type == (byte)CardType.SpecialActions && s.SubType.Equals((byte)AdditionalTypes.SpecialActions.Hide))) { return; } character.Invisible = false; character.Mates.Where(m => m.IsTeamMember).ToList().ForEach(m => character.MapInstance?.Broadcast(m.GenerateIn())); character.MapInstance?.Broadcast(character.GenerateInvisible()); }
private void TargetHit2(IBattleEntity target, TargetHitType hitType, Skill skill, int damage, int hitmode, short?skillEffect = null, short?mapX = null, short?mapY = null, ComboDTO skillCombo = null, bool showTargetAnimation = false, bool isPvp = false, bool isRange = false) { target.GetDamage(damage, Entity, !(Session is MapMonster mon && mon.IsInvicible)); string str = $"su {(byte)Entity.SessionType()} {Entity.GetId()} {(byte)target.SessionType()} {target.GetId()} {skill?.SkillVNum ?? 0} {skill?.Cooldown ?? 0}"; switch (hitType) { case TargetHitType.SingleTargetHit: str += $" {skill?.AttackAnimation ?? 11} {skill?.Effect ?? skillEffect ?? 0} {Entity.GetPos().X} {Entity.GetPos().Y} {(target.CurrentHp > 0 ? 1 : 0)} {(int)(target.CurrentHp / (double)target.MaxHp * 100)} {damage} {hitmode} {skill?.SkillType - 1 ?? 0}"; break; case TargetHitType.SingleTargetHitCombo: str += $" {skillCombo?.Animation ?? 0} {skillCombo?.Effect ?? 0} {Entity.GetPos().X} {Entity.GetPos().Y} {(target.CurrentHp > 0 ? 1 : 0)} {(int)(target.CurrentHp / (double)target.MaxHp * 100)} {damage} {hitmode} {skill.SkillType - 1}"; break; case TargetHitType.SingleAOETargetHit: switch (hitmode) { case 1: hitmode = 4; break; case 3: hitmode = 6; break; default: hitmode = 5; break; } if (showTargetAnimation) { Entity.MapInstance.Broadcast($" {skill?.AttackAnimation ?? 0} {skill?.Effect ?? 0} 0 0 {(target.CurrentHp > 0 ? 1 : 0)} {(int)(target.CurrentHp / (double)target.MaxHp * 100)} 0 0 {skill.SkillType - 1}"); } str += $" {skill?.AttackAnimation ?? 0} {skill?.Effect ?? 0} {Entity.GetPos().X} {Entity.GetPos().Y} {(target.CurrentHp > 0 ? 1 : 0)} {(int)(target.CurrentHp / (double)target.MaxHp * 100)} {damage} {hitmode} {skill.SkillType - 1}"; break; case TargetHitType.AOETargetHit: switch (hitmode) { case 1: hitmode = 4; break; case 3: hitmode = 6; break; default: hitmode = 5; break; } str += $" {skill?.AttackAnimation ?? 0} {skill?.Effect ?? 0} {Entity.GetPos().X} {Entity.GetPos().Y} {(target.CurrentHp > 0 ? 1 : 0)} {(int)(target.CurrentHp / (double)target.MaxHp * 100)} {damage} {hitmode} {skill.SkillType - 1}"; break; case TargetHitType.ZoneHit: str += $" {skill?.AttackAnimation ?? 0} {skillEffect ?? 0} {mapX ?? Entity.GetPos().X} {mapY ?? Entity.GetPos().Y} {(target.CurrentHp > 0 ? 1 : 0)} {(int)(target.CurrentHp / (double)target.MaxHp * 100)} {damage} 5 {skill.SkillType - 1}"; break; case TargetHitType.SpecialZoneHit: str += $" {skill?.AttackAnimation ?? 0} {skillEffect ?? 0} {Entity.GetPos().X} {Entity.GetPos().Y} {(target.CurrentHp > 0 ? 1 : 0)} {(int)(target.CurrentHp / (double)target.MaxHp * 100)} {damage} 0 {skill.SkillType - 1}"; break; } Entity.MapInstance.Broadcast(str); bool isBoss = false; if (Entity.GetSession() is Character character) { character.LastSkillUse = DateTime.Now; RemoveBuff(85); // Hideout } else if (Entity.GetSession() is Mate mate) { mate.LastSkillUse = DateTime.Now; } if (target.GetSession() is MapMonster monster) { if (monster.Target == null) { monster.LastSkill = DateTime.Now; } monster.Target = Entity; isBoss = monster.IsBoss; if (isBoss) { Entity.MapInstance?.Broadcast(monster.GenerateBoss()); } monster.DamageList.AddOrUpdate(Entity, damage, (key, oldValue) => oldValue + damage); } if (!isBoss && skill != null) { foreach (BCard bcard in skill.BCards.Where(b => b != null)) { switch ((CardType)bcard.Type) { case CardType.Buff: Buff.Buff b = new Buff.Buff(bcard.SecondData); switch (b.Card?.BuffType) { case BuffType.Bad: bcard.ApplyBCards(target, Entity); break; case BuffType.Good: case BuffType.Neutral: bcard.ApplyBCards(Entity, Entity); break; } break; case CardType.HealingBurningAndCasting: switch ((AdditionalTypes.HealingBurningAndCasting)bcard.SubType) { case AdditionalTypes.HealingBurningAndCasting.RestoreHP: case AdditionalTypes.HealingBurningAndCasting.RestoreHPWhenCasting: bcard.ApplyBCards(Entity, Entity); break; default: bcard.ApplyBCards(target, Entity); break; } break; case CardType.MeditationSkill: bcard.ApplyBCards(Entity); break; default: bcard.ApplyBCards(target, Entity); break; } } } if (skill == null || (skill.Range <= 0 && skill.TargetRange <= 0) || isRange || !(Entity.GetSession() is MapMonster)) { return; } foreach (IBattleEntity entitiesInRange in Entity.MapInstance?.GetBattleEntitiesInRange(Entity.GetPos(), skill.TargetRange).Where(e => e != target && e.IsTargetable(Entity.SessionType()))) { TargetHit2(entitiesInRange, TargetHitType.SingleTargetHit, skill, damage, hitmode, isRange: true); } }
public void AddBuff(Buff.Buff indicator) => BattleEntity.AddBuff(indicator);
public void RemoveBuff(int id, bool removePermaBuff = false) { Buff.Buff indicator = Buffs.FirstOrDefault(s => s.Card.CardId == id); if (indicator == null || !removePermaBuff && indicator.IsPermaBuff && indicator.RemainingTime <= 0) { return; } if (indicator.IsPermaBuff && !removePermaBuff) { AddBuff(indicator); return; } if (ObservableBag.ContainsKey((short)id)) { ObservableBag[(short)id]?.Dispose(); } Buffs.RemoveWhere(s => s.Card.CardId != id, out ConcurrentBag <Buff.Buff> buffs); Buffs = buffs; if (Session is MapMonster monster) { monster.ReflectiveBuffs.TryRemove((short)id, out _); } if (!(Session is Character character)) { return; } character.ReflectiveBuffs.TryRemove((short)id, out _); // Fairy booster if (indicator.Card.CardId == 131) { character.GeneratePairy(); } if (!character.ReflectiveBuffs.Any()) { IsReflecting = false; } if (indicator.StaticBuff) { character.Session.SendPacket($"vb {indicator.Card.CardId} 0 {indicator.Card.Duration}"); character.Session.SendPacket(character.GenerateSay( string.Format(Language.Instance.GetMessageFromKey("EFFECT_TERMINATED"), indicator.Card.Name), 11)); } else { character.Session.SendPacket($"bf 1 {character.CharacterId} 0.{indicator.Card.CardId}.0 {Level}"); character.Session.SendPacket(character.GenerateSay( string.Format(Language.Instance.GetMessageFromKey("EFFECT_TERMINATED"), indicator.Card.Name), 20)); } // Fairy Booster if (indicator.Card.CardId == 131) { character.Session.SendPacket(character.GeneratePairy()); } if (indicator.Card.BCards.Any(s => s.Type == (byte)CardType.Move)) { character.LoadSpeed(); character.LastSpeedChange = DateTime.Now; character.Session.SendPacket(character.GenerateCond()); } if (!indicator.Card.BCards.Any(s => s.Type == (byte)CardType.SpecialActions && s.SubType.Equals((byte)AdditionalTypes.SpecialActions.Hide)) && indicator.Card.CardId != 559 && indicator.Card.CardId != 560) { return; } if (indicator.Card.CardId == 559 && character.TriggerAmbush) { character.AddBuff(new Buff.Buff(560)); character.TriggerAmbush = false; return; } if (indicator.Card.BCards.Any(s => s.Type == (byte)CardType.HideBarrelSkill && s.SubType.Equals((byte)AdditionalTypes.HideBarrelSkill.NoHPConsumption))) { character.HasGodMode = false; } if (indicator.Card.BCards.Any(s => s.Type == (byte)CardType.NoDefeatAndNoDamage && s.SubType.Equals((byte)AdditionalTypes.NoDefeatAndNoDamage.NeverReceiveDamage))) { character.HasGodMode = false; } character.Invisible = false; character.Mates.Where(m => m.IsTeamMember).ToList() .ForEach(m => character.MapInstance?.Broadcast(m.GenerateIn())); character.MapInstance?.Broadcast(character.GenerateInvisible()); }
public void AddBuff(Buff.Buff indicator, IBattleEntity caster = null) { if (indicator?.Card == null || indicator.Card.BuffType == BuffType.Bad && Buffs.Any(b => b.Card.CardId == indicator.Card.CardId)) { return; } //TODO: add a scripted way to remove debuffs from boss when a monster is killed (475 is laurena's buff) if (indicator.Card.CardId == 475) { return; } Buffs.RemoveWhere(s => !s.Card.CardId.Equals(indicator.Card.CardId), out ConcurrentBag <Buff.Buff> buffs); Buffs = buffs; int randomTime = 0; if (Session is Character character) { randomTime = RandomTimeBuffs(indicator); if (!indicator.StaticBuff) { character.Session.SendPacket( $"bf 1 {character.CharacterId} {(character.ChargeValue > 7000 ? 7000 : character.ChargeValue)}.{indicator.Card.CardId}.{(indicator.Card.Duration == 0 ? randomTime : indicator.Card.Duration)} {Level}"); character.Session.SendPacket(character.GenerateSay( string.Format(Language.Instance.GetMessageFromKey("UNDER_EFFECT"), indicator.Card.Name), 20)); } } if (Session is Mate mate) { randomTime = RandomTimeBuffs(indicator); mate.Owner?.Session.SendPacket($"bf 1 {mate.Owner?.CharacterId} 0.{indicator.Card.CardId}.{(indicator.Card.Duration == 0 ? randomTime : indicator.Card.Duration)} {Level}"); } if (!indicator.StaticBuff) { indicator.RemainingTime = indicator.Card.Duration == 0 ? randomTime : indicator.Card.Duration; indicator.Start = DateTime.Now; } Buffs.Add(indicator); if (indicator.Entity != null) { indicator.Card.BCards.ForEach(c => c.ApplyBCards(Entity, indicator.Entity)); } else { indicator.Card.BCards.ForEach(c => c.ApplyBCards(Entity)); } if (indicator.Card.EffectId > 0 && indicator.Card.EffectId != 7451) { Entity.MapInstance?.Broadcast(Entity.GenerateEff(indicator.Card.EffectId)); } if (ObservableBag.TryGetValue(indicator.Card.CardId, out IDisposable value)) { value?.Dispose(); } ObservableBag[indicator.Card.CardId] = Observable .Timer(TimeSpan.FromMilliseconds(indicator.RemainingTime * (indicator.StaticBuff ? 1000 : 100))) .Subscribe(o => { RemoveBuff(indicator.Card.CardId); if (indicator.Card.TimeoutBuff != 0 && ServerManager.Instance.RandomNumber() < indicator.Card.TimeoutBuffChance) { AddBuff(new Buff.Buff(indicator.Card.TimeoutBuff, Level)); } }); }
public ushort GenerateDamage(IBattleEntity targetEntity, Skill skill, ref int hitmode, ref bool onyxEffect) { BattleEntity target = targetEntity?.BattleEntity; if (target == null) { return(0); } #region Definitions // Percent Damage if (target.Session is MapMonster monster && monster.IsPercentage && monster.TakesDamage > 0) { targetEntity.DealtDamage = monster.TakesDamage; return((ushort)monster.TakesDamage); } AttackType attackType = Entity.GetAttackType(skill); int morale = Level + GetBuff(CardType.Morale, (byte)AdditionalTypes.Morale.MoraleIncreased)[0] - GetBuff(CardType.Morale, (byte)AdditionalTypes.Morale.MoraleDecreased)[0]; short upgrade = AttackUpgrade; int critChance = Critical; int critHit = CriticalRate; int minDmg = MinDamage; int maxDmg = MaxDamage; int hitRate = HitRate; #endregion #region Get Weapon Stats if (Session is Character character) { if (skill == null) { return(0); } if (character.Buff.Any(s => s.Card.CardId == 559)) { character.TriggerAmbush = true; RemoveBuff(559); } if (skill.SkillVNum == 1085) // pas de bcard ... { character.TeleportOnMap(targetEntity.GetPos().X, targetEntity.GetPos().Y); } if (character.Inventory .LoadBySlotAndType <WearableInstance>((byte)EquipmentType.Amulet, InventoryType.Equipment)?.Item ?.Effect == 932) { upgrade += 1; } DefenceUpgrade = character.Inventory?.Armor?.Upgrade ?? 0; if (CharacterHelper.Instance.GetClassAttackType(character.Class) == attackType) { minDmg += character.MinHit; maxDmg += character.MaxHit; hitRate += character.HitRate; critChance += character.HitCriticalRate; critHit += character.HitCritical; upgrade += character.Inventory.PrimaryWeapon?.Upgrade ?? 0; } else { minDmg += character.MinDistance; maxDmg += character.MaxDistance; hitRate += character.DistanceRate; critChance += character.DistanceCriticalRate; critHit += character.DistanceCritical; upgrade += character.Inventory.SecondaryWeapon?.Upgrade ?? 0; } } #endregion skill?.BCards?.ToList().ForEach(s => SkillBcards.Add(s)); #region Switch skill.Type int targetDefence = target.GetBuff(CardType.Defence, (byte)AdditionalTypes.Defence.AllIncreased)[0] - target.GetBuff(CardType.Defence, (byte)AdditionalTypes.Defence.AllDecreased)[0]; sbyte targetDefenseUpgrade = (sbyte)(target.GetBuff(CardType.Defence, (byte)AdditionalTypes.Defence.DefenceLevelIncreased)[0] - target.GetBuff(CardType.Defence, (byte)AdditionalTypes.Defence.DefenceLevelDecreased)[0]); int targetDodge = target.GetBuff(CardType.DodgeAndDefencePercent, (byte)AdditionalTypes.DodgeAndDefencePercent.DodgeIncreased)[0] - target.GetBuff(CardType.DodgeAndDefencePercent, (byte)AdditionalTypes.DodgeAndDefencePercent.DodgeDecreased)[0]; int targetMorale = target.Level + target.GetBuff(CardType.Morale, (byte)AdditionalTypes.Morale.MoraleIncreased)[0] - target.GetBuff(CardType.Morale, (byte)AdditionalTypes.Morale.MoraleDecreased)[0]; int targetBoostpercentage = 0; int boost = GetBuff(CardType.AttackPower, (byte)AdditionalTypes.AttackPower.AllAttacksIncreased)[0] - GetBuff(CardType.AttackPower, (byte)AdditionalTypes.AttackPower.AllAttacksDecreased)[0]; int boostpercentage = GetBuff(CardType.Damage, (byte)AdditionalTypes.Damage.DamageIncreased)[0] - GetBuff(CardType.Damage, (byte)AdditionalTypes.Damage.DamageDecreased)[0]; switch (attackType) { case AttackType.Close: targetDefence += target.CloseDefence; targetDodge += target.DefenceRate; targetBoostpercentage = target.GetBuff(CardType.Defence, (byte)AdditionalTypes.Defence.MeleeIncreased)[0] - target.GetBuff(CardType.Defence, (byte)AdditionalTypes.Defence.MeleeDecreased)[0]; boost += GetBuff(CardType.AttackPower, (byte)AdditionalTypes.AttackPower.MeleeAttacksIncreased)[0] - GetBuff(CardType.AttackPower, (byte)AdditionalTypes.AttackPower.MeleeAttacksDecreased)[0]; boostpercentage += GetBuff(CardType.Damage, (byte)AdditionalTypes.Damage.MeleeIncreased)[0] - GetBuff(CardType.Damage, (byte)AdditionalTypes.Damage.MeleeDecreased)[0]; break; case AttackType.Ranged: targetDefence += target.RangedDefence; targetDodge += target.DistanceDefenceRate; targetBoostpercentage = target.GetBuff(CardType.Defence, (byte)AdditionalTypes.Defence.RangedIncreased)[0] - target.GetBuff(CardType.Defence, (byte)AdditionalTypes.Defence.RangedDecreased)[0]; boost += GetBuff(CardType.AttackPower, (byte)AdditionalTypes.AttackPower.RangedAttacksIncreased)[0] - GetBuff(CardType.AttackPower, (byte)AdditionalTypes.AttackPower.RangedAttacksDecreased)[0]; boostpercentage += GetBuff(CardType.Damage, (byte)AdditionalTypes.Damage.RangedIncreased)[0] - GetBuff(CardType.Damage, (byte)AdditionalTypes.Damage.RangedDecreased)[0]; break; case AttackType.Magical: targetDefence += target.MagicDefence; targetBoostpercentage = target.GetBuff(CardType.Defence, (byte)AdditionalTypes.Defence.MagicalIncreased)[0] - target.GetBuff(CardType.Defence, (byte)AdditionalTypes.Defence.MeleeDecreased)[0]; boost += GetBuff(CardType.AttackPower, (byte)AdditionalTypes.AttackPower.MagicalAttacksIncreased)[0] - GetBuff(CardType.AttackPower, (byte)AdditionalTypes.AttackPower.MagicalAttacksDecreased)[0]; boostpercentage += GetBuff(CardType.Damage, (byte)AdditionalTypes.Damage.MagicalIncreased)[0] - GetBuff(CardType.Damage, (byte)AdditionalTypes.Damage.MagicalDecreased)[0]; break; } targetDefence = (int)(targetDefence * (1 + targetBoostpercentage / 100D)); minDmg += boost; maxDmg += boost; minDmg = (int)(minDmg * (1 + boostpercentage / 100D)); maxDmg = (int)(maxDmg * (1 + boostpercentage / 100D)); #endregion upgrade -= (short)((sbyte)target.DefenceUpgrade + targetDefenseUpgrade); #region Detailed Calculation #region Dodge if (attackType != AttackType.Magical) { double multiplier = targetDodge / (hitRate + 1); if (multiplier > 5) { multiplier = 5; } double chance = -0.25 * Math.Pow(multiplier, 3) - 0.57 * Math.Pow(multiplier, 2) + 25.3 * multiplier - 1.41; if (chance <= 1) { chance = 1; } if (GetBuff(CardType.DodgeAndDefencePercent, (byte)AdditionalTypes.DodgeAndDefencePercent.DodgeIncreased)[0] != 0) { chance = 10; } if (skill?.Type == 0 || skill?.Type == 1) { if (ServerManager.Instance.RandomNumber() <= chance) { targetEntity.DealtDamage = 0; hitmode = 1; SkillBcards.Clear(); return(0); } } } #endregion #region Base Damage int baseDamage = ServerManager.Instance.RandomNumber(minDmg, maxDmg < minDmg ? minDmg + 1 : maxDmg) + morale - targetMorale; short rest = 0; byte times = 0; if (upgrade > 10) { short upgradeCpy = upgrade; while (upgradeCpy - 10 > 10) { times += 1; upgradeCpy -= 10; } rest = (short)(upgradeCpy % 10); } if (upgrade < 0) { targetDefence += (int)(targetDefence * GetUpgradeValue(upgrade)); } else { baseDamage += (int)(baseDamage * GetUpgradeValue((short)(upgrade > 10 ? 10 : upgrade))); if (times > 0) { baseDamage += baseDamage * times * 2; } if (rest > 0) { baseDamage += (int)(baseDamage * (GetUpgradeValue(rest))); } } baseDamage -= target.HasBuff(CardType.SpecialDefence, (byte)AdditionalTypes.SpecialDefence.AllDefenceNullified) ? 0 : targetDefence; if (skill?.Type == 1 && Map.Map.GetDistance(Entity.GetPos(), targetEntity.GetPos()) < 4) { baseDamage = (int)(baseDamage * 0.85); } #endregion #region Elementary Damage #region Calculate Elemental Boost + Rate double elementalBoost = 0; int targetResistance = 0; int elementalDamage = GetBuff(CardType.Element, (byte)AdditionalTypes.Element.AllIncreased)[0] - GetBuff(CardType.Element, (byte)AdditionalTypes.Element.AllDecreased)[0]; int bonusrez = target.GetBuff(CardType.ElementResistance, (byte)AdditionalTypes.ElementResistance.AllIncreased)[0] - target.GetBuff(CardType.ElementResistance, (byte)AdditionalTypes.ElementResistance.AllDecreased)[0]; switch (Element) { case 1: bonusrez += target.GetBuff(CardType.ElementResistance, (byte)AdditionalTypes.ElementResistance.FireIncreased)[0] - target.GetBuff(CardType.ElementResistance, (byte)AdditionalTypes.ElementResistance.FireDecreased)[0]; elementalDamage += GetBuff(CardType.Element, (byte)AdditionalTypes.Element.FireIncreased)[0] - GetBuff(CardType.Element, (byte)AdditionalTypes.Element.FireDecreased)[0]; targetResistance = target.FireResistance; switch (target.Element) { case 0: elementalBoost = 1.3; // Damage vs no element break; case 1: elementalBoost = 1; // Damage vs fire break; case 2: elementalBoost = 2; // Damage vs water break; case 3: elementalBoost = 1; // Damage vs light break; case 4: elementalBoost = 1.5; // Damage vs darkness break; } break; case 2: bonusrez += target.GetBuff(CardType.ElementResistance, (byte)AdditionalTypes.ElementResistance.WaterIncreased)[0] - target.GetBuff(CardType.ElementResistance, (byte)AdditionalTypes.ElementResistance.WaterDecreased)[0]; elementalDamage += GetBuff(CardType.Element, (byte)AdditionalTypes.Element.WaterIncreased)[0] - GetBuff(CardType.Element, (byte)AdditionalTypes.Element.WaterDecreased)[0]; targetResistance = target.WaterResistance; switch (target.Element) { case 0: elementalBoost = 1.3; break; case 1: elementalBoost = 2; break; case 2: elementalBoost = 1; break; case 3: elementalBoost = 1.5; break; case 4: elementalBoost = 1; break; } break; case 3: bonusrez += target.GetBuff(CardType.ElementResistance, (byte)AdditionalTypes.ElementResistance.LightIncreased)[0] - target.GetBuff(CardType.ElementResistance, (byte)AdditionalTypes.ElementResistance.LightDecreased)[0]; elementalDamage += GetBuff(CardType.Element, (byte)AdditionalTypes.Element.LightIncreased)[0] - GetBuff(CardType.Element, (byte)AdditionalTypes.Element.LightDecreased)[0]; targetResistance = target.LightResistance; switch (target.Element) { case 0: elementalBoost = 1.3; break; case 1: elementalBoost = 1.5; break; case 2: elementalBoost = 1; break; case 3: elementalBoost = 1; break; case 4: elementalBoost = 3; break; } break; case 4: bonusrez += target.GetBuff(CardType.ElementResistance, (byte)AdditionalTypes.ElementResistance.DarkIncreased)[0] - target.GetBuff(CardType.ElementResistance, (byte)AdditionalTypes.ElementResistance.DarkDecreased)[0]; targetResistance = target.DarkResistance; elementalDamage += GetBuff(CardType.Element, (byte)AdditionalTypes.Element.DarkIncreased)[0] - GetBuff(CardType.Element, (byte)AdditionalTypes.Element.DarkDecreased)[0]; switch (target.Element) { case 0: elementalBoost = 1.3; break; case 1: elementalBoost = 1; break; case 2: elementalBoost = 1.5; break; case 3: elementalBoost = 3; break; case 4: elementalBoost = 1; break; } break; } #endregion ; if (skill?.Element == 0) { switch (elementalBoost) { case 0.5: elementalBoost = 0; break; case 1: elementalBoost = 0.05; break; case 1.3: case 1.5: elementalBoost = 0.15; break; case 2: case 3: elementalBoost = 0.2; break; } } else if (skill?.Element != Element) { elementalBoost = 0; } int resistance = targetResistance + bonusrez; elementalDamage = (int)(elementalDamage + (baseDamage + 100) * ((ElementRate + ElementRateSp) / 100D)); elementalDamage = (int)(elementalDamage / 100D * (100 - (resistance > 100 ? 100 : resistance)) * elementalBoost); #endregion #region Critical Damage critChance += GetBuff(CardType.Critical, (byte)AdditionalTypes.Critical.InflictingIncreased)[0] - GetBuff(CardType.Critical, (byte)AdditionalTypes.Critical.InflictingReduced)[0]; critHit += GetBuff(CardType.Critical, (byte)AdditionalTypes.Critical.DamageIncreased)[0] - GetBuff(CardType.Critical, (byte)AdditionalTypes.Critical.DamageIncreasedInflictingReduced)[0]; if (ServerManager.Instance.RandomNumber() <= critChance) { if (skill?.Type != 2 && attackType != AttackType.Magical) { double multiplier = critHit / 100D; multiplier = multiplier > 3 ? 3 : multiplier; baseDamage += (int)(baseDamage * multiplier); hitmode = 3; } } #endregion // OFFENSIVE POTION baseDamage += (int)(baseDamage * GetBuff(CardType.Item, (byte)AdditionalTypes.Item.AttackIncreased)[0] / 100D); if (Session is Character charact) { var weapon = charact.Inventory.LoadBySlotAndType <WearableInstance>((short)EquipmentType.MainWeapon, InventoryType.Wear); if (weapon != null) { foreach (BCard bcard in weapon.Item.BCards) { var b = new Buff.Buff(bcard.SecondData); switch (b.Card?.BuffType) { case BuffType.Good: bcard.ApplyBCards(charact, charact); break; case BuffType.Bad: bcard.ApplyBCards(targetEntity, charact); break; } } } int[] weaponSoftDamage = charact.GetWeaponSoftDamage(); if (ServerManager.Instance.RandomNumber() < weaponSoftDamage[0]) { charact.MapInstance.Broadcast(charact.GenerateEff(15)); baseDamage += (int)(baseDamage * (1 + weaponSoftDamage[1] / 100D)); } if (charact.HasBuff(CardType.IncreaseDamage, (byte)AdditionalTypes.IncreaseDamage.IncreasingPropability, true)) { charact.MapInstance.Broadcast(charact.GenerateEff(15)); baseDamage += (int)(baseDamage * (1 + GetBuff(CardType.IncreaseDamage, (byte)AdditionalTypes.IncreaseDamage .IncreasingPropability)[0] / 100D)); } // Falcon invisibility if (charact.Buff.Any(s => s.Card.CardId == 559)) { RemoveBuff(559); charact.AddBuff(new Buff.Buff(560)); } if (charact.ChargeValue > 0) { baseDamage += charact.ChargeValue; charact.ChargeValue = 0; charact.RemoveBuff(0); } baseDamage += charact.Class == ClassType.Adventurer ? 20 : 0; } #region Total Damage int totalDamage = baseDamage + elementalDamage; totalDamage = totalDamage < 5 ? ServerManager.Instance.RandomNumber(1, 6) : totalDamage; #endregion if (Session is MapMonster) { if (Level < 45) { //no minimum damage } else if (Level < 55) { totalDamage += Level; } else if (Level < 60) { totalDamage += Level * 2; } else if (Level < 65) { totalDamage += Level * 3; } else if (Level < 70) { totalDamage += Level * 4; } else { totalDamage += Level * 5; } } if (targetEntity.GetSession() is Character chara && target.HasBuff(CardType.NoDefeatAndNoDamage, (byte)AdditionalTypes.NoDefeatAndNoDamage.TransferAttackPower)) { chara.ChargeValue = totalDamage; chara.AddBuff(new Buff.Buff(0)); totalDamage = 0; hitmode = 1; } #endregion targetEntity.DealtDamage = totalDamage; while (totalDamage > ushort.MaxValue) { totalDamage -= ushort.MaxValue; } #region Onyx Wings onyxEffect = GetBuff(CardType.StealBuff, (byte)AdditionalTypes.StealBuff.ChanceSummonOnyxDragon)[0] > ServerManager.Instance.RandomNumber(); #endregion SkillBcards.Clear(); if (Session is Character charac && targetEntity is MapMonster cali && cali.MonsterVNum == 2305 && Caligor.IsRunning) { switch (charac.Faction) { case FactionType.Angel: Caligor.AngelDamage += targetEntity.DealtDamage + (onyxEffect ? targetEntity.DealtDamage / 2 : 0); break; case FactionType.Demon: Caligor.DemonDamage += targetEntity.DealtDamage + (onyxEffect ? targetEntity.DealtDamage / 2 : 0); break; } } return((ushort)totalDamage); }