• Уважаемые гости и новички, приветствуем Вас на нашем форуме
    Здесь вы можете найти ответы практически на все свои вопросы о серии игр «Готика» (в том числе различных модах на нее), «Ведьмак», «Ризен», «Древние свитки», «Эра дракона» и о многих других играх. Можете также узнать свежие новости о разработке новых проектов, восхититься творчеством наших форумчан, либо самим показать, что вы умеете. Ну и наконец, можете обсудить общие увлечения или просто весело пообщаться с посетителями «Таверны».

    Чтобы получить возможность писать на форуме, оставьте сообщение в этой теме.
    Удачи!
  • Друзья, доброго времени суток!
    Стартовал новый литературный конкурс от "Ордена Хранителей" - "Пираты Миртанского моря".
    Каждый может принять в нём участие и снискать славу и уважение, а в случае занятия призового места ещё и получить награду. Дерзайте
  • Дорогие друзья, год подходит к концу, и пришло время подвести его итоги и наградить достойных

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

Union SDK - Инструменты разработчика

Gratt


Модостроитель
Регистрация
14 Ноя 2014
Сообщения
3.301
Благодарности
4.641
Баллы
625
  • Первое сообщение
  • #1
UnionProjectIcon.png


Union SDK

инструменты разработчика

Тема находится в состоянии наполнения



Короткие видеоролики, смысл которых максимально быстро погрузить смотрящего в устройство движка готики.

Рекомендуется смотреть на YouTube, поскольку там имеется сегментированный таймлайн.






Схемы классов движка
1600263933953.png
1600263981919.png
1600264017579.png
 

Вложения

  • sizeof.xlsx
    896,7 KB · Просмотры: 77
  • Union_SDK_1_0m.zip
    20,6 MB · Просмотры: 94
Последнее редактирование:

Gratt


Модостроитель
Регистрация
14 Ноя 2014
Сообщения
3.301
Благодарности
4.641
Баллы
625
Mefiu123, that mean when you go too far the second NPC removes from the world by the Spawn manager.
You need to activate your NPC after teleportation. For example you can check NPC states and push NPC in the world to the player position:
C++:
if( firstNPC->sleepingMode == zVOB_SLEEPING )
        firstNPC->Enable(player->GetPositionWorld());
or
C++:
if( firstNPC->homeWorld == Null )
        firstNPC->Enable(player->GetPositionWorld());

И еще один вопрос, можно ли откуда-то достать аргументы в функцию? Потому что трудно понять, как у меня есть такая функция, как Foo(int, int), и что это за 1 аргумент int, а что за другой.
Only if you have the source code of ZenGin ;)
But you can ask this, some arguments of Engine SDK can be understood logically.
 

Mefiu123

Участник форума
Регистрация
13 Апр 2021
Сообщения
4
Благодарности
0
Баллы
35
Thank you for help and explain :).
Ye some arguments its easy to undestood and set correct value.
 

Mefiu123

Участник форума
Регистрация
13 Апр 2021
Сообщения
4
Благодарности
0
Баллы
35
I have another question, how can I display an image from the game folder location/images/image1.jpg on the screen after key input?
 

Gratt


Модостроитель
Регистрация
14 Ноя 2014
Сообщения
3.301
Благодарности
4.641
Баллы
625
I have another question, how can I display an image from the game folder location/images/image1.jpg on the screen after key input?
C++:
zCView* view = new zCView();
screen->InsertItem(view); // place drawable object on display
view->InsertBack("image1.tga"); // only tga from _work/data/textures

// Only after place this view to
// screen or other zCView objects
view->SetPos(2048, 2048); // 8192 is a maximum virtual coordinate of window
view->SetSize(zPixelX(300), zPixelY(200)); // 300x200px - zPixel is a macro to convert virtual coordinate from screen to pixel

C++:
void game_loop()
{
    if (zKeyToggled(KEY_Y)) // or zKeyPressed
    {
        // TODO
    }
}
 

Raven25

