Илюзорные бафы

  • Автор темы Автор темы Gigi
  • Дата начала Дата начала

Gigi

Прославленный
Проверенный
Легенда Истоков
Старожил I степени
Сообщения
473
Розыгрыши
0
Решения
3
Репутация
219
Реакции
135
Баллы
1 438
Хроники
  1. Master Class
Исходники
Присутствуют
Сборка
Samurai 542 (Main)
Ребята кто может подсказать как это тут работает вообще, не в интерфейсе окна нашёл ответ не пакетах.
Как воткнуть бафф в ячейку инвентаря, это же не предмет чтоб его одеть (как на скрине к примеру шлем), для бафов в датнике body_part=0

Buff.webp
Всё покупается, удаляется а вот модифицировать не получается, так как не могу воткнуть его в панель
 
Решение
Да читал и представ очень вниматель :), я имел ввиду что из за двух инстансов 8 скилов и 12 удалённых итемов не собираюсь апнуть пакетку, если когдато введут новую расу или внедрят что-то стоющее может тогда апну пакетку

А что у Мобиуса брать ЭТО!
Java:
/**
 * @author CostyKiller
 */
public class RequestExVirtualItemSystem extends ClientPacket
{
    private int _type;
    private int _selectIndexMain;
    private int _selectIndexSub;
    private long _selectSlot;
    // private int _indexMain;
    // private int _indexSub;
    // private long _slot;
    // private int _costVISPoint;
    // private int _itemClass;
    // private int _enchant;
    private final List<VirtualItemHolder> _updateVisItemInfo = new LinkedList<>()...
Ребята кто может подсказать как это тут работает вообще, не в интерфейсе окна нашёл ответ не пакетах.
Как воткнуть бафф в ячейку инвентаря, это же не предмет чтоб его одеть (как на скрине к примеру шлем), для бафов в датнике body_part=0

Всё покупается, удаляется а вот модифицировать не получается, так как не могу воткнуть его в панель
У меня так

Код:
    private static final Set<Integer> VIRTUAL_SKILLS = Set.of(
            29630, 29631, 29632, 29633, 29673, 29674, 29675, 29676, 29677, 29678, 29679, 29680,
            29681, 29682, 29683, 29684, 29685, 29686
    )



private void addItemOrSkill(Player player, VirtualItemHolder template, int paperdollSlot) {
        if (player == null) {
            return;
        }

        final int itemId = template.getItemId();
        final int enchant = template.getEnchant();

        if (VIRTUAL_SKILLS.contains(itemId)) {
            final Skill skill = SkillData.getInstance().getSkill(itemId, enchant);
            if (skill != null) {
                player.getEffectList().stopSkillEffects(SkillFinishType.REMOVED, skill);
                skill.applyEffects(player, player);
                player.sendSkillList();
            }
        } else {
            final InventoryUpdate iu = new InventoryUpdate();

            if (paperdollSlot >= 0) {
                Item existingItem = player.getInventory().getPaperdollItem(paperdollSlot);
                if (existingItem != null && !existingItem.isVirtual()) {
                    player.getInventory().unEquipItemInSlot(paperdollSlot);
                    iu.addModifiedItem(existingItem);
                }
            }

            Item visItem = new Item(itemId);
            visItem.setCount(1);
            visItem.setVirtual(true);
            visItem.setOwnerId(player.getObjectId());
            visItem.setEnchantLevel(enchant);

            visItem = player.getInventory().addItem("VirtualItem", visItem, player, null);

            if (paperdollSlot >= 0) {
                player.getInventory().equipItemInSlot(visItem, paperdollSlot);
            } else {
                player.getInventory().equipItem(visItem);
            }

            iu.addModifiedItem(visItem);
            player.sendPacket(iu);
            player.broadcastUserInfo();
        }
    }

