Пакет NpcInfo (Grand Crusade)

TheMads

Знаменитый
Участник
Сообщения
118
Розыгрыши
0
Репутация
5
Реакции
15
Баллы
1 270
Апаю пакетку Lindvior 530 -> GC 110, застрял на пакете NpcInfo.
С флагами разобрался во всех основных пакетах включая NpcInfo, но на удивление не нашел отправку ColRadius и ColHeight, теперь их отправляет другой пакет или колизии обрабатывает клиент? Сейчас NPC спавнятся без анимаций, имя и титул на уровне пояса.

Делал синх пакета с рабочей сборки GC включая вызовы этого пакета. В чем может быть проблема?
 
коллизии берутся из клиента - они теперь явно заданы в файле NpcGrp.dat (так же теперь оттуда можно взять данные о скорости ходьбы/бега, а так же базовые значения хп/мп для всех неписей)
проблем с этим пакетом вроде быть не должно, разве что ты может быть не учел что там два поля шлются в новом формате - модификаторы скорости движения и атаки шлются сейчас как float, а не как double
 
Последнее редактирование:
коллизии берутся из клиента - они теперь явно заданы в файле NpcGrp.dat (так же теперь оттуда можно взять данные о скорости ходьбы/бега, а так же базовые значения хп/мп для всех неписей)
проблем с этим пакетом вроде быть не должно, разве что ты может быть не учел что там два поля шлются в новом формате - модификаторы скорости движения и атаки шлются сейчас как float, а не как double
Код:
        pkt.writeD(npcObjId);
        pkt.writeC(showSpawnAnimation); // // 0=teleported 1=default 2=summoned
        pkt.writeH(37); // mask_bits_37
        pkt.writeB(_masks);
       
        // Block 1
        pkt.writeC(_initSize);
       
        if(containsMask(NpcInfoType.ATTACKABLE))
        {
            pkt.writeC(isAttackable ? 1 : 0);
        }

        if(containsMask(NpcInfoType.UNKNOWN1))
        {
            pkt.writeD(0x00); // unknown
        }

        if(containsMask(NpcInfoType.TITLE))
        {
            pkt.writeS(title);
        }
       
        // Block 2
        pkt.writeH(_blockSize);

        if(containsMask(NpcInfoType.ID))
        {
            pkt.writeD(npcId + 1000000);
        }

        if(containsMask(NpcInfoType.POSITION))
        {
            pkt.writeD(loc.x);
            pkt.writeD(loc.y);
            pkt.writeD(loc.z);
        }

        if(containsMask(NpcInfoType.HEADING))
        {
            pkt.writeD(loc.h);
        }

        if(containsMask(NpcInfoType.UNKNOWN2))
        {
            pkt.writeD(0x00); // Unknown
        }

        if(containsMask(NpcInfoType.ATK_CAST_SPEED))
        {
            pkt.writeD(pAtkSpd);
            pkt.writeD(mAtkSpd);
        }

        if(containsMask(NpcInfoType.SPEED_MULTIPLIER))
        {
            pkt.writeCutF(_runSpdMul);
            pkt.writeCutF(_atkSpdMul);
        }

        if(containsMask(NpcInfoType.EQUIPPED))
        {
            pkt.writeD(rhand);
            pkt.writeD(0x00); // Slot Chest
            pkt.writeD(lhand);
        }

        if(containsMask(NpcInfoType.ALIVE))
        {
            pkt.writeC(dead);
        }

        if(containsMask(NpcInfoType.RUNNING))
        {
            pkt.writeC(running);
        }
       
        if(containsMask(NpcInfoType.SWIM_OR_FLY))
        {
            pkt.writeC(isInsideWater ? 0x01 : isFlying ? 0x02 : 0x00);
        }

        if (containsMask(NpcInfoType.TEAM))
        {
            pkt.writeC(team.ordinal());
        }
       
        if (containsMask(NpcInfoType.ENCHANT))
        {
            pkt.writeD(enchantEffect);
        }
       
        if (containsMask(NpcInfoType.FLYING))
        {
            pkt.writeD(isFlying ? 0x01 : 00);
        }
       
        if(containsMask(NpcInfoType.CLONE))
        {
            pkt.writeD(0x00); // Player ObjectId with Decoy
        }

        if(containsMask(NpcInfoType.UNKNOWN8))
        {
            // No visual effect
            pkt.writeD(0x00); // Unknown
        }
       
        if(containsMask(NpcInfoType.DISPLAY_EFFECT))
        {
            pkt.writeD(state);
        }

        if(containsMask(NpcInfoType.TRANSFORMATION))
        {
            pkt.writeD(_transformId);
        }
       
        if(containsMask(NpcInfoType.CURRENT_HP))
        {
            pkt.writeD(_HP);
        }

        if(containsMask(NpcInfoType.CURRENT_MP))
        {
            pkt.writeD(_MP);
        }

        if(containsMask(NpcInfoType.MAX_HP))
        {
            pkt.writeD(_maxHP);
        }

        if(containsMask(NpcInfoType.MAX_MP))
        {
            pkt.writeD(_maxMP);
        }

        if(containsMask(NpcInfoType.UNKNOWN11))
        {
            pkt.writeC(0x00);    // тип клона 1 == приманка, 2 = клон у ножа
        }

        if(containsMask(NpcInfoType.COMPANION))
        {
            pkt.writeD(0x00); // CompanionObjectId
            pkt.writeD(0x00); // CompanionDistance
        }

        if(containsMask(NpcInfoType.NAME))
        {
            pkt.writeS(name);
        }

        if(containsMask(NpcInfoType.NAME_NPCSTRINGID))
        {
            pkt.writeD(nameNpcString.getId()); // NPCStringId for name
        }

        if(containsMask(NpcInfoType.TITLE_NPCSTRINGID))
        {
            pkt.writeD(titleNpcString.getId()); // NPCStringId for title
        }

        if(containsMask(NpcInfoType.PVP_FLAG))
        {
            pkt.writeC(pvp_flag); // PVP flag
        }

        if(containsMask(NpcInfoType.NAME_COLOR))
        {
            pkt.writeD(0x00); // Reputation
        }

        if(containsMask(NpcInfoType.CLAN))
        {
            pkt.writeD(clan_id);
            pkt.writeD(clan_crest_id);
            pkt.writeD(0); // Large Clan Crest Id
            pkt.writeD(ally_id);
            pkt.writeD(ally_crest_id);
        }
       
        if(containsMask(NpcInfoType.VISUAL_STATE))
        {
            pkt.writeC(_statusMask);
        }

        if(containsMask(NpcInfoType.ABNORMALS))
        {
            pkt.writeH(_abnormalEffects.length);
            for(AbnormalEffect abnormal : _abnormalEffects)
            {
                pkt.writeH(abnormal.getId());
            }
        }

