Esempio n. 1
0
        private static void HandleAoeDamage(GameSession session, PacketReader packet)
        {
            List <IFieldObject <Mob> > mobs = new List <IFieldObject <Mob> >();
            long   skillSN        = packet.ReadLong();
            int    unkValue       = packet.ReadInt();
            int    playerObjectId = packet.ReadInt();
            CoordF coords         = packet.Read <CoordF>();
            CoordF coords2        = packet.Read <CoordF>();
            CoordF coords3        = packet.Read <CoordF>();

            packet.ReadByte();
            byte count = packet.ReadByte();

            packet.ReadInt();

            for (int i = 0; i < count; i++)
            {
                int entity = packet.ReadInt();
                mobs.Add(session.FieldManager.State.Mobs.GetValueOrDefault(entity));
                packet.ReadByte();
                if (mobs[i] != null)
                {
                    mobs[i].Value.UpdateStats(session.FieldPlayer.Value.SkillCast.GetDamage());
                    session.Send(StatPacket.UpdateMobStats(mobs[i]));
                }
            }
            session.Send(SkillDamagePacket.ApplyDamage(session.FieldPlayer, skillSN, unkValue, coords, mobs));
        }
    private static void HandleRegionDamage(FieldManager field, SkillCast skillCast)
    {
        if (!field.State.Players.TryGetValue(skillCast.CasterObjectId, out Character caster))
        {
            // Handle NPCs/Triggers sending skills
            return;
        }

        List <DamageHandler> damages = new();

        foreach (IFieldActor <NpcMetadata> mob in field.State.Mobs.Values)
        {
            foreach (CoordF effectCoord in skillCast.EffectCoords)
            {
                if ((mob.Coord - effectCoord).Length() > skillCast.SkillAttack.RangeProperty.Distance)
                {
                    continue;
                }

                DamageHandler damage = DamageHandler.CalculateDamage(skillCast, caster, mob);
                mob.Damage(damage, caster.Value.Session);

                damages.Add(damage);
            }
        }

        if (damages.Count <= 0)
        {
            return;
        }

        field.BroadcastPacket(SkillDamagePacket.RegionDamage(skillCast, damages));
    }
Esempio n. 3
0
        private static void HandleSyncDamage(GameSession session, PacketReader packet)
        {
            long   skillSN     = packet.ReadLong();
            byte   attackPoint = packet.ReadByte();
            CoordF position    = packet.Read <CoordF>();
            CoordF rotation    = packet.Read <CoordF>();
            byte   count       = packet.ReadByte();

            packet.ReadInt();

            List <int>   atkCount  = new List <int>();
            List <int>   sourceId  = new List <int>();
            List <int>   targetId  = new List <int>();
            List <short> animation = new List <short>();

            // TODO: Handle multiple projectiles
            for (int i = 0; i < count; i++)
            {
                atkCount.Add(packet.ReadInt());
                sourceId.Add(packet.ReadInt());
                targetId.Add(packet.ReadInt());
                animation.Add(packet.ReadShort());
            }

            session.FieldManager.BroadcastPacket(SkillDamagePacket.SyncDamage(skillSN, position, rotation, session.FieldPlayer, sourceId, count, atkCount, targetId, animation));
        }
Esempio n. 4
0
        private Task StartHealingSpot()
        {
            return(Task.Run(async() =>
            {
                while (!State.Players.IsEmpty)
                {
                    foreach (IFieldObject <HealingSpot> healingSpot in State.HealingSpots.Values)
                    {
                        CoordS healingCoord = healingSpot.Value.Coord;
                        foreach (IFieldObject <Player> player in State.Players.Values)
                        {
                            if ((healingCoord - player.Coord.ToShort()).Length() < Block.BLOCK_SIZE * 2 && healingCoord.Z == player.Coord.ToShort().Z - 1) // 3x3x1 area
                            {
                                int healAmount = (int)(player.Value.Stats[PlayerStatId.Hp].Max * 0.03);
                                Status status = new Status(new SkillCast(70000018, 1, 0, 1), owner: player.ObjectId, source: healingSpot.ObjectId, duration: 100, stacks: 1);

                                player.Value.Session.Send(BuffPacket.SendBuff(0, status));
                                BroadcastPacket(SkillDamagePacket.ApplyHeal(status, healAmount));

                                player.Value.Session.Player.Stats.Increase(PlayerStatId.Hp, healAmount);
                                player.Value.Session.Send(StatPacket.UpdateStats(player, PlayerStatId.Hp));
                            }
                        }
                    }

                    await Task.Delay(1000);
                }
            }));
        }
