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

Gameplay - как сделать ЭТО, чтобы ОНО всем нравилось ;)


Dennis_Chikin

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

Не знаю, наверное это наиболее подходящая тема. Что можно придумать со свойствами артефактов?) Как-то хотелось бы показатели подправить.

Привожу на примерах.

health_restore_speed - это скорость восстановления здоровья. По идее логично считать в процентах. Мы же увеличиваем эту скорость. Следовательно, при ста процентах здоровье должно восполниться мгновенно. Ну и, соответственно, при -100 мгновенно убить ГГ. (кому бы оно надо было :) )

Но за какое время его восстанавливать? Этот процент, два или три? За секунду?

Например, если у артефакта в свойствах написано:

Восстановление здоровья: +1%
Это будет значить, что за секунду добавляется процент к общему здоровью ГГ?
radiation_restore_speed а это в чем лучше измерять? Также в процентах? Или какие-нибудь бэры, рады и прочее нарисовать? (ещё бы я в этом что-то понимал  :))
Собственно, сделав это будет нереально легко настраивать параметры для артефактов и, что самое главное, игрок когда посмотрит на все эти циферки будет понимать, чего от такого артефакта ждать.
Но, если сделать проценты в секунду, то из практически мертвого состояния за ~100 секунд показатель полностью восстановится/обнулится.
Это подходит далеко не для всех параметров, если при ношении артефакта ГГ получит полную шкалу радиации за ~ 1:40 секунд (причем не факт что он доживёт до момента заполнения этой шкалы.) это будет как минимум плохо. Это при том что 1% типа минимальная циферка после 0  :)  а может быть и 3, и 5, и 10%.
С технической точки зрения вопросов нет, благо есть исходники движка и подправить в нём коэффициенты труда не составит. Мне нужны Ваши идеи, как рассчитывать тот или иной показатель. Что бы это нравилось в первую очередь игроку. Ну или ткните куда-нибудь, если где-то это вменяемо оформлено.
Изменено пользователем Kondr48

Поделиться этим сообщением


Ссылка на сообщение

 

ed_rez, вот об этом и речь. Нужны разумные единицы влияния. Собственно по ним мне и нужны идеи. Какой показатель с течением времени как должен на ГГ действовать.

 

Поделиться этим сообщением


Ссылка на сообщение

а чем не устраивает текущее? +1% к скорости восстановления здоровья означает, что скорость восстановления здоровья увеличится на 1%

Ну как минимум тем, что в конфигах там никакими процентами не пахнет, задаются абстрактные 0,0002 и т. п. Мб это только на исходниках так, но сейчас там при выведении свойств артефакта показатель просто умножается на 100, т. е. те же 0,0002 * 100 = 0,02% ~= 0% последнее и выводится. А там же не ноль, здоровье то будет восстанавливаться.

 если менять, то я бы поменял только способ задания скоростей восстановления и т.п. Что бы не в абсолютных величинах задавать, как сейчас, а в процентах от соотв. параметров актора.

А вот это уже интересно. Только не для всего сгодится. Например для выносливости, голода, жажды вполне годится (так скорее всего и сделаю) пси-здоровье то, наверное, со временем должно в форму приходить, так что ему тоже подойдет. а вот для здоровья как-то иначе придется делать. Потому что по факту скорость восстановления здоровья без всяких "улучшителей" вроде артефактов и медикаментов должна быть очень близкой к 0  :) . То же относится и к радиации, кровотечению. 

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

Тогда уж отключить вывод характеристики артефактов вообще, сделать разумно-рандомные свойства и вообще не ясно будет чего ждать от артефакта. Реалистично, может быть, но уже в ущерб играбельности по-моему. Конечно геймплейно-сюжетно можно сюда учёных приплести, для оценки свойств или девайс какой (сканер, анализатор) опять же связанный с базой данных ученых, тут уже насколько фантазии хватит.

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

Поделиться этим сообщением


Ссылка на сообщение

если была бы возможность проводить перерасчет в конфигураторе

Я никак не пойму, что значит перерасчет в конфигураторе.  :)

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

Поделиться этим сообщением


Ссылка на сообщение

Видимо я не совсем понял Kondr48-а и он иную проблему рассматривает. В общем, я высказал то, с чем сам столкнулся. Да, личная хотелка, да, самому решать- тут не в этом дело.

Ну не то чтобы иную, в целом именно её, хочется переписать расчёт артефактов так чтобы удобно было настраивать их модмейкеру и всё было более чем ясно для игрока.

