        IF1
INCLUDE COMDEF.INC              ; Include command definition
        ENDIF
VOL     EQU     0               ; Define volume number
LOGIC   SEGMENT BYTE
        ASSUME  CS:LOGIC
        BEGIN                   ; Start up

; logic 09; картина грозы
; А.В.Хорев, обучающая программа "ГРОЗА", 1991 год.

         if_
           isset 5      ; f5 установлен (=1) ?
         else_ NotNr

;┌───────────────────────────────────────────────────────────────────────────┐
;│   Инициализация log09.                                                    │
;│   Сюда мы попадаем только при первом вхождении в log09 по ком. new_room 9,│
;│ выданной в log07 (см.описание new_room). При этом автоматически f5 -> 1.  │
;│   После возврата из этой части в log0 по оператору return, log0 передаст  │
;│ управление интерпретатору, который в своем следующем цикле установит      │
;│ f5 -> 0 (см.цикл работы интерпретатора). Именно поэтому управление этой   │
;│ части программы передается только один раз.                               │
;│   Поэтому, если из логики будут вызываться другие логики, имеющие части   │
;│ инициализации, то они должны быть загружены и вызваны в инициализационной │
;│ части вызывающей логики.                                                  │
;└───────────────────────────────────────────────────────────────────────────┘


	  set_horizon 1   ; установить линию горизонта у=1
       ;   load_logic 4
       ;   call_      4

	  load_pic    0   ; загрузить picture по значению v0 (v0 = 9)    
	  draw_pic    0   ; изобразить декорацию в буфере интерпретатора 
	  discard_pic 0   ; уничтожить picture в памяти                

     ;    загрузить звуки по их номеру

          load_sound  21 ; завывание ветра
          load_sound  12 ; начало дождя
          load_sound  31 ; появление молнии
          load_sound  42 ; якобы гром
          load_sound  49 ; тревожное состояние
          load_sound  54 ; привлечение внимания перед выводом сообщений
          reset 21       ; f21 -> 0

	  load_view      5 ; загрузить view #5 (гнущееся дерево)

       ; объект #1 - первое дерево
	  animate_obj    1        ; объект #1 вкл.в список упр.объектов 
	  ignore_horizon 1        ; объекту #1 не замечать линию горизонта
	  ignore_objs    1        ; объекту #1 не замечать др.объекты     
	  ignore_blocks  1        ; объекту #1 не замечать блоки          
	  set_view       1, 5     ; связать объект #1 с view #5          
	  set_priority   1, 9     ; объекту #1 устан.приоритет 9          
	  position       1, 0, 68 ; объекту #1 устан.нач.х=0, у=68       
          set_loop       1, 0     ; объекту #1 устан.цикл 0 во view #5   
     	  set_cel        1, 4     ; объекту #1 устан.кадр 0 в цикле 0     
				  ; во view #5
       ; объект #2 -  второе дерево			                             
	  animate_obj    2        ; объект #2 вкл.в список упр.объектов
	  ignore_horizon 2        ; объекту #2 не замечать линию горизонта
	  ignore_objs    2        ; объекту #2 не замечать др.объекты     
	  ignore_blocks  2        ; объекту #2 не замечать блоки          
	  set_view       2, 5     ; связать объект #2 с view #5           
	  set_priority   2, 9     ; объекту #2 устан.приоритет 9          
	  position       2, 12, 87; объекту #2 устан.нач.х=12, у=87       
          set_loop       2, 0     ; объекту #2 устан.цикл 0 во view #5    
     	  set_cel        2, 4     ; объекту #2 устан.кадр 0 в цикле 0     
				  ; во view #5
       ; объект #3 -  третье дерево			                              
	  animate_obj    3          ; объект #3 вкл.в список упр.объектов
	  ignore_horizon 3          ; объекту #3 не замечать линию горизонта
	  ignore_objs    3          ; объекту #3 не замечать др.объекты     
	  ignore_blocks  3          ; объекту #3 не замечать блоки          
	  set_view       3, 5       ; связать объект #3 с view #5           
	  set_priority   3, 9       ; объекту #3 устан.приоритет 9          
	  position       3, 101, 104; объекту #3 устан.нач.х=101, у=104       
          set_loop       3, 0       ; объекту #3 устан.цикл 0 во view #5    
     	  set_cel        3, 4       ; объекту #3 устан.кадр 0 в цикле 0     
				    ; во view #5 
       ; объект #4 -  молния			                               
          load_view 7               ; загрузить view #7 (молния)
          animate_obj    4          ; объект #4 вкл.в список упр.объектов                                        
	  ignore_horizon 4          ; объекту #4 не замечать линию горизонта 
	  ignore_objs    4          ; объекту #4 не замечать др.объекты      
	  ignore_blocks  4          ; объекту #4 не замечать блоки           
	  set_view       4, 7       ; связать объект #4 с view #7            
	  set_priority   4, 15      ; объекту #4 устан.приоритет 15          
	  position       4, 100, 101; объекту #4 устан.нач.х=100, у=101       
          set_loop       4, 0       ; объекту #4 устан.цикл 0 во view #7     
     	  set_cel        4, 0       ; объекту #4 устан.кадр 0 в цикле 0      
				    ; во view #7                           
	  load_logic 10   ; загрузить log10 (падающие капли дождя) в память
	  call_ 10        ; и вызвать ее для выполнения

          show_pic         ; изобразить декорацию на экране
          status_line_on   ; дать строку состояния
	  draw           1 ; изобразить на экране объект #1
	  draw           2 ; изобразить на экране объект #2
	  draw           3 ; изобразить на экране объект #3

          assignn 123, 11 ; присвоить переменнным 123, 124 и 125
	  assignn 124, 10 ; задержки в циклах интерпр. для деревьев
          assignn 125,  9 ; соответственно

          cycle_time 1, 123 ; объектам ## 1, 2, 3 установить время в циклах         
          cycle_time 2, 124 ; интепр.между сменой кадров по значению v123, 
          cycle_time 3, 125 ; v124, v125

          clear_lines 23, 24, 0   ; строки 23 и 24 очистить цветом 0
          set_text_attribute 6, 0 ; установить цвет букв 6 и фона 0
          display 24, 1, 1        ; в стоку 24 с поз.1 вывести сообщ. 1

          reset   15        ; f15 -> 0
          assignn 21, 20    ; окно удал. автоматически через (v21=20)/2 сек
	  sound   49, 52    ; исполнить звук 49 (тревожно), по оконч. f52 -> 1
          print    2        ; печать сообщения 2
          sound 21, 52      ; исполнить звук 49 (ветер), по оконч. f52 -> 1

          assignn 152, 1    ; v152 = 1 - проверяется при выводе сообщений
	                    ;            о последовательности событий. Перед
			    ;            очередным событием увеличивается на 1
          assignn 154, 1    ; v154 = 1 ; счетчик молний
	  set      58       ; f58 -> 1 ; связан с печатью сообщ.4
          reset    59       ; f59 -> 0 ; отмечает окончание грозы

	  return            ; вернуть управление в log0

