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

[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 файл, а из него тогда редактировать загрузочный экран?

Это не так просто как кажется, 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 пользователей

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