Несколько вопросов по мейкерам и спавнам в ПТС

Алиос

Выдающийся
Участник
Сообщения
44
Розыгрыши
0
Решения
1
Репутация
184
Реакции
56
Баллы
1 338
Здравствуйте. Пытаюсь понять логику работы Npc и Spawn движка в ПТС-ах, и по некоторым вопросам уже весь мозг сломал в догадках и предположениях. А посему, любые подсказки от знающих людей были бы крайне ценными. Вопросы такие:

1) Те, кто спавнятся функцией CreateOnePrivateEx(...) по сути являются такими же миньонами, как и созданные функцией CreatePrivates() и добавляются в пати с нпц, чья аишка вызвала эту функцию? Или это просто функция для спавна моба в том же мейкере, где и тот нпц, через чью аишку идет спавн, и призывающий с призванным никакими пати не связаны?

2) В какую группу мейкера(SpawnDefine) добавляются нпц, которые не были изначально прописаны в npcpos, а были доспавнены АИшкой через CreatePrivates() или CreateOnePrivateEx(...)? Ведь тот же миньон далеко не всегда исчезает сразу же после удаления хозяина, но если сказать мейкеру убрать всех мобов в том или ином SpawnDefine - все призванные аишками нпц должны также удалиться. А для этого им, по идее, нужно принадлежать к тому же SpawnDefine. Но при этом, если посмотреть, как устроен контроль респа в том или ином дефайне мейкера, то возникают вопросы. Например, код из default_maker:
C-подобный:
EventHandler ON_NPC_DELETED(deleted_def, i0, i1, maker0, reply) {
    if (deleted_def.respawn_time != 0) {
        if (myself.maximum_npc >= myself.npc_count + 1) {
            if (AtomicIncreaseTotal(deleted_def, 1, 1)) {
                deleted_def.Spawn2(1, deleted_def.respawn_time, deleted_def.respawn_rand);
            }
        }
    }
}

Он принимает ссылку на SpawnDefine удаленного моба и, как я понимаю, вешает отложенный таск на спавн моба. Но это ведь должно распространяться только на "родных" мобов этого дефайна. И если "доспавненные" аишкой мобы находятся в той же группе, то как оно отличает, удален родной моб или доспавненный? А если доспавненные мобы не добавляются в ту же группу, где и владелец призвавшей его аишки, то каким образом сервер понимает, каких доспавненных нпц нужно удалить при деспавне всего Define? Вот это противоречие заставляет меня ломать мозг в догадках, как оно на самом деле устроено и куда добавляются такие вот "доспавненные" нпц.

3) Хотелось бы точно знать, как работает функция мейкера AtomicIncreaseTotal(SpawnDefine, int, int). Это просто потокобезопасная реализация примерно такого кода? Она проверяет и увеличивает только пару define.total и define.npc_count или учитывает также и maximum_npc и npc_count самого мейкера? Если учитывает счетчики мейкера - зачем тогда перед ней обычно идут прямые проверки на maximum_npc мейкера в их аишках? А если нет, то значит атомарное увеличение счетчика заспавненных в мейкере мобов происходит где-то "под капотом" в ядре?
Java:
public boolean AtomicIncreaseTotal(final SpawnDefine define, final int count, final int unk)
{
    lock.lock();

    //if(maximum_npc < npc_count + count)
        //return false;
    if(define.getTotal() < define.getNpcCount() + count)
        return false;

    //npc_count += count;
    define.increaseNpcCount(count);

    lock.unlock();

    return true;
}

4) Не смог понять, как ПТС-ка определяет статус дружественности\враждебности того или иного нпц по отношению к игроку. Не агрессивности, а именно того, с кем бы без ctrl говоришь, а кого бьешь, кого задевают массухи, а кого нет. В АИшках и пара метрах npcdata толком не нашел параметров, намекающих на такой смысл. Думал, дело в типах, прописанных в нпцдате(типа boss, warrior, citizen, zzoldagu) как аналогов Npc, Monster, RaidBoss, Minion в яве. Но в результате тестов выяснил, что двух разных нпц типа citizen воспринимает по-разному - одного как моба и пытается сразу бить, а второго - как нпц, с которым персонаж пытается говорить. Так где же прописывается этот статус условно npc/monster в ПТС?