NotNR: 
       ; clear_lines 23, 23 0
       ; display 23, 2, 11 ; показать число страниц, v17, v18

        if_
          equaln   152, 3 ; v152 = 3 (выведены все сообщ.о грозе) и
          have_key        ; нажата любая клавиша и
          greatern 154, 3 ; v154 > 3 (показано больше 3-х молний) ?
        else_ Sunny       ; нет => переход на Sunny
			  ; да:
          reset 15        ; f15 -> 0
          assignn 21, 20  ; окно удал. автоматически через 20/2 сек
	  sound 54, 52    ; привлечь внимание звуком 54, по оконч.f52 -> 0
          print 5         ; печать сообщения 5                            
          unanimate_all   ; исключить все объекты из списка управления
          stop_sound      ; прекратить звук

	  load_view      1 ; загрузить в память интерпретатора view #1 (солнце)
          animate_obj    1 ; сделать объекты 1, 2, 3 управляемыми интерпретато-
          animate_obj    2 ; ром автоматически (деревья)
          animate_obj    3 ;

	  set_priority   1, 9  ; объектам 1, 2, 3 установить приоритет 9
	  set_priority   2, 9
	  set_priority   3, 9

	  animate_obj    5     ; объект #5 (солнце) вкл.в список упр.объектов
	  ignore_horizon 5          ; объекту #5 не замечать линию горизонта
	  ignore_objs    5          ; объекту #5 не замечать др.объекты     
	  ignore_blocks  5          ; объекту #5 не замечать блоки          
	  set_view       5, 1       ; связать объект #5 с view #1           
	  set_priority   5, 4       ; объекту #5 устан.приоритет 4          
	  position       5, 110, 82 ; объекту #5 устан.нач.х=110, у=82     
          set_loop       5, 0       ; объекту #5 устан.цикл 0 во view #1    
     	  set_cel        5, 0       ; объекту #5 устан.кадр 0 в цикле 0     
				    ; во view #1                            
          assignn      123,   4
          cycle_time     5, 123

          assignn     30, 10  ; v30 = 10;(pic10 - берег, но залитый солнцем)
          load_pic    30      ; загрузить в этой же комнате новую декорацию
          draw_pic    30      ; изобразить декорацию в буфере интерпретатора
          discard_pic 30      ; уничтожить picture в памяти                 

          load_logic  112     ; загрузить logic 112 (чайки)
          show_pic            ; нарисовать декорацию на экране
          draw           1    ;
          draw           2    ; изобразить объекты 1, 2, 3 (деревья)
          draw           3    ;
	  stop_update    1
	  stop_update    2    ; и запретить для них авт.перебор кадров
	  stop_update    3
          draw           5    ; изобразить объект 5 (солнце)
          
          reset   15          ; f15 -> 0                                        
          assignn 21, 10      ; окно удал. автоматически через 10/2 сек         
	  sound   54, 52      ; исполнить звук 54 (внимание), по оконч.f52 -> 1
          print    6          ; печать сообщения 6                            

          set 59              ; f59 -> 0 (гроза закончилась)
          assignn 152, 0      ; v152 = 0 (чтобы сразу берег, залитый солнцем)
          assignn 154, 0      ; v154 = 0

          set       5         ; для инициализации logic 112 :  f5 -> 1
          assignn  36, 1      ; v36 = 1 ( в logic 112 выбир.уменьшенные чайки)
          call_   112         ; вызов подпрогор. полета трех чаек
          reset     5         ; f5 -> 0
          load_sound  68      ; загрузить мелодию 62 (после грозы)
          sound 68, 52        ; исполнить мелодию 62, по оконч. f52-> 1

          return              ; вернуть управление в log0