Участник форума
Регистрация
18 Дек 2018
Сообщения
186
Благодарности
75
Баллы
190
Хей! Есть такой вот вопрос... Я тут накатил "vs10", и при попытке ещё раз нажать (установить сдк) у меня идёт установка на vs19. Хз, может такая хрень из-за того что я при установке не оставил всё по дефолту, то есть путь установки поставил на диск "D". В мыслях остался последний вариант поставить сдк вручную, только вот хз куда пихать.
Подскажите как быть, пожалуйста-
p.s. проблему решил.
 
Последнее редактирование:

DocNight

Участник форума
Регистрация
6 Июн 2020
Сообщения
32
Благодарности
1
Баллы
100
Ребят, как получить данные NPC, за которого играет игрок из класса oCAIHuman?
 

DocNight

Участник форума
Регистрация
6 Июн 2020
Сообщения
32
Благодарности
1
Баллы
100
Да, спасибо
 

Auronen

Участник форума
Регистрация
5 Сен 2021
Сообщения
20
Благодарности
3
Баллы
45
Hello,
I really enjoy working with this SDK, it is amazing!
I have few questions:
  1. Is there a way to get the version of Union? I want to give a warning to the user, that he is using older version of Union and ask him to update.
  2. Is there a way to perform checks for other Union plug-ins? In case I want to give a warning to a user, that this plug-in is not fully compatible.
And one last, perhaps a bit more technical, question:
If I want to extend named enum - to contain more values - is there a different way than editing the header files? I know, I shouldn't really edit them, since they get rewritten by the updater, so my question is how would you approach this?

Example:
I want to add a enum member to the oEIndexDamage enum
C++:
  typedef enum oEIndexDamage {
    oEDamageIndex_Barrier,
    oEDamageIndex_Blunt,
    oEDamageIndex_Edge,
    oEDamageIndex_Fire,
    oEDamageIndex_Fly,
    oEDamageIndex_Magic,
    oEDamageIndex_Point,
    oEDamageIndex_Fall,
    oEDamageIndex_MAX
  } oEDamageIndex, oEProtectionIndex;
Usually, when I encountered this, I would jsut add it like this

C++:
  typedef enum oEIndexDamage {
    oEDamageIndex_Barrier,
    oEDamageIndex_Blunt,
    oEDamageIndex_Edge,
    oEDamageIndex_Fire,
    oEDamageIndex_Fly,
    oEDamageIndex_Magic,
    oEDamageIndex_Point,
    oEDamageIndex_Fall,
    oEDamageIndex_Demon,
    oEDamageIndex_MAX
  } oEDamageIndex, oEProtectionIndex;

But that results in problems with the updater, as I stated above. I know, those are integers, so I could just define my own, but that doesn't look as neat. Is there a way to overload the first enum in user API inl file?

Thank you for your answers

Auronen
 

Slavemaster


Модостроитель
Регистрация
10 Июн 2019
Сообщения
1.086
Благодарности
1.909
Баллы
320
Is there a way to get the version of Union? I want to give a warning to the user, that he is using older version of Union and ask him to update.
Union.GetUnionVersion()
Is there a way to perform checks for other Union plug-ins? In case I want to give a warning to a user, that this plug-in is not fully compatible.

[CODE lang="cpp" title="NiceNewForumFeature.h"]for (const CList<CPlugin>* list = CPlugin::GetPluginList().GetNext(); list; list = list->GetNext())
if (const CPlugin* plugin = list->GetData())
if (plugin->GetName().HasWordI("zMarkItems"))
Message::Info("Plugin zMarkItems is unsupported. Remove the plugin!!!");[/CODE]
If I want to extend named enum - to contain more values - is there a different way than editing the header files? I know, I shouldn't really edit them, since they get rewritten by the updater, so my question is how would you approach this?
By editing this enum (or any other entry in ZenGin API) you only break the binary compatibility between Union and ZenGin classes.
There is no easy way to add new damage type. To do so you at least need:
  • Create new oEDamageIndexEx and oEDamageTypeEx enumerations
  • Create new oSDamageDescriptorEx class
  • Extend oCItem and oCNpc classes with the new extended damage arrays
  • Force parser to use new arrays when it accesses C_ITEM.damage or C_NPC.damage
  • Intercept damage messages in order to convert oSDamageDescriptor and create oSDamageDescriptorEx as wise copy + addition entry
  • Write your own damage handling function that works with extended descriptor. For G2A you can use this as a start point: https://worldofplayers.ru/threads/42513/
  • Maybe there are some other important engine functions which rely on old damage arrays...
 