5) Есть четкий список возможных хендлеров типа ON_NPC_DELETED, ON_NPCPOS_EVENT и т.д. Однако. в одних АИшках они прописаны с одной сигнатуркой, в других - с другой, и вариаций могут быть сотни. Зачастую, они таким образом просто объявляют локальные переменные метода в его сигнатурке - это я понимаю. Но есть ли какой-то хитрый способ узнать некую базовую сигнатуру, то есть, аргументы, которые ядро передает всегда в тот или иной хендлер, чтобы отличить нормальные аргументы от таких вот "объявлений локальных переменных"? Или только анализировать каждое применение вручную и пытаться прослеживать закономерности, делая из них вывод? Нужно это, разумеется, для формирования правильной структуры аишек и взаимодействия ядра с ними в своей говнояве, при попытке реализации оффлайк-структуры мейкеров/аишек мейкеров/аишек нпц с их частичным парсом + постепенным допилом руками.
 

Вы сейчас пытаетесь получить на халяву те функции, которые люди реверсят годами, из l2npc server. Я думаю никто на ваши вопросы не ответит. Бесплатно по крайней мере. Аи это всего лишь '' исходный код минимального исходного кода'', по крайней мере я для себя так считаю, npc сервера птс. Нет, конечно если есть доброжелатели поделится реверсом этих функций, я не против, я не стану, извините. Да ещё чтобы это пытались на джаве повторить.
 
Вы сейчас пытаетесь получить на халяву те функции, которые люди реверсят годами, из l2npc server. Я думаю никто на ваши вопросы не ответит. Бесплатно по крайней мере. Аи это всего лишь '' исходный код минимального исходного кода'', по крайней мере я для себя так считаю, npc сервера птс. Нет, конечно если есть доброжелатели поделится реверсом этих функций, я не против, я не стану, извините. Да ещё чтобы это пытались на джаве повторить.
Расходимся, барин не поделится.
 
Расходимся, барин не поделится.
Дефольт извини, конечно, для тебя наверное это уже раз плюнуть. Я только начал дизасемблить птс, не так давно, и считаю, что любая инфа из приложений птс, не должна так просто попадать в шару. Если я не прав, извини.
 
Здравствуйте. Пытаюсь понять логику работы Npc и Spawn движка в ПТС-ах, и по некоторым вопросам уже весь мозг сломал в догадках и предположениях. А посему, любые подсказки от знающих людей были бы крайне ценными. Вопросы такие:

1) Те, кто спавнятся функцией CreateOnePrivateEx(...) по сути являются такими же миньонами, как и созданные функцией CreatePrivates() и добавляются в пати с нпц, чья аишка вызвала эту функцию? Или это просто функция для спавна моба в том же мейкере, где и тот нпц, через чью аишку идет спавн, и призывающий с призванным никакими пати не связаны?

2) В какую группу мейкера(SpawnDefine) добавляются нпц, которые не были изначально прописаны в npcpos, а были доспавнены АИшкой через CreatePrivates() или CreateOnePrivateEx(...)? Ведь тот же миньон далеко не всегда исчезает сразу же после удаления хозяина, но если сказать мейкеру убрать всех мобов в том или ином SpawnDefine - все призванные аишками нпц должны также удалиться. А для этого им, по идее, нужно принадлежать к тому же SpawnDefine. Но при этом, если посмотреть, как устроен контроль респа в том или ином дефайне мейкера, то возникают вопросы. Например, код из default_maker:
C-подобный:
EventHandler ON_NPC_DELETED(deleted_def, i0, i1, maker0, reply) {
    if (deleted_def.respawn_time != 0) {
        if (myself.maximum_npc >= myself.npc_count + 1) {
            if (AtomicIncreaseTotal(deleted_def, 1, 1)) {
                deleted_def.Spawn2(1, deleted_def.respawn_time, deleted_def.respawn_rand);
            }
        }
    }
}

