Jr13San
Модостроитель
- Регистрация
- 1 Апр 2010
- Сообщения
- 449
- Благодарности
- 266
- Баллы
- 230
Часть 1 - Работа с проектом в Visual Studio.
1) Скачиваем последнюю актуальную версию пакета AST: "AST_RELEASE_V1_003_SNAP072.zip".
2) Распаковываем архив. В папке SDK находится ещё один архив "Plugin.zip". В нём содержится готовый шаблон проекта плагина. Распаковываем его в любую папку. В эту же папку копируем файл Exchange.cpp с логикой обмена (файл см. во вложениях к теме).
Немного информации о файле "Exchange.cpp":
- Предоставляет режим обмена
- Исправляет пропадание текстур задних планов контейнеров и информации о предмете
- Исправляет смещение текста цены после применения коэффициента торговли.
3) Запускаем проект с помощью Visual Studio 2012 Ultimate.
4) После открытия - выбираем тип конфигурации решения: "Release", как показано на рисунке:
5) Теперь добавляем файл "Exchange.cpp" в проект следующий образом. В обозревателе решений выбираем фильтр, в который мы собираемся добавить файл, например, "Plugin main". Нажимаем на него правой кнопкой мыши, в открывшемся меню выбираем: Добавить → Существующий элемент...
В открывшемся проводнике выбираем файл Exchange.cpp.
6) Файл добавлен. Если его открыть, то можно заметить, что некоторые места в коде подчёркнуты красной волнистой линией. Это означает, что нет описания каких-то классов или методов классов.
Чтобы исправить это, нужно открыть в проекте файл включений "AST.h" и дописать в него следующие заголовки:
C++:
#include "G2API\oviewtrade.h"
#include "G2API\oinfo.h"
8) Снова ищем заголовочный файл, только уже "oviewtrade.h". Также открываем для редактирования и находим в нём класс "oCViewDialogStealContainer". Открываем публичный доступ к элементу "StealContainer" как показано на рисунке. Сохраняем файл.
9) Для того, чтобы отключить fps, время и другую отладочную информацию на экране, открываем файл "dllRefApp.cpp" в нашем проекте и делаем таким образом:
C++:
void _cb_ZenGin_WinMain()
{
_CFG::DisableAll(); //Отключить все настройки конфига
}
Здесь можно настроить выходной каталог прямо в папку с Готикой, чтобы каждый раз не копировать файл плагина. Также можно изменить название выходного файла плагина. Пример показан на рисунке.
11) Для того, чтобы по пути выходного каталога не создавался ещё и файл с отладочной информацией "Exchange.pdb", необходимо выбрать в главном меню: ПРОЕКТ → Свойства. Затем открыть: Свойства конфигурации → Компоновщик → Отладка. Изменить: Создавать отладочную информацию - Нет.
Сохраняем изменения.
12) Компилируем проект с помощью клавиши F7. После успешной компиляции заходим в выходной каталог и видим там файл нашего плагина: "Exchange.dll".
13) Чтобы запустить созданный плагин "Exchange.dll", необходимо прописать его в ini-файле вашего мода, в секции "[PLUGINS]" параметр "PluginList". Также необходимо указать в секции "[FILES]" загрузку библиотеки AST.dll в параметре "dll". Сама библиотека AST.dll должна находится в папке System игры. Найти её можно в архиве "AST_RELEASE_V1_003_SNAP072.zip" в папке "Release".
1) Открываем свой рабочий проект в GothicSourcer или просто папку с игровыми скриптами.
2) Находим подходящего персонажа для открытия у него функции обмена, например "VLK_404_Lutero". Заходим в его скрипт диалогов "dia_VLK_404_Lutero.d" и добавляем в него следующий код:
Daedalus:
instance DIA_Lutero_Exchange(C_Info)
{
npc = VLK_404_Lutero;
nr = 5;
condition = DIA_Lutero_Exchange_Condition;
information = DIA_Lutero_Exchange_Info;
permanent = TRUE;
description = "(Свободный обмен)";
trade = 2;//режим обмена
};
func int DIA_Lutero_Exchange_Condition()
{
return TRUE;
};
func void DIA_Lutero_Exchange_Info()
{
AI_Output(other,self,"DIA_Lutero_Exchange_15_00"); //Давай меняться.
};
Обратите внимание:
trade = 1 - это по прежнему режим торговли
trade = 2 - это уже режим обмена
3) На этом всё. Компилируем проект. Затем копируем скрипты либо с заменой в каталог с игрой, либо создаём том. Запускаем мод через "GothicStarter_AST.exe", который должен находится в папке System игры. Файл найти можно во вложении.
4) Результат работы:
Отечественный вариант плагина можно оставить в таком виде, в каком он есть сейчас, а вот зарубежный вариант должен поддаваться переводу. Для этого необходимо все текстовые названия вынести из плагина в скрипты, чтобы их можно было переводить и изменять. И потом уже из скриптов спокойно считывать эти названия и работать с ними в плагине.
Итак, из видимых названий у нас есть только заголовок обмена, поэтому выносим его в скрипты следующим образом:
1) В своём рабочем скриптовом проекте создаём текстовую переменную, например, в скрипте "Constants.d":
Daedalus:
//предположим, что название "Режим обмена" переведено на англ. язык
const string ExchangeTitle_Name = "Exchange mode";
2) В плагине задаём начальное значение переменной:
C++:
zSTRING ExchangeTitle_Name = "";
3) А также добавляем в код плагина функцию поиска переменной с названием заголовка.
Запуск функции будет происходить во время открытия режима обмена:
C++:
//Функция поиска текстовой переменной в скриптах
//(в данном случае заголовка обмена)
void parser_FindExchangeTitle()
{
//ищем текстовую переменную в скриптах с названием "ExchangeTitle_Name"
zCPar_Symbol* ps = parser->GetSymbol("ExchangeTitle_Name");
if (ps)//если нашли
//извлекаем значение переменной и записываем его...
//...в такую же здешнюю переменную "ExchangeTitle_Name"
ps->GetValue(ExchangeTitle_Name, 0);
//При отсутствии переменной в скриптах - будет пустая строка.
}
//**********************************************
// Перехват во время запуска блока информации
//**********************************************
//0x00662290 protected: void __fastcall oCInformationManager::OnInfo(class oCInfo *)
void __fastcall InfoMan_OnInfo(oCViewDialogTrade* _this, oCInfo* pInfo);
CInvoke <void(__fastcall*) (oCViewDialogTrade*, oCInfo*)> pInfoMan_OnInfo(0x00662290, InfoMan_OnInfo, IVK_AUTO);
void __fastcall InfoMan_OnInfo(oCViewDialogTrade* _this, oCInfo* pInfo)
{
//если включена торговля в режиме обмена
if (pInfo->pd.trade == 2)
{
//ставим флаг обмена
INV_MODE_EXCHANGE = TRUE;
//выполняем поиск названия заголовка обмена в скриптах
parser_FindExchangeTitle();
}
else//иначе обмен выключен
//обнуляем флаг обмена
INV_MODE_EXCHANGE = FALSE;
//вызываем оригинальную функцию
pInfoMan_OnInfo(_this, pInfo);
}
Примечание:
- Если переменная с заголовком обмена не объявлена в скриптах или объявлена, но у неё нет значения, то заголовок обмена отображаться не будет.
- Если переменная объявлена и у неё есть значение, то заголовок будет отображаться со значением этой переменной.
4) Компилируем скрипты, а также новый плагин. Смотрим результат. В данном случае он будет примерно таким:
Выражаю благодарность за помощь товарищам под никами: Дикарь, Gratt, hell9999, Saturas.