Esempio n. 5
0
    private static void HandleRegionDamage(GameSession session, SkillCast skillCast)
    {
        List <DamageHandler> damages = new();
        bool isCrit = DamageHandler.RollCrit(session.Player.Stats[StatId.CritRate].Total);

        foreach (IFieldActor <NpcMetadata> mob in session.FieldManager.State.Mobs.Values)
        {
            foreach (CoordF effectCoord in skillCast.EffectCoords)
            {
                if ((mob.Coord - effectCoord).Length() > skillCast.SkillAttack.RangeProperty.Distance)
                {
                    continue;
                }

                DamageHandler damage = DamageHandler.CalculateDamage(skillCast, session.Player.FieldPlayer, mob, isCrit);
                mob.Damage(damage, session);

                damages.Add(damage);
            }
        }

        if (damages.Count <= 0)
        {
            return;
        }

        session.FieldManager.BroadcastPacket(SkillDamagePacket.RegionDamage(skillCast, damages));
    }
Esempio n. 6
0
        private static void HandleAoeDamage(GameSession session, PacketReader packet)
        {
            List <(IFieldObject <Mob>, DamageHandler)> mobs = new List <(IFieldObject <Mob>, DamageHandler)>();
            long   skillSN        = packet.ReadLong();
            int    unkValue       = packet.ReadInt();
            int    playerObjectId = packet.ReadInt();
            CoordF coords         = packet.Read <CoordF>();
            CoordF coords2        = packet.Read <CoordF>();
            CoordF coords3        = packet.Read <CoordF>();

            packet.ReadByte();
            byte count = packet.ReadByte();

            packet.ReadInt();

            bool isCrit = DamageHandler.RollCrit(session.Player.Stats[PlayerStatId.CritRate].Current);

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

                IFieldObject <Mob> mob = session.FieldManager.State.Mobs.GetValueOrDefault(entity);
                if (mob != null)
                {
                    DamageHandler damage = DamageHandler.CalculateDamage(session.FieldPlayer.Value.SkillCast, session.FieldPlayer.Value, mob.Value, isCrit);

                    mob.Value.Damage(damage.Damage);
                    session.Send(StatPacket.UpdateMobStats(mob));

                    if (mob.Value.IsDead)
                    {
                        HandleMobKill(session, mob);
                    }

                    if (mob.Value.Id == 29000128) // Temp fix for tutorial barrier
                    {
                        session.Send("4F 00 03 E8 03 00 00 00 00 00 00 00 00 00 00 00 00 80 3F".ToByteArray());
                        session.Send("4F 00 03 D0 07 00 00 00 00 00 00 00 00 00 00 00 00 80 3F".ToByteArray());
                        session.Send("4F 00 08 01 04 01 00 00".ToByteArray());
                    }

                    mobs.Add((mob, damage));
                }
            }
            session.Send(SkillDamagePacket.ApplyDamage(skillSN, unkValue, coords, session.FieldPlayer, mobs));
        }
Esempio n. 7
0
        private static void HandleAoeDamage(GameSession session, PacketReader packet)
        {
            List <IFieldObject <Mob> > mobs = new List <IFieldObject <Mob> >();
            long   skillSN        = packet.ReadLong();
            int    unkValue       = packet.ReadInt();
            int    playerObjectId = packet.ReadInt();
            CoordF coords         = packet.Read <CoordF>();
            CoordF coords2        = packet.Read <CoordF>();
            CoordF coords3        = packet.Read <CoordF>();

            packet.ReadByte();
            byte count = packet.ReadByte();

            packet.ReadInt();

            for (int i = 0; i < count; i++)
            {
                int entity = packet.ReadInt();
                mobs.Add(session.FieldManager.State.Mobs.GetValueOrDefault(entity));
                packet.ReadByte();
                if (mobs[i] != null)
                {
                    mobs[i].Value.UpdateStats(session.FieldPlayer.Value.SkillCast.GetDamage());
                    session.Send(StatPacket.UpdateMobStats(mobs[i]));

                    // TODO: There needs to be a more centralized way to give rewards from killing mobs...
                    // TODO: Add trophy, exp, meso and item drops
                    if (mobs[i].Value.IsDead)
                    {
                        QuestHelper.UpdateQuest(session, mobs[i].Value.Id.ToString(), "npc");
                    }

                    if (mobs[i].Value.Id == 29000128) // Temp fix for tutorial barrier
                    {
                        session.Send("4F 00 03 E8 03 00 00 00 00 00 00 00 00 00 00 00 00 80 3F".ToByteArray());
                        session.Send("4F 00 03 D0 07 00 00 00 00 00 00 00 00 00 00 00 00 80 3F".ToByteArray());
                        session.Send("4F 00 08 01 04 01 00 00".ToByteArray());
                    }
                }
            }
            session.Send(SkillDamagePacket.ApplyDamage(session.FieldPlayer, skillSN, unkValue, coords, mobs));
        }