    private void removeItemOrSkill(Player player, VirtualItemHolder holder, int paperdollSlot) {
        if (player == null) {
            return;
        }

        final int itemId = holder.getItemId();
        final int enchant = holder.getEnchant();

        if (VIRTUAL_SKILLS.contains(itemId)) {
            final Skill skill = SkillData.getInstance().getSkill(itemId, enchant);
            if (skill != null) {
                player.removeSkill(skill);
                player.getEffectList().stopSkillEffects(SkillFinishType.REMOVED, skill);
                player.sendSkillList();
            }
        } else {
            Item itemToDestroy = null;

            if (paperdollSlot >= 0) {
                Item paperdollItem = player.getInventory().getPaperdollItem(paperdollSlot);
                if (paperdollItem != null && paperdollItem.isVirtual() && paperdollItem.getId() == itemId && paperdollItem.getEnchantLevel() == enchant) {
                    itemToDestroy = paperdollItem;
                }
            }

            if (itemToDestroy == null) {
                for (Item item : player.getInventory().getItems()) {
                    if (item.isVirtual() && item.getId() == itemId && item.getEnchantLevel() == enchant) {
                        itemToDestroy = item;
                        break;
                    }
                }
            }

            if (itemToDestroy != null) {
                player.getInventory().destroyItem("VirtualItemUpgrade", itemToDestroy, player, null);

                final InventoryUpdate iu = new InventoryUpdate();
                iu.addRemovedItem(itemToDestroy);
                player.sendInventoryUpdate(iu);
            }
        }
    }
 
У меня так

Код:
    private static final Set<Integer> VIRTUAL_SKILLS = Set.of(
            29630, 29631, 29632, 29633, 29673, 29674, 29675, 29676, 29677, 29678, 29679, 29680,
            29681, 29682, 29683, 29684, 29685, 29686
    )



private void addItemOrSkill(Player player, VirtualItemHolder template, int paperdollSlot) {
        if (player == null) {
            return;
        }

        final int itemId = template.getItemId();
        final int enchant = template.getEnchant();

        if (VIRTUAL_SKILLS.contains(itemId)) {
            final Skill skill = SkillData.getInstance().getSkill(itemId, enchant);
            if (skill != null) {
                player.getEffectList().stopSkillEffects(SkillFinishType.REMOVED, skill);
                skill.applyEffects(player, player);
                player.sendSkillList();
            }
        } else {
            final InventoryUpdate iu = new InventoryUpdate();

            if (paperdollSlot >= 0) {
                Item existingItem = player.getInventory().getPaperdollItem(paperdollSlot);
                if (existingItem != null && !existingItem.isVirtual()) {
                    player.getInventory().unEquipItemInSlot(paperdollSlot);
                    iu.addModifiedItem(existingItem);
                }
            }

            Item visItem = new Item(itemId);
            visItem.setCount(1);
            visItem.setVirtual(true);
            visItem.setOwnerId(player.getObjectId());
            visItem.setEnchantLevel(enchant);

            visItem = player.getInventory().addItem("VirtualItem", visItem, player, null);

            if (paperdollSlot >= 0) {
                player.getInventory().equipItemInSlot(visItem, paperdollSlot);
            } else {
                player.getInventory().equipItem(visItem);
            }

            iu.addModifiedItem(visItem);
            player.sendPacket(iu);
            player.broadcastUserInfo();
        }
    }