Он принимает ссылку на SpawnDefine удаленного моба и, как я понимаю, вешает отложенный таск на спавн моба. Но это ведь должно распространяться только на "родных" мобов этого дефайна. И если "доспавненные" аишкой мобы находятся в той же группе, то как оно отличает, удален родной моб или доспавненный? А если доспавненные мобы не добавляются в ту же группу, где и владелец призвавшей его аишки, то каким образом сервер понимает, каких доспавненных нпц нужно удалить при деспавне всего Define? Вот это противоречие заставляет меня ломать мозг в догадках, как оно на самом деле устроено и куда добавляются такие вот "доспавненные" нпц.

3) Хотелось бы точно знать, как работает функция мейкера AtomicIncreaseTotal(SpawnDefine, int, int). Это просто потокобезопасная реализация примерно такого кода? Она проверяет и увеличивает только пару define.total и define.npc_count или учитывает также и maximum_npc и npc_count самого мейкера? Если учитывает счетчики мейкера - зачем тогда перед ней обычно идут прямые проверки на maximum_npc мейкера в их аишках? А если нет, то значит атомарное увеличение счетчика заспавненных в мейкере мобов происходит где-то "под капотом" в ядре?
Java:
public boolean AtomicIncreaseTotal(final SpawnDefine define, final int count, final int unk)
{
    lock.lock();

    //if(maximum_npc < npc_count + count)
        //return false;
    if(define.getTotal() < define.getNpcCount() + count)
        return false;

    //npc_count += count;
    define.increaseNpcCount(count);

    lock.unlock();

    return true;
}

4) Не смог понять, как ПТС-ка определяет статус дружественности\враждебности того или иного нпц по отношению к игроку. Не агрессивности, а именно того, с кем бы без ctrl говоришь, а кого бьешь, кого задевают массухи, а кого нет. В АИшках и пара метрах npcdata толком не нашел параметров, намекающих на такой смысл. Думал, дело в типах, прописанных в нпцдате(типа boss, warrior, citizen, zzoldagu) как аналогов Npc, Monster, RaidBoss, Minion в яве. Но в результате тестов выяснил, что двух разных нпц типа citizen воспринимает по-разному - одного как моба и пытается сразу бить, а второго - как нпц, с которым персонаж пытается говорить. Так где же прописывается этот статус условно npc/monster в ПТС?

5) Есть четкий список возможных хендлеров типа ON_NPC_DELETED, ON_NPCPOS_EVENT и т.д. Однако. в одних АИшках они прописаны с одной сигнатуркой, в других - с другой, и вариаций могут быть сотни. Зачастую, они таким образом просто объявляют локальные переменные метода в его сигнатурке - это я понимаю. Но есть ли какой-то хитрый способ узнать некую базовую сигнатуру, то есть, аргументы, которые ядро передает всегда в тот или иной хендлер, чтобы отличить нормальные аргументы от таких вот "объявлений локальных переменных"? Или только анализировать каждое применение вручную и пытаться прослеживать закономерности, делая из них вывод? Нужно это, разумеется, для формирования правильной структуры аишек и взаимодействия ядра с ними в своей говнояве, при попытке реализации оффлайк-структуры мейкеров/аишек мейкеров/аишек нпц с их частичным парсом + постепенным допилом руками.
1) Yes these functions add these npcs to the party. Handlers like PARTY_ATTACKED / PARTY_DIED / etc are triggered by the master npc or npcs that were created by createprivates().

4) can_be_attacked= 0 / 1 (npcdata parameter)
 
  • Мне нравится