Esempio n. 8
0
        private void HealingSpot()
        {
            foreach (IFieldObject <HealingSpot> healingSpot in State.HealingSpots.Values)
            {
                CoordS healingCoord = healingSpot.Value.Coord;
                foreach (IFieldObject <Player> player in State.Players.Values)
                {
                    if ((healingCoord - player.Coord.ToShort()).Length() < Block.BLOCK_SIZE * 2 && healingCoord.Z == player.Coord.ToShort().Z - 1) // 3x3x1 area
                    {
                        int    healAmount = (int)(player.Value.Stats[PlayerStatId.Hp].Max * 0.03);
                        Status status     = new Status(new SkillCast(70000018, 1, 0, 1), target: player.ObjectId, source: healingSpot.ObjectId, stacks: 1);

                        player.Value.Session.Send(BuffPacket.SendBuff(0, status));
                        BroadcastPacket(SkillDamagePacket.Heal(status, healAmount));

                        player.Value.Session.Player.Stats.Increase(PlayerStatId.Hp, healAmount);
                        player.Value.Session.Send(StatPacket.UpdateStats(player, PlayerStatId.Hp));
                    }
                }
            }
        }
Esempio n. 9
0
        private Task StartHealingSpot(GameSession session, IFieldObject <Player> player)
        {
            int    healAmount = 30;
            Status status     = new Status(new SkillCast(70000018, 1, 0, 1), player.ObjectId, player.ObjectId, 1, healAmount);

            return(Task.Run(async() =>
            {
                while (!State.Players.IsEmpty)
                {
                    CoordS healingCoord = MapEntityStorage.GetHealingSpot(MapId);

                    if ((healingCoord - player.Coord.ToShort()).Length() < Block.BLOCK_SIZE * 2 && healingCoord.Z == player.Coord.ToShort().Z - 1) // 3x3x1 area
                    {
                        session.Send(BuffPacket.SendBuff(0, status));
                        session.Send(SkillDamagePacket.ApplyHeal(player, status));
                        session.Player.Stats.Increase(PlayerStatId.Hp, healAmount);
                        session.Send(StatPacket.UpdateStats(player, PlayerStatId.Hp));
                    }

                    await Task.Delay(1000);
                }
            }));
        }
Esempio n. 10
0
        private void HandleAoeDamage(GameSession session, PacketReader packet)
        {
            List <IFieldObject <Mob> > mobs = new List <IFieldObject <Mob> >();
            long   skillUid       = packet.ReadLong();
            int    someValue      = packet.ReadInt();
            int    playerObjectId = packet.ReadInt();
            CoordF coords         = packet.Read <CoordF>();
            CoordF coords2        = packet.Read <CoordF>();
            CoordF coords3        = packet.Read <CoordF>();

            packet.ReadByte();
            byte count = packet.ReadByte();

            packet.ReadInt();
            for (int i = 0; i < count; i++)
            {
                mobs.Add(session.FieldManager.State.Mobs.GetValueOrDefault(packet.ReadInt()));
                packet.ReadByte();
                session.Send(StatPacket.UpdateMobStats(mobs[i]));
            }

            session.Send(SkillDamagePacket.ApplyDamage(session.FieldPlayer, skillUid, someValue, coords, mobs));
        }
