|
•Ок. Ещё предложения. - Hruks, 11.06.2010 10:45:13 |
|
|
1. Сделать функцию переключения zmnunum и использовать только её для изменения состояния zmnunum.
2. Сделать аналогичную функцию для mg_menu.game_menu_num и при смене сбрасывать наконец-то mg_menu.rmnu. Она в куче мест сбрасывается
3. Разделить функцию calcmnuinfo по стейтам, а ещё лучше по менюшкам.
4. Поместить горячую кнопку пункта меню юнита в структуру rmrec и в mg_keydown проверять в виде: for i:=0 to mg_menu.rmnuc-1 do mg_menu.rmnuf.hotkey=key then begin MG_Event(evt_domenu_r,i+1,0,0,0);break;end; И этим заменить весь блок кода if (key>=48)and(key<=57)or(key=97) then в функции mg_keydown Ну между begin end нужно будет чуть больше написать: begin mg_menu.rmnu:=true; nogm2:=true;nogm4:=true; MG_Event(evt_calcmenu_r,pl.selunit[0],0,0,0); normnu:=true; MG_Event(evt_domenu_r,i+1,0,0,0); mg_menu.rmnu:=false; nogm2:=true;nogm4:=true; break; end;
5. Разделить mg_keydown и mg_keyup по стейтам, оставив только общую часть с глобальными хоткеями, вроде снятия скриншота. Обязательно нужно разделить на игровые и неигровые состояния. Чит с паролем поместить в неигровую часть, читы с картой и подрывом - в игровую.
6. Вынести mg_msmove из файла sdikeyinput. Я бы объединил sdimouseup и sdimousedwn в один файл и туда же эту функцию запихал.
7. Выделить из mg_msmove часть, связанную с игровым курсором (mg_game.state=ST_THEGAME) в отдельную функцию. Также разбить movecurs на 2 части и вызывать их соответственно.
8. Вынести весь код из функций mg_mswheelup и mg_mswheeldown и запускать её с параметрами shift и true/false. Также разделить на игровое и неигровое состояния. Возникающее дублирование кода в 3 строки (Material scroll) незначительное. Если нужно, то написать отдельную мелкую процедуру для обслуживания этого Material scroll.
9. Для чего вызывается movecurs при нажатии и отпускании кнопок мышки? Вроде бы mouse move должен покрывать всё необходимое. Убрать вызовы из mg_msdown и mg_msup.
10. Разделить onmnubtn по менюшкам.
11. Обучить кнопки ещё одному атрибуту. Он может быть в 3х состояниях - regular, ok, cancel. И будет означать буквально следующее - обычная кнопка, кнопка подтверждающая диалог, кнопка отменяющая диалог. В функции onmnubtn сделать проверку этого атрибута. Если он равен ok, то вызывать sdimenuok для текущего стейта и диалога. Если cancel, то создать и вызывать sdimenucancel для текущего диалога. Так как диалог зависит от стейта, то делать поверку на игровые и неигровые стейты и потом уже определять номер диалога. Если же атрибут regular, то это какая-то диалоговая кнопка и её нужно конкретно проверять по параметру, как это делается сейчас. параметр par может быть уникальным среди контролов одного диалога, если обработчик onmnubtn будет разделён по менюшкам. В качетсве такого атрибута можно задействовать par с каким-то конкретным номером. Сейчас идёт дублирование кода, везде вызывается sdimenuok. При этом можно ошибиться и j,hf,jnftncz кнопка OK для совершенно другого состояния и диалога. Если же вызывать OK только для текущего, то такой ошибки получиться не должно.
12. sdimenuok. Обязательно разделять по состояниям. я бы вообще убрал из её параметров и состояние и диалог. То есть просто нажали Ok для текущего диалога. Который сейчас там на экране. Она сама определяет что за состояние и что за диалог и вызывает OK функцию этого диалога. У нескольких диалогов могут быть одинаковые функции или не быть вовсе. Сделать аналогичную функцию sdimenucancel, в которой корректно завершать диалог, восстанавливать исходные значения, изменённые в диалоге. Например вызывать MG_Event(evt_set_game_menu,MG_NOMENU,0,0,0); для игровых меню. Интересно, что sdimenuok возвращает значение, которое нигде не используется. Может если диалог не обрабатывает кнопку OK, а её нажали, то это злобный баг (ну хотя бы закрыться диалог должен?) и тогда выдавать ошибку?
13. draw_gamemnu - вот образец для подражания на данном этапе. Доделить её уже окончательно и вместо кучи проверок запихать адреса функций рисовалок конкретных менюшек в что-нить подобное структуре: ibases[mg_game.state][mg_menu.game_menu_num] и будет совсем хорошо. Кстати размерность ibases можно уменьшать - нет уже отрицательных стейтов.
14. Проверки Есть вот такие проверки, объединённые по И //Building note if((u.siz+bor=2)and(zoom<3.45))or((u.siz+bor=1)and(zoom<1.75)) then begin if((((u.isact and mg_isa(u,a_building))or(not mg_isa(u,a_building)))and u.isbuild)or u.isbuildfin)and(u.own=mg_game.cur_plr)and(u.builds_cnt<>0)then if eu.sprb.cnt<>0 then begin Происходит куча вычислений прежде чем решить, а строит ли этот юнит вообще чего-нить. Так вот, самая простая проверка, не зависящая от остального должна быть первой. Следующие даже проверяться не будут. В часности есть атрибут u.isbuild и u.isbuildfin. Вот их и нужно проверять в первую очередь. А вот если они true, то можно для гарантии проверить всю остальную кучу. первые проверки отсеют 90% всех остальных юнитов.
Тоже самое для бульдозера: u.isclrg должна быть на первом месте. Потом проверка игрока - это простые операции (u.own=mg_game.cur_plr). Игрока полезно проверить вообще для нескольких - в частности для сторительства и для бульдозера проверка одна и таже.
15. Функция gnearestpc вызывается кучу раз. Например для обводки радиуса атаки разным оружием. Не проще ли завести табличку, заполнить её при смене палитры и вместо вызова функции просто брать по заранее известному индексу цвет из этой таблички? Там-то нужно всего десяток значений.
|
|
| |