Когда-то (в марте этого года) я на этом форуме заводил какую-то тему про добавление модификаторов к параметров... В общем, опишу, что у меня есть.
Некоторые параметры объекта "человек", такие, как скорость, сила атаки, максимальное здоровье, являются модифицируемыми. То есть, у параметра есть начальное значение и набор модификаторов. Модификатор - это структура типа "+5 к этому параметру". Я реализовал это в виде классов. Класс intM - это модифицируемый инт, floatM - модифицируемый флоат. Ну, вы поняли.
Возникла проблема такого рода. Рассмотрим, для примера, параметр "сила". Он влияет на силу атаки. Сила - модифицируемый параметр, так как могут быть бонусы типа "+1 к силе". При изменении значения силы нужно изменить значение силы атаки. Таким образом, нужно отследить, когда меняется значение параметра, и сделать какие-то действия.
Тут начинаются следующие грабли: дело в том, что добавление модификаторов к параметру может происходить не только как human->strength.addModifier(...), а ещё и извращённым способом human->getIntParam(HUMAN_PARAM_STRENGTH).addModifier(...). Это сделано для того, чтобы проще можно было реализовывать способности. Способность - это некая структура, в которой описано, что делать, когда способность применяют. Если не использовать этот getIntParam, то придётся писать некие костыли. А так можно указать, что эффект способности - добавить модификатор +1 к параметру HUMAN_PARAM_STRENGTH.
Так что просто изменять силу атаки после каждого вызова strength.addModifier(...) нельзя.
Мой мозг выдал такую извращённую идею: в intM хранить указатель на функцию, которую нужно вызывать при изменении значения этого параметра. Например, у параметра "сила" эта функция будет изменять силу атаки.
Насколько разумна эта идея? По быстродействию - не умрёт?
Ещё вариант: в intM хранить не указатель на функцию, а номер параметра (этот самый HUMAN_PARAM_STRENGTH). Вызывать после изменения параметра функцию, передавать в неё номер параметра. В самой функции - многокилометровый switch.
Если "сила атаки" напрямую зависит от параметра "сила", можно просто рассчитывать ее каждый раз при попытке доступа, а не пытаться отлавливать изменения.
Во-первых, не обязательно напрямую, а во-вторых, есть ещё куча зависимостей...
1. Ну есть какие-то базовые параметры, на них накладываются модификаторы.
2. Есть Второстепенные, которые зависят от базовых. Что-бы получить второстепенный берем базовые + модификаторы --> в мега формулу расчета.
3. Есть Третьестепенные, которые зависят от второстепенных и базовых. Для их расчета получаем сначала второстепенные (снова рассчитываем) ну и сюда же базовые и модификаторы.
4. 4-ой степени ...
5. ....
Неужели упрется в производительность перерасчет характеристик при получении значения.
Если так, то организовывать подписку на изменения ("слушатели" и иже с ними).
Ок, а как насчёт изменения размера динамического массива инвентаря при изменении значения вместимости?
Насколько разумно использование указателя на функцию?
Можно и указатель, почему нет.
Для инвентаря можно определить максимальный размер, а все ячейки, который не вошли в рассчитанный размер блокировать.
Еще схема: при изменении какого-либо базового параметра ставим флаг needUpdate. в процедуре апдейта "человека" пробегаем по всем зависимым параметрам и вызываем у них Update, а они там у себя что-то пересчитывают (меняют размерность массива инвентаря, к примеру) и сбрасываем needUpdate. Тут только надо правильно организовать последовательность пересчета.
Еще схема: организовываем событие EV_PARAM_CHANGED, а в функции апдейта отлавливаем его и определяем, что изменилось, и вызываем соответствующий обработчик (ну это уж как-то совсем заморочено).
Silver Overlord
> Класс intM - это модифицируемый инт, floatM - модифицируемый флоат. Ну, вы
> поняли.
Не.. я чёт не въехал.. можешь код показать ? Мне кажется ты что-то перехимичил немного. Проще надо делать ИМХО.
Silver Overlord
Что мешает поступать как делают все нормальные люди?
У тебя есть Monster с БАЗОВЫМИ параметрами и набором баффом.
Перед обсчетом цикла (ну допустим АИ свой ход продумывает) - пересчитываем у всех объектов параметры с учетом базовых. И так - каждый цикл.
Тема в архиве.