Example #1
0
        public static MapleAttack ParseBody(CInPacket p, Character c)
        {
            return(ParseMelee(p, c));            //TODO: Confirm below one day. Delta said melee works for this

            // Recv [CP_UserBodyAttack] [32 00] [01] [FF FF FF FF] [FF FF FF FF] [11] [FF FF FF FF] [FF FF FF FF] [CB F9 41 01] [00] [C3 C0 24 6A] [1F 46 7E D1] [9D D4 DD D5] [9D D4 DD D5] [00 00] 80 5F CF 88 C3 02 00 F9 9E D9 1F 00 00 00 00 2F 27 00 00 07 00 01 05 A9 00 8B 01 A5 00 8B 01 00 00 0B 00 00 00 B8 8D DB 27 B9 00 8B 01

            MapleAttack ret = new MapleAttack();

            p.Decode1();                                   // field key
            p.Decode4();                                   // pDrInfo.dr0
            p.Decode4();                                   // pDrInfo.dr1

            ret.nDamagePerMob = (byte)(p.Decode1() & 0xF); // nDamagePerMob | 0x10 * nRange

            p.Decode4();                                   // pDrInfo.dr2
            p.Decode4();                                   // pDrInfo.dr3

            ret.nSkillID = p.Decode4();

            ret.ValidateSkill(c);
            if (!ret.bValidAttack)
            {
                return(ret);
            }

            p.Decode1();             // cd->nCombatOrders
            p.Decode4();             // get_rand(pDrInfo.dr0, 0)
            p.Decode4();             // CCrc32::GetCrc32(pData, 4u, n, 0, 0)

            // todo lol

            return(null);
        }
Example #2
0
        public static MapleAttack ParseMagic(CInPacket p, Character c)
        {
            MapleAttack ret = new MapleAttack();

            p.Skip(8);             // -1

            var tByte1 = p.Decode1();

            ret.nDamagePerMob = (byte)(tByte1 & 0xF);
            ret.nMobCount     = (byte)((tByte1 >> 4) & 0xF);

            p.Skip(8);             //-1

            var v11 = p.Decode4(); //2017

            ret.nSkillID = v11;
            p.Skip(1);             // nCombatOrders
            p.Skip(4);             // get_rand(pDrInfo.dr0, 0);
            p.Skip(4);             // CCrc32::GetCrc32(pData, 4u, n, 0, 0);
            p.Skip(8);
            p.Skip(8);

            p.Skip(4);             //dwInit
            p.Skip(4);             //COutPacket::Encode4(&v468, dwInit);

            p.Skip(4);             //SKILLLEVELDATA Crc ?
            p.Skip(4);             //SKILLLEVELDATA Crc ?

            ret.ValidateSkill(c);

            if (!ret.bValidAttack)
            {
                return(ret);
            }

            ret.bNoItemConsume = true;

            if (v11 == 2121001 || v11 == 2221001 || v11 == 2321001 || v11 == 22121000 || v11 == 22151001)
            {
                ret.tKeyDown = p.Decode4();
            }
            else
            {
                ret.tKeyDown = -1;
            }

            ret.nOption = p.Decode1();             // p.Skip(1); // Zero !

            ret.nActionAndDir = p.Decode2();
            ret.bLeft         = (ret.nActionAndDir >> 15) & 1;
            ret.nAction       = ret.nActionAndDir & 0x7FFF; //nAttackAction
            p.Skip(4);                                      //CRC i think
            ret.nAttackActionType = p.Decode1();            //nAttackSpeed | 16 * nReduceCount
            ret.nAttackSpeed      = p.Decode1();

            ret.tAttackTime = p.Decode4();
            p.Skip(4);             //nPhase

            ret.DecodeAttackInfo(p);

            //ret.position = p.DecodePos(); //Confirm this

            return(ret);
        }
