Exemple #1
0
    private static void HandleDamage(GameSession session, PacketReader packet)
    {
        long   skillSn        = packet.ReadLong();
        int    attackCounter  = packet.ReadInt();
        int    playerObjectId = packet.ReadInt();
        CoordF position       = packet.Read <CoordF>();
        CoordF impactPos      = packet.Read <CoordF>();
        CoordF rotation       = packet.Read <CoordF>();
        int    attackPoint    = packet.ReadByte();
        byte   count          = packet.ReadByte();

        packet.ReadInt();

        IFieldActor <Player> fieldPlayer = session.Player.FieldPlayer;

        SkillCast skillCast = fieldPlayer.SkillCast;

        if (skillCast is null || skillCast.SkillSn != skillSn)
        {
            return;
        }

        // TODO: Verify if its the player or an ally
        if (skillCast.IsRecovery())
        {
            Status status = new(skillCast, fieldPlayer.ObjectId, fieldPlayer.ObjectId, 1);
            StatusHandler.Handle(session, status);

            // TODO: Heal based on stats
            fieldPlayer.Heal(session, status, 50);
            return;
        }

        bool isCrit = DamageHandler.RollCrit(session.Player.Stats[StatId.CritRate].Total);
        List <(int targetId, byte damageType, double damage)> damages = new();

        for (int i = 0; i < count; i++)
        {
            int entityId = packet.ReadInt();
            packet.ReadByte();

            if (entityId == playerObjectId)
            {
                damages.Add(new(playerObjectId, 0, 0));
                continue;
            }

            IFieldActor <NpcMetadata> mob = session.FieldManager.State.Mobs.GetValueOrDefault(entityId);
            if (mob == null)
            {
                continue;
            }
            skillCast.Target = mob;

            DamageHandler damage = DamageHandler.CalculateDamage(skillCast, fieldPlayer, mob, isCrit);

            mob.Damage(damage, session);

            damages.Add(new(damage.Target.ObjectId, (byte)(isCrit ? 1 : 0), damage.Damage));

            // TODO: Check if the skill is a debuff for an entity
            if (!skillCast.IsDebuffElement() && !skillCast.IsDebuffToEntity() && !skillCast.IsDebuffElement())
            {
                continue;
            }

            Status status = new(skillCast, mob.ObjectId, fieldPlayer.ObjectId, 1);
            StatusHandler.Handle(session, status);
        }

        session.FieldManager.BroadcastPacket(SkillDamagePacket.Damage(skillCast, attackCounter, position, rotation, damages));
    }