Реакции: kick
Вы сейчас пытаетесь получить на халяву те функции, которые люди реверсят годами, из l2npc server. Я думаю никто на ваши вопросы не ответит. Бесплатно по крайней мере. Аи это всего лишь '' исходный код минимального исходного кода'', по крайней мере я для себя так считаю, npc сервера птс. Нет, конечно если есть доброжелатели поделится реверсом этих функций, я не против, я не стану, извините. Да ещё чтобы это пытались на джаве повторить.
Это так или иначе уже делалось на java, не мы первые и не мы последние занимаемся подобным мазохизмом. Реализовать можно разными способами, какой-то будет лучше, какой-то хуже, но результат по итогу один и тот же. От ответов в данной теме зависит только то, насколько похожей будет структура кода. Просто наткнулись на парочку непонятных моментов и дабы до конца сложить картинку, решили задать вопрос тут. Нет желания делиться информацией - не делитесь.
 
Дефольт извини, конечно, для тебя наверное это уже раз плюнуть. Я только начал дизасемблить птс, не так давно, и считаю, что любая инфа из приложений птс, не должна так просто попадать в шару. Если я не прав, извини.
Я клоню к тому, что когда ты задавал вопросы - тебе на них весьма подробно отвечали и давали советы, а не писали: "мы тут годами сю изучаем, поэтому делиться не будем". Разве не так?

//Это комьюнити для того и создано, что бы люди находили ответы на вопросы. Не можешь\не хочешь? Проходи мимо.
 
1) Yes these functions add these npcs to the party. Handlers like PARTY_ATTACKED / PARTY_DIED / etc are triggered by the master npc or npcs that were created by createprivates().

4) can_be_attacked= 0 / 1 (npcdata parameter)
4)

RU: Почему 2 NPC sitizen имеющие can_be_attacked=0, ведут себя по разному? Один может быть атакован без ctrl, а второй выбрасывает диалоговое окно.

EN: Why do 2 sitizen NPCs with can_be_attacked=0 behave differently? One can be attacked without ctrl, while the second one throws out a dialog box.

Я клоню к тому, что когда ты задавал вопросы - тебе на них весьма подробно отвечали и давали советы, а не писали: "мы тут годами сю изучаем, поэтому делиться не будем". Разве не так?

//Это комьюнити для того и создано, что бы люди находили ответы на вопросы. Не можешь\не хочешь? Проходи мимо.
Человек реверсит ПТС, делает важную работу и видимо в суматохе подзабыл как на этой же площадке ему давали информацию без всяких претензий и упреков. Вернуться к выполнению функции после хука.
Ну оно понять можно, такое всегда быстро забывается.
 
4)

RU: Почему 2 NPC sitizen имеющие can_be_attacked=0, ведут себя по разному? Один может быть атакован без ctrl, а второй выбрасывает диалоговое окно.

EN: Why do 2 sitizen NPCs with can_be_attacked=0 behave differently? One can be attacked without ctrl, while the second one throws out a dialog box.
Hmm, which one? Can you tell me the NPC ID?
 
Hmm, which one? Can you tell me the NPC ID?
RU: Купол и почти любой NPC из мирки, например, телепорт. Купол саммонили через команду. Как будто что-то еще влияет.
EN: Dome and almost any NPC from the world, for example, a teleporter. The dome summoned the team. It's like something else is involved.
 
Я хз, актуально еще для тебя это или нет)
Для начала открою небольшую тайну. Скрипты ИИ из AI.obj, это не ИИ в привычном нам смысле слова. Это скрипты, которые управляются из общего игрового ИИ. Т.е по факту, они не наследуются от AbstractAI. Из наследников AbstractAI объявляются события, которые "опускаются" в скрипты и выполняются там. Т.е пример. Моб получает урон, умирает. В основном ИИ, например NpcAI, происходят все базовые обработки смерти и от туда "спускается" метод MY_DYING в скрипт, который уже проходит по супервызовам насколько ему это позволяют.
1) Те, кто спавнятся функцией CreateOnePrivateEx(...) по сути являются такими же миньонами, как и созданные функцией CreatePrivates() и добавляются в пати с нпц, чья аишка вызвала эту функцию? Или это просто функция для спавна моба в том же мейкере, где и тот нпц, через чью аишку идет спавн, и призывающий с призванным никакими пати не связаны?
Все НПЦ изначально имеющие мейкер и заспавненные через его механизмы, спавнят миньонов в тот же мейкер.
Миньон - это такой же моб, но имеющий двухстороннюю связь с мобом, который его засумонил. Это действительно, что-то типа пати, т.к эта связь обрабатывается корректно для проверок в скилла типа party и party_pledge
CreateOnePrivateEx в качестве одного из параметров принимает как раз таки ИИ моба, который управляет его дальнейшим поведением. Если он наследуется от party_private, то он как правило обретает типичные особенности поведения миньона, но это не обязательно. Моб заспавненный через CreateOnePrivateEx может быть каким угодно.

