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

    Чтобы получить возможность писать на форуме, оставьте сообщение в этой теме.
    Удачи!

В разработке... Union. Пожелания насчёт плагинов

MW 7


Модостроитель
Регистрация
26 Мар 2004
Сообщения
1.482
Благодарности
689
Баллы
255
вообщем тут надо как то строчки zstring сравнивать.
_this->useWithItem и FocusHero->useWithItem
если совпадают то возвращать 0.

какая функция сравнивает строчки я не знаю :-(

C++:
    //0x0071DB40 public: virtual int __thiscall oCMobInter::GetUseWithItem(void)
    int __fastcall GetUseWithItem(oCMobInter* _this);
    CInvoke <int(__fastcall*) (oCMobInter*)> pGetUseWithItem(0x0071DB40, GetUseWithItem, IVK_AUTO);
    int __fastcall GetUseWithItem(oCMobInter* _this)
    {
        oCMobInter* FocusHero = player->GetFocusVob()->CastTo<oCMobInter>();
        if (FocusHero)
        {
            //if (_this->useWithItem)
            //{
               // if (FocusHero->useWithItem)
               // {
                    cmd << Z"FocusHero: " + FocusHero->sceme + FocusHero->useWithItem << endl;
                    cmd << Z"GetUseWithItem: " + _this->sceme + _this->useWithItem << endl;
                    return 0;
                //}
            //}
        }
        return pGetUseWithItem(_this);
    }
 
Последнее редактирование:

Xeдин

Участник форума
Регистрация
3 Дек 2008
Сообщения
1.089
Благодарности
1.582
Баллы
335
MW 7, сравнение строк this->useWithItem.CompareI(FocusHero->useWithItem)
Но я бы саму запись хука сделал по-другому, как-то так
Добавить строчку int GetUseWithItem_New(); в файлик CMobInter.inl (User API ->oGame->M->CMobInter.inl) и потом в каком-нибудь своем классе MyHooks.cpp

C++:
    HOOK Ivk_oCMobInter_GetUseWithItem_New PATCH(&oCMobInter::GetUseWithItem, &oCMobInter::GetUseWithItem_New);
    int oCMobInter::GetUseWithItem_New() {
        if (player && player->GetFocusVob() && this == player->GetFocusVob() && this->useWithItem.CompareI("ItMiSwordRaw")) {
            return FALSE;
        }
        return THISCALL(Ivk_oCMobInter_GetUseWithItem_New)();
    }
 
Последнее редактирование:

Slavemaster


Модостроитель
Регистрация
10 Июн 2019
Сообщения
866
Благодарности
1.369
Баллы
160

Xeдин

Участник форума
Регистрация
3 Дек 2008
Сообщения
1.089
Благодарности
1.582
Баллы
335
В фокусе игрока может быть объект, которым воспользуется другой NPC.
Одновременно наверное не может быть, надо проверять. Вообще у него проверка на фокус в принципе там ничо не даст мне кажется. Вернее полностью не решит проблему.
 

MW 7


Модостроитель
Регистрация
26 Мар 2004
Сообщения
1.482
Благодарности
689
Баллы
255
я бы саму запись хука сделал по-другому, как-то так
там же у тебя проверка только на ItMiSwordRaw? а как же другие производственные предметы?

сравнение строк this->useWithItem.CompareI(FocusHero->useWithItem)
C++:
    //0x0071DB40 public: virtual int __thiscall oCMobInter::GetUseWithItem(void)
    int __fastcall GetUseWithItem(oCMobInter* _this);
    CInvoke <int(__fastcall*) (oCMobInter*)> pGetUseWithItem(0x0071DB40, GetUseWithItem, IVK_AUTO);
    int __fastcall GetUseWithItem(oCMobInter* _this)
    {
        oCMobInter* FocusHero = player->GetFocusVob()->CastTo<oCMobInter>();
        if (FocusHero)
        {
            if (_this->focusNameIndex == FocusHero->focusNameIndex)
            {
                if (_this->useWithItem.CompareI(FocusHero->useWithItem))
                {
                            cmd << Z"FocusHero: " + FocusHero->sceme + FocusHero->useWithItem << endl;
                            cmd << Z"GetUseWithItem: " + _this->sceme + _this->useWithItem << endl;
                            cmd << Z"focusNameIndex: " + zSTRING(_this->focusNameIndex)  << endl;
                            //cmd << Z"focusNameIndex: " + zSTRING(FocusHero->focusNameIndex)  << endl;
                }
                return 0;
            }
        }
        return pGetUseWithItem(_this);
    }
Добавить строчку int GetUseWithItem_New(); в файлик CMobInter.inl (User API ->oGame->M->CMobInter.inl) и потом в каком-нибудь своем классе MyHooks.cpp

C++:
    HOOK Ivk_oCMobInter_GetUseWithItem_New PATCH(&oCMobInter::GetUseWithItem, &oCMobInter::GetUseWithItem_New);
    int oCMobInter::GetUseWithItem_New()
    {
        if (player && player->GetFocusVob())
        {
            oCMobInter* FocusHero = player->GetFocusVob()->CastTo<oCMobInter>();

            if (this == player->GetFocusVob())
            {
                if (this->useWithItem.CompareI(FocusHero->useWithItem))
                {
                    cmd << Z"this: " + this->useWithItem << endl;
                    cmd << Z"FocusHero: " + FocusHero->sceme + FocusHero->useWithItem << endl;
                    return FALSE;
                }
            }
        }
        return THISCALL(Ivk_oCMobInter_GetUseWithItem_New)();
    }
 
Последнее редактирование:

Xeдин

Участник форума
Регистрация
3 Дек 2008
Сообщения
1.089
Благодарности
1.582
Баллы
335
MW 7, ItMiSwordRaw для примера я дал. Все твои три проверки можно заменить одной
C++:
    int __fastcall GetUseWithItem(oCMobInter* _this);
    CInvoke <int(__fastcall*) (oCMobInter*)> pGetUseWithItem(0x0071DB40, GetUseWithItem, IVK_AUTO);
    int __fastcall GetUseWithItem(oCMobInter* _this)
    {
        if (player && _this == player->GetFocusVob()) {
            //cmd << Z"FocusHero: " + FocusHero->sceme + FocusHero->useWithItem << endl;
            cmd << Z"GetUseWithItem: " + _this->sceme + _this->useWithItem << endl;
            cmd << Z"focusNameIndex: " + zSTRING(_this->focusNameIndex) << endl;
            return FALSE;
        }
        return pGetUseWithItem(_this);
    }
Но проще и универсальнее как я написал (сразу для всех платформ)
C++:
    HOOK Ivk_oCMobInter_GetUseWithItem_New PATCH(&oCMobInter::GetUseWithItem, &oCMobInter::GetUseWithItem_New);
    int oCMobInter::GetUseWithItem_New() {
        if (player && this == player->GetFocusVob()) {
            return FALSE;
        }
        return THISCALL(Ivk_oCMobInter_GetUseWithItem_New)();
    }
 

Xeдин

Участник форума
Регистрация
3 Дек 2008
Сообщения
1.089
Благодарности
1.582
Баллы
335
MW 7, забыл в твой код return FALSE; дописать, а так да, просто выведется
 

MW 7


Модостроитель
Регистрация
26 Мар 2004
Сообщения
1.482
Благодарности
689
Баллы
255
C++:
    HOOK Ivk_oCMobInter_GetUseWithItem_New PATCH(&oCMobInter::GetUseWithItem, &oCMobInter::GetUseWithItem_New);
    int oCMobInter::GetUseWithItem_New()
    {
        if (player && this == player->GetFocusVob())
        {
            oCMobInter* FocusHero = player->GetFocusVob()->CastTo<oCMobInter>();
            if (this->useWithItem.CompareI(FocusHero->useWithItem))
            //if (this->useWithItem.CompareI(player->GetFocusVob()->useWithItem))
            {
                cmd << Z"this: " + this->useWithItem << endl;
                //cmd << Z"player->GetFocusVob: " + player->GetFocusVob()->useWithItem << endl;
                cmd << Z"FocusHero: " + FocusHero->sceme +" :: Item=" + FocusHero->useWithItem << endl;
                return FALSE;
            }
            return THISCALL(Ivk_oCMobInter_GetUseWithItem_New)();
        }
    }
C++:
    HOOK Ivk_oCMobInter_GetUseWithItem_New PATCH(&oCMobInter::GetUseWithItem, &oCMobInter::GetUseWithItem_New);
    int oCMobInter::GetUseWithItem_New()
    {
        if (player && player->GetFocusVob())
        {
            oCMobInter* FocusHero = player->GetFocusVob()->CastTo<oCMobInter>();

            if (this == player->GetFocusVob())
            {
                if (this->useWithItem.CompareI(FocusHero->useWithItem))
                {
                    //cmd << Z"this: " + this->useWithItem << endl;
                    cmd << Z"FocusHero: " + FocusHero->sceme +" :: Item=" + FocusHero->useWithItem << endl;
                    return FALSE;
                }
            }
        }
        return THISCALL(Ivk_oCMobInter_GetUseWithItem_New)();
    }
1685030126317.jpeg
1685029987025.jpeg
 

MW 7


Модостроитель
Регистрация
26 Мар 2004
Сообщения
1.482
Благодарности
689
Баллы
255
теперь наверное надо как то прикрутить парсер скриптовой функции что бы уже на уровне скриптов расписать тонкую обработку под свои нужны
Daedalus:
func int C_MobInter_UseWithItem(var string sceme, var int useWithItem)
{
    return useWithItem;
};
 

Xeдин

Участник форума
Регистрация
3 Дек 2008
Сообщения
1.089
Благодарности
1.582
Баллы
335
MW 7, тебе проверка this->useWithItem.CompareI(FocusHero->useWithItem) вообще не нужна, ты по фокусу выше уже сравниваешь. Да и сам фокус не очень идея. Если я правильно понял что ты хочешь, попробуй такой, немного костыльный вариант.
Daedalus:
func int C_MobInter_UseWithItem(var string sceme, var int useWithItem)
{
    Hlp_PrintConsole(Str_Format(" call C_MobInter_UseWithItem useWithItem: %i, sceme: %s", useWithItem, sceme));
    return ItMiSwordRaw;
};
C++:
// Supported with union (c) 2020 Union team
// User API for oCMobInter
// Add your methods here
int GetUseWithItem_New();
int CanInteractWith_New(oCNpc*);
C++:
void Game_Loop() {
      GetUseWithItemGameLoop();
}
C++:
// Supported with union (c) 2020 Union team
// Union SOURCE file

namespace GOTHIC_ENGINE {
    // Add your code here . . .

    oCMobInter* lastPlayerMobInter = nullptr;

    HOOK Ivk_oCMobInter_CanInteractWith_New PATCH(&oCMobInter::CanInteractWith, &oCMobInter::CanInteractWith_New);
    int oCMobInter::CanInteractWith_New(oCNpc* npc) {
        if (player == npc) {
            lastPlayerMobInter = this;
        }
        return THISCALL(Ivk_oCMobInter_CanInteractWith_New)(npc);
    }

    HOOK Ivk_oCMobInter_GetUseWithItem_New PATCH(&oCMobInter::GetUseWithItem, &oCMobInter::GetUseWithItem_New);
    int oCMobInter::GetUseWithItem_New() {
        if (player && this == lastPlayerMobInter) {
            int sym_index = parser->GetIndex("C_MobInter_UseWithItem");
            if (sym_index != -1) {
                int idxUseWithItem = parser->GetIndex(this->useWithItem);
                if (idxUseWithItem != -1) {      
                    parser->datastack.Push(reinterpret_cast<int>(&this->sceme));
                    parser->datastack.Push(zPAR_TOK_PUSHVAR);
                    parser->datastack.Push(idxUseWithItem);
                    parser->datastack.Push(zPAR_TOK_PUSHINT);
                    parser->DoStack(parser->GetSymbol(sym_index)->single_intdata);
                    zCPar_Symbol* newUseWithItemSym = parser->GetSymbolInfo(parser->PopDataValue());
                    if (newUseWithItemSym) {
                        zSTRING old = Z this->useWithItem;
                        this->SetUseWithItem(newUseWithItemSym->name);
                        int resCall = THISCALL(Ivk_oCMobInter_GetUseWithItem_New)();
                        this->SetUseWithItem(old);
                        return resCall;
                    }
                }
            }
        }
        return THISCALL(Ivk_oCMobInter_GetUseWithItem_New)();
    }

    void GetUseWithItemGameLoop() {
        if (player && !player->GetInteractMob() && lastPlayerMobInter) {
            lastPlayerMobInter = nullptr;
        }  
    }
}
В примере при взаимодействии с ведром с водой игрок будет доставать ItMiSwordRaw

36.jpg


Хотя с ITFO_BEER лучше выглядит :)