Example #3
0
        public static MapleAttack ParseShoot(CInPacket p, Character c)
        {
            MapleAttack ret = new MapleAttack();

            p.Skip(8);             // -1

            var tByte1 = p.Decode1();

            ret.nDamagePerMob = (byte)(tByte1 & 0xF);
            ret.nMobCount     = (byte)((tByte1 >> 4) & 0xF);

            //c.SendMessage("Damage per mob " + ret.nDamagePerMob);
            //c.SendMessage("Mob count " + ret.nMobCount);

            p.Skip(8);                  //-1

            ret.nSkillID = p.Decode4(); //2017

            ret.ValidateSkill(c);

            if (!ret.bValidAttack)
            {
                return(ret);
            }

            var skillTemplate = MasterManager.SkillTemplates[ret.nSkillID];

            var nCombatOrders = p.Decode1(); // nCombatOrders

            p.Skip(4);                       // get_rand(pDrInfo.dr0, 0);
            p.Skip(4);                       // CCrc32::GetCrc32(pData, 4u, n, 0, 0);
            p.Skip(8);

            ret.tKeyDown = skillTemplate?.is_keydown_skill ?? false?p.Decode4() : -1;

            ret.nOption = p.Decode1();             //COutPacket::Encode1(&v498, (bSpark << 7) | (bSpiritJavelin << 6) | 8 * bShadowPartner | 4 * bMortalBlow | 2 * bSoulArrow);

            var bSpark         = (ret.nOption & 0x80) != 0;
            var bSpiritJavelin = (ret.nOption & 0x40) != 0;
            var bSerial        = (ret.nOption & 0x20) != 0;
            var bShadowPartner = (ret.nOption & 0x8) != 0;
            var bMortalBlow    = (ret.nOption & 0x4) != 0;
            var bSoulArrow     = (ret.nOption & 0x2) != 0;

            ret.bNextShootExJablin = p.Decode1() > 0;             //v339->m_bNextShootExJablin && CUserLocal::CheckApplyExJablin(v339, pSkill, nAttackAction);

            ret.nActionAndDir = p.Decode2();
            ret.bLeft         = (ret.nActionAndDir >> 15) & 1;
            ret.nAction       = ret.nActionAndDir & 0x7FFF; //nAttackAction
            p.Skip(4);                                      //CRC i think
            ret.nAttackActionType = p.Decode1();            //nAttackSpeed | 16 * nReduceCount
            ret.nAttackSpeed      = p.Decode1();

            ret.tAttackTime = p.Decode4();
            p.Skip(4);             //nPhase

            ret.nBulletItemPos     = p.Decode2();
            ret.nBulletCashItemPos = p.Decode2();
            var nShootRange0a = p.Decode1();             // nSLV (BMS)

            ret.bNoItemConsume = skillTemplate?.is_shoot_skill_not_consuming_bullet ?? false;

            if (!ret.bNoItemConsume)
            {
                if (JobLogic.is_mechanic_job(c.Stats.nJob))
                {
                    ret.bNoItemConsume = true;
                }
                else if (bSoulArrow)
                {
                    ret.bNoItemConsume = c.Buffs[(int)Skills.HUNTER_SOUL_ARROW_BOW] != null ||
                                         c.Buffs[(int)Skills.CROSSBOWMAN_SOUL_ARROW_CROSSBOW] != null ||
                                         c.Buffs[(int)Skills.WINDBREAKER_SOUL_ARROW_BOW] != null ||
                                         c.Buffs[(int)Skills.WILDHUNTER_SOUL_ARROW_CROSSBOW] != null;
                }
                else if (bSpiritJavelin)
                {
                    if (ret.bNextShootExJablin)
                    {
                        ret.bNextShootExJablin = false;
                    }
                    else
                    {
                        ret.nSpiritJavelinItemID = p.Decode4();

                        var nBulletType = (ret.nSpiritJavelinItemID % 10000) + 1;

                        c.Buffs.TryGetValue((int)Skills.NIGHTLORD_SPIRIT_JAVELIN, out AbstractBuff secondaryStat_nSpiritJavelin);

                        if (c.InventoryConsume.Get(ret.nBulletItemPos)?.nItemID != ret.nSpiritJavelinItemID)
                        {
                            c.Buffs.Remove((int)Skills.NIGHTLORD_SPIRIT_JAVELIN);                             // they have to use the same item as they
                        }
                        else
                        {
                            if (secondaryStat_nSpiritJavelin != null && nBulletType != secondaryStat_nSpiritJavelin.Stat[SecondaryStatFlag.SpiritJavelin].nValue)
                            {
                                ret.bValidAttack = false;                                 // PE
                                return(ret);
                            }

                            ret.bNoItemConsume = true;
                        }
                    }
                }
                else if (ret.bNextShootExJablin)
                {
                    ret.bNoItemConsume = true;
                }
            }

            ret.DecodeAttackInfo(p);

            p.Skip(4);             // char pos

            if (JobLogic.IsWildhunterJob(c.Stats.nJob))
            {
                var m_ptBodyRelMove = p.Decode2();                 // unsure what this is used for
            }

            p.Skip(4);             // another pos.. unsure for what

            if (ret.nSkillID == (int)Skills.STRIKER_SPARK)
            {
                ret.tReserveSpark = p.Decode4();
            }

            return(ret);
        }