    private void removeItemOrSkill(Player player, VirtualItemHolder holder, int paperdollSlot) {
        if (player == null) {
            return;
        }

        final int itemId = holder.getItemId();
        final int enchant = holder.getEnchant();

        if (VIRTUAL_SKILLS.contains(itemId)) {
            final Skill skill = SkillData.getInstance().getSkill(itemId, enchant);
            if (skill != null) {
                player.removeSkill(skill);
                player.getEffectList().stopSkillEffects(SkillFinishType.REMOVED, skill);
                player.sendSkillList();
            }
        } else {
            Item itemToDestroy = null;

            if (paperdollSlot >= 0) {
                Item paperdollItem = player.getInventory().getPaperdollItem(paperdollSlot);
                if (paperdollItem != null && paperdollItem.isVirtual() && paperdollItem.getId() == itemId && paperdollItem.getEnchantLevel() == enchant) {
                    itemToDestroy = paperdollItem;
                }
            }

            if (itemToDestroy == null) {
                for (Item item : player.getInventory().getItems()) {
                    if (item.isVirtual() && item.getId() == itemId && item.getEnchantLevel() == enchant) {
                        itemToDestroy = item;
                        break;
                    }
                }
            }

            if (itemToDestroy != null) {
                player.getInventory().destroyItem("VirtualItemUpgrade", itemToDestroy, player, null);

                final InventoryUpdate iu = new InventoryUpdate();
                iu.addRemovedItem(itemToDestroy);
                player.sendInventoryUpdate(iu);
            }
        }
    }
Ну я примерно использую такую же логику, но скилы вы тоже накладываете просто так
если отбросить все бла-бла и проверки, идея у вас тоже такая

Java:
if (VIRTUAL_SKILLS.contains(itemId)) {
    // Если это иллюзорный скилл, они просто накладывают баф:
    skill.applyEffects(player, player);
} else {
    // А если это предмет, они создают виртуальный предмет и экипируют его:
    Item visItem = new Item(itemId);
    player.getInventory().equipItemInSlot(visItem, paperdollSlot);
}

Если разобрать в интерфейсе VirtualItemWnd то там для бафов отведени маски (1073741824, 2147483648 и 4294967296) это маски Драгоценных камней, броши.
Если мы заставим сервер создать предмет-баф и надеть его в этот слот (чтобы он появился в UI), то сервер автоматически снимет с персонажа реальные камни из брошки, в один слот нельзя надеть два предмета
 
У тебя в пакете же передается
int indexMain, int indexSub, int slotIndex

По этим данным храни скилл в xml и цепляй при equip пакете
1783932359751.webp
 
У тебя в пакете же передается
int indexMain, int indexSub, int slotIndex

По этим данным храни скилл в xml и цепляй при equip пакете
Посмотреть вложение 96558
ну тут для меня совсем не понятно, описания иллюзорного скила у меня такое

XML:
<virtualItem indexMain="1"> <!-- XP - Illusory Equipment -->
        <virtualItemStat slot="0" indexSub="1" itemId="29630" enchant="1" costVISPoint="20" /> <!-- Level 1: Acquired XP/ SP +1% -->
        <virtualItemStat slot="0" indexSub="2" itemId="29630" enchant="2" costVISPoint="20" /> <!-- Level 2: Acquired XP/ SP +2% -->
        <virtualItemStat slot="0" indexSub="3" itemId="29630" enchant="3" costVISPoint="40" /> <!-- Level 3: Acquired XP/ SP +3% -->
        <virtualItemStat slot="0" indexSub="4" itemId="29630" enchant="4" costVISPoint="40" /> <!-- Level 4: Acquired XP/ SP +4% -->
        <virtualItemStat slot="0" indexSub="5" itemId="29630" enchant="5" costVISPoint="60" /> <!-- Level 5: Acquired XP/ SP +5% -->
        <virtualItemStat slot="0" indexSub="6" itemId="29630" enchant="6" costVISPoint="60" /> <!-- Level 6: Acquired XP/ SP +6% -->
        <virtualItemStat slot="0" indexSub="7" itemId="29630" enchant="7" costVISPoint="80" /> <!-- Level 7: Acquired XP/ SP +7% -->
        <virtualItemStat slot="0" indexSub="8" itemId="29630" enchant="8" costVISPoint="80" /> <!-- Level 8: Acquired XP/ SP +8% -->
        <virtualItemStat slot="0" indexSub="9" itemId="29630" enchant="9" costVISPoint="100" /> <!-- Level 9: Acquired XP/ SP +9% -->
        <virtualItemStat slot="0" indexSub="10" itemId="29630" enchant="10" costVISPoint="100" /> <!-- Level 10: Acquired XP/ SP +10% -->
    </virtualItem>

itemId="29630" это скилл который вешается на чаре при покупке (с этим всё ок)
но так как это не итем и его невозможно одеть на чара, в slot="0" немогу нечего передать

если можно чуть подробнее как у вас это происходит
спасибо
 
Код:
    public int equip(int indexMain, int indexSub, int slotIndex) {
        VirtualItemHolder holder = VirtualItemHolder.getInstance();
        if (!holder.isEnabled())
            return RESULT_FAIL;

        VirtualItem virtualItem = holder.getVirtualItem(indexMain);
        if (virtualItem == null)
            return RESULT_FAIL;

        VirtualItemSubInfo subInfo = virtualItem.getSubInfo(indexSub);
        if (subInfo == null)
            return RESULT_FAIL;

...
Код:
if (subInfo.isSkill()) {
 if (!grantSkill(slot))
return RESULT_FAIL;
} else {
 if(!equipCreatedItem(slot, createdItem)) {
return RESULT_FAIL;
    }
}


У меня на моменте парсера определят скил это или итем, исходя из этого разные логики проходит при equip
1783938604467.webp
Ранее скрин был со скиллом
 
1783939873733.webp
тут предельно всё ясно, речь о поясе 35564 и передаётся в слот по маске 268435456 что гарантирует его отоброжение в ячейке пояса

1783940193963.webp
тут не понятно, во первых индекса 57 у меня нет, тем более скила 48057, ну не суть, что у вас происходит когда передаёте в маске 0 в slot_byte_type, что и как сервер воспринимает 0, в какой именно слот он должен иконку отрисовать?
Сообщение объединено:
Код:
    public int equip(int indexMain, int indexSub, int slotIndex) {
        VirtualItemHolder holder = VirtualItemHolder.getInstance();
        if (!holder.isEnabled())
            return RESULT_FAIL;

        VirtualItem virtualItem = holder.getVirtualItem(indexMain);
        if (virtualItem == null)
            return RESULT_FAIL;

        VirtualItemSubInfo subInfo = virtualItem.getSubInfo(indexSub);
        if (subInfo == null)
            return RESULT_FAIL;

...
Код:
if (subInfo.isSkill()) {
 if (!grantSkill(slot))
return RESULT_FAIL;
} else {
 if(!equipCreatedItem(slot, createdItem)) {
return RESULT_FAIL;
    }
}


У меня на моменте парсера определят скил это или итем, исходя из этого разные логики проходит при equip
Посмотреть вложение 96562
Ранее скрин был со скиллом
а что у вас под grantSkill(slot) подразумевается?
 
Последнее редактирование:
Посмотреть вложение 96563
тут предельно всё ясно, речь о поясе 35564 и передаётся в слот по маске 268435456 что гарантирует его отоброжение в ячейке пояса

Посмотреть вложение 96564
тут не понятно, во первых индекса 57 у меня нет, тем более скила 48057, ну не суть, что у вас происходит когда передаёте в маске 0 в slot_byte_type, что и как сервер воспринимает 0, в какой именно слот он должен иконку отрисовать?
Сообщение объединено:
а что у вас под grantSkill(slot) подразумевается?
Ты не заморачивайся, завтра обнова - в ней же, очередной раз систему изменяют, будешь новую реализацию делать.
Инфа идентично в интерфейсе.
А почка что, почитай:
 
Последнее редактирование:
Ты не заморачивайся, завтра обнова - в ней же, очередной раз систему изменяют, будешь новую реализацию делать.
Инфа идентично в интерфейсе.
А почка что, ознакомься:
Да читал я эти гранд-фиксы, но пока не собираюсь апнутся, по крайней мере до новой расы, мне бы самурая довести до ума. Так что эта тема для меня актуально. да там всего нечего осталось доделать, разобраться со скилами и сделать синхронизацию левой и правой панели УИ илюзорки. даже токены купил для ИИ но толку от него ноль, я ему про Ивана он про болвана :)
 
Да читал я эти гранд-фиксы, но пока не собираюсь апнутся, по крайней мере до новой расы, мне бы самурая довести до ума. Так что эта тема для меня актуально. да там всего нечего осталось доделать, разобраться со скилами и сделать синхронизацию левой и правой панели УИ илюзорки. даже токены купил для ИИ но толку от него ноль, я ему про Ивана он про болвана :)
Какой новой Расы? - ты видимо не на той стенке читал обнову.
Ну видимо, Чатик не получил весь контекст для понимания реализации.
Предоставь ему всю инфу из интерфейса + код с сервера.
+ Напиши описание словами - что к чему нужно анализировать/реализовать/понять (если сам понимаешь), и получишь +/- направление.

По сути тебе выше намекают таки верно, но ты почему то думаешь не в ту сторону (тебе должно быть похуй на то как оно реализовано у Мобиуса, делай свое).
И все хз, как ты датку открыл, верно или нет - потому что инфа одна для все кто это делает (но у тебя почему то нету того и сего), я про ответы выше, по инфе что показали.
 
Какой новой Расы? - ты видимо не на той стенке читал обнову.
Ну видимо, Чатик не получил весь контекст для понимания реализации.
Предоставь ему всю инфу из интерфейса + код с сервера.
+ Напиши описание словами - что к чему нужно анализировать/реализовать/понять (если сам понимаешь), и получишь +/- направление.

По сути тебе выше намекают таки верно, но ты почему то думаешь не в ту сторону (тебе должно быть похуй на то как оно реализовано у Мобиуса, делай свое).
И все хз, как ты датку открыл, верно или нет - потому что инфа одна для все кто это делает (но у тебя почему то нету того и сего), я про ответы выше, по инфе что показали.
Да читал и представ очень вниматель :), я имел ввиду что из за двух инстансов 8 скилов и 12 удалённых итемов не собираюсь апнуть пакетку, если когдато введут новую расу или внедрят что-то стоющее может тогда апну пакетку

