public static int PhysicalAttack(YiObj attacker, MsgInteractType attackType = MsgInteractType.Physical) { if (!CanAttackPhysical(attacker, attacker.CurrentTarget)) { return(-1); } if (attacker.HasFlag(StatusEffect.Invisibility)) { attacker.RemoveStatusEffect(StatusEffect.Invisibility); } if (attacker is Player player) { if (player.AttackJob != null) { player.AttackJob.Cancelled = true; } if (player.CurrentTarget != null && player.CurrentTarget.Alive) { player.AttackJob = YiScheduler.Instance.DoReturn(TimeSpan.FromMilliseconds(attacker.AttackSpeed), () => MsgInteract.Handle(player, MsgInteract.Create(attacker, attacker.CurrentTarget, attackType, 0))); } } return(AttackCalcs.GetDamage(attacker, attacker.CurrentTarget, attackType)); }
public static byte[] Create(int attackerUniqueId, int targetUniqueId, ushort targetX, ushort targetY, MsgInteractType type, int value) { var msgP = stackalloc MsgInteract[1]; msgP->Size = (ushort)sizeof(MsgInteract); msgP->Id = 1022; msgP->Timestamp = Environment.TickCount; msgP->AttackerUniqueId = attackerUniqueId; msgP->TargetUniqueId = targetUniqueId; msgP->X = targetX; msgP->Y = targetY; msgP->Type = type; msgP->Value = value; var buffer = BufferPool.GetBuffer(); fixed(byte *p = buffer) * (MsgInteract *)p = *msgP; return(buffer); }
public static byte[] Create(YiObj source, YiObj target, MsgInteractType type, int value) { if (target == null || source == null) { return(null); } var msgP = stackalloc MsgInteract[1]; msgP->Size = (ushort)sizeof(MsgInteract); msgP->Id = 1022; msgP->Timestamp = Environment.TickCount; msgP->AttackerUniqueId = source.UniqueId; msgP->TargetUniqueId = target.UniqueId; msgP->X = target.Location.X; msgP->Y = target.Location.Y; msgP->Type = type; msgP->Value = value; var buffer = BufferPool.GetBuffer(); fixed(byte *p = buffer) * (MsgInteract *)p = *msgP; return(buffer); }
public static int GetDamage(YiObj attacker, YiObj target, MsgInteractType attackType) { if (!YiCore.Success(attacker.Dexterity)) { return(0); } var damage = 1.0d; switch (attackType) { case MsgInteractType.Physical: damage = YiCore.Random.Next(attacker.MinimumPhsyicalAttack, attacker.MaximumPhsyicalAttack); if (attacker is Monster) { damage = YiCore.Random.Next(attacker.MinimumPhsyicalAttack, attacker.MaximumPhsyicalAttack); } if (target is Monster monster) { damage = AdjustPvE((float)damage, attacker, monster); } if (attacker is Monster monster1 && target != null) { damage = AdjustEvP((float)damage, monster1, target); } if (target != null) { damage -= target.Defense; } break; case MsgInteractType.Magic: damage = attacker.MagicAttack; //if (attacker is Monster) // damage = (attacker as Monster).Base.MagicAttack; //if (attacker is YiObj && target is Monster) // damage = AdjustPvE(damage, (YiObj)attacker, (Monster)target); //if (attacker is Monster && target is YiObj) // damage = AdjustEvP(damage, (Monster)attacker, (YiObj)target); if (target != null) { damage *= (float)(100 - Math.Min(target.MagicDefense, 95)) / 100; damage -= target.MagicDefense; //MagicBlock damage *= 0.65; } else { damage *= 0.75; } break; case MsgInteractType.Archer: if (attacker == null) { return(0); } damage = YiCore.Random.Next(attacker.MinimumPhsyicalAttack, attacker.MaximumPhsyicalAttack); damage = AdjustPvE((float)damage, attacker, attacker.CurrentTarget as Monster); break; } if (target != null) { if (target.Reborn) { damage *= 0.7; } damage *= Math.Max(target.Bless, 1); } if (damage > 0) { damage = YiCore.Random.Next((int)(damage / 1.2), (int)damage); } damage *= 0.75; damage = Math.Max(1, damage); if (attacker is Player aPlayer) { if (target == null) { return((int)Math.Round(damage, 0)); } if (attacker.HasFlag(StatusEffect.SuperMan)) { damage *= 10; } } if (target != null) { TeamSystem.ShareExp(attacker, target, (uint)Math.Round(target.MaximumHp * 0.05)); } attacker.Experience += AdjustExp((int)Math.Round(damage, 0), attacker, target); return((int)Math.Round(damage, 0)); }