Esempio n. 11
0
        private static void HandleDamage(GameSession session, PacketReader packet)
        {
            List <(IFieldObject <Mob>, DamageHandler)> mobs = new List <(IFieldObject <Mob>, DamageHandler)>();
            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();

            bool isCrit = DamageHandler.RollCrit(session.Player.Stats[PlayerStatId.CritRate].Current);

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

                IFieldObject <Mob> mob = session.FieldManager.State.Mobs.GetValueOrDefault(entity);
                if (mob == null)
                {
                    continue;
                }

                DamageHandler damage = DamageHandler.CalculateDamage(session.FieldPlayer.Value.SkillCast, session.FieldPlayer.Value, mob.Value, isCrit);

                mob.Value.Damage(damage.Damage);
                session.Send(StatPacket.UpdateMobStats(mob));

                if (mob.Value.IsDead)
                {
                    HandleMobKill(session, mob);
                }

                mobs.Add((mob, damage));

                // TODO: Check if the skill is a debuff for an entity
                SkillCast skillCast = session.FieldPlayer.Value.SkillCast;
                if (skillCast.IsDebuffElement() || skillCast.IsDebuffToEntity() || skillCast.IsDebuffElement())
                {
                    Status status = new Status(session.FieldPlayer.Value.SkillCast, mob.ObjectId, session.FieldPlayer.ObjectId, 1);
                    StatusHandler.Handle(session, status);
                }
            }
            // TODO: Verify if its the player or an ally
            if (session.FieldPlayer.Value.SkillCast.IsHeal())
            {
                Status status = new Status(session.FieldPlayer.Value.SkillCast, session.FieldPlayer.ObjectId, session.FieldPlayer.ObjectId, 1);
                StatusHandler.Handle(session, status);

                // TODO: Heal based on stats
                session.FieldManager.BroadcastPacket(SkillDamagePacket.Heal(status, 50));
                session.FieldPlayer.Value.Stats.Increase(PlayerStatId.Hp, 50);
                session.Send(StatPacket.UpdateStats(session.FieldPlayer, PlayerStatId.Hp));
            }
            else
            {
                session.FieldManager.BroadcastPacket(SkillDamagePacket.Damage(skillSN, attackCounter, position, rotation, session.FieldPlayer, mobs));
            }
        }
Esempio n. 12
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));
    }
Esempio n. 13
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;

        bool isCrit = DamageHandler.RollCrit(session.Player.Stats[StatId.CritRate].Total);

        // TODO: Check if skillSN matches server's current skill for the player
        // TODO: Verify if its the player or an ally
        if (fieldPlayer.SkillCast.IsHeal())
        {
            Status status = new(fieldPlayer.SkillCast, fieldPlayer.ObjectId, fieldPlayer.ObjectId, 1);
            StatusHandler.Handle(session, status);

            // TODO: Heal based on stats
            session.FieldManager.BroadcastPacket(SkillDamagePacket.Heal(status, 50));
            fieldPlayer.Stats[StatId.Hp].Increase(50);
            session.Send(StatPacket.UpdateStats(fieldPlayer, StatId.Hp));
        }
        else
        {
            List <DamageHandler> damages = new();
            for (int i = 0; i < count; i++)
            {
                int entityId = packet.ReadInt();
                packet.ReadByte();

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

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

                mob.Damage(damage);
                // TODO: Move logic to Damage()
                session.FieldManager.BroadcastPacket(StatPacket.UpdateMobStats(mob));
                if (mob.IsDead)
                {
                    HandleMobKill(session, mob);
                }

                damages.Add(damage);

                // TODO: Check if the skill is a debuff for an entity
                SkillCast skillCast = fieldPlayer.SkillCast;
                if (skillCast.IsDebuffElement() || skillCast.IsDebuffToEntity() || skillCast.IsDebuffElement())
                {
                    Status status = new(fieldPlayer.SkillCast, mob.ObjectId, fieldPlayer.ObjectId, 1);
                    StatusHandler.Handle(session, status);
                }
            }

            session.FieldManager.BroadcastPacket(SkillDamagePacket.Damage(skillSN, attackCounter, position, rotation, fieldPlayer, damages));
        }
    }
Esempio n. 14
0
 public virtual void Heal(GameSession session, Status status, int amount)
 {
     session.FieldManager.BroadcastPacket(SkillDamagePacket.Heal(status, amount));
     Stats[StatAttribute.Hp].AddValue(amount);
     session.Send(StatPacket.UpdateStats(this, StatAttribute.Hp));
 }