Это популярное сообщение. Kondr48 314 Опубликовано 15 Августа 2016 Это популярное сообщение. Поделиться Опубликовано 15 Августа 2016 (изменено) Ковыряемся в исходниках SoC. На данный момент тема ориентирована в большей степени на новичков. Здесь будут собираться готовые решения по мелкому ковырянию исходников движка SoC. Собственно приглашаю всех желающих присоединиться. Сборка исходников, необходимые программы. Расширения для диалогов: Скрытый текст Один из вариантов реализации случайных фраз у диалогов. Автор: Winsor. Часть 2. + немного переделанная функция дампа xml Автор: Winsor. Исправление ошибок: Скрытый текст Исправление отображения зеленым цветом прочитанных записей в разделе КПК "Дневник". Автор: lvg_brest Маленькое исправление колбека before save. Нашел: Карлан. Исправление сохранения клиентских объектов. Автор: Shoker Фикс вертикальной синхронизации (r2) Автор: SkyLoader Фикс не отключения ПНВ при удалении броника ф-циями release\transfer_item или продаже\выкладывании в другой инвентарь, автор: UnLoaded Исправление вылета по отсутствию звука. Путь до звука выводится в лог (как с текстурами в ЗП). Исправление пулестойкости костюма. Расширение скриптового функционала: Скрытый текст Функции, возвращающие текущий год и месяц. Функция перемотки времени из CoP. Создание колбеков для Актора на примере колбека на удар ножом. Назначение скриптам горячих клавиш, изменяемых в главном меню. Создание функции, перебирающей предметы на поясе. Работа с интерфейсом (худ, инвентарь и т.п.): визуальная часть: Скрытый текст Редактирование загрузочного экрана. Создание нового индикатора на худе. Расширение геймплея: Скрытый текст Создание нового слота. Новые параметры для бронежилетов. Восстановление функции рождения артефактов при срабатывании аномалии. Автор: Bak Добавление изменения переносимого веса в свойства артефактов. Массовое перемещение предметов между окнами, Автор: UnLoaded Зум в один клик. Автор: Shkiper2012. Дополнение: Kondr48 Порция мелких правок от Shkiper2012. Работа с рендером: Скрытый текст Скриншоты в формате png. Изменено 2 Ноября 2017 пользователем Kondr48 4 13 Ссылка на комментарий
Kondr48 314 Опубликовано 1 Февраля 2017 Автор Поделиться Опубликовано 1 Февраля 2017 (изменено) Совсем мелочь, но мне понадобилось, мб ещё кому-то будет надо. В SHoC существует три функции, для возврата игрового времени, в пространстве level: get_time_days() -- день get_time_hours() -- час get_time_minutes() -- минута Собственно, для своих целей я добавил аналогичные функции, которые возвращают текущий месяц и год. level_script.cpp: Перед: u32 get_time_days() { u32 year = 0, month = 0, day = 0, hours = 0, mins = 0, secs = 0, milisecs = 0; split_time(Level().GetGameTime(), year, month, day, hours, mins, secs, milisecs); return day; } добавим: u32 get_time_year() { u32 year = 0, month = 0, day = 0, hours = 0, mins = 0, secs = 0, milisecs = 0; split_time(Level().GetGameTime(), year, month, day, hours, mins, secs, milisecs); return year; } u32 get_time_month() { u32 year = 0, month = 0, day = 0, hours = 0, mins = 0, secs = 0, milisecs = 0; split_time(Level().GetGameTime(), year, month, day, hours, mins, secs, milisecs); return month; } и перед: def("get_time_days", get_time_days), добавим: def("get_time_year", get_time_year), def("get_time_month", get_time_month), На этом - всё, использовать в своих скриптах, вот так: local year = level.get_time_year() local month = level.get_time_month() Изменено 1 Февраля 2017 пользователем Kondr48 1 1 Ссылка на комментарий
Winsor 177 Опубликовано 2 Февраля 2017 Поделиться Опубликовано 2 Февраля 2017 (изменено) В продолжении темы борьбы с диалогами - необходимо в выше приведенном xr_3da\xrGame\PhraseDialog.cpp void CPhraseDialog::Load(shared_str dialog_id) заменить на такой: void CPhraseDialog::Load(shared_str dialog_id) { m_DialogId = dialog_id; bool need_load=inherited_shared::start_load_shared(m_DialogId); //начинаем загрузку if (need_load) //свеже созданное inherited_shared::load_shared(m_DialogId, nullptr); else if (GetDialogForceReload()) //уже создавалось раньше { CUIGameSP* ui_sp = smart_cast<CUIGameSP*>(HUD().GetUI()->UIGame()); if (ui_sp && ui_sp->TalkMenu->GetInitState()) //читать только если идет инициализация окна диалога. в других Load - загружать наново не надо { ITEM_DATA item_data = *id_to_index::GetById(m_DialogId); //перечитаем xml часть диалога std::string file_name=item_data._xml->m_xml_file_name; const size_t sidx = file_name.rfind('\\'); if (std::string::npos != sidx) file_name=file_name.substr(sidx+1,file_name.length()); item_data._xml->ClearInternal(); //почистим внутреннюю структуру xml парсера item_data._xml->Init(CONFIG_PATH, GAME_PATH, file_name.c_str());//заново запустим парсинг xml с диска data()->SetLoad(false); inherited_shared::load_shared(m_DialogId, nullptr); //перестроим граф диалогов на основании новой структуры xml } } } это позволит при установленном вышеописанном параметре для диалога заново перечитывать и распарсивать эго xml. Также , для меня чрезвычайно полезной оказалась немного переделанная функция дампа структуры xml, взятая с официальной документации TinyXML. Добавляем в в начало: #include <locale> #include <iostream> #include <sstream> и куда-нибудь, можно в конец: #pragma region dump xml from tinyxml docs const unsigned int NUM_INDENTS_PER_SPACE=2; const char * getIndent( unsigned int numIndents ) { static const char * pINDENT=" + "; static const unsigned int LENGTH=strlen( pINDENT ); unsigned int n=numIndents*NUM_INDENTS_PER_SPACE; if ( n > LENGTH ) n = LENGTH; return &pINDENT[ LENGTH-n ]; } // same as getIndent but no "+" at the end const char * getIndentAlt( unsigned int numIndents ) { static const char * pINDENT=" "; static const unsigned int LENGTH=strlen( pINDENT ); unsigned int n=numIndents*NUM_INDENTS_PER_SPACE; if ( n > LENGTH ) n = LENGTH; return &pINDENT[ LENGTH-n ]; } std::string dump_attributes(TiXmlElement* pElement, unsigned int indent) { if ( !pElement ) return ""; std::string result=""; TiXmlAttribute* pAttrib=pElement->FirstAttribute(); // const char* pIndent=getIndentAlt(indent); while (pAttrib) { std::stringstream ss; ss << pAttrib->Name() << ": value=["<<pAttrib->Value()<<"]"; pAttrib=pAttrib->Next(); result+=ss.str()+(result.length()>0? " " : ""); } return result; } void dumpTree(XML_NODE* startNode, unsigned int indent = 0) { TiXmlNode* pChild; TiXmlText* pText; int t = startNode->Type(); LPCSTR indentStr= getIndent(indent); switch ( t ) { case TiXmlNode::DOCUMENT: Msg( "Document" ); break; case TiXmlNode::ELEMENT: { std::string attrInfo=dump_attributes(startNode->ToElement(), indent+1); if (attrInfo.length()==0) Msg( "%sElement [%s]", indentStr,startNode->Value()); else Msg( "%sElement [%s] attributes:(%s)", indentStr,startNode->Value() ,attrInfo.c_str()); } break; case TiXmlNode::COMMENT: Msg( "%sComment: [%s]",indentStr, startNode->Value()); break; case TiXmlNode::UNKNOWN: Msg( "%sUnknown" ,indentStr); break; case TiXmlNode::TEXT: pText = startNode->ToText(); Msg( "%sText: [%s]", indentStr,pText->Value() ); break; case TiXmlNode::DECLARATION: Msg( "%sDeclaration",indentStr ); break; default: break; } //printf( "\n" ); for ( pChild = startNode->FirstChild(); pChild != nullptr; pChild = pChild->NextSibling()) dumpTree( pChild, indent+1 ); } #pragma endregion void CXml::dump() { Msg("--- start dump content for xml object based on %s ---",this->m_xml_file_name); dumpTree(GetRoot()); Msg("--- end dump content for xml object based on %s ---",this->m_xml_file_name); } В описание класса CXml добавляем в public: void dump(); Теперь, вызвав, например, в выше приведенном коде item_data._xml->dump(); в консоли мы увидим структуру распарсенного xml файла. Изменено 3 Февраля 2017 пользователем Kondr48 объединил посты 1 Ссылка на комментарий
Это популярное сообщение. Kondr48 314 Опубликовано 2 Февраля 2017 Автор Это популярное сообщение. Поделиться Опубликовано 2 Февраля 2017 (изменено) По сути с этого и нужно было начинать Сборка исходников в Visual Studio: Скрытый текст Это сложно назвать какой-то инструкцией, скорее описание того как это делаю я, на правильность не претендую, но у меня работает. Итак, для сборки исходников, нам нужно, для начала, их скачать. Я лично работаю на репозитории xp-dev, собственно альтернативы, которые в открытом доступе довольны печальны. Я лично "форкнулся" с r-180 потому что дальше там пошли какие то баги и непонятности, а так выбирать можно ревизию, собственно, любую, какую душе угодно. Дальнейшая статья будет относится именно к этому репо. Итак, скачать исходники можно тут. Для скачивания нам понадобится TorotoiseSVN. Найти можно на официальном сайте. Ссылка, которую нужно будет вставлять: https://xp-dev.com/svn/xray Как скачать исходники с помощью TorotoiseSVN Скрытый текст Создаём папку, в которую будем скачивать репозитории (для удобства лучше хранить все репозитории в одной папке, например, C:\SVN). Заходим в неё в проводнике Windows, нажимаем правой кнопкой мыши по свободному месту и выбираем «SVN Checkout…«. В поле «URL of repository» пишем полный URL до репозитория SVN, который нам нужно скачать, а в поле «Checkout directory» корректируем путь, в которой будет помещена локальная копия. Внимание! Вам нужно делать checkout только каталога /trunk/ svn-репозитория, либо корневого, если /trunk/ не существует (очень редко, т.к. в 99% репозиториев trunk существует и содержит всегда самую последнюю версию файлов). В списке «Checkout Depth» укажите «Fully recursive«, что означает, что будет скачан весь репозиторий от указанного пути. Если установить флажок «Omit externals«, то внешние файлы, на которые есть ссылки в репозитории (например, из других репозиториев, либо репозиториев третьих лиц), скачаны не будут, поэтому ставить флажок здесь не рекомендуется. В блоке «Revision» Вы можете запросить выдать Вам последнюю версию репозитория: «HEAD revision» (рекомендуется именно этот вариант), либо указанную Вам в поле ревизию: «Revision ###» (не рекомендуется). Кнопка «Show log» покажет Вам список изменений в репозитории с информацией об авторах каждого изменения, описании изменений (если авторы их вводили при коммите изменений), а также списке добавленных, изменённых и удалённых файлов. Здесь же можно просмотреть чем файл одной ревизии (версии) отличается от файла другой, а также запросить показать унифицированный diff-файл изменений либо нескольких файлов, либо нескольких ревизий (отображается только для текстовых файлов). Более подробную информацию о Log Viewer читайте ниже. Нажимаем кнопку «OK» и ждём скачивания репозитория с Subversion-сервера (зависит от скорости Вашего Интернет-соединения, а также от загруженности svn-сервера). Внимание! Некоторые svn-серверы могут запросить пароль. Если Вы не знаете пароля, то вводите anonsvn как логин и пароль. Это стандартный логин/пароль для анонимного доступа. Если Вы хотите в дальнейшем публиковать свои изменения в этот репозиторий и у Вас есть на это право, то введите здесь свой логин и пароль. Готово. В каталоге, который Вы указали на третьем шаге в поле «Checkout directory» теперь находится локальная версия репозитория (рабочая копия). Полная версия инструкции - здесь. Итак, теперь мы имеем на руках исходники. Для сборки нам понадобится установить на ПК: 1. Visual Studio 2010 (НЕ Express Version, у меня, по моему pro) 2. Visual Studio 2010 Service Pack 1 3. DirectX SDK June 2010. Я не уверен в необходимости его установки, но в изначальной инструкции он был. 4. DirectX SDK June 2007. Если ставили 2010, то 2007 ОБЯЗАТЕЛЬНО нужно ставить после 10. 5. Windows SDK 6. Скорее всего, понадобятся также некоторые dll из 6 патча: wrap_oal.dll, eax.dll, OpenAl32.dll (или же установить его). Для вашей звуковой карты, возможно придётся подобрать оптимальную комбинацию. У меня даже xrSound.dll какое-то время была от 1.0006. Как только мы установили всё это, открываем студию, ставим Solution Configurations - Release (насколько помню, дебаговая версия с репо не собирается) Все, дальше идет сборка, делать build\build solution я не советую, для этого проект, скорее всего придется отдельно настраивать. Я лично собираю библиотеки по очереди в таком порядке: 1. libogg_static 2. libtheora_static 3. libvorbis_static 4. libvorbisfile 5. nvtt 6. ode 7. xrD3D9-Null 8. LuaJIT 9. xrCore 10. Luabind 11. xrCDB 12. xrGameSpy 13. xrParticles 14. xrSound 15. xrXMLParser 16. xrNetServer 17. XR_3DA 18. xrCPU_Pipe 19. xrRender_R1 20. xrRender_R2 21. xrGame Скорее всего, можно и по другому, этот порядок у меня сложился эмпирически и вникать в настройки проекта мне пока банально лень: собирается и ладно. Собственно на этом всё. xrGame: level_script.cpp: В начала файла, перед: using namespace luabind; добавим инклуды: #include "alife_time_manager.h" #include "game_sv_single.h" #include "alife_simulator.h" Потом после: u32 get_time_minutes() { u32 year = 0, month = 0, day = 0, hours = 0, mins = 0, secs = 0, milisecs = 0; split_time(Level().GetGameTime(), year, month, day, hours, mins, secs, milisecs); return mins; } добавить: void change_game_time(u32 days, u32 hours, u32 mins) { game_sv_Single* tpGame = smart_cast<game_sv_Single *>(Level().Server->game); if (tpGame && ai().get_alife()) { u32 value = days * 86400 + hours * 3600 + mins * 60; float fValue = static_cast<float>(value); value *= 1000; // msec g_pGamePersistent->Environment().ChangeGameTime(fValue); tpGame->alife().time_manager().change_game_time(value); } } и в этом же файле, после: def("get_time_minutes", get_time_minutes), добавим: def("change_game_time", change_game_time), Теперь в файле alife_time_manager.h, после: IC float normal_time_factor () const; добавим: IC void change_game_time (u32 value); В файле alife_time_manager_inline.h добавим в конце: IC void CALifeTimeManager::change_game_time(u32 value) { m_game_time += value; } XR_3DA: Environment.h: после: shared_str GetWeather () { return CurrentWeatherName;} добавим: void ChangeGameTime (float game_time); Environment.cpp: перед: void CEnvironment::SetGameTime(float game_time, float time_factor) добавим: void CEnvironment::ChangeGameTime(float game_time) { fGameTime = NormalizeTime(fGameTime + game_time); }; Изменено 4 Апреля 2018 пользователем Kondr48 3 4 Ссылка на комментарий
Kondr48 314 Опубликовано 11 Февраля 2017 Автор Поделиться Опубликовано 11 Февраля 2017 Итак, за те картинки и надписи, которые мы видим при загрузке локации / сохранения, отвечает файл x_ray.cpp. Не только за них, но всё, что мы там видим настраивается именно в нём. Собственно, интерес представляет: load_texture = "ui\\ui_load"; Всё однозначно - фон загрузочного экрана. strconcat (sizeof(temp),temp,"intro\\intro_",Levels[L].folder); тут формируется картинка загружаемой локации. А это: hLevelLogo.create ("font", "intro\\intro_no_start_picture"); текстура "белого шума" которая выводится, если нужной картинки для локации у нас нету. Это: pFontSystem->SetColor (color_rgba(35,71,74,255)); Цвет надписей типа: "Клиент: синхронизация". RGBA Это: pFontSystem->OutI (0.f,0.524f,app_title); Координаты надписи: x,y. Надпись отрисовывается по центру, о чём нам говорит: pFontSystem->SetAligment (CGameFont::alCenter); Теперь, как настраивать размер и положение картинки загружаемой локации: находим: //draw level-specific screenshot if(hLevelLogo){ смотрим дальше: r.lt.set (0,175); собственно, координаты, x и y. А это: r.rb.add (r.lt,Fvector2().set(1024,399)); уже размеры, длина ширина. В прогресс бар, честно, не вникал. Ну не нравится мне его реализация. У себя я его просто закомментировал. Но настройки можно посмотреть после: progress bar back_size.set (479,26); 1 1 2 Ссылка на комментарий
Kondr48 314 Опубликовано 16 Февраля 2017 Автор Поделиться Опубликовано 16 Февраля 2017 (изменено) Кто-то из форумчан Карлан упоминал, вспомнил вот. Ошибка-опечатка в оригинальном репозитории xp-dev в колбеке на before save (вызывается перед созданием сейва, насколько я понял), точно есть с r180 и до финальной так и осталось. script_game_object_script.cpp: находим: value("on_before_save", int(GameObject::ePostSave)), и заменяем на: value("on_before_save", int(GameObject::eBeforeSave)), Изменено 16 Февраля 2017 пользователем Kondr48 1 Ссылка на комментарий
Kondr48 314 Опубликовано 17 Февраля 2017 Автор Поделиться Опубликовано 17 Февраля 2017 (изменено) Исправление сохранения клиентских объектов. Скрытый текст Автор: Shoker Более подробно о ошибке Из за этой опечатки в оригинале есть баг, что при сохранении игры в серверный объект попадают данные клиентского объекта, устаревшие на несколько апдейтов - именно в момент сохранения синхронизации не происходит. (Например если убрать в оружии сохранение патронов у клиентского объекта в CWeaponMagazined::save, оставив сохранение патронов только у серверного объекта - то если выстрелить и сразу сохраниться -> при загрузке число патронов будет прежним) Кто хочет понять природу бага - надо начинать смотреть с функции void CALifeStorageManager::prepare_objects_for_save() в alife_storage_manager.cpp. Она вызывается во время сохранения и в свою очередь вызывает CLevel::ClientSend(), однако там из за опечатки происходит проверка на пропускную способность сети net_HasBandwith() (для МП), которая в 99% возвращает false. Баг не то, чтобы критичный но всё же серьёзный. Исправление: В файле xr_3da\xrGame\Level_network.cpp в начале функции void CLevel::ClientSend() Перед проверкой GameID() == GAME_SINGLE нужно поставить отрицание: if (GameID() != GAME_SINGLE && OnClient()) Фикс вертикальной синхронизации (r2) Скрытый текст Автор: SkyLoader Файл: xr_3da\HW.cpp Найти DevPP.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; и P.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; Затем просто заменить D3DPRESENT_INTERVAL_IMMEDIATE на selectPresentInterval() Добавление изменения переносимого веса в свойства артефактов. Скрытый текст Artifact.h: после: float m_fBleedingRestoreSpeed; добавить: float m_additional_weight; Artifact.cpp: После: SetSlot (ARTEFACT_SLOT); добавить: m_additional_weight = 0.0f; После: m_fBleedingRestoreSpeed = pSettings->r_float(section,"bleeding_restore_speed"); добавить: m_additional_weight = pSettings->r_float(section,"additional_inventory_weight"); ActorCondition.cpp: после: CCustomOutfit* outfit = m_object->GetOutfit(); if(outfit) max_w += outfit->m_additional_weight; добавить: for(TIItemContainer::const_iterator it = object().inventory().m_belt.begin(); object().inventory().m_belt.end() != it; ++it) { CArtefact* cast_artefact = smart_cast<CArtefact*>(*it); if(cast_artefact) max_w += cast_artefact->m_additional_weight; } Чтобы добавляемый вес отображался в описании артефакта. На самом деле это стоит поверять: сработает ли именно так, потому что у себя я просто много уже в этом окошке переписывал Скрытый текст ui_af_params.h: после: _item_bleeding_restore_speed, добавить: _item_additional_inventory_weight, находим: LPCSTR af_item_sect_names[] = { после: "bleeding_restore_speed", добавим: "additional_inventory_weight", находим: LPCSTR af_item_param_names[] = { после: "ui_inv_bleeding", добавим: "ui_inv_additional_inventory_weight", после: LPCSTR _sn = "%"; if(i==_item_radiation_restore_speed || i==_item_power_restore_speed) { _val /= 100.0f; _sn = ""; } добавим: else if (i==_item_additional_inventory_weight) { _val /= 100.0f; _sn = *CStringTable().translate("st_kg"); } Изменено 22 Июня 2017 пользователем Kondr48 Добавлено Kondr48, 18 Февраля 2017 По поводу переносимого веса артефакта: нужно тестирование как работает, у самого пока нет возможности проверить, чуть позже дополню "как надо" 1 2 Ссылка на комментарий
Карлан 1 049 Опубликовано 18 Февраля 2017 Поделиться Опубликовано 18 Февраля 2017 @Kondr48, по поводу последнего спойлера. В ТЧ (оригинальном) два параметра переносимого веса. Я их называю ограничивающий и расчетный, ты изменяешь в коде только первый. Что это означает на практике? Это означает, что носить ты сможешь больше, но критический вес остается на той же отметке. Данная логика работы является некорректной с точки зрения оригинального механизма. Отсюда вытекает и проблема какой именно параметр из двух отображать в окне описания, поэтому чтобы все разрешить корректно нужно либо объединить все воедино, либо прибегнуть к какому-то иному алгоритму для массы. Мое решение можно рассмотреть как один из вариантов. Добавлено Kondr48, 18 Февраля 2017 Спасибо, у себя я, по-моему от второго параметра отказался. 1 Ссылка на комментарий
ARayKo60 240 Опубликовано 28 Февраля 2017 Поделиться Опубликовано 28 Февраля 2017 Редактирование загрузочного экрана. А есть ли возможность вывести в xml файл, а из него тогда редактировать загрузочный экран? Ссылка на комментарий
krop 11 Опубликовано 28 Февраля 2017 Поделиться Опубликовано 28 Февраля 2017 А есть ли возможность вывести в xml файл, а из него тогда редактировать загрузочный экран? Вполне. Ссылка на комментарий
Kondr48 314 Опубликовано 28 Февраля 2017 Автор Поделиться Опубликовано 28 Февраля 2017 (изменено) А есть ли возможность вывести в xml файл, а из него тогда редактировать загрузочный экран? Это не так просто как кажется, xml он в xr_game, а загрузочный экран в экзешнике, а экзешник он перед xr_game собирается, т. е там надо будет как-то переносить в xr_game это, что скорее всего будет не так просто, как я думаю. Изменено 28 Февраля 2017 пользователем Kondr48 1 Ссылка на комментарий
ARayKo60 240 Опубликовано 4 Марта 2017 Поделиться Опубликовано 4 Марта 2017 Возник вопрос, все знают что для иконок амуниции, оружия, артефактов и разных инвентарных предметов используется файл ui_icon_equipment.dds, и как бы сделать так, чтобы можно было не использовать оригинальный а создавать свой собственный(дополнительный) аналогичный ui_icon_equipment.dds чтобы движок использовал тоже? Добавлено Kondr48, 4 Марта 2017 Я посмотрю где это, думаю получится сделать так, чтобы если в конфиге не указан "новый" файл, игра юзала стандартный, если получится у меня, распишу и выложу здесь. Ссылка на комментарий
Kober(BRUC) 99 Опубликовано 5 Марта 2017 Поделиться Опубликовано 5 Марта 2017 @Kondr48, если не получится, расскажи хоть где копать. Ссылка на комментарий
UnLoaded 313 Опубликовано 5 Марта 2017 Поделиться Опубликовано 5 Марта 2017 (изменено) расскажи хоть где копать. в xrGame\ui\UIInventoryUtilities.cpp объявлен дефайн #define EQUIPMENT_ICONS "ui\\ui_icon_equipment" далее, там-же ref_shader& InventoryUtilities::GetEquipmentIconsShader() { if(!g_EquipmentIconsShader) { g_EquipmentIconsShader.create("hud\\default", EQUIPMENT_ICONS); } return g_EquipmentIconsShader; } Остается только продумать, как организовать указание движку, откуда иконки читать... Обнаружил такую вот бяку: если на ГГ надет броник с ПНВ, и ПНВ включен, то при удалении этого броника ф-циями release\transfer_item или продаже\выкладывании в другой инвентарь, ПНВ не выключается. Порылся в исходниках, нашел такое решение: в xrGame\Inventory.cpp находим ф-цию bool CInventory::DropItem(CGameObject *pObj). Прямо перед ней добавляем #include "customoutfit.h" #include "torch.h" в теле ф-ции находим и добавляем(то, что выделено): case eItemPlaceSlot: { R_ASSERT (InSlot(pIItem)); if(m_iActiveSlot == pIItem->GetSlot()) Activate(NO_ACTIVE_SLOT); m_slots[pIItem->GetSlot()].m_pIItem = NULL; pIItem->object().processing_deactivate(); ///это добавить CCustomOutfit* pOutfit = smart_cast(pObj); if (pOutfit) { CTorch* pTorch = smart_cast(ItemFromSlot(TORCH_SLOT)); if (pTorch) pTorch->SwitchNightVision(false); } /// }break; Потестил, вроде все как надо. Хотя может можно и по другому ? Изменено 5 Марта 2017 пользователем Kondr48 Убрал портянки под спойлеры 2 Ссылка на комментарий
Kondr48 314 Опубликовано 5 Марта 2017 Автор Поделиться Опубликовано 5 Марта 2017 (изменено) Остается только продумать, как организовать указание движку, откуда иконки читать... Конкретно текстура иконок в нескольких местах читается, там надо просто найти место, где задается иконка и там уже задавать путь к текстуре. А везде где дергается текстура просто функцией вроде get_enqurimet_texture() читать. Сложностей возникнуть не должно, надо просто размотать всю эту цепочку и вникнуть где что и откуда читается и куда присваивается, чтобы свое добавить. Потестил, вроде все как надо. Хотя может можно и по другому ? Да, в принципе, как и надо, я правда не вникал, во всех ли названный случаях вызвается drop, но если все работает, то это хорошо. Изменено 5 Марта 2017 пользователем Kondr48 Ссылка на комментарий
UnLoaded 313 Опубликовано 5 Марта 2017 Поделиться Опубликовано 5 Марта 2017 (изменено) надо просто размотать всю эту цепочку Дак вроде ж выше уже размоталась: поиск по файлам проекта "ui_icon_equipment" - результат 1 строка, выше уже писал где и какая. Далее, поиск "EQUIPMENT_ICONS" - результатов уже 4, но 2 из них - файл xrGame\game_cl_mp.cpp, в нем все касаемо мультиплеера + там совсем другой файл дефайнится, значит нам не интересны. Оставшиеся 2 - описаны выше, и следовательно, вся размотка заканчивается на ф-ции ref_shader& InventoryUtilities::GetEquipmentIconsShader(). Я думаю, можно дефайн убрать(зачем он, если используется всего один раз?), а в ф-ции сделать вычитывание имени файла как нам хоца. Ну, к примеру, из добавленного нового параметра в system.ltx, в котором прописывать новый файл... Всегда, играя в какой-нить мод, где есть квесты типа "собери 30 детекторов, отнеси кому-то - получишь обертку от чупа-чупсы", напрягало меня отсутствие возможности взять разом из нычки все эти накопленные 30 детекторов. По этому, сделал такую себе правочку, для окна обыска инв.ящиков\нычек\трупов: В xrGame\ui\UIMessages.h добавляем в конец(у меня после MAP_SELECT_SPOT): ..... MAP_HIDE_HINT, MAP_SELECT_SPOT, INVENTORY_TAKE_ALL //<- это Далее, в xrGame\ui\UICarBodyWnd.cpp, в ф-ции void CUICarBodyWnd::ActivatePropertiesBox(): ..... m_pUIPropertiesBox->RemoveAll(); LPCSTR _action = NULL; ///// это добавить - если в ячейке инв. более одного предмета, то добавляем соотв. пункт в меню правого клика мыша bool b_added = false; CUICellItem* itm = CurrentItem(); for (u32 i = 0; i < itm->ChildsCount(); ++i) { b_added = true; break; } if (b_added) { _action = "st_move_all"; b_show = true; m_pUIPropertiesBox->AddItem(_action, NULL, INVENTORY_TAKE_ALL); } ///// if (m_pInventoryBox) { ..... затем в том же файле, в ф-ции void CUICarBodyWnd::SendMessage(CUIWindow *pWnd, s16 msg, void *pData): ..... switch(m_pUIPropertiesBox->GetClickedItem()->GetTAG()) { case INVENTORY_EAT_ACTION: EatItem(); break; ///// это добавить - обрабатываем выбор добавленного пункта меню case INVENTORY_TAKE_ALL: MoveAllfromCell(); break; ///// case INVENTORY_UNLOAD_MAGAZINE: { ..... Теперь добавим саму ф-цию перемещения, сначала в xrGame\ui\UICarBodyWnd.h объявим как protected: void MoveAllfromCell(); затем, опять в xrGame\ui\UICarBodyWnd.cpp, сама ф-ция: void CUICarBodyWnd::MoveAllfromCell() { u16 tmp_id = 0; CUIDragDropListEx* owner_list = CurrentItem()->OwnerList(); if (owner_list != m_pUIOthersBagList) { // перемещаем в актерский инв. CUICellItem* ci = CurrentItem(); for (u32 j = 0; j<ci->ChildsCount(); ++j) { PIItem _itm = (PIItem)(ci->Child(j)->m_pData); if (m_pOthersObject) TransferItem(_itm, m_pOurObject, m_pOthersObject, false); else { move_item(tmp_id, m_pInventoryBox->ID(), _itm->object().ID()); // ЭТО ПОХОЖЕ заткнута выдача кэллбэка на взятие предмета из инв. ящика //. Actor()->callback(GameObject::eInvBoxItemTake)( m_pInventoryBox->lua_game_object(), _itm->object().lua_game_object() ); } } PIItem itm = (PIItem)(ci->m_pData); if (m_pOthersObject) TransferItem(itm, m_pOurObject, m_pOthersObject, false); else { move_item(tmp_id, m_pInventoryBox->ID(), itm->object().ID()); // ЭТО ПОХОЖЕ заткнута выдача кэллбэка на взятие предмета из инв. ящика //. Actor()->callback(GameObject::eInvBoxItemTake)(m_pInventoryBox->lua_game_object(), itm->object().lua_game_object() ); } } else { // перемещаем из актерского в другой инв. CUICellItem* ci = CurrentItem(); for (u32 j = 0; j<ci->ChildsCount(); ++j) { PIItem _itm = (PIItem)(ci->Child(j)->m_pData); if (m_pOthersObject) TransferItem(_itm, m_pOthersObject, m_pOurObject, false); else { move_item(m_pInventoryBox->ID(), tmp_id, _itm->object().ID()); // ЭТО ПОХОЖЕ заткнута выдача кэллбэка на взятие предмета из инв. ящика //. Actor()->callback(GameObject::eInvBoxItemTake)( m_pInventoryBox->lua_game_object(), _itm->object().lua_game_object() ); } } PIItem itm = (PIItem)(ci->m_pData); if (m_pOthersObject) TransferItem(itm, m_pOthersObject, m_pOurObject, false); else { move_item(m_pInventoryBox->ID(), tmp_id, itm->object().ID()); // ЭТО ПОХОЖЕ заткнута выдача кэллбэка на взятие предмета из инв. ящика //. Actor()->callback(GameObject::eInvBoxItemTake)(m_pInventoryBox->lua_game_object(), itm->object().lua_game_object() ); } } } Ну и последнее: в конфиге config\text\rus\ui_st_inventory.xml добавляем идентификатор "st_move_all" и текст для него: <?xml version="1.0" encoding="windows-1251" ?> <string_table> <string id="st_move_all"> <text>переместить все</text> </string> <string id="st_activate_artefact"> <text>активировать артефакт</text> </string>..... ..... Вроде все, теперь, если в окне обыска будет в ячейке более одного предмета - правый клик мыша -> "переместить все". Работает в обоих направлениях: инв. ГГ <-> другой инв. P.S. может что забыл из добавленного, если не взлетит у кого - отпишитесь, по-вспоминаю точнее. Изменено 5 Марта 2017 пользователем UnLoaded Добавлено Kondr48, 5 Марта 2017 "ui_icon_equipment" встретилась мне еще в maingame по-моему. Добавлено Kondr48, 16 Марта 2017 По поводу пункта в менюшке "взять всё". Оно, вероятно должно работать, вот только в репозитории КД начиная со 180 ревизии (а мб и раньше) менюшка по клику пкм в car body изначально не работает =) 1 1 Ссылка на комментарий
ARayKo60 240 Опубликовано 11 Марта 2017 Поделиться Опубликовано 11 Марта 2017 Давний вопрос, в пда есть вкладка Лучшая 20-ка сталкеров, можно бы сделать чтобы в списке отображались все сталкеры которые реально присутствуют в игре, и также чтобы попадали в список и новые заспавненные? Многие играя собирают за всю игру много хабара и в течении игры продают но в пда нет статистики на этот счет, было бы удобно особенно для тестов модов, все это конечно можно сделать скриптами , но хотелось что бы движково было. Ну и про артефакты: неплохо бы реализовать параметры у артефактов как например: страх-при ношении которого у мутантов, может даже и у нпс вызывает панику и многие рангом ниже вашего пытаются убежать от вас. Или например агрессия-все нпс и мобы начинают нападать друг на друга особенно на вас. Можно даже котроль: управление нпс и мутантами попадающие в поле воздействия артефакта. Добавлено Kondr48, 11 Марта 2017 Сделать то можно, найти бы кто будет этим заниматься) Ссылка на комментарий
плащ 0 Опубликовано 13 Марта 2017 Поделиться Опубликовано 13 Марта 2017 Где-то на форуме я уже слышал о попытках переноса детекторов артефактов из ЧН/ЗП в ТЧ.Вопросы со слотом, невидимости артефактов опустим (А - Просто, Б - уже реализовано и выложено в свободный доступ), а вот сами детекторы с рабочем функционалом?Есть у кого наработки на эту тему? Добавлено Kondr48, 15 Марта 2017 Ну как наработки... Частично перенес я себе визуал отклика, там со свечением возник небольшой затык, позже собираюсь доделать. В принципе если кому интересно, на вопросы, если смогу отвечу) Пытаюсь создать глобальный мод с новым сюжетом,буду рад любой оказанной помощи Ссылка на комментарий
Kondr48 314 Опубликовано 15 Марта 2017 Автор Поделиться Опубликовано 15 Марта 2017 Прошу кого-нибудь на чистой ревизии попробовать по тутору добавить артефакту переносимый вес и отписаться все ли корректно-таки работает. Ссылка на комментарий
UnLoaded 313 Опубликовано 16 Марта 2017 Поделиться Опубликовано 16 Марта 2017 (изменено) Оно, вероятно должно работать, вот только в репозитории КД начиная со 180 ревизии (а мб и раньше) менюшка по клику пкм в car body изначально не работает =)Я забыл уточнить, для всех правок за моим авторством, что сделаны они для "чистых" исходников 1.0007rc1(скачаны из этого места). Изменено 16 Марта 2017 пользователем UnLoaded 1 Ссылка на комментарий
плащ 0 Опубликовано 22 Марта 2017 Поделиться Опубликовано 22 Марта 2017 (изменено) Хотелось бы спросить по поводу урока: "Новые параметры для бронежилетов.".Параметры есть и прекрасно работают, но возник вопрос на тему их визуализации.Ведь в инвентаре есть такой блок как <outfit_info> и ясное дело новые параметры не будут отображаться так как в движке их нет.Как я понял вся возня крутиться в файлах UIOutfitInfo.h и UIOutfitInfo.срр.Решить эту проблему я хотел такими методами, но задумка не увенчалась успехом:UIOutfitInfo.сср LPCSTR _imm_names []={ "health_restore_speed", "radiation_restore_speed", "satiety_restore_speed", "power_restore_speed", "bleeding_restore_speed", LPCSTR _imm_st_names[]={ "ui_inv_health", "ui_inv_radiation", "ui_inv_satiety", "ui_inv_power", "ui_inv_bleeding", UIOutfitInfo.h enum{ _item_health_restore_speed, _item_radiation_restore_speed, _item_satiety_restore_speed, _item_power_restore_speed, _item_bleeding_restore_speed, Изменено 22 Марта 2017 пользователем плащ Добавлено Kondr48, 22 Марта 2017 Так их же еще и вывести надо, перебирать созданные массивы и создавать статики, смотрите как сделано у иммунитетов, где массив в цикле перебирается. Пытаюсь создать глобальный мод с новым сюжетом,буду рад любой оказанной помощи Ссылка на комментарий
Рекомендуемые сообщения
Создайте аккаунт или авторизуйтесь, чтобы оставить комментарий
Комментарии могут оставлять только зарегистрированные пользователи
Создать аккаунт
Зарегистрировать новый аккаунт в нашем сообществе. Это несложно!
Зарегистрировать новый аккаунтВойти
Есть аккаунт? Войти.
Войти