Sunny:   if_
           isset 59      ; f59 -> 0 (гроза закончилась)?
	 else_ Raining   ; нет: переход на Raining
           call_ 112     ; вызвать logic 112 (чайки)
			 ; да, гроза уже прошла:
	   if_           
	     have_key    ; любая клавиша нажата?
	   else_ ENDLOG  ; нет: переход на ENDLOG (возврат упр.в log0 и затем
			 ;      интерпретатору, т.е. показывать берег после
			 ;      грозы пока не будет нажата любая клавиша).
			 ; да: переходим к вопросам
             set        15     ; f15 -> 1 (окно с вопросами авт.не удалять)
             load_sound  7     ; загр. звук 7 (сопровождает вывод вопросов)
	     sound       7, 21 ; исполнить звук 7, по оконч. f21 -> 0
             print 7           ; вывести сообщ. 7 (вопросы)
             clear_lines 23, 23, 0    ; очистить строку 23 цветом 0
             set_text_attribute 13, 0 ; устан.цвет символов 13 на фоне 0 для
				      ; приглашения, кот.будет выведено в стр.
				      ; 23 (см.команду configure_screen в log01)
             accept_input             ; разрешить ввод с клавиатуры
             get_num 8, 40            ; ввести число в v40 по приглашению,
	                              ; которым служит сообщение 8
	     prevent_input            ; запретить ввод с клавиатуры
             close_window             ; закрыть текстовое окно (с вопросами)
             set_text_attribute 6, 0  ; восстановить цвет символов и фона
	     reset 21                 ; f21 -> 0

             if_
               equaln 40, 3   ; v40 = 3 (выбран ответ 3) ?
             else_ REPEAT     ; нет: переход на метку REPEAT (неправ.ответ)
			      ; да: ответ правильный !

	       load_sound  90   ; загр.звук 90, сопровожд.правильный ответ
               sound    90, 21  ; исполн. звук 90, по оконч. f21 -> 1

               reset    15      ; f15 -> 0 - окно убирать автоматически
               assignn  21, 8   ; через (v21 = 8)/2 сек
               print     9      ; вывести сообщение 9
               reset    21      ; f21 -> 0 
	       addn      3, 2   ; v3=v3+2 - добавить два очка за правильн.ответ


               assignn  21, 0   ; очистить vars & flags
	       assignn  30, 0   
	       assignn  37, 0   
	       assignn  38, 0   
	       assignn  39, 0   
	       assignn  40, 0   
               assignn 123, 0 
               assignn 124, 0 
               assignn 125, 0 
               assignn 135, 0 
               assignn 137, 0
               assignn 152, 0
               assignn 153, 0
               assignn 154, 0

	       reset    52
	       reset    58
	       reset    59
	       reset   123
	       reset   124
	       reset   125
	       reset   126
	       reset   206
	       reset   207
	       reset   208
	       reset   209
	       reset   210
	       reset   211
	       reset   212
	       reset   213

               new_room 11 ; переход в след.комнату (эксперименты с облаком)

