Monk: Triple Attack Bug

07/01/2013 07:40 snappy#1
I'm having issues with this Monk skill, when it attacks a Monster, whatever the drop is.. It gets it x2 or 4. And when you Kill another player and triple attack goes off. It show's you killed the player 4 times..

Any ideas? Thanks


Here is the Code:
Code:
 #region TripleAttack
                                case 10490:
                                    {
                                        if (CanUseSpell(spell, attacker.Owner))
                                        {
                                            ushort Xx, Yx;
                                            if (attacked != null)
                                            {
                                                Xx = attacked.X;
                                                Yx = attacked.Y;
                                            }
                                            else
                                            {
                                                Xx = attackedsob.X;
                                                Yx = attackedsob.Y;
                                            }
                                            if (ServerBase.Kernel.GetDistance(attacker.X, attacker.Y, X, Y) <= attacker.AttackRange + 1)
                                            {
                                                if (attackedsob != null)
                                                    if (attacker.ContainsFlag(Network.GamePackets.Update.Flags.Fly))
                                                        return;

                                                PrepareSpell(spell, attacker.Owner);

                                                SpellUse suse = new SpellUse(true);
                                                suse.Attacker = attacker.UID;
                                                suse.SpellID = spell.ID;
                                                suse.SpellLevel = spell.Level;
                                                suse.X = X;
                                                suse.Y = Y;

                                                bool send = false;

                                                if (attackedsob != null)
                                                {
                                                    if (CanAttack(attacker, attackedsob, spell))
                                                    {
                                                        PrepareSpell(spell, attacker.Owner);
                                                        suse.MakeConst();
                                                        for (uint c = 0; c < 4; c++)
                                                        {
                                                            uint damage = Game.Attacking.Calculate.Melee(attacker, attackedsob);
                                                            if (damage > attackedsob.Hitpoints)
                                                                damage = attackedsob.Hitpoints;

                                                            ReceiveAttack(attacker, attackedsob, attack, damage, spell);

                                                            suse.Targets.Add(attackedsob.UID + c, damage);
                                                            send = true;
                                                        }
                                                    }
                                                }
                                                else
                                                {
                                                    if (CanAttack(attacker, attacked, spell, attack.AttackType == Attack.Melee))
                                                    {
                                                        PrepareSpell(spell, attacker.Owner);
                                                        suse.MakeConst();
                                                        for (uint c = 0; c < 4; c++)
                                                        {
                                                            uint damage = Game.Attacking.Calculate.Melee(attacker, attacked, spell);
                                                            if (damage > attacked.Hitpoints)
                                                                damage = attacked.Hitpoints;
                                                            ReceiveAttack(attacker, attacked, attack, damage, spell);

                                                            suse.Targets.Add(attacked.UID + c, damage);
                                                            send = true;
                                                        }
                                                    }
                                                }
                                                if (send)
                                                    attacker.Owner.SendScreen(suse, true);
                                            }
                                            else
                                            {
                                                attacker.AttackPacket = null;
                                            }
                                        }
                                        break;
                                    }
                            
                                #endregion
07/01/2013 08:14 pro4never#2
You're not checking if they are dead when dealing damage. As such the death code runs multiple times.

Number of ways to handle this with the simplest being write the source correctly the first time but if you want a bandaid style fix then just go inside the ReceiveAttack handler and check if they are still alive. If not then you can just return as the display of the spell is already handled outside the method.
07/01/2013 08:17 Santa#3
Quote:
Originally Posted by snappy View Post
I'm having issues with this Monk skill, when it attacks a Monster, whatever the drop is.. It gets it x2 or 4. And when you Kill another player and triple attack goes off. It show's you killed the player 4 times..

Any ideas? Thanks
Code:
if (damage > attackedsob.Hitpoints)
           damage = attackedsob.Hitpoints;
If that is true, there is no sense in looping it back 3 more times...thats where it seems your problem is. Just don't repeat the loop and you should be good.

Also, please correct me if I am wrong but for skills such as triple kick you only need to send one packet and the client handles the "triple" kick. If not, change your 4 to a 3 so it only sends it 3 times.
07/01/2013 09:14 snappy#4
Where in recievedattack would this go? I tried this code... It seemed to have stopped the multiple deaths and multiple drops. But now the attack only goes off on Bosses. Not sure what i'm doing wrong here. Thanks

Code:
                                               if (attackedsob != null)
                                                {
                                                    if (CanAttack(attacker, attackedsob, spell))
                                                    {
                                                        PrepareSpell(spell, attacker.Owner);
                                                        suse.MakeConst();
                                                        for (uint c = 0; c < 4; c++)
                                                        {
                                                            uint damage = Game.Attacking.Calculate.Melee(attacker, attackedsob);
                                                            if (damage > attackedsob.Hitpoints)
                                                                damage = attackedsob.Hitpoints;
                                                            
                                                            ReceiveAttack(attacker, attackedsob, attack, damage, spell);

                                                            suse.Targets.Add(attackedsob.UID + c, damage);
                                                            send = true;
                                                        }
                                                    }
                                                }
                                                else
                                                {
                                                    if (CanAttack(attacker, attacked, spell, attack.AttackType == Attack.Melee))
                                                    {
                                                        PrepareSpell(spell, attacker.Owner);
                                                        suse.MakeConst();
                                                        for (uint c = 0; c < 4; c++)
                                                        {
[B]                                                            //J_newcode
                                                            if (attacked.Dead)
                                                            {
                                                                return;
                                                            }
                                                            //J_newcode ^^^[/B]
                                                            uint damage = Game.Attacking.Calculate.Melee(attacker, attacked, spell);
                                                            if (damage > attacked.Hitpoints)
                                                                damage = attacked.Hitpoints;
                                                            ReceiveAttack(attacker, attacked, attack, damage, spell);

                                                            suse.Targets.Add(attacked.UID + c, damage);
                                                            send = true;
                                                        }
                                                    }
                                                }
                                                if (send)
                                                    attacker.Owner.SendScreen(suse, true);
                                            }
                                            else
                                            {
                                                attacker.AttackPacket = null;
                                            }
                                        }
                                        break;
                                    }
07/01/2013 18:34 pro4never#5
Quote:
Originally Posted by StarBucks View Post
Code:
if (damage > attackedsob.Hitpoints)
           damage = attackedsob.Hitpoints;
If that is true, there is no sense in looping it back 3 more times...thats where it seems your problem is. Just don't repeat the loop and you should be good.

Also, please correct me if I am wrong but for skills such as triple kick you only need to send one packet and the client handles the "triple" kick. If not, change your 4 to a 3 so it only sends it 3 times.
No. The packet needs to contain the target + damage for the # of times that the attack hits (because ideally each attack is a different damages amount)

He needs to go into the handle damage method and check that the targets health is > 0
07/01/2013 21:47 Santa#6
Quote:
Originally Posted by pro4never View Post
No. The packet needs to contain the target + damage for the # of times that the attack hits (because ideally each attack is a different damages amount)

He needs to go into the handle damage method and check that the targets health is > 0
Huh. Interesting. I don't know what skill I was thinking of then.
07/01/2013 22:02 pro4never#7
Quote:
Originally Posted by StarBucks View Post
Huh. Interesting. I don't know what skill I was thinking of then.
whirlwind I believe has a simple # of attacks but I could be wrong. Been aggeessssss since I coded either.