home *** CD-ROM | disk | FTP | other *** search
/ Virtual Reality Homebrewer's Handbook / vr.iso / vroom / soakpit.pas < prev    next >
Pascal/Delphi Source File  |  1996-03-19  |  34KB  |  994 lines

  1. program soakpit;
  2.  
  3. uses swoop, swoop_discrete, vroom, graph, swoop_vr, clock1, fix_math, bar3d, cyberman;
  4.  
  5. const batch_size=9;
  6.  
  7. type terminal_pos=object
  8.        x,y,z : real;
  9.        free : boolean;
  10.        thisentity : entityptr;
  11.        destination : integer;
  12.        nextprocess : process;
  13.        permission : resource;
  14.        constructor Init(xpos, ypos, zpos : real; next_process : process);
  15.      end;
  16.  
  17.      ingot_slot_type=record
  18.        thisentity : entityptr;
  19.        dx, dy : real;
  20.      end;
  21.  
  22.      entity_attptr=^entity_att;
  23.      entity_att=record
  24.        crane, pit : integer;
  25.        last : boolean;
  26.      end;
  27.  
  28.      pit_ob=object
  29.        pit_therm : z_level_bar2d;
  30.        pit_pic, lid_pic : file_object3d;
  31.        furnace_temp, ingot_temp : statevar;
  32.        furnace_const, ingot_const, fuel : real;
  33.        free, turned, heating, lid_opening : boolean;
  34.        pit_no, next_slot : integer;
  35.        ingot_slot : array[1..batch_size] of ingot_slot_type;
  36.        arrive_in_pit, let_crane_go, heat_up, call_crane, store_crane_info, seize_mill_separately, seize_terminal, wait
  37.          : process;
  38.        constructor Init(number : integer; x,y : real; turn : boolean);
  39.        procedure Open_Lid(start, open_time : real);
  40.        procedure Close_Lid(start, close_time : real);
  41.        procedure Calculate;
  42.        procedure Ingot_Colour;
  43.      end;
  44.  
  45.      crane_obptr=^crane_ob;
  46.      crane_ob=object(processob)
  47.        picture, top_cable, bot_cable : file_object3d;
  48.        crane_entity, carried_entity : entityptr;
  49.        present_terminal, route_pos, next_stop : integer;
  50.        ready_to_travel, moving, free, lowering : boolean;
  51.        unit_time, lowering_time : real;
  52.        this_route : array[1..13] of integer;
  53.        procedure Request(destination : integer);
  54.        procedure Reset_Position;
  55.        procedure Execute(thisentity : entityptr); virtual;
  56.        constructor Init(initial_terminal : integer; init_unit_time : real);
  57.        procedure Monitor; virtual;
  58.        function Check : boolean; virtual;
  59.      end;
  60.  
  61.      seize_pitobptr=^seize_pitob;
  62.      seize_pitob=object(seize_topob)
  63.        this_terminal : integer;
  64.        constructor Init(terminal_no, init_priority : integer; max_queue_length : real; x1, y1, z1, x2, y2, z2 : real);
  65.        procedure Monitor; virtual;
  66.        function Check : boolean; virtual;
  67.      end;
  68.  
  69.      seize_craneobptr=^seize_craneob;
  70.      seize_craneob=object(seize_topob)
  71.        this_terminal : integer;
  72.        constructor Init(terminal_no, init_priority : integer; max_queue_length : real);
  73.        procedure Monitor; virtual;
  74.        function Check : boolean; virtual;
  75.      end;
  76.  
  77. var temp_ingot, temp_panzer, temp_flattop, temp_lid, temp_crane, temp_cable, temp_rolled, roller_picture : file_object3d;
  78.     crane : array [1..2] of crane_ob;
  79.     pit : array [1..17] of pit_ob;
  80.     routing : array[1..21,1..21,1..13] of integer;
  81.     terminals : array[1..32] of terminal_pos;
  82.     panzer_create, flattop_create, panzer_picture, flattop_picture, set_att,  seize_track, delay_track, release_track,
  83.     send_to_pits, call_crane, timing_start, timing_proc, timing_delay, first_flattop, first_panzer,
  84.     put_on_loading_bay, let_crane_go, ingot_to_roller, dump_ingot_picture, strip_picture, to_end1,
  85.     load_ingot_waiting, ingot_on_loading_bay, replicator,  wait_until_unloaded, release_terminals, release_loading_bay,
  86.     dump_waggon, lose_waggon_picture, get_next_ingot : process;
  87.  
  88.     back_to_roller1, flatter1, back_to_start, back_to_roller2, flatter2, to_end2, dump_last_picture, release_roller : process;
  89.     rolling_mill, loading_bay, track : resource;
  90.     my_clock : clock_3d;
  91.     mouse, cyber, clock_selected : boolean;
  92.     pit_data : array[1..17] of boolean;
  93.  
  94. {$F+}
  95. procedure Arrive_in_pit_proc;
  96. var this_att : entity_attptr;
  97.     temppic : copy_object3d_ptr;
  98.     i : integer;
  99. begin
  100.      this_att:=simulation.thisentity^.attributes;
  101.      temppic:=simulation.thisentity^.picture;
  102.      i:=pit[this_att^.pit].next_slot;
  103.      with pit[this_att^.pit].ingot_slot[i] do
  104.      begin
  105.           thisentity:=simulation.thisentity;
  106.           temppic^.MoveTo(dx,dy,0);
  107.      end;
  108.      pit[this_att^.pit].Close_Lid(now+10,20);
  109.      simulation.thisentity^.ChangeTime(simulation.time+crane[this_att^.crane].lowering_time);
  110. end;
  111.  
  112. procedure Let_crane_go_proc;
  113. var this_att : entity_attptr;
  114.     i : integer;
  115. begin;
  116.      this_att:=simulation.thisentity^.attributes;
  117.      i:=pit[this_att^.pit].next_slot;
  118.      if i<>batch_size then
  119.      begin
  120.           crane[this_att^.crane].Request(18);
  121.           simulation.thisentity^.ChangeTime(infinity);
  122.           pit[this_att^.pit].ingot_temp.state:=1100;
  123.           pit[this_att^.pit].furnace_temp.state:=1100;
  124.      end
  125.      else
  126.      begin
  127.           crane[this_att^.crane].free:=true;
  128.           pit[this_att^.pit].heating:=true;
  129.      end;
  130.     inc(pit[this_att^.pit].next_slot);
  131. end;
  132.  
  133. procedure crane_info_proc;
  134. var i, crane_no, pit_no : integer;
  135.     this_att : entity_attptr;
  136. begin
  137.      this_att:=simulation.thisentity^.attributes;
  138.      crane_no:=this_att^.crane;
  139.      pit_no:=this_att^.pit;
  140.      for i:=1 to batch_size do
  141.      begin
  142.           this_att:=pit[pit_no].ingot_slot[i].thisentity^.attributes;
  143.           this_att^.crane:=crane_no;
  144.      end;
  145. end;
  146.  
  147.  
  148. procedure pit_unload_proc;
  149. var this_att : entity_attptr;
  150.     temppic : copy_object3d_ptr;
  151. begin
  152.      this_att:=simulation.thisentity^.attributes;
  153.      temppic:=simulation.thisentity^.picture;
  154.      terminals[this_att^.pit].thisentity:=simulation.thisentity;
  155.      terminals[this_att^.pit].destination:=21;
  156.      temppic^.MoveTo(terminals[this_att^.pit].x,terminals[this_att^.pit].y,2.5);
  157.      with pit[this_att^.pit] do
  158.      begin
  159.           heating:=false;
  160.           dec(next_slot);
  161.           ingot_slot[next_slot].thisentity:=nil;
  162.           simulation.thisentity^.ChangeTime(infinity);
  163.           if (next_slot)>1 then
  164.           begin
  165.                ingot_slot[next_slot-1].thisentity^.ChangeTime(simulation.time);
  166.                ingot_slot[next_slot-1].thisentity^.ChangeProc(pit[this_att^.pit].seize_mill_separately);
  167.                this_att^.last:=false;
  168.           end
  169.           else
  170.               this_att^.last:=true;
  171.      end;
  172. end;
  173.  
  174. procedure lid_proc(this_obj : object3d_ptr);
  175. var i : integer;
  176. begin
  177.      for i:=1 to 17 do if (@pit[i].lid_pic=this_obj) then
  178.      begin
  179.           if pit[i].lid_opening then pit[i].close_lid(now,30)
  180.           else pit[i].open_lid(now,30);
  181.      end;
  182. end;
  183.  
  184. procedure pit_proc(this_obj : object3d_ptr);
  185. var i : integer;
  186. begin
  187.      for i:=1 to 17 do if (@pit[i].pit_pic=this_obj) then pit_data[i]:=not(pit_data[i]);
  188. end;
  189.  
  190. procedure clock_proc(this_obj : object3d_ptr);
  191. begin
  192.      clock_selected:=not(clock_selected);
  193. end;
  194.  
  195.  
  196. {$F-}
  197.  
  198. {------------------------------------------------}
  199. { Terminal pos method implementations            }
  200. {------------------------------------------------}
  201.  
  202. constructor Terminal_pos.Init(xpos, ypos, zpos : real; next_process : process);
  203. begin
  204.      x:=xpos; y:=ypos; z:=zpos;
  205.      nextprocess:=next_process;
  206.      thisentity:=nil;
  207.      destination:=0;
  208.      free:=true;
  209.      permission.Set_Capacity(1);
  210. end;
  211.  
  212.  
  213. {------------------------------------------------}
  214. { Pit_ob method implementations                  }
  215. {------------------------------------------------}
  216.  
  217. constructor Pit_ob.Init(number: integer; x,y : real; turn : boolean);
  218. var i : integer;
  219. begin
  220.      turned:=turn;
  221.      pit_no:=number;
  222.      furnace_const:=0.0005;
  223.      ingot_const:=0.00018;
  224.      fuel:=0;
  225.      furnace_temp.Initial_Value(1100);
  226.      ingot_temp.Initial_Value(1100);
  227.      heating:=false;
  228.      lid_opening:=false;
  229.      pit_pic.Init('Pit.3d');
  230.      pit_pic.Set_Reference_Point(5,5,0);
  231.      pit_pic.Select_procedure:=pit_proc;
  232.      lid_pic.Init('PitLid.3d');
  233.      lid_pic.Select_procedure:=lid_proc;
  234.      if not(turned) then lid_pic.Set_Reference_Point(5,0,10)
  235.      else lid_pic.Set_Reference_Point(5,10,10);
  236.      pit_pic.AddChild(@lid_pic);
  237.      pit_pic.MoveTo(x,y,0);
  238.      pit_therm.Init(@furnace_temp.state,1000,2200,x,y-7,0,2,10,3,1,6,1);
  239.  {    if turn then pit_therm.Init(@furnace_temp.state,1000,2500,x,y-6,0,2,10,3,6)
  240.      else
  241.      begin
  242.           pit_therm.Init(@furnace_temp.state,1000,2200,x,y+6,0,2,10,3,6);
  243.           pit_therm.RotateZ(180);
  244.      end;  }
  245.      free:=true;
  246.      arrive_in_pit:=userproc(arrive_in_pit_proc);
  247.      let_crane_go:=userproc(let_crane_go_proc);
  248.      heat_up:=delay_until(@ingot_temp.state,GT,2000,0.1,infinity);
  249.      call_crane:=new(seize_craneobptr,Init(pit_no,2,100));
  250.      store_crane_info:=userproc(crane_info_proc);
  251.      seize_mill_separately:=seize(@rolling_mill,5,1);
  252.      seize_terminal:=seize(@terminals[pit_no].permission,5,1);
  253.      wait:=userproc(pit_unload_proc);
  254.      arrive_in_pit^.Link(let_crane_go);
  255.      let_crane_go^.Link(heat_up);
  256.      heat_up^.Link(call_crane);
  257.      call_crane^.Link(store_crane_info);
  258.      store_crane_info^.Link(seize_terminal);
  259.      seize_mill_separately^.Link(seize_terminal);
  260.      seize_terminal^.Link(wait);
  261.      ingot_slot[1].dx:=-2.5; ingot_slot[1].dy:=2.5;
  262.      ingot_slot[2].dx:=0; ingot_slot[2].dy:=2.5;
  263.      ingot_slot[3].dx:=2.5; ingot_slot[3].dy:=2.5;
  264.      ingot_slot[4].dx:=-2.5; ingot_slot[4].dy:=0;
  265.      ingot_slot[5].dx:=2.5; ingot_slot[5].dy:=0;
  266.      ingot_slot[6].dx:=-2.5; ingot_slot[6].dy:=-2.5;
  267.      ingot_slot[7].dx:=0; ingot_slot[7].dy:=-2.5;
  268.      ingot_slot[8].dx:=2.5; ingot_slot[8].dy:=-2.5;
  269.      ingot_slot[9].dx:=0; ingot_slot[9].dy:=0;
  270.      for i:=1 to batch_size do
  271.      begin
  272.           ingot_slot[i].thisentity:=nil;
  273.           ingot_slot[i].dx:=ingot_slot[i].dx+x;
  274.           ingot_slot[i].dy:=ingot_slot[i].dy+y;
  275.      end;
  276.      next_slot:=1;
  277. end;
  278.  
  279. procedure Pit_ob.Open_Lid(start, open_time : real);
  280. var i : integer;
  281.     temppic : copy_object3d_ptr;
  282. begin
  283.      if lid_opening then exit;
  284.      lid_opening:=true;
  285.      if turned=false then lid_pic.timed_rotateX(90,start,open_time)
  286.      else lid_pic.timed_rotateX(-90,start,open_time);
  287.      for i:=1 to batch_size do
  288.      if ingot_slot[i].thisentity<>nil then
  289.      begin
  290.           temppic:=ingot_slot[i].thisentity^.picture;
  291.           temppic^.Show;
  292.      end;
  293. end;
  294.  
  295. procedure Pit_ob.Close_Lid(start, close_time : real);
  296. var i : integer;
  297.     temppic : copy_object3d_ptr;
  298. begin
  299.      if not lid_opening then exit;
  300.      lid_opening:=false;
  301.      if turned=false then lid_pic.timed_rotateX(-90,start,close_time)
  302.      else lid_pic.timed_rotateX(90,start,close_time);
  303.      for i:=1 to batch_size do
  304.      if ingot_slot[i].thisentity<>nil then
  305.      begin
  306.           temppic:=ingot_slot[i].thisentity^.picture;
  307.           temppic^.Hide;
  308.      end;
  309. end;
  310.  
  311. procedure Pit_ob.Calculate;
  312. begin
  313.      if heating then
  314.      begin
  315.           if furnace_temp.state<2200 then fuel:=1 else fuel:=0;
  316.           furnace_temp.dot:=furnace_const*fuel*(2500-furnace_temp.state);
  317.           ingot_temp.dot:=ingot_const*(furnace_temp.state-ingot_temp.state);
  318.      end
  319.      else
  320.      begin
  321.           furnace_temp.dot:=0;
  322.           ingot_temp.dot:=0;
  323.      end;
  324. end;
  325.  
  326. procedure Pit_ob.Ingot_Colour;
  327. var i : integer;
  328.     temppic : copy_object3d_ptr;
  329.     shade : real;
  330. begin
  331.      if next_slot<=batch_size then exit;
  332.      shade:=(ingot_temp.state-1100)/(2000-1100);
  333.      shade:=shade/2+0.5;
  334.      for i:=1 to batch_size do
  335.          if ingot_slot[i].thisentity<>nil then
  336.          begin
  337.               temppic:=ingot_slot[i].thisentity^.picture;
  338.               temppic^.Change_Colour(3,shade);
  339.          end;
  340. end;
  341.  
  342.  
  343. {------------------------------------------------}
  344. { Crane_ob method implementations                }
  345. {------------------------------------------------}
  346.  
  347. constructor crane_ob.Init(initial_terminal : integer; init_unit_time : real);
  348. var temp : monitorptr;
  349. begin
  350.      processob.Init;
  351.      ready_to_travel:=false;
  352.      moving:=false;
  353.      free:=true;
  354.      lowering:=false;
  355.      picture.Init('crane.3d');
  356.      picture.Set_Reference_Point(0,0,0);
  357.      picture.Scale(2,2,2);
  358.      top_cable.Init('cable.3d');
  359.      top_cable.Set_Reference_Point(0,0,0);
  360.      picture.AddChild(@top_cable);
  361.      bot_cable.Init('cable.3d');
  362.      bot_cable.Set_Reference_Point(0,0,0);
  363.      top_cable.AddChild(@bot_cable);
  364.      present_terminal:=initial_terminal;
  365.      terminals[present_terminal].free:=false;
  366.      with terminals[present_terminal] do
  367.        picture.MoveTo(x,y,z);
  368.      unit_time:=init_unit_time;
  369.      lowering_time:=20;
  370.      temp:=new(monitorptr,Init(@thisprocess,1));
  371.      crane_entity:=new(entityptr,Init(infinity,@thisprocess));
  372.      carried_entity:=nil;
  373. end;
  374.  
  375. procedure crane_ob.Request(destination : integer);
  376. var i : integer;
  377. begin
  378.      for i:=1 to 13 do
  379.      this_route[i]:=routing[present_terminal,destination,i];
  380.      route_pos:=1;
  381.      ready_to_travel:=true;
  382.      if (destination>0) and (destination<18) then
  383.      begin
  384.           if destination=present_terminal then
  385.           pit[destination].open_lid(now,20)
  386.           else pit[destination].open_lid(now+30,20);
  387.      end;
  388. end;
  389.  
  390. procedure crane_ob.Reset_Position;
  391. var source, dest : vertex_ptr;
  392. begin
  393.      dest:=picture.first_vertex;
  394.      source:=temp_crane.first_vertex;
  395.      while (source<>nil) and (dest<>nil) do
  396.      begin
  397.            with terminals[present_terminal] do
  398.            begin
  399.                 dest^.world.x:=source^.world.x+Real_to_fixed(x);
  400.                 dest^.world.y:=source^.world.y+Real_to_fixed(y);
  401.                 dest^.world.z:=source^.world.z+Real_to_fixed(z);
  402.            end;
  403.            source:=source^.next;
  404.            dest:=dest^.next;
  405.       end;
  406.      dest:=top_cable.first_vertex;
  407.      source:=temp_cable.first_vertex;
  408.      while (source<>nil) and (dest<>nil) do
  409.      begin
  410.            with terminals[present_terminal] do
  411.            begin
  412.                 dest^.world.x:=source^.world.x+Real_to_fixed(x);
  413.                 dest^.world.y:=source^.world.y+Real_to_fixed(y);
  414.                 dest^.world.z:=source^.world.z+Real_to_fixed(z);
  415.            end;
  416.            source:=source^.next;
  417.            dest:=dest^.next;
  418.       end;
  419.      dest:=bot_cable.first_vertex;
  420.      source:=temp_cable.first_vertex;
  421.      while (source<>nil) and (dest<>nil) do
  422.      begin
  423.            with terminals[present_terminal] do
  424.            begin
  425.                 dest^.world.x:=source^.world.x+Real_to_fixed(x);
  426.                 dest^.world.y:=source^.world.y+Real_to_fixed(y);
  427.                 dest^.world.z:=source^.world.z+Real_to_fixed(z);
  428.            end;
  429.            source:=source^.next;
  430.            dest:=dest^.next;
  431.       end;
  432. end;
  433.  
  434. procedure crane_ob.Execute(thisentity : entityptr);
  435. var ent_picture : copy_object3d_ptr;
  436. begin
  437.      if moving then
  438.      begin
  439.           if this_route[route_pos]<>0 then
  440.           begin
  441.                terminals[present_terminal].free:=true;
  442.                present_terminal:=this_route[route_pos];
  443.                inc(route_pos);
  444.           end;
  445.           if this_route[route_pos]<>0 then
  446.           begin
  447.                with terminals[this_route[route_pos]] do
  448.                  picture.timed_moveto(x,y,z,now,unit_time);
  449.                crane_entity^.ChangeTime(simulation.time+unit_time);
  450.           end
  451.           else
  452.           begin
  453.                moving:=false;
  454.                Reset_Position;
  455.                lowering:=true;
  456.                crane_entity^.ChangeTime(simulation.time+lowering_time);
  457.                bot_cable.Timed_MoveTo(terminals[present_terminal].x,terminals[present_terminal].y,20,now,lowering_time);
  458.           end;
  459.      end
  460.      else
  461.      if lowering then
  462.      begin
  463.           crane_entity^.ChangeTime(infinity);
  464.           lowering:=false;
  465.           if carried_entity<>nil then
  466.           begin
  467.                carried_entity^.ChangeTime(simulation.time);
  468.                carried_entity^.ChangeProc(terminals[present_terminal].nextprocess);
  469.                ent_picture:=carried_entity^.picture;
  470.                bot_cable.RemoveChild(ent_picture);
  471.                carried_entity:=nil;
  472.                if terminals[present_terminal].nextprocess=nil then writeln('Entity gets lost at terminal ',present_terminal);
  473.                next_stop:=0;
  474.           end
  475.           else
  476.           if terminals[present_terminal].thisentity<>nil then
  477.           begin
  478.                if terminals[present_terminal].destination=present_terminal then
  479.                begin
  480.                     terminals[present_terminal].thisentity^.ChangeTime(simulation.time);
  481.                     terminals[present_terminal].thisentity^.ChangeProc(terminals[present_terminal].nextprocess);
  482.                     next_stop:=0;
  483.                     if terminals[present_terminal].permission.Release(terminals[present_terminal].thisentity)=false then
  484.                     writeln('Error releasing terminal ',present_terminal);
  485.                     terminals[present_terminal].thisentity:=nil;
  486.                end
  487.                else
  488.                begin
  489.                     carried_entity:=terminals[present_terminal].thisentity;
  490.                     ent_picture:=carried_entity^.picture;
  491.                     bot_cable.AddChild(ent_picture);
  492.                     if present_terminal=18 then
  493.                     begin
  494.                          ent_picture^.RotateY(-90);
  495.                          ent_picture^.MoveTo(terminals[18].x,terminals[18].y,2.5);
  496.                     end;
  497.                     next_stop:=terminals[present_terminal].destination;
  498.                end;
  499.           end;
  500.           crane_entity^.ChangeTime(simulation.time+lowering_time);
  501.           bot_cable.Timed_MoveTo(terminals[present_terminal].x,terminals[present_terminal].y,30,now,lowering_time);
  502.      end
  503.      else
  504.      begin
  505.           crane_entity^.ChangeTime(infinity);
  506.           if next_stop<>0 then
  507.           begin
  508.                Request(next_stop);
  509.                if terminals[present_terminal].permission.Release(terminals[present_terminal].thisentity)=false then
  510.                writeln('Error releasing terminal ',present_terminal);
  511.                terminals[present_terminal].thisentity:=nil;
  512.                if (present_terminal<18) then
  513.                begin
  514.                     pit[present_terminal].close_lid(now+30,20);
  515.                     if pit[present_terminal].next_slot=1 then pit[present_terminal].free:=true;
  516.                end;
  517.           end;
  518.      end;
  519. end;
  520.  
  521. function crane_ob.Check : boolean;
  522. var res : boolean;
  523.     i : integer;
  524. begin
  525.      res:=true;
  526.      if ready_to_travel then
  527.      begin
  528.           for i:=1 to 13 do if this_route[i]<>0 then res:=res and terminals[this_route[i]].free;
  529.      end
  530.      else res:=false;
  531.      Check:=res;
  532. end;
  533.  
  534. procedure crane_ob.Monitor;
  535. var i : integer;
  536. begin
  537.      ready_to_travel:=false;
  538.      for i:=1 to 13 do
  539.      if this_route[i]<>0 then terminals[this_route[i]].free:=false;
  540.      moving:=true;
  541.      if this_route[1]<>0 then
  542.      begin
  543.           with terminals[this_route[route_pos]] do
  544.                picture.timed_moveto(x,y,z,now,unit_time);
  545.           crane_entity^.ChangeTime(simulation.time+unit_time);
  546.      end
  547.      else
  548.          crane_entity^.ChangeTime(simulation.time+20);
  549. end;
  550.  
  551.  
  552. {------------------------------------------------}
  553. { Seize pit method implementations               }
  554. {------------------------------------------------}
  555.  
  556. constructor seize_pitob.Init(terminal_no, init_priority : integer; max_queue_length : real; x1, y1, z1, x2, y2, z2 : real);
  557. begin
  558.      thisqueue:=new(anim_queue_3dptr,Init(x1, y1, z1, x2, y2, z2));
  559.      seize_topob.Init(@loading_bay, max_queue_length, init_priority);
  560.      this_terminal:=terminal_no;
  561. end;
  562.  
  563. procedure seize_pitob.Monitor;
  564. var thisentity : entityptr;
  565.     this_att : entity_attptr;
  566.     i : integer;
  567.     result : boolean;
  568. begin
  569.      thisentity:=thisqueue^.Remove;
  570.      if thisentity<>nil then
  571.      begin
  572.           result:=thisresource^.Seize(thisentity);
  573.           thisentity^.ChangeTime(simulation.time);
  574.           thisentity^.ChangeProc(nextprocess);
  575.           this_att:=thisentity^.attributes;
  576.           i:=1;
  577.           while not(pit[i].free) do inc(i);
  578.           this_att^.pit:=i;
  579.           pit[i].free:=false;
  580.           if crane[1].free then this_att^.crane:=1 else this_att^.crane:=2;
  581.           crane[this_att^.crane].Request(this_terminal);
  582.           crane[this_att^.crane].free:=false;
  583.      end;
  584. end;
  585.  
  586. function seize_pitob.Check;
  587. var test : boolean;
  588.     i : integer;
  589. begin
  590.      test:=false;
  591.      if thisqueue^.length>0 then
  592.      begin
  593.           for i:=1 to 17 do test:=test or pit[i].free;
  594.           test:=test and ((crane[1].free or crane[2].free) and seize_topob.Check)
  595.      end;
  596.      Check:=test;
  597. end;
  598.  
  599.  
  600. {------------------------------------------------}
  601. { Seize crane method implementations             }
  602. {------------------------------------------------}
  603.  
  604. constructor seize_craneob.Init(terminal_no, init_priority : integer; max_queue_length : real);
  605. begin
  606.      thisqueue:=new(queueptr,Init);
  607.      seize_topob.Init(@rolling_mill, max_queue_length, init_priority);
  608.      this_terminal:=terminal_no;
  609. end;
  610.  
  611. procedure seize_craneob.Monitor;
  612. var thisentity : entityptr;
  613.     this_att : entity_attptr;
  614.     i : integer;
  615.     result : boolean;
  616. begin
  617.      thisentity:=thisqueue^.Remove;
  618.      if thisentity<>nil then
  619.      begin
  620.           result:=thisresource^.Seize(thisentity);
  621.           thisentity^.ChangeTime(simulation.time);
  622.           thisentity^.ChangeProc(nextprocess);
  623.           this_att:=thisentity^.attributes;
  624.           if crane[1].free and (crane[1].present_terminal=this_terminal) then this_att^.crane:=1
  625.           else if crane[2].free and (crane[2].present_terminal=this_terminal) then this_att^.crane:=2
  626.           else if crane[1].free then this_att^.crane:=1
  627.           else this_att^.crane:=2;
  628.           crane[this_att^.crane].Request(this_terminal);
  629.           crane[this_att^.crane].free:=false;
  630.      end;
  631. end;
  632.  
  633. function seize_craneob.Check;
  634. var test : boolean;
  635.     i : integer;
  636. begin
  637.      if thisqueue^.length>0 then
  638.         Check:=((crane[1].free or crane[2].free) and seize_topob.Check)
  639.      else
  640.         Check:=false;
  641. end;
  642.  
  643. {------------------------------------------------}
  644.  
  645. {$F+}
  646. procedure Calculate;
  647. var i : integer;
  648. begin
  649.      for i:=1 to 17 do pit[i].Calculate;
  650. end;
  651.  
  652. procedure text_display;
  653. var temp_str1, temp_str2, temp_str3 : string;
  654.     xpos, ypos, zpos, zpos2, last_z, i, i2 : integer;
  655. begin
  656.      if clock_selected then
  657.      begin
  658.           Str(round(simulation.time) mod 60 : 2,temp_str1);
  659.           Str((round(simulation.time) mod 3600) div 60 : 2,temp_str2);
  660.           Str(trunc(simulation.time / 3600):0,temp_str3);
  661.           my_clock.face.Screen_Position(xpos,ypos,zpos);
  662.           write_text_at(round((xpos-4)/8)-3,round((ypos-4)/8),temp_str3+':'+temp_str2+':'+temp_str1,3,1.0,2,1.0);
  663.      end;
  664.      last_z:=$7FFF;
  665.      repeat
  666.            i2:=0;
  667.            zpos2:=integer($8000);
  668.            for i:=1 to 17 do if pit_data[i] then
  669.            begin
  670.                 pit[i].pit_pic.Screen_Position(xpos,ypos,zpos);
  671.                 if (zpos>zpos2) and (zpos<last_z) then
  672.                 begin
  673.                      i2:=i; zpos2:=zpos;
  674.                 end;
  675.            end;
  676.            if i2<>0 then
  677.            begin
  678.                 pit[i2].pit_pic.Screen_Position(xpos,ypos,zpos);
  679.                 xpos:=round((xpos-4)/8);
  680.                 ypos:=round((ypos-4)/8);
  681.                 Str(pit[i2].furnace_temp.state : 5 : 0,temp_str1);
  682.                 Str(pit[i2].ingot_temp.state : 5 : 0,temp_str2);
  683.                 Str(i2 : 5,temp_str3);
  684.                 write_text_at(xpos,ypos,  '╔═══════════════════╗',2,0,6,0.8);
  685.                 write_text_at(xpos,ypos+1,'║Pit number   :'+temp_str3+'║',2,0,6,0.8);
  686.                 write_text_at(xpos,ypos+2,'║Furnace temp.:'+temp_str1+'║',2,0,6,0.8);
  687.                 write_text_at(xpos,ypos+3,'║Ingot temp.  :'+temp_str2+'║',2,0,6,0.8);
  688.                 write_text_at(xpos,ypos+4,'╚═══════════════════╝',2,0,6,0.8);
  689.            end;
  690.            last_z:=zpos2;
  691.      until i2=0;
  692. end;
  693.  
  694. procedure Update_Screen;
  695. var junk1 : boolean;
  696.     i : integer;
  697. begin
  698.      if cyber then junk1:=Cyberman_Check;
  699.      if mouse then junk1:=Mouse_Check;
  700.      junk1:=KeyBoard_Check;
  701.      for i:=1 to 17 do
  702.      begin
  703.           pit[i].pit_therm.Update;
  704.           pit[i].Ingot_Colour;
  705.      end;
  706.      redraw_scene;
  707. end;
  708.  
  709. function My_KeyCheck(key : char) : boolean;
  710. var f : text;
  711.     test : boolean;
  712.     temp1 : pointer;
  713.     temp2 : delayptr;
  714.     pit_no : integer;
  715. begin
  716.      test:=true;
  717.      if key='>' then
  718.           begin
  719.                temp1:=timing_delay;
  720.                temp2:=temp1;
  721.                temp2^.first:=temp2^.first*2;
  722.           end
  723.      else
  724.      if key='<' then
  725.           begin
  726.                temp1:=timing_delay;
  727.                temp2:=temp1;
  728.                temp2^.first:=temp2^.first/2;
  729.           end
  730.      else
  731.      if key='o' then
  732.           begin
  733.                write_text_at(5,15,'Open Pit: Enter number :- ',5,1.0,0,1.0);
  734.                readln(pit_no);
  735.                if (pit_no>0) and (pit_no<18) then pit[pit_no].open_lid(now,30);
  736.           end
  737.      else
  738.      if key='c' then
  739.           begin
  740.                write_text_at(5,15,'Close Pit: Enter number :- ',5,1.0,0,1.0);
  741.                readln(pit_no);
  742.                if (pit_no>0) and (pit_no<18) then pit[pit_no].close_lid(now,30);
  743.           end
  744.      else
  745.      test:=false;
  746.      My_KeyCheck:=test;
  747. end;
  748.  
  749. procedure loading_bay_proc;
  750. var i : integer;
  751.     temp : process;
  752.     temppic : copy_object3d_ptr;
  753. begin
  754.      temppic:=simulation.thisentity^.picture;
  755.      temppic^.MoveTo(240,55,0);
  756.      temp:=simulation.thisentity^.nextprocess;
  757.      for i:=1 to batch_size do replicator^.Execute(simulation.thisentity);
  758.      {simulation.thisentity^.ChangeProc(temp);
  759.      simulation.thisentity^.ChangeTime(infinity);}
  760. end;
  761.  
  762. procedure ingot_loading_bay_proc;
  763. var this_att : entity_attptr;
  764.     temppic : copy_object3d_ptr;
  765. begin
  766.      temppic:=new(copy_object3d_ptr,Init(@temp_ingot));
  767.      temppic^.redraw:=true;
  768.      simulation.thisentity^.picture:=temppic;
  769.      terminals[18].thisentity:=simulation.thisentity;
  770.      this_att:=simulation.thisentity^.attributes;
  771.      terminals[18].destination:=this_att^.pit;
  772.      simulation.thisentity^.ChangeTime(infinity);
  773. end;
  774.  
  775. procedure Let_crane_go_proc2;
  776. var this_att : entity_attptr;
  777.     temppic : copy_object3d_ptr;
  778. begin
  779.      this_att:=simulation.thisentity^.attributes;
  780.      temppic:=simulation.thisentity^.picture;
  781.      temppic^.RotateX(90);
  782.      if this_att^.last then crane[this_att^.crane].free:=true;
  783. end;
  784.  
  785. procedure Next_ingot_proc;
  786. var this_att : entity_attptr;
  787. begin
  788.      this_att:=simulation.thisentity^.attributes;
  789.      if not(this_att^.last) then crane[this_att^.crane].Request(this_att^.pit);
  790. end;
  791.  
  792. {$F-}
  793.  
  794. procedure Initialise_Routings;
  795. var s,f,i : integer;
  796.     rf : text;
  797. begin
  798.      assign(rf,'routing.dat');
  799.      reset(rf);
  800.      for s:=1 to 21 do
  801.      for f:=1 to 21 do
  802.      begin
  803.           for i:=1 to 13 do read(rf,routing[s,f,i]);
  804.           readln(rf);
  805.      end;
  806.      close(rf);
  807.  
  808.      for i:= 21 to 32 do with terminals[i] do
  809.      begin
  810.           Init((i-21)*20,55,30,nil);
  811.      end;
  812.      with terminals[18] do
  813.      begin
  814.           Init(240,55,30,nil);
  815.      end;
  816.      for i:= 1 to 7 do with terminals[i] do
  817.      begin
  818.           pit[i].Init(i,i*20,35,false);
  819.           Init(i*20,35,30,pit[i].arrive_in_pit);
  820.      end;
  821.      with terminals[19] do
  822.      begin
  823.           Init(220,35,30,nil);
  824.      end;
  825.      with terminals[20] do
  826.      begin
  827.           Init(180,35,30,nil);
  828.      end;
  829.      for i:= 8 to 17 do with terminals[i] do
  830.      begin
  831.           pit[i].Init(i,(i-7)*20+20,75,true);
  832.           Init((i-7)*20+20,75,30,pit[i].arrive_in_pit);
  833.      end;
  834.      for i:=1 to 17 do pit_data[i]:=false;
  835. end;
  836.  
  837.  
  838.  
  839. begin
  840.      mouse:=false; cyber:=false;
  841.      if cyberman_available then cyber:=true
  842.      else if mouse_available then mouse:=true;
  843.      simulation.Init;
  844.      init_system;
  845.      set_for_swoop;
  846.  
  847.      graphics_time:=@simulation.time;
  848.      clock_selected:=false;
  849.  
  850.      Set_Ambient_Intensity(1);
  851.  {    Set_Light(0.75,0,-1,-0.75);
  852.      Set_View(200,0,0,0,0,0);   }
  853.      Set_View(72236320/65536,-17222016/65536,5440032/65536,-18,-4.7,0);
  854.      Store_Settings;
  855.      User_KeyCheck_Proc(My_KeyCheck);
  856.      set_text_proc(text_display);
  857.  
  858.      simulation.Continuous(1,1,0,Calculate);
  859.      simulation.Integrate_Method(Euler);
  860. {     simulation.Run_Time(Update_Screen); }
  861.  
  862.      loading_bay.Set_Capacity(1);
  863.      track.Set_Capacity(1);
  864.      rolling_mill.Set_Capacity(1);
  865.      roller_picture.Init('Mill.3d');
  866.      roller_picture.Set_Reference_Point(5,5,0);
  867.      roller_picture.MoveTo(0,105,0);
  868.      roller_picture.Scale(1.4,4,1);
  869.      Initialise_Routings;
  870.  
  871.      crane[1].Init(1,30);
  872.      crane[2].Init(8,30);
  873.      temp_crane.Init('crane.3d');
  874.      temp_crane.Set_Reference_Point(0,0,0);
  875.      temp_crane.Scale(2,2,2);
  876.      temp_crane.Hide;
  877.      temp_cable.Init('cable.3d');
  878.      temp_cable.Set_Reference_Point(0,0,0);
  879.      temp_cable.Hide;
  880.      temp_panzer.Init('panzer.3d');
  881.      temp_panzer.Set_Reference_Point(0,0,0);
  882.      temp_panzer.Hide;
  883.      temp_flattop.Init('flattop.3d');
  884.      temp_flattop.Set_Reference_Point(0,0,0);
  885.      temp_flattop.Hide;
  886.      temp_rolled.Init('rolled.3d');
  887.      temp_rolled.Set_Reference_Point(5,8.5,0);
  888.      temp_rolled.Hide;
  889.      temp_ingot.Init('box.3d');
  890.      temp_ingot.Set_Reference_Point(0,5,5);
  891.      temp_ingot.Scale(0.7,0.1,0.1);
  892.      temp_ingot.Change_Colour(3,0.5);
  893.      temp_ingot.MoveTo(236,55,2.5);
  894.      temp_ingot.Hide;
  895.  
  896.      my_clock.Init(-40,55,30,60*60,3600*12);
  897.      my_clock.Hand1.Change_Colour(7,0.7);
  898.      my_clock.Hand2.Change_Colour(7,0.7);
  899.      my_clock.Face.Select_Procedure:=clock_proc;
  900.  
  901.      {sort_by_furthest_point;}
  902.  
  903.      timing_start:=create(constant,1,0,0,1);
  904.      timing_proc:=userproc(update_screen);
  905.      timing_delay:=delay(constant,1,0,0);
  906.  
  907.      timing_start^.Link(timing_proc);
  908.      timing_proc^.Link(timing_delay);
  909.      timing_delay^.Link(timing_proc);
  910.  
  911.      first_panzer:=create(constant,400,0,0,1);
  912.      panzer_create:=create(uniform,11000,15000,0,infinity);
  913.      panzer_picture:=copy_picture3d(@temp_panzer);
  914.      first_flattop:=create(constant,1,0,0,1);
  915.      flattop_create:=create(uniform,8000,10000,0,infinity);
  916.      flattop_picture:=copy_picture3d(@temp_flattop);
  917.      set_att:=Set_Attributes(SizeOf(entity_att));
  918.      seize_track:=seize(@track,infinity,1);
  919.      delay_track:=delay(constant,5,0,0);
  920.      release_track:=release(@track);
  921.      send_to_pits:=route3d(constant,60,0,0,250,-100,0,250,35,0);
  922.      call_crane:=new(seize_pitobptr,Init(18,1,100,250,55,0,250,-450,0));
  923.      put_on_loading_bay:=userproc(loading_bay_proc);
  924.      wait_until_unloaded:=seize(@terminals[18].permission,1,1);
  925.      release_terminals:=release(@terminals[18].permission);
  926.      release_loading_bay:=release(@loading_bay);
  927.      dump_waggon:=route3d(constant,60,0,0,240,45,0,240,-100,0);
  928.      lose_waggon_picture:=destroy_picture3d;
  929.  
  930.      replicator:=replicate;
  931.      load_ingot_waiting:=seize(@terminals[18].permission,10,2);
  932.      ingot_on_loading_bay:=userproc(ingot_loading_bay_proc);
  933.  
  934.      first_panzer^.Link(panzer_picture);
  935.      panzer_create^.Link(panzer_picture);
  936.      panzer_picture^.Link(set_att);
  937.      first_flattop^.Link(flattop_picture);
  938.      flattop_create^.Link(flattop_picture);
  939.      flattop_picture^.Link(set_att);
  940.      set_att^.Link(seize_track);
  941.      seize_track^.Link(delay_track);
  942.      delay_track^.Link(release_track);
  943.      release_track^.Link(send_to_pits);
  944.      send_to_pits^.Link(call_crane);
  945.      call_crane^.Link(put_on_loading_bay);
  946.      replicator^.Link(wait_until_unloaded);
  947.      wait_until_unloaded^.Link(release_terminals);
  948.      release_terminals^.Link(release_loading_bay);
  949.      release_loading_bay^.Link(dump_waggon);
  950.      dump_waggon^.Link(lose_waggon_picture);
  951.  
  952.      replicator^.Link2(load_ingot_waiting);
  953.      load_ingot_waiting^.Link(ingot_on_loading_bay);
  954.  
  955.      let_crane_go:=userproc(let_crane_go_proc2);
  956.      terminals[21].nextprocess:=let_crane_go;
  957.  
  958.      ingot_to_roller:=route3d(constant,100,0,0,0,55,0,0,105,0);
  959.      dump_ingot_picture:=destroy_picture3d;
  960.      strip_picture:=copy_picture3d(@temp_rolled);
  961.      to_end1:=route3d(constant,100,0,0,0,105,0,0,155,0);
  962.      back_to_roller1:=route3d(constant,100,0,0,0,155,0,0,105,0);
  963.      flatter1:=scale_picture3d(1,1.5,1);
  964.      back_to_start:=route3d(constant,100,0,0,0,105,0,0,55,0);
  965.      back_to_roller2:=route3d(constant,100,0,0,0,55,0,0,105,0);
  966.      flatter2:=scale_picture3d(1,1.5,1);
  967.      to_end2:=route3d(constant,100,0,0,0,105,0,0,155,0);
  968.      dump_last_picture:=destroy_picture3d;
  969.      release_roller:=release(@rolling_mill);
  970.      get_next_ingot:=userproc(next_ingot_proc);
  971.  
  972.      let_crane_go^.Link(ingot_to_roller);
  973.      ingot_to_roller^.Link(dump_ingot_picture);
  974.      dump_ingot_picture^.Link(strip_picture);
  975.      strip_picture^.Link(to_end1);
  976.      to_end1^.Link(back_to_roller1);
  977.      back_to_roller1^.Link(flatter1);
  978.      flatter1^.Link(back_to_start);
  979.      back_to_start^.Link(back_to_roller2);
  980.      back_to_roller2^.Link(flatter2);
  981.      flatter2^.Link(to_end2);
  982.      to_end2^.Link(dump_last_picture);
  983.      dump_last_picture^.Link(release_roller);
  984.      release_roller^.Link(get_next_ingot);
  985.  
  986.      redraw_scene;
  987.      simulation.Execute(infinity);
  988.  
  989.      stop_graphics;
  990.      writeln('Out of time');
  991.  
  992. end.
  993.  
  994.