Там в движке вообще какая-то непонятная магия в свойствах артефактов на самом деле, вроде и на первый взгляд как-то логично, но сделано довольно странно. Свойства из конфига артефакта делятся на некие соответствующие у актора, потом это всё умножается на 100. Потом идут дальнейшие деления / умножения для конкретных свойств. Например кровотечение потом опять делится на 100, и выходит что цифра должна выводиться прямо из конфига?

#include "stdafx.h"
#include "ui_af_params.h"
#include "UIStatic.h"
#include "../object_broker.h"
#include "../Artifact.h"
#include "../Actor.h"
#include "../ActorCondition.h"
#include "UIXmlInit.h"

CUIArtefactParams::CUIArtefactParams()
{
	Memory.mem_fill			(m_info_items, 0, sizeof(m_info_items));
}

CUIArtefactParams::~CUIArtefactParams()
{
	for(u32 i=_item_start; i<_max_item_index; ++i)
	{
		CUIStatic* _s			= m_info_items[i];
		xr_delete				(_s);
	}
}

LPCSTR af_item_sect_names[] = {
	"health_restore_speed",
	"radiation_restore_speed",
	"satiety_restore_speed",
	"power_restore_speed",
	"bleeding_restore_speed",
	
	"burn_immunity",
	"strike_immunity",
	"shock_immunity",
	"wound_immunity",		
	"radiation_immunity",
	"telepatic_immunity",
	"chemical_burn_immunity",
	"explosion_immunity",
	"fire_wound_immunity",
};

LPCSTR af_item_param_names[] = {
	"ui_inv_health",
	"ui_inv_radiation",
	"ui_inv_satiety",
	"ui_inv_power",
	"ui_inv_bleeding",

	"ui_inv_outfit_burn_protection",			// "(burn_imm)",
	"ui_inv_outfit_strike_protection",			// "(strike_imm)",
	"ui_inv_outfit_shock_protection",			// "(shock_imm)",
	"ui_inv_outfit_wound_protection",			// "(wound_imm)",
	"ui_inv_outfit_radiation_protection",		// "(radiation_imm)",
	"ui_inv_outfit_telepatic_protection",		// "(telepatic_imm)",
	"ui_inv_outfit_chemical_burn_protection",	// "(chemical_burn_imm)",
	"ui_inv_outfit_explosion_protection",		// "(explosion_imm)",
	"ui_inv_outfit_fire_wound_protection",		// "(fire_wound_imm)",
};

LPCSTR af_actor_param_names[]={
	"satiety_health_v",
	"radiation_v",
	"satiety_v",
	"satiety_power_v",
	"wound_incarnation_v",
};
#ifdef AF_SHOW_DYNAMIC_PARAMS
float CArtefact::* af_prop_offsets[] = {
	&CArtefact::m_fHealthRestoreSpeed,
	&CArtefact::m_fRadiationRestoreSpeed,
	&CArtefact::m_fSatietyRestoreSpeed,
	&CArtefact::m_fPowerRestoreSpeed,
	&CArtefact::m_fBleedingRestoreSpeed
};
#endif



void CUIArtefactParams::InitFromXml(CUIXml& xml_doc)
{
	LPCSTR _base				= "af_params";
	if (!xml_doc.NavigateToNode(_base, 0))	return;

	string256					_buff;
	CUIXmlInit::InitWindow		(xml_doc, _base, 0, this);

	for(u32 i=_item_start; i<_max_item_index; ++i)
	{
		m_info_items[i]			= xr_new<CUIStatic>();
		CUIStatic* _s			= m_info_items[i];
		_s->SetAutoDelete		(false);
		strconcat				(sizeof(_buff),_buff, _base, ":static_", af_item_sect_names[i]);
		CUIXmlInit::InitStatic	(xml_doc, _buff,	0, _s);
	}
}