2) В какую группу мейкера(SpawnDefine) добавляются нпц, которые не были изначально прописаны в npcpos, а были доспавнены АИшкой через CreatePrivates() или CreateOnePrivateEx(...)? Ведь тот же миньон далеко не всегда исчезает сразу же после удаления хозяина, но если сказать мейкеру убрать всех мобов в том или ином SpawnDefine - все призванные аишками нпц должны также удалиться. А для этого им, по идее, нужно принадлежать к тому же SpawnDefine. Но при этом, если посмотреть, как устроен контроль респа в том или ином дефайне мейкера, то возникают вопросы. Например, код из default_maker:
Миньоны спавнятся в тот же SpawnDefine, что и их лидер. Количество НПЦ в SpawnDefine не ограничено, но не может превышать лимит maximum_npc для мейкера. Т.е например, если в мейкере лимит 4 моба, то лидер сможет породить только 3 миньонов, после чего все дальнейшие попытки будут фейлится. Пример: ГК(Кларисса например), которая порождает Аллегрию. Лимит на 3 штуки Аллегрии, это как раз ограничения maximum_npc мейкера.
Существование миньонов после смерти мастера управляется через ИИ миньонов. Как правило, это таймер 1004, который запускается на интервал в 20с, и в случае если миньон не в бою, деспавнит его, но могут быть и другие варианты в зависимости от ИИ. Общее правило - это то, что миньоны принудительно деспавнятся после респавна мастера. Также, респавн и спавн миньонов управляется общим движком респавна и может быть отложен на определенное время из ИИ.

3) Хотелось бы точно знать, как работает функция мейкера AtomicIncreaseTotal(SpawnDefine, int, int). Это просто потокобезопасная реализация примерно такого кода? Она проверяет и увеличивает только пару define.total и define.npc_count или учитывает также и maximum_npc и npc_count самого мейкера? Если учитывает счетчики мейкера - зачем тогда перед ней обычно идут прямые проверки на maximum_npc мейкера в их аишках? А если нет, то значит атомарное увеличение счетчика заспавненных в мейкере мобов происходит где-то "под капотом" в ядре?
define.total фиксированное значение и не может быть изменено.
AtomicIncreaseTotal увеличивает только npc_count для мейкера. Значения внутри метода не валидируются, все проверки происходят из кода в ИИ. Да, это потокобезопасный код.

5) Есть четкий список возможных хендлеров типа ON_NPC_DELETED, ON_NPCPOS_EVENT и т.д. Однако. в одних АИшках они прописаны с одной сигнатуркой, в других - с другой, и вариаций могут быть сотни. Зачастую, они таким образом просто объявляют локальные переменные метода в его сигнатурке - это я понимаю. Но есть ли какой-то хитрый способ узнать некую базовую сигнатуру, то есть, аргументы, которые ядро передает всегда в тот или иной хендлер, чтобы отличить нормальные аргументы от таких вот "объявлений локальных переменных"? Или только анализировать каждое применение вручную и пытаться прослеживать закономерности, делая из них вывод? Нужно это, разумеется, для формирования правильной структуры аишек и взаимодействия ядра с ними в своей говнояве, при попытке реализации оффлайк-структуры мейкеров/аишек мейкеров/аишек нпц с их частичным парсом + постепенным допилом руками.
Я себе сделал абстрактный класс, variables, который объявляет все переменные из сигнатур, кроме тех, которые могут быть параметрами хэндлеров и наследую от нее все скрипты ИИ. Таким образом, я могу передавать в хендлеры только шаред-параметры.

