M.A.X.    Вы вошли как гость
Российский Клуб игроков M.A.X.
 
[Новости]   [Новичку]   [Энциклопедия]   [Документы]   [Файлы]   [Игроки]   [Архивы]   [Архив форума]  
[Новый сайт]   [M.A.X. Gold]   [Партии]  

 
 
 
Архив форума  МаксГолд
[Основной форум] [Голосования] [МаксГолд] [Off-Topic]
 


Refactoring. Проверка флагов юнитов. (свернуто)  -  Hruks,  01.06.2010  8:25:05

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

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

Ну и чтобы начать сразу предложу обсудить флаги юнитов.
Речь про typunits.flags
Во первых количество флагов сильно ограничено.
Во вторых информация дублируется.
Флаги это сущьность, характерная для типа юнита, но не для экземпляра юнита.
Стало быть и дублировать в каждом юните особого смысла нет. Тем более, что кроме инициализации они всегда доступны только для чтения.

Посмотрев код я обнаружил, что практически везде флаги это всего лишь проверки вида:
if isf(u.flags,f_building) then ...;
Их можно заменить на следующие варианты:
if IsBuilding(u) then ...;
if isbuilding(u) then ...;
if uisbuilding(u) then ...;
if uflag(u,f_building) then …;
if isflag(u,f_building) then …;
Внутри этих функций уже реализовать всю необходимую функциональность, а именно по типу юнита и параметру (или имени функции) вернуть значение соответствующего атрибута.

В качестве типа можно воспользоваться u.dbn, но этот параметр не очень подходит, так как может быть использован только как число.
Лучше иметь указатель, тогда можно использовать в виде
u.type.is_building

Если же обязательно это должен быть byte или word, то есть хранить id типа, то можно сделать примерно так:
mg_game.utypes[u.type].is_building

Чтобы каждый раз не писать mg_game.cfgs стоит добавить переменную utypes для быстрого доступа.
В итоге проверка будет вида:
tpes[u.type].is_building

Использование функций улучшают гибкость кода, зато таблички будут работать быстрее и выглядят компактнее. Но и сопровождаемость у функций лучше - сложно ошибиться при вызове IsBuilding(u).

Кстати очень похожий механизм понадобится, когда нужно будет реализовать механизм апгрейдов.
По сути есть массив массивов и это у каждого игрока. Одна размерность это все типы юнитов (u.dbn), другая это конфигурации (модели) юнита. Модели появляются, когда юнит производится или апгрейдится до текущего уровня и текущий уровень был улучшен. Тогда создаётся новая конфигурация и ссылка (номер) на неё присваивается юниту.
В конфигурации будет храниться все базовые параметры юнита (их как раз можно апгрейдить), которые хранятся у самого юнита (speed,hits,armr и т.д.)
И к ним тоже нужно будет добираться из кода в более удобном виде.
Конечно, их можно копировать из конфигурации в юнит, но это не совсем верный подход.
например в окне параметров юнитов нужно выводить черту между базовыми и текущими параметрами юнитов. Хранить и те и другие у юнита? Проще хранить у юнита 2 айдишки конфигураций - базовую и собственную. А параметры запрашивать с учётом того, какая конфигурация нужна. Для этого всего лишь сделать у функции, возвращающей параметры флажок и выставить его по умолчанию для собственной конфигурации.
Для самих же апгрейдов будет важно знать уровень развития науки, начальную конфигурацию, последнюю конфигурацию юнита и параметры этих конфигураций.
При апгрейде юнита достаточно знать, что собственная конфигурация юнита не последняя.