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

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


Ок. Ещё предложения.  -  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 вызывается кучу раз. Например для обводки радиуса атаки разным оружием. Не проще ли завести табличку, заполнить её при смене палитры и вместо вызова функции просто брать по заранее известному индексу цвет из этой таблички? Там-то нужно всего десяток значений.