Собственно сам WriteCutF:
Код:
    protected void writeCutF(double value)
    {
        getByteBuffer().putFloat((float) value);
    }

Собственно веселуха которая на выходе во вложении
 

Вложения

  • Shot00009.webp
    Shot00009.webp
    95,9 КБ · Просмотры: 251
Такое ощущение, будто они лежат мертвые, но при этом у них "лежачей" анимации нет и в итоге она вовсе не юзается. Попробуй сходить к мобам куда-то, дабы проверить это.
 
Такое ощущение, будто они лежат мертвые, но при этом у них "лежачей" анимации нет и в итоге она вовсе не юзается. Попробуй сходить к мобам куда-то, дабы проверить это.
Мобы стоят с одним heading-ом, анимацией нет, SocialAction-ы мобов бродкастятся.

При атаке корректно бегут (но не все) но постоянно улетают в потолок, возможно из-за отсутствия гео.

После атаки кстати никнейм с титулом перемещаются в корректное положение над головой
 

Вложения

  • Shot00011.webp
    Shot00011.webp
    83,9 КБ · Просмотры: 171
С NPC разобрался, в GC инверсировали отправку dead-флага
Код:
        dead = character.isAlikeDead() ? 0 : 1;

Но проблема с мобами осталась - не проигрывается randomAnimation и при атаке улетают в воздух (Подозреваю проблема в пакете Attack).
За что отвечает бродкаст рандомного передвижения у моба? MoveToLocation вроде бы верен.
 
randomAnimation делается через SocialAction - в нем насколько помню ничего не менялось
за движения да, вроде как только MTL и он тоже не менялся.
 
Фикс Attack-пакета решил проблему с исчезновением мобов. С randomAnimation проблема осталась, вроде бы за передвижение должен отвечать MoveToLocation но он верен).
randomAnimation делается через SocialAction - в нем насколько помню ничего не менялось
за движения да, вроде как только MTL и он тоже не менялся.

В SocialAction в конце добавился какой то unk, по сравнению с HF точно, в линде его не добавлял, хотя возможно его там и не было. В любом случае все работает без этого нуля.
Код:
        pkt.writeD(playerId);
        pkt.writeD(actionId);
        pkt.writeD(0);

MTL не менялся, но странно что мобам что-то мешает использовать rdnWalk.

Так же добавился новый пакет NpcInfoState, когда его нужно отправлять?
 
хм, у меня с таким названием нет пакета, может речь про NpcInfoAbnormalVisualEffect?

а какой опкод у этого NpcInfoState?
 
хм, у меня с таким названием нет пакета, может речь про NpcInfoAbnormalVisualEffect?

а какой опкод у этого NpcInfoState?

Не совсем
  • C1


Проблему с rndWalk решил, забыл что вырубил передвижение мобов при работе без гео что бы не захламлять пакетку, теперь все ок, спасибо.
 
хм, ну судя по всему его уже давно добавили - в той же Артее он уже есть
но что он делает непонятно, да и без него все работает вроде нормально у меня в версии сервера для Артеи.

шлется там какая-то битовая маска, могу предположить лишь что шлется в ней текущее состояние непися, т.е. то что в NpcInfo в переменной _statusMask
думаю его можно юзать разве что ради экономии, чтобы не слать весь NpcInfo при смене только значений для этого статуса.
 
Назад
Сверху Снизу