Перейти к контенту

[SOC] Мелкие правки движка


Рекомендуемые сообщения

Совсем мелочь, но мне понадобилось, мб ещё кому-то будет надо.

В 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()

 

 

Изменено пользователем Kondr48
  • Нравится 1
  • Полезно 1
Ссылка на комментарий

В продолжении темы борьбы с диалогами - необходимо в выше приведенном 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 файла.

Изменено пользователем Kondr48
объединил посты
  • Спасибо 1
Ссылка на комментарий

Итак, за те картинки и надписи, которые мы видим при загрузке локации / сохранения, отвечает файл 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
Ссылка на комментарий

Кто-то из форумчан Карлан упоминал, вспомнил вот. Ошибка-опечатка в оригинальном репозитории xp-dev в колбеке на before save (вызывается перед созданием сейва, насколько я понял), точно есть с r180 и до финальной так и осталось.

script_game_object_script.cpp:

находим:

value("on_before_save", int(GameObject::ePostSave)),

и заменяем на:

value("on_before_save", int(GameObject::eBeforeSave)),
Изменено пользователем Kondr48
  • Нравится 1
Ссылка на комментарий

Исправление сохранения клиентских объектов.

Скрытый текст

Автор: 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");
		} 

 

 

 

Изменено пользователем Kondr48
Добавлено Kondr48,

По поводу переносимого веса артефакта: нужно тестирование как работает, у самого пока нет возможности проверить, чуть позже дополню "как надо"

  • Спасибо 1
  • Полезно 2
Ссылка на комментарий

@Kondr48, по поводу последнего спойлера. В ТЧ (оригинальном) два параметра переносимого веса. Я их называю ограничивающий и расчетный, ты изменяешь в коде только первый. Что это означает на практике? Это означает, что носить ты сможешь больше, но критический вес остается на той же отметке. Данная логика работы является некорректной с точки зрения оригинального механизма. Отсюда вытекает и проблема какой именно параметр из двух отображать в окне описания, поэтому чтобы все разрешить корректно нужно либо объединить все воедино, либо прибегнуть к какому-то иному алгоритму для массы. Мое решение можно рассмотреть как один из вариантов.

Добавлено Kondr48,

Спасибо, у себя я, по-моему от второго параметра отказался.

  • Полезно 1
Ссылка на комментарий

 

 

Редактирование загрузочного экрана.

А есть ли возможность вывести в xml файл, а из него тогда редактировать загрузочный экран?

Ссылка на комментарий

А есть ли возможность вывести в xml файл, а из него тогда редактировать загрузочный экран?

Это не так просто как кажется, xml он в xr_game, а загрузочный экран в экзешнике, а экзешник он перед xr_game собирается, т. е там надо будет как-то переносить в xr_game это, что скорее всего будет не так просто, как я думаю.

Изменено пользователем Kondr48
  • Полезно 1
Ссылка на комментарий

Возник вопрос, все знают что для иконок амуниции, оружия, артефактов и разных инвентарных предметов используется файл ui_icon_equipment.dds, и как бы сделать так, чтобы можно было не использовать оригинальный а создавать свой собственный(дополнительный) аналогичный ui_icon_equipment.dds чтобы движок использовал тоже?

Добавлено Kondr48,

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

Ссылка на комментарий
расскажи хоть где копать.

в 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;

 

 

Потестил, вроде все как надо. Хотя может можно и по другому ?

Изменено пользователем Kondr48
Убрал портянки под спойлеры
  • Спасибо 2
Ссылка на комментарий

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

Конкретно текстура иконок в нескольких местах читается, там надо просто найти место, где задается иконка и там уже задавать путь к текстуре. А везде где дергается текстура просто функцией вроде get_enqurimet_texture() читать. Сложностей возникнуть не должно, надо просто размотать всю эту цепочку и вникнуть где что и откуда читается и куда присваивается, чтобы свое добавить.

Потестил, вроде все как надо. Хотя может можно и по другому ?

Да, в принципе, как и надо, я правда не вникал, во всех ли названный случаях вызвается drop, но если все работает, то это хорошо.

Изменено пользователем Kondr48
Ссылка на комментарий
надо просто размотать всю эту цепочку

Дак вроде ж выше уже размоталась: поиск по файлам проекта "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. может что забыл из добавленного, если не взлетит у кого - отпишитесь, по-вспоминаю точнее.

 

Изменено пользователем UnLoaded
Добавлено Kondr48,

"ui_icon_equipment" встретилась мне еще в maingame по-моему.

Добавлено Kondr48,

По поводу пункта в менюшке "взять всё".

Оно, вероятно должно работать, вот только в репозитории КД начиная со 180 ревизии (а мб и раньше) менюшка по клику пкм в car body изначально не работает =)

  • Спасибо 1
  • Согласен 1
Ссылка на комментарий

Давний вопрос, в  пда есть вкладка Лучшая 20-ка сталкеров, можно бы сделать чтобы в списке отображались все сталкеры которые реально присутствуют в игре, и также чтобы попадали в список и новые заспавненные?

 

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

 

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

Добавлено Kondr48,

Сделать то можно, найти бы кто будет этим заниматься)

Ссылка на комментарий

Где-то на форуме я уже слышал о попытках переноса детекторов артефактов из ЧН/ЗП в ТЧ.
Вопросы со слотом, невидимости артефактов опустим (А - Просто, Б - уже реализовано и выложено в свободный доступ), а вот сами детекторы с рабочем функционалом?
Есть у кого наработки на эту тему?


  

Добавлено Kondr48,

Ну как наработки... Частично перенес я себе визуал отклика, там со свечением возник небольшой затык, позже собираюсь доделать. В принципе если кому интересно, на вопросы, если смогу отвечу)

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

Ссылка на комментарий

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

Ссылка на комментарий

Оно, вероятно должно работать, вот только в репозитории КД начиная со 180 ревизии (а мб и раньше) менюшка по клику пкм в car body изначально не работает =)

Я забыл уточнить, для всех правок за моим авторством, что сделаны они для "чистых" исходников 1.0007rc1(скачаны из этого места). Изменено пользователем UnLoaded
  • Спасибо 1
Ссылка на комментарий

Хотелось бы спросить по поводу урока: "Новые параметры для бронежилетов.".
Параметры есть и прекрасно работают, но возник вопрос на тему их визуализации.
Ведь в инвентаре есть такой блок как <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,

 

 

Изменено пользователем плащ
Добавлено Kondr48,

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

 

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

Ссылка на комментарий

Создайте аккаунт или авторизуйтесь, чтобы оставить комментарий

Комментарии могут оставлять только зарегистрированные пользователи

Создать аккаунт

Зарегистрировать новый аккаунт в нашем сообществе. Это несложно!

Зарегистрировать новый аккаунт

Войти

Есть аккаунт? Войти.

Войти
  • Недавно просматривали   0 пользователей

    • Ни один зарегистрированный пользователь не просматривает эту страницу.
×
×
  • Создать...