REPEAT: ; ответ неправильный  
          load_sound 8     ; загр.звук 8 (сопровождает неправ.ответ)
          sound      8, 21 ; и исполнить его, по оконч. f21 -> 1
          reset     15     ; f15 -> 0 - окно убирать автоматически        
          assignn   21, 8  ; через (v21 = 8)/2 сек                          
          print     10     ; вывести сообщение 10                         
          reset     21     ; f21 -> 0                                     
          decrement  3     ; v3=v3-1 - вычесть очко за неправильный ответ
          new_room   7     ; повторить обучение в комн. 7 заново

Raining: if_
           equaln 152, 3 ; v152 = 3?
         else_ Wind      ; нет: перейти на Wind (ветер)
			 ; да: показать дождь
           call_ 10      ; вызывается подпрограмма падающих капель
	   increment 153 ; v153 = v153 + 1 (счетчик циклов интерпретации
	                 ; для ввода задержек между появлением молнии и
			 ; ударами грома)
         if_
           greatern 153, 64  ; v153 > 64 и 
           lessn    153, 73  ; v153 < 73 ? (значение в интерв.[153,164])?
         else_ SndRain   ; нет: воспроизводить звук 12 (падающих капель)
			 ; да: звук грома
           sound 42, 52  ; иммитация звука грома (исп.звук 42, но проверки
	                 ; на его окончание по f52 не производится, поэтому
			 ; звук 42, не успев окончиться, начинается сначала и
			 ; это несколько похоже на гром. Звук грома прерывает
			 ; звук падающих капель, т.к. 2 звука одновременно
			 ; исполняться не могут.
           jump Wind     ; безусловный переход на Wind

SndRain: sound  12, 52  ; исполнить звук 12  - на окончание по f52 не прове-
			; ряется, поэтому не окончившись начинается вновь и 
			; это похоже на падающие капли

Wind:   if_
          isset 52      ; f52 -> 1 и
          lessn 152, 3  ; v152 < 3 ?
        else_ Rain      ; нет: переход на Rain (дождь)

          reset 52      ; f52 -> 0
          sound 21, 52  ; исполнить звук 21 (завывание ветра), по оконч. f52->1
          increment 152 ; v152 = v152 + 1

Rain:   if_             
          equaln 152, 2  ; v152 = 2 ?
        else_ Lightn     ; нет: переход на Lightn (молния)

          increment 152  ; v152 = v152 + 1
          reset   15     ; f15 -> 0 - окно убирать автоматически
          assignn 21, 15 ; через (v21 = 15)/2 сек                  
          print    3     ; вывести сообщение 3                  

	  draw  8               ;                                           
	  end_of_loop  8, 206   ;                                       
	  draw  9               ;                                          
	  end_of_loop  9, 207   ; изобразить дождевые капли (объекты 8,9,10,                                       
	  draw 10               ; 11,12,13,14,15), однократно прокрутить                                            
	  end_of_loop 10, 208   ; связанные с этими объектами мультфильмы и                   
	  draw 11               ; по окончании каждого из них установить                                              
	  end_of_loop 11, 209   ; флаги 206,207,208,209,210,211,212,213 в                                               
	  draw 12               ; 1 соответственно.                                                               
	  end_of_loop 12, 210   ; Инициализация всех этих объектов (капель)  
	  draw 13               ; производится в инициализационной (выполняю-
	  end_of_loop 13, 211   ; щейся при f5 -> 1) части логики log10      
	  draw 14               ;
	  end_of_loop 14, 212   ;
	  draw 15               ;
	  end_of_loop 15, 213   ;
          sound 12, 52          ; исполнить звук 12 (дождь), по оконч. f52->1

          assignn 153, 1      ; v153=1 (служит для ввода задержки между появ-
	                      ; лением молнии и звуком грома)

Lightn: if_
          equaln 153, 30  ; v153 = 30 и
	  isset 58        ; f58 -> 0 ?
	else_ Ltn1        ; нет: переход на Ltn1
			  ; да: вывести сообщение 4 (о молниях)
          reset   15     ; f15 -> 0                                       
          assignn 21, 10 ; окно удал. автоматически через (v21=10)/2 сек        
	  sound   54, 52 ; исполнить звук 54 (внимание), по оконч.f52 -> 1
          print    4     ; печать сообщения 4                             
	  reset   58     ; чтобы напечатать сообщение 4 только один раз
			 ; (т.е. обходить эту часть)
Ltn1:   if_
          equaln 153, 40  ; v153 = 40 ?
        else_ Ltn2        ; нет: переход на Ltn2

          stop_sound             ; прекратить звук

; случайно выбрать тип молнии (между облаками или облаком иземлей)

	  random     0,   1, 135 ; присвоить v135 случайное число из инт.[0,1]
	  set_loop_v 4, 135      ; установить объекту 4 (молния) номер цикла 
				 ; по значению v135
          set_cel    4,   0      ; номер кадра в выбранном для объекта 4 цикле
				 ; установить равным 0
; случайно выбрать приоритет молнии

          random 7, 10, 137      ; присвоить v137 случайное число из инт.[7,10]
          if_
            not_
            greatern 137, 8 ; значение v137 не > 8 ?
          else_ ChngPr ; нет (больше): переход на ChngPr (изм.приоритет)
		       ; да:
            assignn 137, 7 ; v137 = 7
            jump Ltn1a     ; безусловный переход на Ltn1a

ChngPr:   assignn 137, 10  ; v137 = 10

Ltn1a:	  if_
	    equaln 135, 1  ; выбрана молния типа 1 (между облаками) ?
	  else_ Choose0    ; нет: переход на Choose0 ( тип 0 - на землю)
			   ; да: тип - между облаками

            assignn 38, 30       ; коорд.базовой точки x=30 молнии присвоить
                                 ; v38
            random 13, 31, 39    ; коорд.базовой точки у (v39) молнии случайно
				 ; выбирается в интервале [13,31]
	    jump Ltn1b           ; безусловный переход на Ltn1b

Choose0: ; молния между облаком и землей
 
          random  50, 130, 38    ; коорд.базовой точки x (v38) молнии случайно
				 ; выбирается в интервале [50,130]
          random 101, 130, 39    ; коорд.базовой точки у (v39) молнии случайно
				 ; выбирается в интервале [101,130]

Ltn1b:	  erase 4                  ; уничт.об.4 (молния, если есть на экране)
          set_priority_v 4, 137    ; установить приоритет об.4 по знач. v137
          reposition_to_v 4, 38, 39; переместить об.4 в точку с коорд., являю-
				   ; щимися значениями перем. v38 и v39
	  draw    4                ; изобразить об.4 (молния) в новом месте и
	                           ; с новым приоритетом,
          sound 31, 52             ; сопроводив его появление звуком 31, по
				   ; окончании которого f52 -> 1
          end_of_loop 4, 126       ; и прокрутить мультфильм для об.4 один раз
				   ; после чего установить f126 -> 1

Ltn2:   if_
          equaln 153, 65 ; v153 = 65 ( после появления молнии прошло
	                 ;             необх.время) ?
        else_ Ltn3       ; нет: переход на проверку по метке Ltn3

          shake_screen 1 ; потрясти экран 1 раз (это сопровождается звуком
			 ; грома (см.действия по метке Raining))
Ltn3:   if_
          equaln 153, 72 ; v153 = 72 (интервал между раскатами грома выдержан)?
        else_ ENDLOG     ; нет: перейти на ENDLOG
			 ; да:
          shake_screen 2 ; потрясти экран 2 раза (это сопровождается звуком
			 ; грома (см.действия по метке Raining))          
	  assignn 153, 1 ; v153 =1 сбросить счетчик циклов интерперетации
          increment 154  ; v154=v154+1 - счетчик количества проскочивших молний
          reset 126      ; f126 -> 0

ENDLOG:  return          ; вернуть управление в log0

         MESSAGES 11     ; сообщения

m1      db   "Для продолжения нажмите Enter/Return", 0

m2      db   " Темные облака скрыли солнце, посерело небо.", 10
        db   " Задул холодный ветер, предвещающий грозу.",10
        db   " Почувствовав приближение ненастья, Вы успели забежать "
        db   "в дом и наблюдаете за происходящим из окна.", 0
	 
m3      db   " Вслед за ветром капли достигают земли и начинается дождь.", 10
	db   " Вы слышите стук падающих капель.", 10
        db   " Надвигается гроза.", 0

m4      db   " Вдали видны зигзаги молний.", 10, " Через некоторое время все "
        db   "сотрясается от раскатов грома.", 0
          
m5      db   " Через некоторое время после начала грозы теплого "
        db   "воздуха уже нет - тяга вверх прекратилась.", 10, " Последние "
        db   "капли дождя падают на землю. Грозовое облако разрушилось."
        db   " Гроза закончилась.", 0

m6      db   " И вновь светит солнце !", 10, " Все вокруг сияет яркими "
        db   "красками !", 0

m7      db   " A теперь постарайтесь выбрать правильный ответ на следующий "
        db   "вопрос :", 10
        db   " Всегда ли в верхней части грозового облака содержатся "
	db   "кристаллики льда и почему?", 10
        db   " 1. Только зимой, так как температура воздуха ниже нуля.", 10
        db   " 2. Не всегда, т.к. летом облако состоит только из капель воды, "
        db   "потому что температура воздуха больше нуля.", 10
        db   " 3. Всегда, так как из-за больших размеров облака его "
	db   "верхняя часть находится в области низких температур.", 0

m8      db   " Я считаю правильным ответ номер : ", 0
m9      db   " Вы совершенно правы !", 10,"      Отлично !", 0
m10     db   "  Увы. Ответ неверен.", 10,"  Придется повторить !", 0
m11     db   " Страниц %v8,  %v17,  %v18 ", 0

VERYEND EQU $
LOGIC   ENDS
        END