А что у Мобиуса брать ЭТО!
Java:
/**
 * @author CostyKiller
 */
public class RequestExVirtualItemSystem extends ClientPacket
{
    private int _type;
    private int _selectIndexMain;
    private int _selectIndexSub;
    private long _selectSlot;
    // private int _indexMain;
    // private int _indexSub;
    // private long _slot;
    // private int _costVISPoint;
    // private int _itemClass;
    // private int _enchant;
    private final List<VirtualItemHolder> _updateVisItemInfo = new LinkedList<>();
   
    @Override
    protected void readImpl()
    {
        _type = readByte();
        _selectIndexMain = readInt();
        _selectIndexSub = readInt();
        _selectSlot = readInt();
        readShort(); // Always 26
        // _indexMain = readInt();
        // _indexSub = readInt();
        // _slot = readInt();
        // _costVISPoint = readInt();
        // _itemClass = readInt();
        // _enchant = readInt();
       
        // final VirtualItemHolder virtualItem = new VirtualItemHolder(_nIndexMain, _nSlot, _nIndexSub, _nItemClass, _nEnchant, _nCostVISPoint);
        // _updateVisItemInfo.add(virtualItem);
    }
   
    @Override
    protected void runImpl()
    {
        final Player player = getPlayer();
        if (player == null)
        {
            return;
        }
       
        if (player.isInStoreMode() || player.isCrafting() || player.isProcessingRequest() || player.isProcessingTransaction())
        {
            player.sendPacket(SystemMessageId.YOU_CANNOT_USE_THIS_SYSTEM_DURING_TRADING_PRIVATE_STORE_AND_WORKSHOP_SETUP);
            return;
        }
       
        if (player.isFishing())
        {
            // You can't mount, dismount, break and drop items while fishing.
            player.sendPacket(SystemMessageId.YOU_CANNOT_DO_THAT_WHILE_FISHING_2);
            return;
        }
       
        if (player.isFlying())
        {
            return;
        }
       
        player.sendPacket(new ExVirtualItemSystem(player, _type, _selectIndexMain, _selectIndexSub, _selectSlot, _updateVisItemInfo));
    }
}