1679880100333.webp
1679880251512.webp
1679880291255.webp
 
Я хз, актуально еще для тебя это или нет)
Для начала открою небольшую тайну. Скрипты ИИ из AI.obj, это не ИИ в привычном нам смысле слова. Это скрипты, которые управляются из общего игрового ИИ. Т.е по факту, они не наследуются от AbstractAI. Из наследников AbstractAI объявляются события, которые "опускаются" в скрипты и выполняются там. Т.е пример. Моб получает урон, умирает. В основном ИИ, например NpcAI, происходят все базовые обработки смерти и от туда "спускается" метод MY_DYING в скрипт, который уже проходит по супервызовам насколько ему это позволяют.

Все НПЦ изначально имеющие мейкер и заспавненные через его механизмы, спавнят миньонов в тот же мейкер.
Миньон - это такой же моб, но имеющий двухстороннюю связь с мобом, который его засумонил. Это действительно, что-то типа пати, т.к эта связь обрабатывается корректно для проверок в скилла типа party и party_pledge
CreateOnePrivateEx в качестве одного из параметров принимает как раз таки ИИ моба, который управляет его дальнейшим поведением. Если он наследуется от party_private, то он как правило обретает типичные особенности поведения миньона, но это не обязательно. Моб заспавненный через CreateOnePrivateEx может быть каким угодно.


Миньоны спавнятся в тот же SpawnDefine, что и их лидер. Количество НПЦ в SpawnDefine не ограничено, но не может превышать лимит maximum_npc для мейкера. Т.е например, если в мейкере лимит 4 моба, то лидер сможет породить только 3 миньонов, после чего все дальнейшие попытки будут фейлится. Пример: ГК(Кларисса например), которая порождает Аллегрию. Лимит на 3 штуки Аллегрии, это как раз ограничения maximum_npc мейкера.
Существование миньонов после смерти мастера управляется через ИИ миньонов. Как правило, это таймер 1004, который запускается на интервал в 20с, и в случае если миньон не в бою, деспавнит его, но могут быть и другие варианты в зависимости от ИИ. Общее правило - это то, что миньоны принудительно деспавнятся после респавна мастера. Также, респавн и спавн миньонов управляется общим движком респавна и может быть отложен на определенное время из ИИ.


define.total фиксированное значение и не может быть изменено.
AtomicIncreaseTotal увеличивает только npc_count для мейкера. Значения внутри метода не валидируются, все проверки происходят из кода в ИИ. Да, это потокобезопасный код.


Я себе сделал абстрактный класс, variables, который объявляет все переменные из сигнатур, кроме тех, которые могут быть параметрами хэндлеров и наследую от нее все скрипты ИИ. Таким образом, я могу передавать в хендлеры только шаред-параметры.

Посмотреть вложение 48625
Посмотреть вложение 48626
Посмотреть вложение 48627
Большое спасибо за столь детальное объяснение. Временно, для меня это неактуально, так как, пока что, занимаюсь другими вопросами, но все равно интересно. Да и будет актуально в будущем, так как хочу еще вернуться к этой теме. Судя по скринам, ты прилично так заморочился - респект! А мне вот и хочется, и колется реализовать нечто подобное. Не только из-за сложности(она компенсируется интересом), но и из-за того, что декомпильнутый код из AI.obj не всегда корректен. Пока переписывал движок инстов, с перфекционизмом желая 100% правильно их реализовать, смотря АИшки каждого мейкера, босса и особенрного моба в них, не раз замечал логические противоречия. То есть, там был код написан так, что непонятно, как он вообще работает. От багов в коде и фактически игре, до моментов, когда в коде белиберда, но в игре все адекватно по факту. И не угадаешь, сколько там таких приколов. Да и некоторые моменты мне не очень нравятся в ПТС-структуре. Например, те же квесты разбиты по взаимодействию АИшек тучи пнц, но нет единого класса квеста, объединяющего по смыслу все или большую часть того, что с ним связано. Аналогично в инстанс-зонах нет некого единого класса АИшки инста - оно разбито по куче АИшек нпц и мейкеров. С точки зрения "спарсил -> работает" - это норм подход, но в плане удобства поддержки такого кода - не очень.
 