Example #4
0
        public static MapleAttack ParseMelee(CInPacket p, Character c)
        {
            MapleAttack ret = new MapleAttack();

            var nFirstByte = p.Decode1();

            if (nFirstByte == 1 || nFirstByte == 2)             // CUserLocal::TryDoingNormalAttack
            {
                p.Skip(8);
            }
            else             // CUserLocal::TryDoingMeleeAttack
            {
                p.Skip(7);
            }

            var tByte1 = p.Decode1();

            ret.nDamagePerMob = (byte)(tByte1 & 0xF);
            ret.nMobCount     = (byte)((tByte1 >> 4) & 0xF);

            p.Skip(8);             //-1

            var v11 = p.Decode4();

            ret.nSkillID = v11;

            ret.ValidateSkill(c);
            if (!ret.bValidAttack)
            {
                return(ret);
            }

            ret.bNoItemConsume = true;

            var template = MasterManager.SkillTemplates[ret.nSkillID];

            p.Skip(1);
            p.Skip(8);             // 0.74
            p.Skip(8);             // 0.88

            ret.tKeyDown = template?.is_keydown_skill ?? false?p.Decode4() : -1;

            var bSomeFlag = p.Decode1();             // bFinalAfterSlashBlast | 8 * bShadowPartner | 16 * v685 | 32 * (nSerialAttackSkillID != 0) | ((_BYTE)v694 << 7));

            var bSpark                = ((bSomeFlag >> 7) & 1) > 0;
            var bSerialAttackSkill    = ((bSomeFlag >> 5) & 1) > 0;
            var bShadowPartner        = ((bSomeFlag >> 3) & 1) > 0;
            var bFinalAfterSlashBlast = (bSomeFlag & 1) > 0;

            ret.nActionAndDir = p.Decode2();
            ret.bLeft         = (ret.nActionAndDir >> 15) & 1;
            ret.nAction       = ret.nActionAndDir & 0x7FFF;
            p.Skip(4);             //CRC i think
            ret.nAttackActionType = p.Decode1();
            ret.nAttackSpeed      = p.Decode1();

            ret.tAttackTime = p.Decode4();
            p.Skip(4);             //bmage?

            //More decode for bullets here

            //if (ret.skill == 4211006)
            //{ // Meso Explosion
            //    return parseMesoExplosion(lea, ret);
            //}

            ret.DecodeAttackInfo(p);

            p.Skip(4);             // position

            if (ret.nSkillID == (int)Skills.NIGHTWALKER_POISON_BOMB)
            {
                ret.nGrenadePtX = p.Decode2();
                ret.nGrenadePtY = p.Decode2();
            }

            return(ret);
        }