Auronen

Участник форума
Регистрация
5 Сен 2021
Сообщения
20
Благодарности
3
Баллы
45

Jedi

Участник форума
Регистрация
11 Янв 2023
Сообщения
11
Благодарности
2
Баллы
15
Привет всем, уважаемые форумчане.

Пытаюсь разобраться в написании плагина на Union. Очень долго ищу информацию\пример того как можно создать своего npc.
Не полностью с нуля - используя визуал из игры.
Пытался копать в сторону использовании существующего npc как донора, например через player->GetFocusNpc(); но не влиять на npc донора не вышло)
Если есть пример какой-нибудь фабрики - было бы круто.
В идеале я хочу добиться генератора случайного персонажа, со случайной внешностью, которого можно будет безболезненно удалить из мира.
Пока все что мне удалось - это немного адаптировать пример из генерации статичного vob'а куста (нашел где то в этой теме).
C++:
oCNpc* npc = player->GetFocusNpc();
oCNpc* mob = new oCNpc();
mob->SetVisual(npc->GetVisual());
ogame->GetGameWorld()->AddVob(mob);
//mob->SetPositionWorld(player->GetPositionWorld() + player->GetAtVectorWorld() * 100.0f);
mob->Enable(player->GetPositionWorld() + player->GetAtVectorWorld() * 100.0f);
mob->Release();
Как я понял из-за того что я использую визуал донора по ссылке npc->GetVisual() - созданная кукла влияет и на донора. В итоге оба моба начинают валяться как трупы xD Но как создать собственный визуал (zCVisual) я так и не понял.

Если подобный вопрос уже задавали или где то есть пример - прошу тыкнуть меня лицом туда) Потому что я уже наверное неделю читаю форум в поиске примера)

Так же мне интересно как созданному npc
1) прописать текстовые диалоги
2) управлять его анимациями (mob->GetModel()->StartAnimation("BABE-S_DANCE1"); - не вышло)
3) заставить его бегать за игроком и самому инициировать диалог
 

MEG@VOLT

★★★★★★★★★
ТехАдмин
Регистрация
24 Мар 2006
Сообщения
9.900
Благодарности
6.777
Баллы
1.625
Привет.
Пытаюсь разобраться в написании плагина на Union. Очень долго ищу информацию\пример того как можно создать своего npc.
Это почти тоже самое, как пойти за молоком, а купить бутылку уксуса...
Читаем: https://worldofplayers.ru/forums/978/
Читаем: https://worldofplayers.ru/threads/36463/
А не...вру, я как обычно спешу))
Тебе сюда:
А хотя... Поехали сразу туда...
 
Последнее редактирование:

Slavemaster


Модостроитель
Регистрация
10 Июн 2019
Сообщения
1.086
Благодарности
1.909
Баллы
320
В идеале я хочу добиться генератора случайного персонажа, со случайной внешностью, которого можно будет безболезненно удалить из мира.
Скриптами создай. Только добавь рандома при задании внешности.
2. Такой анимации нет, есть просто S_DANCE1
 
Последнее редактирование:

Jedi

Участник форума
Регистрация
11 Янв 2023
Сообщения
11
Благодарности
2
Баллы
15
Благодарю, буду курить.
Скриптами создай. Только добавь рандома при задании внешности.
Насколько я понимаю в таком случае на лету я создавать npc не смогу? Только создать пул и спанить их.

Но со спавном у меня тоже проблемы)
Нашел зацепку в 4м примере тут https://worldofplayers.ru/threads/40173/ . Вот таким образом получилось добавить нового npc, но заставить его хотя бы делать хоть что то не вышло.