да там коментов больше чем самого кода.

А вопрос мой совсем простой, для тех кто в теме конечно а не держит неиронку в рабство

Код:
virtualitem_begin    index=1    body_part=0    itemlist={{1;29630;1;20};{2;29630;2;20};{3;29630;3;40};{4;29630;4;40};{5;29630;5;60};{6;29630;6;60};{7;29630;7;80};{8;29630;8;80};{9;29630;9;100};{10;29630;10;100}}    virtualitem_end

Что и как передать клиенту index=1 body_part=0. Если с итемами всё ясно, так как они тупо надеваются и всё, для них как бы отдельные слоте, то в эти 3 слота (что на скрине выше) как воткнуть скилы. а мне отвечаю с перечнем скилов и проверкой скилл это или итем
 
Последнее редактирование:
Да читал и представ очень вниматель :), я имел ввиду что из за двух инстансов 8 скилов и 12 удалённых итемов не собираюсь апнуть пакетку, если когдато введут новую расу или внедрят что-то стоющее может тогда апну пакетку

А что у Мобиуса брать ЭТО!
Java:
/**
 * @author CostyKiller
 */
public class RequestExVirtualItemSystem extends ClientPacket
{
    private int _type;
    private int _selectIndexMain;
    private int _selectIndexSub;
    private long _selectSlot;
    // private int _indexMain;
    // private int _indexSub;
    // private long _slot;
    // private int _costVISPoint;
    // private int _itemClass;
    // private int _enchant;
    private final List<VirtualItemHolder> _updateVisItemInfo = new LinkedList<>();
  