декомпильнутый код из AI.obj не всегда корректен.
Многое зависит от декомпилятора, а также от выбранного принципа разбора скриптов.
Я взял за основной тезис, что скрипты ПТСа верные(это касается ai.obj и остального датапака), т.к они успешно работают на ПТС.
Следовательно, если у меня что-то не работает, то это не скрипты кривые, а я дурак. Поэтому почти с самого начала разработки, мой датапак выглядит вот так и я работаю с ним в формате read-only:
1680408924247.webp

не раз замечал логические противоречия
Я пока столкнулся с только одним не понятным вопросом, но успешно получилось его решить.

Например, те же квесты разбиты по взаимодействию АИшек тучи пнц, но нет единого класса квеста, объединяющего по смыслу все или большую часть того, что с ним связано.
С точки зрения создания нового квеста - проблем нет, т.к по больше части все максимально просто в самом движке.
С точки зрения исправления старых квестов - проблем нет, т.к исправления вносятся централизовано, через внесение правок в декомпилятор и конвертер(который декомпил NASC собирает в читаемый Java)
С точки зрения навигации по классам, которые участвуют в квесте, то можно прикрутить manual_pch в качестве интерфейса с константами и наследоваться от него. В этом случае, можно в любой момент посмотреть, где используется та или иная константы. Это удобно и с точки зрения квестов, да и в целом.

1680409492143.webp
1680409540714.webp

В целом, если вдруг надумаешь пилить в этом направлении и будут вопросы, пиши в телегу) Поделюсь опытом, если сам уже к тому времени найду решение)
 
Многое зависит от декомпилятора, а также от выбранного принципа разбора скриптов.
Я взял за основной тезис, что скрипты ПТСа верные(это касается ai.obj и остального датапака), т.к они успешно работают на ПТС.
Следовательно, если у меня что-то не работает, то это не скрипты кривые, а я дурак. Поэтому почти с самого начала разработки, мой датапак выглядит вот так и я работаю с ним в формате read-only:
Посмотреть вложение 48775


Я пока столкнулся с только одним не понятным вопросом, но успешно получилось его решить.


С точки зрения создания нового квеста - проблем нет, т.к по больше части все максимально просто в самом движке.
С точки зрения исправления старых квестов - проблем нет, т.к исправления вносятся централизовано, через внесение правок в декомпилятор и конвертер(который декомпил NASC собирает в читаемый Java)
С точки зрения навигации по классам, которые участвуют в квесте, то можно прикрутить manual_pch в качестве интерфейса с константами и наследоваться от него. В этом случае, можно в любой момент посмотреть, где используется та или иная константы. Это удобно и с точки зрения квестов, да и в целом.

Посмотреть вложение 48776
Посмотреть вложение 48777

В целом, если вдруг надумаешь пилить в этом направлении и будут вопросы, пиши в телегу) Поделюсь опытом, если сам уже к тому времени найду решение)
Да я тоже стараюсь изначально исходить из того, что в ai.obj все правильно, а это я дурак, но все равно находил там немало проблемных мест. Но я уже конкретики не вспомню, так как лазил туда последний раз ещё летом 2022-го. Кстати, по поводу навигации по классам и manual_pch интерфейсом - у нас мысли сошлись) Тоже использую такой метод на минималке(пока что, только SCE_PCH и имплементирую его в AbstractNpcAI и AbstractInzoneAI :)
1680410624876.webp
1680410667375.webp
P.S. За предложение помощи в телеге спасибо. Нам явно будет о чем пообщаться, учитывая схожесть интересов в плане реализации ПТС-механик на яве, как и поделиться опытом друг с другом)
 
Назад
Сверху Снизу