C++:
zSTRING str_instance = "grd_254_orry"; // любой существующий npc
int idx = parser->GetIndex(str_instance);
oCNpc* pNpc = dynamic_cast<oCNpc*>(ogame->GetGameWorld()->CreateVob(zTVobType::zVOB_TYPE_NSC, idx));
if (pNpc && player) {
    zVEC3 vp = player->GetPositionWorld();
    zVEC3 vdir = player->GetAtVectorWorld();
    ogame->spawnman->InsertNpc(pNpc, vp);
    /*
    В перебирал публичные методы, которые звучат как то что мне бы помогло запустить npc
    */
    //pNpc->ResetToHumanAI();
    //pNpc->AI_Follow(player);
    //pNpc->Follow();
    //pNpc->GetModel()->StartAnimation("S_DANCE1");
    //pNpc->GetEM(false)->SetActive(false);
}
pNpc->Release();

2. Такой анимации нет, есть просто S_DANCE1
player->GetModel()->StartAnimation("S_DANCE1"); тоже не вышло(
 

Slavemaster


Модостроитель
Регистрация
10 Июн 2019
Сообщения
1.086
Благодарности
1.909
Баллы
320
Насколько я понимаю в таком случае на лету я создавать npc не смогу? Только создать пул и спанить их.
Не понял вопроса.
но заставить его хотя бы делать хоть что то не вышло.
Сначала посмотри как это в обычных скриптах делается. На крайний случай можешь из плагина нужные функции вызвать.
Обычно функции ИИ добавляют сообщение в очередь:
C++:
npc -> GetEM() -> OnMessage(zNEW(oCMsgMovement)(oCMsgMovement::EV_GOTOVOB,other), npc);
player->GetModel()->StartAnimation("S_DANCE1"); тоже не вышло(
Это женская анимация. И по-моему из Г1.
 
Последнее редактирование:

Slavemaster


Модостроитель
Регистрация
10 Июн 2019
Сообщения
1.086
Благодарности
1.909
Баллы
320
В скриптах можно как-то прописать рандомизатор внешности для NPC?
Параметры внешности задаются в скриптах. Плюс, там есть функция Random. Следовательно, как-то можно.
 

Jedi

Участник форума
Регистрация
11 Янв 2023
Сообщения
11
Благодарности
2
Баллы
15
Не понял вопроса.

Насколько я понимаю скрипт создаст мне npc с определенным id и будет присутствовать всегда в мире и в сейве. Рандом отработает при новой игре или загрузке игры, не знаю точно как это работает. Мне что бы сделать хотя бы имитацию рандома придется сделать пул таких npc (штук 20 к примеру), что бы уже рандомом выбирать из этого пула.
В моем случае это в принципе применимо, но было бы удобнее, если бы можно было брать за основу существующего npc, брать его visual и немного крутить его рандомом. Например другое тело и голову, а все остальное не важно. В таком случае рандом был бы динамический, а не ограничен пулом заготовок.

Мне нужны персонажи массовки. Например сценарий такой: По динамическому событию (например по нажатию кнопки F12) появляется рандомный селянин где то сзади персонажа, бежит к персонажу, начинает с ним диалог и сообщает рандомный факт о котах xD После этого убегает, а затем выпиливается из мира навсегда.
Это женская анимация. И по-моему из Г1.
Да ты прав, поискал в VDF рандомную анимацию мужскую и удалось запустить. Да, сейчас я пишу для Г1 пока.

npc -> GetEM() -> OnMessage(zNEW(oCMsgMovement)(oCMsgMovement::EV_GOTOVOB,other), npc);
Попытался сделать это так:
C++:
int idx = parser->GetIndex("grd_254_orry");
oCNpc* pNpc = dynamic_cast<oCNpc*>(ogame->GetGameWorld()->CreateVob(zTVobType::zVOB_TYPE_NSC, idx));
zVEC3 vp = player->GetPositionWorld() + player->GetAtVectorWorld() * 200.0f;
ogame->spawnman->InsertNpc(pNpc, vp);
pNpc->GetEM()->OnMessage(zNEW(oCMsgMovement)(oCMsgMovement::EV_GOTOVOB, player), pNpc);
pNpc->Release();
Но не вышло. Может нужно активировать что то после InsertNpc() что бы начала обрабатываться очередь?
 
Последнее редактирование:
Сверху Снизу