bool CUIArtefactParams::Check(const shared_str& af_section)
{
	return !!pSettings->line_exist(af_section, "af_actor_properties");
}
#include "../string_table.h"
void CUIArtefactParams::SetInfo(CGameObject *obj)
{	
	CArtefact *art = smart_cast<CArtefact*> (obj);
	R_ASSERT2(art, "object is not CArtefact");
	const shared_str& af_section = art->cNameSect();
	CActor *pActor = Actor();
	if (!pActor) return;

	string128					_buff;
	float						_h = 0.0f;
	DetachAll					();
	for(u32 i=_item_start; i<_max_item_index; ++i)
	{
		CUIStatic* _s			= m_info_items[i];

		float					_val;
		if(i<_max_item_index1)
		{
#ifdef AF_SHOW_DYNAMIC_PARAMS
			float _actor_val	= pActor->conditions().GetParamByName(af_actor_param_names[i]);			
			float CArtefact::* pRestoreSpeed = af_prop_offsets[i];
			_val = (art->*pRestoreSpeed); // alpet: используется указатель на данные класса
#else
			_val				= pSettings->r_float	(af_section, af_item_sect_names[i]);
			float _actor_val	= pSettings->r_float	("actor_condition", af_actor_param_names[i]);
#endif
			if					(fis_zero(_val))				continue;
			
			_val				= (_val/_actor_val)*100.0f;
		}else
		{
#ifdef AF_SHOW_DYNAMIC_PARAMS			
			u32 idx = i - _max_item_index1;  // absorbation index			 
			_val = art->m_ArtefactHitImmunities.immunities()[idx]; // real absorbation values			
#else
			shared_str _sect	= pSettings->r_string(af_section, "hit_absorbation_sect");
			_val				= pSettings->r_float(_sect, af_item_sect_names[i]);
#endif
			if					(fsimilar(_val, 1.0f))				continue;
			_val				= (1.0f - _val);
			_val				*= 100.0f;

		}
		LPCSTR _sn = "%";
		if(i==_item_radiation_restore_speed || i==_item_power_restore_speed)
		{
			_val				/= 100.0f;
			_sn					= "";
		}

		LPCSTR _color = (_val>0)?"%c[green]":"%c[red]";
		
		if(i==_item_bleeding_restore_speed)
			_val		*=	-1.0f;

		if(i==_item_bleeding_restore_speed || i==_item_radiation_restore_speed)
			_color = (_val>0)?"%c[red]":"%c[green]";


		sprintf_s					(	_buff, "%s %s %+.0f %s", 
									CStringTable().translate(af_item_param_names[i]).c_str(), 
									_color, 
									_val, 
									_sn);
		_s->SetText				(_buff);
		_s->SetWndPos			(_s->GetWndPos().x, _h);
		_h						+= _s->GetWndSize().y;
		AttachChild				(_s);
	}
	SetHeight					(_h);
}
 

 

 

Собственно, из этого обсуждения я уже кое-что для себя почерпнул), осталось только разобраться со здоровьем и кровотечением. Собственно, к каким единицам времени их лучше привязать? % в реальную секунду или игровую минуту? Или, может быть, реальную минуту.

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

Поделиться этим сообщением


Ссылка на сообщение

 Но из написанного понимаю, что в движке есть только единое влияние, которое собирается по всем параметрам, как ГГ, так и сторонних (артефакты, аномальные зоны,...)

А вот, самое интересное, это не так. (Хотя при просмотре кода вывода свойств артефакта и складывается такое впечатление, потому что зачем-то - ну а правда, зачем? - значение из конфига артефакта делится на похожее значение актора) На самом деле само применение свойств артефакта выглядит примерно так:

conditions().ChangeBleeding(artefact->m_fBleedingRestoreSpeed*f_update_time);

ChangeBleeding это функция которая прибавляет к текущему значению кровотечения указанное. Тут просто получается очень маленькое число, которое прибавляется раз в определенный момент времени который, если размотать цепочку приводит к m_fDeltaTime который, кстати, и от таймфактора зависит  :)

А как высчитывали ПЫС, от этого и плясать.

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

А как это работает в ЗП? Там же есть параметр magnitude, который как-то там влияет на то, что отображается в описании артефакта.

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

Поделиться этим сообщением


Ссылка на сообщение

abramcumner, вот это уже более понятно, значения приобретают какой-то смысл. Спасибо. Однако в ЗП я вроде бы не видел таких артефактов как в ТЧ прибавляющих +600% здоровья. Там как-то иначе сделано, или просто нет в ЗП таких?)

P.S. стало понятно, почему у меня радиацию исправно показывает 0 чего бы я там не ставил, а я просто выставил в 0 скорость вывода радиации в actor.ltx, мда  :)

Поделиться этим сообщением


Ссылка на сообщение

 ed_rezaromatizer, а что она должна создавать? Я просто почти никогда оптикой не пользовался, мне интересно что так сказать требуется, мб можно "малой кровью" реализовать (нужно ли?).

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

Поделиться этим сообщением


Ссылка на сообщение
  • Недавно просматривали   0 пользователей

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