ПрограммированиеФорумОбщее

Отлов изменения значения. C++

#0
14:33, 23 авг 2013

Когда-то (в марте этого года) я на этом форуме заводил какую-то тему про добавление модификаторов к параметров... В общем, опишу, что у меня есть.
Некоторые параметры объекта "человек", такие, как скорость, сила атаки, максимальное здоровье, являются модифицируемыми. То есть, у параметра есть начальное значение и набор модификаторов. Модификатор - это структура типа "+5 к этому параметру". Я реализовал это в виде классов. Класс intM - это модифицируемый инт, floatM - модифицируемый флоат. Ну, вы поняли.
Возникла проблема такого рода. Рассмотрим, для примера, параметр "сила". Он влияет на силу атаки. Сила - модифицируемый параметр, так как могут быть бонусы типа "+1 к силе". При изменении значения силы нужно изменить значение силы атаки. Таким образом, нужно отследить, когда меняется значение параметра, и сделать какие-то действия.
Тут начинаются следующие грабли: дело в том, что добавление модификаторов к параметру может происходить не только как human->strength.addModifier(...), а ещё и извращённым способом human->getIntParam(HUMAN_PARAM_STRENGTH).addModifier(...). Это сделано для того, чтобы проще можно было реализовывать способности. Способность - это некая структура, в которой описано, что делать, когда способность применяют. Если не использовать этот getIntParam, то придётся писать некие костыли. А так можно указать, что эффект способности - добавить модификатор +1 к параметру HUMAN_PARAM_STRENGTH.
Так что просто изменять силу атаки после каждого вызова strength.addModifier(...) нельзя.
Мой мозг выдал такую извращённую идею: в intM хранить указатель на функцию, которую нужно вызывать при изменении значения этого параметра. Например, у параметра "сила" эта функция будет изменять силу атаки.
Насколько разумна эта идея? По быстродействию - не умрёт?

#1
14:58, 23 авг 2013

Ещё вариант: в intM хранить не указатель на функцию, а номер параметра (этот самый HUMAN_PARAM_STRENGTH). Вызывать после изменения параметра функцию, передавать в неё номер параметра. В самой функции - многокилометровый switch.

#2
15:33, 23 авг 2013

Если "сила атаки" напрямую зависит от параметра "сила", можно просто рассчитывать ее каждый раз при попытке доступа, а не пытаться отлавливать изменения.

#3
15:37, 23 авг 2013

Во-первых, не обязательно напрямую, а во-вторых, есть ещё куча зависимостей...

#4
15:49, 23 авг 2013

1. Ну есть какие-то базовые параметры, на них накладываются модификаторы.
2. Есть Второстепенные, которые зависят от базовых. Что-бы получить второстепенный берем базовые + модификаторы --> в мега формулу расчета.
3. Есть Третьестепенные, которые зависят от второстепенных и базовых. Для их расчета получаем сначала второстепенные (снова рассчитываем) ну и сюда же базовые и модификаторы.
4. 4-ой степени ...
5. ....

Неужели упрется в производительность перерасчет характеристик при получении значения.
Если так, то организовывать подписку на изменения ("слушатели" и иже с ними).

#5
16:19, 23 авг 2013

Ок, а как насчёт изменения размера динамического массива инвентаря при изменении значения вместимости?
Насколько разумно использование указателя на функцию?

#6
16:39, 23 авг 2013

Можно и указатель, почему нет.
Для инвентаря можно определить максимальный размер, а все ячейки, который не вошли в рассчитанный размер блокировать.
Еще схема: при изменении какого-либо базового параметра ставим флаг needUpdate. в процедуре апдейта "человека" пробегаем по всем зависимым параметрам и вызываем у них Update, а они там у себя что-то пересчитывают (меняют размерность массива инвентаря, к примеру) и сбрасываем needUpdate. Тут только надо правильно организовать последовательность пересчета.
Еще схема: организовываем событие EV_PARAM_CHANGED, а в функции апдейта отлавливаем его и определяем, что изменилось, и вызываем соответствующий обработчик (ну это уж как-то совсем заморочено).

#7
19:17, 26 авг 2013

Silver Overlord
> Класс intM - это модифицируемый инт, floatM - модифицируемый флоат. Ну, вы
> поняли.
Не.. я чёт не въехал.. можешь код показать ? Мне кажется ты что-то перехимичил немного. Проще надо делать ИМХО.

#8
19:24, 26 авг 2013

Silver Overlord
Что мешает поступать как делают все нормальные люди?
У тебя есть Monster с БАЗОВЫМИ параметрами и набором баффом.
Перед обсчетом цикла (ну допустим АИ свой ход продумывает) - пересчитываем у всех объектов параметры с учетом базовых. И так - каждый цикл.

ПрограммированиеФорумОбщее

Тема в архиве.