    @Override
    protected void readImpl()
    {
        _type = readByte();
        _selectIndexMain = readInt();
        _selectIndexSub = readInt();
        _selectSlot = readInt();
        readShort(); // Always 26
        // _indexMain = readInt();
        // _indexSub = readInt();
        // _slot = readInt();
        // _costVISPoint = readInt();
        // _itemClass = readInt();
        // _enchant = readInt();
      
        // final VirtualItemHolder virtualItem = new VirtualItemHolder(_nIndexMain, _nSlot, _nIndexSub, _nItemClass, _nEnchant, _nCostVISPoint);
        // _updateVisItemInfo.add(virtualItem);
    }
  
    @Override
    protected void runImpl()
    {
        final Player player = getPlayer();
        if (player == null)
        {
            return;
        }
      
        if (player.isInStoreMode() || player.isCrafting() || player.isProcessingRequest() || player.isProcessingTransaction())
        {
            player.sendPacket(SystemMessageId.YOU_CANNOT_USE_THIS_SYSTEM_DURING_TRADING_PRIVATE_STORE_AND_WORKSHOP_SETUP);
            return;
        }
      
        if (player.isFishing())
        {
            // You can't mount, dismount, break and drop items while fishing.
            player.sendPacket(SystemMessageId.YOU_CANNOT_DO_THAT_WHILE_FISHING_2);
            return;
        }
      
        if (player.isFlying())
        {
            return;
        }
      
        player.sendPacket(new ExVirtualItemSystem(player, _type, _selectIndexMain, _selectIndexSub, _selectSlot, _updateVisItemInfo));
    }
}

да там коментов больше чем самого кода.

А вопрос мой совсем простой, для тех кто в теме конечно а не держит неиронку в рабство

Код:
virtualitem_begin    index=1    body_part=0    itemlist={{1;29630;1;20};{2;29630;2;20};{3;29630;3;40};{4;29630;4;40};{5;29630;5;60};{6;29630;6;60};{7;29630;7;80};{8;29630;8;80};{9;29630;9;100};{10;29630;10;100}}    virtualitem_end

Что и как передать клиенту index=1 body_part=0. Если с итемами всё ясно, так как они тупо надеваются и всё, для них как бы отдельные слоте, то в эти 3 слота (что на скрине выше) как воткнуть скилы. а мне отвечаю с перечнем скилов и проверкой скилл это или итем
В чем твоя проблема? Главный вопрос как в клиент передать "надетый" скилл? точно также как и итем, в пакете есть четкая структура, которая по сути в dat файле прослеживается. Оттдебаж пакет от клиента в сервер, оно тебе покажет какой слот ты пытаешься "надеть" в поле
nSelectSlot
Сообщение объединено:
3 скилла "надетых"

Код:
==================== SExVirtualItemSystem ====================
  cType             = 2
  cResult           = 1
  nEndTime          = 1785531599
  nTotalGetVISPoint = 530
  nTotalUsedVISPoint= 120
  nVISMaxPoint      = 5000
  nSelectIndexMain  = 4
  nSelectIndexSub   = 1
  nSelectSlot       = 3
  nSize (slots)     = 3
  --- slot[0] ---
      nIndexMain     = 1
      nIndexSub      = 1
      nSlot          = 2
      nCostVISPoint  = 20
      nItemClass     = 29630
      nEnchant       = 1

  --- slot[1] ---
      nIndexMain     = 2
      nIndexSub      = 1
      nSlot          = 1
      nCostVISPoint  = 20
      nItemClass     = 29631
      nEnchant       = 1

  --- slot[2] ---
      nIndexMain     = 4
      nIndexSub      = 1
      nSlot          = 3
      nCostVISPoint  = 80
      nItemClass     = 29633
      nEnchant       = 1

==============================================================
1784105194515.webp
Сообщение объединено:
1784105252478.webp
 
Последнее редактирование:
Решение
Ну да, абсолютно также передаю, ну чуть название другие. Структура таже. Остался один вариант мой interface.u не то курит 🚬
 
Последнее редактирование:
Назад
Сверху Снизу