37.jpg
 
Последнее редактирование:

MW 7


Модостроитель
Регистрация
26 Мар 2004
Сообщения
1.482
Благодарности
689
Баллы
255
Xeдин, работает как надо, спасибо.

***

пример использования в г2
Daedalus:
instance ItMi_Flask_fake(c_item)  {    ItMi_Flask();  };
    
func int C_MobInter_UseWithItem(var string sceme, var int useWithItem)
{
    Hlp_PrintConsole(Str_Format(" call C_MobInter_UseWithItem sceme: %s, useWithItem: %i", sceme, useWithItem));
 
    if (Hlp_StrCmp(sceme,"LAB") == true)
    {        
        // новый предмет
        var int itmid;  itmid=ItMi_Flask_fake;
        
        // если нет предмета, то создаём
        if (!Npc_GetInvItem(hero,itmid))    {   CreateInvItem(hero,itmid);  };
        
        // возвращаем новодел
        return itmid;
    };
    
    
    // возвращаем оригинальную инстанцию
    return useWithItem;
};
 

Вложения

  • zMobInter.zip
    89,6 KB · Просмотры: 1

Diego9979

Участник форума
Регистрация
15 Июл 2015
Сообщения
24
Благодарности
5
Баллы
170
Ребятушки можно скинуть два плагина 1. по увеличению суток в игре 2. когда подходишь к воде можно будет умываться(ну люблю я быть чистюлей)
 

KirTheSeeker

Участник форума
Регистрация
18 Авг 2017
Сообщения
1.781
Благодарности
484
Баллы
260
1. по увеличению суток в игре
Если речь об изменении длительности игровых суток, то это можно выполнить в Gothic.ini, установив плагин ZMISCUTILS.
Union:
SecondsPerGameHour=1200
; ... sets the duration of game hour
 
Сверху Снизу