[comp.sources.x] v11i092: Another Star Trek Game, Part06/14

pfuetz@agd.fhg.de (02/26/91)

Submitted-by: pfuetz@agd.fhg.de
Posting-number: Volume 11, Issue 92
Archive-name: xstrek/part06

#!/bin/sh
# To unshare, sh or unshar this file
echo xstrek/original_code/strek_create_form.f 1>&2
sed -e 's/^X//' > xstrek/original_code/strek_create_form.f <<'E!O!F! xstrek/original_code/strek_create_form.f'
X      program strek_create_form
Xc
Xc    *******************************************************************
Xc    *****                                                         *****
Xc    *****                STAR TREK VERSION 3.0                    *****
Xc    *****                                                         *****
Xc    *****                     written by                          *****
Xc    *****                                                         *****
Xc    *****                Justin S. Revenaugh                      *****
Xc    *****                                                         *****
Xc    *****                       7/87                              *****
Xc    *****                                                         *****
Xc    *****        Massachussetts Institute of Technology           *****
Xc    *****  Department of Earth, Atmospheric and Planetary Science *****
Xc    *****                                                         *****
Xc    *******************************************************************
Xc     
Xc    STREK_CREATE_FORM creates a key defs form for use in STREK
Xc
Xc    version 1
Xc                                         -jsr 8/85
Xc
X      character*5 key_name(90)
X      character*256 key_file
Xc
Xc    keynames in order
Xc
X      data key_name /'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
X     &'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
X     &'x', 'y', 'z', 'l1', 'l2', 'l3', 'l4', 'l5', 'l6', 'l7', 'l8',
X     &'l9', 'la', 'lb', 'lc', 'ld', 'le', 'lf', 'l1a', 'l2a', 'l3a',
X     &'l1u', 'l2u', 'l3u', 'l4u', 'l5u', 'l6u', 'l7u', 'l8u', 'l9u',
X     &'lau', 'lbu', 'lcu', 'ldu', 'leu', 'lfu', 'l1au', 'l2au', 'l3au',
X     &'f1', 'f2', 'f3', 'f4', 'f5', 'f6', 'f7', 'f8','f1u', 'f2u',
X     &'f3u', 'f4u', 'f5u', 'f6u', 'f7u', 'f8u', 'r1', 'r2', 'r3', 'r4',
X     &'r5', 'r6', 'space', ',', '.', '/', ';', '['/
Xc
Xc   request file pathname, open and write to it
Xc
X      print*,' '
X      print*,'This program creates a key definition form for use with'
X      print*,'Strek.'
X      print*,' '
X      print*,'Enter the desired pathname of the form (<256 char.).'
X      read (*,'(a)') key_file
X      open (unit =1 , file = key_file)
X      write (1, 100)
X100   format ('enter character definition in column 7')
X      write (1, 110)
X110   format ('e.g.  x')
X      do 10 j = 1,90
X        write (1,'(a5)') key_name(j)
X 10   continue          
X      close(1)
X      stop
X      end
E!O!F! xstrek/original_code/strek_create_form.f
echo xstrek/original_code/strek_db_subs.f 1>&2
sed -e 's/^X//' > xstrek/original_code/strek_db_subs.f <<'E!O!F! xstrek/original_code/strek_db_subs.f'
X      subroutine strek_write (new, ship_name, capt_name, nick_name, 
X     &                        key_file, ship_avail, last_score,
X     &                        cum_score, ship_active, top_ten)
Xc
Xc
Xc    *******************************************************************
Xc    *****                                                         *****
Xc    *****                STAR TREK VERSION 3.0                    *****
Xc    *****                                                         *****
Xc    *****                     written by                          *****
Xc    *****                                                         *****
Xc    *****                Justin S. Revenaugh                      *****
Xc    *****                                                         *****
Xc    *****                       7/87                              *****
Xc    *****                                                         *****
Xc    *****        Massachussetts Institute of Technology           *****
Xc    *****  Department of Earth, Atmospheric and Planetary Science *****
Xc    *****                                                         *****
Xc    *******************************************************************
X
Xc    STREK_WRITE updates the two STREK info files (strek_info and
Xc    strek_top_scores). If (new) then a name is appended, else the
Xc    name is updated. 
Xc
Xc
X      integer*4 ship_avail(3), last_score, cum_score, ship_retired
X      integer*4 num_lines, count, top_scores(10)
X      logical ship_active, new, fyn, top_ten
X      character ship_name*30, capt_name*10, nick_name*10, temp*30
X      character ctemp(10)*10, stemp(10)*30, key_file*256
Xc
Xc    if ship name is blank then return
Xc
X      if (ship_name.eq.' ') then
X        top_ten = .false.
X        return
X      end if
Xc
Xc    open up strek_info file
Xc
X      inquire(file='strek_info',exist=fyn)
X      if (.not.fyn) then
X        status = 1
X        return
X      end if
X      open (unit=1,file='strek_info',access ='direct',form = 
X     &      'unformatted', status='old',recl=1000)
X      inquire(file='strek_top_scores', exist=fyn)
X      if (.not.fyn) then
X        status = 1
X        return
X      end if
X      open (unit=2,file='strek_top_scores' ,status='old',recl=1000)
Xc
Xc    if new then update num_lines and append info
Xc
X      if (ship_active) then
X        ship_retired = 0
X      else
X        ship_retired = 1
X      end if
X      if (new) then
X        read (1,rec=1) num_lines
X        num_lines = num_lines + 1
X        write (1,rec=1) num_lines
X        write (1,rec=num_lines+1) ship_name, capt_name, nick_name,
X     &         key_file, (ship_avail(i),i=1,3), last_score,
X     &         cum_score, ship_retired
X        close(1)
X      else 
Xc
Xc    name is old, find it and update
Xc
X        read(1,rec=1) num_lines
X        count = 1
X 10     continue
X        read(1,rec=count+1) temp
X        if (temp.eq.ship_name) then
X          write (1,rec=count+1) ship_name, capt_name, nick_name,
X     &           key_file, (ship_avail(i),i=1,3), last_score,
X     &           cum_score, ship_retired
X          goto 20
X        end if
X        if (count.eq.num_lines) then
X          close(1)
X        end if
X        count = count + 1
X        goto 10
X 20     continue
X        close(1)
X      end if
Xc
Xc    determine if the score is a top ten score
Xc
X      do 30 j=1,10
X        read (2,110) ctemp(j), stemp(j), top_scores(j)
X 30   continue
X      rewind(2)
X110   format(a10,a30,i10)
X      i = 1
X      top_ten = .false.
X 40   continue
X      if (cum_score.gt.top_scores(i)) then
X        top_ten = .true.
X        goto 50
X      end if
X      if (i.eq.10) goto 50
X      i = i + 1
X      goto 40
X 50   continue
X      if (top_ten) then
Xc
Xc    see if ship is already on the list
Xc
X        do 55 j = 1,i-1
X          if (stemp(j).eq.ship_name) then  
X            top_ten = .false.
X            close(2)
X            return
X          end if
X 55     continue
X        do 60 j = i,10
X          if (stemp(j).eq.ship_name) then
Xc
Xc    move everybody up one to delete the duplicate entry
Xc
X            do 70 k = j,9
X              stemp(k) = stemp(k+1)
X              ctemp(k) = ctemp(k+1)
X              top_scores(k) = top_scores(k+1)
X 70         continue
X          end if
X 60     continue
Xc
Xc    write out the new list, note that a ship that was previously
Xc    on the list and who's score drops as a result of a mission
Xc    will remain on the list.
Xc
X        do 80 j = 1,i-1
X          write (2,110) ctemp(j), stemp(j), top_scores(j)
X 80     continue
X        write (2,110) capt_name, ship_name, cum_score
X        do 90 j = i,9
X          write (2,110) ctemp(j), stemp(j), top_scores(j) 
X 90     continue
X      end if
X      close(2)
X      return
X      end
X               
X
X
X
X
X      subroutine strek_review (ship_name, capt_name, nick_name,
X     &                         ship_avail, cum_score, last_score,
X     &                         ship_active, key_file, status)
Xc
Xc     STREK_REVIEW reviews the STREK database which includes
Xc     ships, shipnames, captains, cumulative scores, ship avail-
Xc     ability times and last outing scores. File is hardwired to
Xc     be STREK_INFO. The file structure is as follows:
Xc
Xc     line 1 number of lines (i8)
Xc
Xc     lines 2 - last:
Xc
Xc     shipname (char*30), captain (char*10), nickname (char*10),
Xc     ship availability (3i*4), last outing score (i*10), cumu-
Xc     lative score (i*10), ship active toggle (i*1).
Xc
Xc     The file is direct access, and all new entries are appended
Xc     to the end. 
Xc
Xc     A second file called STREK_TOP_SCORES is maintained. In it
Xc     are the current ten best scores (ascii). The file is struct-
Xc     ered:
Xc
Xc     lines 1 - 10 captains name (char*10), shipname (char*30), and
Xc     cumulative score (i*10).
Xc
Xc
Xc     version 1
Xc                                     -jsr 8/85
Xc
Xc
X      integer*4 ship_avail(3), cum_score, ship_retired, last_score
X      integer*4 status, num_lines, count
X      logical ship_active, fyn
X      character ship_name*30, capt_name*10, nick_name*10, temp*30
X      character key_file*256
Xc
Xc    open up strek_info file
Xc
X      status = 0
X      inquire(file='strek_info',exist=fyn)
X      if (.not.fyn) then
X        status = 1
X        return
X      end if
X      open (unit=1,file='strek_info',access = 'direct',form =
X     &      'unformatted', status='old',recl=1000)
Xc
Xc    read number of lines
Xc
X      read(1, rec=1) num_lines
X      count = 1
X 10   continue
X      read(1,rec=count+1) temp
X      if (temp.eq.ship_name) then
X        read(1,rec=count+1) temp, capt_name, nick_name, key_file,
X     &      (ship_avail(i),i=1,3), last_score, cum_score, ship_retired
X        goto 20
X      end if
X      if (count.eq.num_lines) then
X        close(1)
X        status = 2
X        return
X      end if
X      count = count + 1
X      goto 10
X 20   continue
X      close(1)
X      if (ship_retired.eq.1) then
X        ship_active = .false.
X      else
X        ship_active = .true.
X      end if
X      return
X      end
X
X
X
X
X
X
X      subroutine strek_question (capt_name, nick_name, ship_name,
X     &                           key_file, new)
Xc
Xc    STREK_QUESTION determines if the player has a ship or if he
Xc    is new (or just a new ship). 
Xc
Xc    version 1
Xc                                -jsr 8/85
Xc
X      logical new, found
X      character capt_name*10, nick_name*10, ship_name*30
X      character answer*1, key_file*256, means(256)*1
Xc
Xc    key definition common
Xc
X      common /key_defs/ means           
X      nick_name = ' '
Xc
Xc    question captains
Xc
X      print*,'STAR TREK v.3'
X      print*,' '
X      print*,'What is your name, captain?'
X      read (*,'(a)') capt_name
X      call strek_search_name (capt_name, ship_name, key_file, new)
X      if (new) then
X        print*,' '
X        print*, 'What do your friends call you sir?'
X        read(*,'(a)') nick_name
X 10     continue
X        print*,' '
X        print*,'Enter pathname of your key definition file.'
X        print*,'<return> for no file.'
X        read (*,'(a)') key_file
X        if (key_file .ne. ' ') then
X          call strek_parse_key_defs (key_file, found)
X          if (.not.found) then
X            print*,'The key definition file was not found, try again.'
X            goto 10
X          end if
X        else
X          do 20 j = 1, 256
X            means(j) = char(j)
X 20       continue                    
X        end if
X      else
X        if (key_file .ne. ' ') then
X          call strek_parse_key_defs (key_file, found)
X          if (.not.found) then
X            print*,' '
X            print*,'The key definition file was not found,'
X            print*,'enter the pathname of another file.'
X            print*,'<return> for no file.'
X            print*,' '
X            read(*,'(a)') key_file
X            if (key_file .ne. ' ') then
X              call strek_parse_key_defs (key_file, found)
X            end if
X            if (.not. found .or. key_file .eq. ' ') then
X              do 30 j = 1, 256
X                means(j) = char(j)
X 30           continue                    
X            end if
X          end if      
X        else
X          do 40 j = 1, 256
X            means(j) = char(j)
X 40       continue                    
X        end if
X      end if
X      print*,' '
X      return
X      end
X                                                                 
X
X
X
X
X      subroutine strek_ships
Xc
Xc    STREK_SHIPS outputs the current ship list including the
Xc    scores of their last outings.
Xc
Xc    version 1
Xc                                                 -jsr 8/85
Xc
X% include '/sys/ins/base.ins.ftn'
X% include '/sys/ins/cal.ins.ftn'
X% include '/sys/ins/time.ins.ftn'
Xc
X      integer*2 decoded_clock(6)
X      integer*4 num_lines, last_score, cum_score, ship_avail(3)
X      integer*4 ship_retired
X      logical fyn
X      character ship_name*30, capt_name*10, nick_name*10, retired*10
X      character key_file*256
X      save retired
X      data retired /'retired'/
Xc
Xc    get local time
Xc
X      call cal_$decode_local_time (decoded_clock)
Xc
Xc    open database
Xc
X      inquire(file='strek_info',exist=fyn)
X      if (.not.fyn) then
X        status = 1
X        return
X      end if
X      open (unit=1,file='strek_info',access ='direct',form =
X     &      'unformatted', status='old',recl=1000)           
Xc
Xc    print out header
Xc
X      print*,' '
X      print*,' '
X      write (*,100) (decoded_clock(i),i=1,3)
X100   format ('STAR TREK Ship Registry as of ',i4,'/',i2,'/',i2)
X      print*,' '
X      print*,' SHIP NAME                     LAST SCORE   AVAILABLE     
X     &SCORE'
X      print*,' '
X      read (1,rec=1) num_lines
X      do 10 j=2,num_lines+1
X        read (1,rec=j) ship_name, capt_name, nick_name, key_file,
X     &                     (ship_avail(i), i=1,3), last_score,
X     &                     cum_score, ship_retired
X        if (ship_retired.eq.1) then
X          write (*,120) ship_name, last_score, retired, cum_score
X        else
X          write (*,130) ship_name, last_score, (ship_avail(i), i=1,3),
X     &                  cum_score
X        end if
X 10   continue
X120   format (1x,a30,x,i10,5x,a7,i10)
X130   format (1x,a30,x,i10,2x,i4,'/',i2,'/',i2,i10)
X      print*,' '
X      print*,' '
X      close(1)
X      return
X      end
X            
X
X
X
X
X      subroutine strek_scores 
Xc
Xc    STREK_SCORES prints out the list of top scores currently
Xc    in STREK_TOP_SCORES.
Xc
Xc    version 1
Xc                                                   -jsr 8/85
Xc
X% include '/sys/ins/base.ins.ftn'      
X% include '/sys/ins/cal.ins.ftn'
X% include '/sys/ins/time.ins.ftn'
X      integer*2 decoded_clock(6)
X      integer*4 top_scores
X      logical fyn
X      character capt_name*10, ship_name*30
Xc
Xc    get local time
Xc
X      call cal_$decode_local_time (decoded_clock)
Xc
Xc    open up top scores file and read
Xc
X      inquire(file='strek_top_scores', exist=fyn)
X      if (.not.fyn) then
X        status = 1
X        return
X      end if
X      open (unit=2,file='strek_top_scores' ,status='old',recl=1000)
Xc
Xc    print out header
Xc
X      print*,' '
X      write (*,100) (decoded_clock(i),i=1,3)
X100   format (' Top 10 STAR TREK Scores as of ',i4,'/',i2,'/',i2)
X      print*,' '
X      print*,'    CAPTAIN    SHIP NAME                          SCORE'
X      print*,' '
X      do 10 j=1,10
X        read (2,110) capt_name, ship_name, top_scores
X        write (*,120) j, capt_name, ship_name, top_scores
X 10   continue
X      print*,' '
X      print*,' '
X110   format(a10,a30,i10)                                   
X120   format(i2,'.',2x,a10,x,a30,i10)
X      close(2)
X      return
X      end
X
X
X
X
X
X      subroutine strek_damage_date (damage_days, ship_avail)
Xc
Xc    STREK_DAMAGE_DATE computes the ship availability date
Xc    given the damage repair time in whole days. This is
Xc    used after a game but before updating STREK_INFO via
Xc    STREK_WRITE. Note that damage date can't exceed 1 year
Xc    and is not adjusted for leap years encountered when
Xc    damage occurs in a non-leap year.
Xc
Xc    version 1
Xc                                                -jsr 8/85
Xc
X% include '/sys/ins/base.ins.ftn'
X% include '/sys/ins/cal.ins.ftn'
X% include '/sys/ins/time.ins.ftn'
Xc
X      integer*2 decoded_clock(6)
X      integer*4 ship_avail(3), damage_days, days(12)
Xc
Xc    days in months data
Xc
X      data days/31,28,31,30,31,30,31,31,30,31,30,31/
Xc
Xc    get local time
Xc
X      call cal_$decode_local_time (decoded_clock)      
Xc
Xc    if a leap year change days(2)
Xc
X      ichk = mod(decoded_clock(1),4)
X      if (ichk.eq.0) then
X        days(2) = 29
X        ichk1 = mod(decoded_clock(1),100)
X        ichk2 = mod(decoded_clock(1),400)
X        if (ichk1.eq.0) then
X          if (ichk2.eq.0) then
X            days(2) = 29
X          else
X            days(2) = 28
X          end if
X        end if
X      end if      
Xc
Xc    add damage days to local time
Xc
X      iday = damage_days + decoded_clock(3)
X      imonth = decoded_clock(2)
X      if (iday.gt.days(imonth)) then
X        iday = iday - days(imonth)
X        imonth = decoded_clock(2) + 1
X      end if
X      if (imonth.le.12) then
X        iyear = decoded_clock(1)
X      else
X        iyear = decoded_clock(1) + 1
X        imonth = imonth - 12
X      end if
Xc
Xc    load ship availability date
Xc
X      ship_avail(1) = iyear      
X      ship_avail(2) = imonth
X      ship_avail(3) = iday
X      return
X      end     
X                                           
X
X
X
X
X
X      subroutine strek_startup (capt_name, nick_name, ship_name,
X     &                          last_score, cum_score, key_file, new)
Xc
Xc    STREK_STARTUP initializes the strek system. The order
Xc    of calls is:
Xc
Xc    STREK_QUESTION - get captain info and ship name,
Xc
Xc    STREK_REVIEW - if ship is old get it's stats.
Xc
Xc    options: STREK_SHIPS - review the current ship registry,
Xc         and STREK_SCORES - review the top 10 scores.
Xc
Xc    version 1
Xc                                            -jsr 8/85
Xc
X      integer*4 ship_avail(3), last_score, cum_score, status
X      logical ship_active, open, new, avail
X      character capt_name*10, nick_name*10, ship_name*30, answer*1
X      character*256 key_file
Xc
Xc    STREK is open so question the captain
Xc
X      call strek_question (capt_name, nick_name, ship_name,
X     &                     key_file, new)
Xc
Xc    if this is a new ship or captain set up scores
Xc
X      if (new) then
X        cum_score = 0
X        last_score = 0
X      else
Xc
Xc    this is an old ship, check her status in the registry
Xc
X        call strek_review (ship_name, capt_name, nick_name, ship_avail,
X     &                     cum_score, last_score, ship_active, key_file,
X     &                     status)
X        if (status.eq.1) then
X          print*,'STREK_INFO doesn''t exist, execution stops!'
X          print*,'Run STREK_STARTUP_DB to initialize the database.'
X          print*,' '
X          stop
X        end if
X      end if
Xc
Xc    review the registry or scores?
Xc
X 10   continue
X      print*,'Enter <r> to view the ship registry,'
X      print*,'      <s> to view the top ten scores or'
X      print*,'      <return> to start.'
X      print*,' '
X      read (*,'(a)') answer
X      if (answer.eq.'r') then
X        call strek_ships
X        goto 10
X      else if (answer.eq.'s') then
X        call strek_scores
X        goto 10
X      else
X        print*,' '
X      end if
X      return
X      end  
X                                     
X
X
X       
X
X      subroutine strek_ship_avail (ship_avail, avail)
Xc
Xc    STREK_SHIP_AVAIL decodes the ship available time from
Xc    STREK_INFO and decides if the ship is ready or not.
Xc    Dead ships are flagged in STREK_INFO and needn't
Xc    be processed herein.
Xc   
Xc    If (avail) then the ship is available.
Xc 
Xc    version 1
Xc                                         -jsr 8/85
Xc
X% include '/sys/ins/base.ins.ftn'
X% include '/sys/ins/time.ins.ftn'
X% include '/sys/ins/cal.ins.ftn'
Xc
X      integer*2 decoded_clock(6)
X      integer*4 ship_avail(3)
X      logical avail
Xc
Xc    get local time
Xc
X      call cal_$decode_local_time (decoded_clock)      
Xc
Xc    compare dates and see if ship is ready
Xc
X      if (ship_avail(1).gt.decoded_clock(1)) then
X        avail = .false.
X        return
X      else if (ship_avail(1).lt.decoded_clock(1)) then
X        avail = .true.
X        return
X      else if (ship_avail(2).gt.decoded_clock(2)) then
X        avail = .false.
X        return
X      else if (ship_avail(2).lt.decoded_clock(2)) then
X        avail = .true.
X        return
X      else if (ship_avail(3).gt.decoded_clock(3)) then
X        avail = .false.
X        return
X      else 
X        avail = .true.
X      end if
X      return
X      end           
X
X
X
X
X      subroutine strek_dock (d_pct, score, capt_name, nick_name,
X     &                       ship_name, cum_score, key_file, new_ship)
Xc
Xc    STREK_DOCK updates the STREK database after docking
Xc
Xc    version 1
Xc                                     -jsr 8/85
Xc
X% include '/sys/ins/base.ins.ftn'
X% include '/sys/ins/cal.ins.ftn'
X% include '/sys/ins/gpr.ins.ftn'
X% include '/sys/ins/time.ins.ftn'
Xc
X      integer*2 clock(3)
X      integer*4 score, cum_score, days, ship_avail(3), status
X      integer*4 seconds
X      real*4 d_pct(6), time(6), damage
X      character*80 message(3)
X      character capt_name*10, nick_name*10, ship_name*30, key_file*256
X      logical new_ship, active, top_ten
X      data time /1.25, 1.25, .75, 0.5, .75, 0.5/
X      data active /.true./
X      data seconds /2/
Xc
Xc    do house keeping
Xc
X      cum_score = cum_score + score
X      call cal_$sec_to_clock (seconds, clock)
Xc
Xc    add up damage times
Xc
X      damage = 0.5
X      do 10 j = 1,6
X        damage = damage + (1.00 - d_pct(j))*time(j)
X 10   continue
X      days = nint(damage)
X      call strek_damage_date (days, ship_avail)
Xc
Xc    write update info to STREK_INFO
Xc
X      call strek_write (new_ship, ship_name, capt_name, nick_name,
X     &                  key_file, ship_avail, score, cum_score,
X     &                  active, top_ten)
Xc
Xc    write messages to screen
Xc
X      message(1) = ' '
X      message(2) = 'Awaiting permission to dock.'
X      message(3) = ' '
X      call strek_message (message, 3)
X      call time_$wait (time_$relative, clock, status)
X      message(2) = 'Docking completed, good going captain. '
X      call strek_message (message, 3)
X      call time_$wait (time_$relative, clock, status)      
Xc
Xc    terminate graphics
Xc
X      call gpr_$terminate (.true., status)
X      print*,' '
X      if (ship_name.ne.' ') then
X        write (*,100) (ship_avail(i), i=1,3)
X      end if
X100   format(' Your ship will be ready on ',i4,'/',i2,'/',i2)
X      print*,' '
X      print*,'Score for this mission: ',score
X      print*,'Cumulative score: ',cum_score
X      print*,' '
X      if (top_ten) then
X        call strek_scores
X        print*,' '
X        print*,'Congratulations! Your score places you in the Top 10.'
X        print*,' '
X      end if
X      return
X      end
X
X
X
X
X
X      subroutine strek_no_energy (num_times, capt_name, nick_name, 
X     &                            ship_name, key_file, score,
X     &                            cum_score, new)
Xc
Xc    STREK_NO_ENERGY advises the captain to cut energy use. Messages
Xc    become more and more urgent as the number of turns w/o energy
Xc    increases. After 150 turns the ship is retired and the database
Xc    updated.
Xc
Xc    version 1
Xc                                         -jsr 8/85
Xc
X% include '/sys/ins/base.ins.ftn'
X% include '/sys/ins/cal.ins.ftn'
X% include '/sys/ins/gpr.ins.ftn'
X% include '/sys/ins/time.ins.ftn'
Xc
X      integer*2 clock(3)
X      integer*4 num_times, score, cum_score, status, ship_avail(3)
X      integer*4 seconds
X      character capt_name*10, nick_name*10, ship_name*30, key_file*256
X      character*80 message_1(3), message_2(3), message_3(3), blank(3)
X      logical top_ten, new
X      save message_1, message_2, message_3, seconds, ship_avail
X      data seconds, ship_avail /5, 3*0/
Xc
Xc    data for message strings
Xc
X      data message_1 /'Message from engineering:',
X     &                'Sir, the battery reserves are critically low.',
X     &                'Non-vital subsystems being dropped.'/
X      data message_2 /'Message from engineering:',
X     &                'Main system shutdown occuring on all decks.',
X     &                'Life-support system is in danger of failure.'/
X      data message_3 /'Message from engineering:',
X     &                'Life-support system is down, oxygen content is dr
X     &opping.',
X     &                'Main system shutdown complete.'/
X      if (num_times.eq.1) then
X        call strek_message (message_1, 3)
X      else if (num_times.eq.50) then
X        call strek_message (message_2, 3)
X      else if (num_times.eq.100) then
X        call strek_message (message_3, 3)
X      else if (num_times.eq.150) then
X        blank(1) = 'Message from chief engineer Scotty:'
X        blank(2) = 'Sir, aye can''t hold on much longah.'
X        write (blank(3),'(a30, a10)') 'It looks like the game''s over ',
X     &                                nick_name
X        call strek_message (blank, 3)
Xc
Xc    do house keeping
Xc
X        cum_score = cum_score + score
X        call cal_$sec_to_clock (seconds, clock)
X        call strek_write (new, ship_name, capt_name, nick_name,
X     &                    key_file, ship_avail, score, cum_score,
X     &                    .false., top_ten)
X        call time_$wait (time_$relative, clock, status)
Xc
Xc    terminate graphics
Xc
X        call gpr_$terminate (.true., status)
X        print*,' '
X        print*,'Score for this mission: ',score
X        print*,'Cumulative score: ',cum_score
X        print*,' '
X        if (top_ten) then
X          call strek_scores
X          print*,' '
X          print*,'Congratulations! Your score places you in the Top 10.'
X          print*,'A rather hollow victory I would think.'
X          print*,' '
X        end if
X        print*,' '
X        if (ship_name.ne.' ') then
X          print*,'Your ship, the ',ship_name
X          print*,'was decommissioned after being found by Federation sco
X     &uts.'
X          print*,' '
X        end if
X        stop
X      end if
X      return
X      end        
X
X
X
X
X
X
X
X      subroutine strek_search_name (capt_name, ship_name, key_file, new)
Xc
Xc     STREK_SEARCH_NAME searches for the names of ships for a certain 
Xc     captain.  To fly a certain ship he need only type the number 
Xc     associated with it.
Xc
Xc     4/86                                             -jsr
Xc
X      integer num_lines, ship_avail(3), last_score, cum_score
X      integer ship_retired, count
X      logical new, avail, ready(10)
X      character capt_name*10, nick_name*10, ship_name*30
X      character key_file*256, temp1*30, temp2*10, practice*30
X      character ships(10)*30, nick(10)*10, key(10)*256
Xc
Xc    open the info file and read off all ship names
Xc
X      open (unit=1,file='strek_info',access = 'direct',form =
X     &      'unformatted', status='old',recl=1000)
Xc
Xc    read number of lines
Xc
X      read(1, rec=1) num_lines
X      count = 2
X      do 10 i = 2, num_lines + 1
X        read(1,rec = i) temp1, temp2
X        if (temp2.eq.capt_name) then
X          read(1,rec=i) ships(count), temp2, nick(count), key(count),
X     &        (ship_avail(j),j=1,3), last_score, cum_score, ship_retired
X          call strek_ship_avail (ship_avail, avail)
X          if (avail) then
X            ready(count) = .true.
X          else
X            ready(count) = .false.
X          end if
X          count = count + 1
X        end if
X 10   continue
X      close(1)
X      count = count - 1
X      practice = 'practice flight'
X      ships(1) = 'initiate new ship'
X      ready(1) = .true.
X      print*,' '
X      print*,'Ships available:'
X      print*,' '
X      write(*, 100) 0, practice
X      do 20 i = 1, count
X        if (ready(i)) then
X          write(*, 100) i, ships(i)
X        end if
X 20   continue
X 30   continue
X100   format (x, i1, '. ', a30)
X      print*,' '
X      print*,'Enter the number of the ship you wish to fly.'
X      print*,' '
X      read*,number
X      if (number .eq. 1) then
X        print*,' '
X        print*,'What do you want to call your ship sir?'
X        read(*,'(a)') ship_name
X        new = .true.
X      else if (number .gt. 1 .and. ready(number)) then
X        new = .false.
X        ship_name = ships(number)
X        nick_name = nick(number)
X        key_file = key(number)    
X      else if (number .eq. 0) then
X        new = .true.
X        ship_name = ' '           
X      else 
X        goto 30
X      end if
X      return
X      end
E!O!F! xstrek/original_code/strek_db_subs.f
echo xstrek/original_code/strek_enemy_subs.f 1>&2
sed -e 's/^X//' > xstrek/original_code/strek_enemy_subs.f <<'E!O!F! xstrek/original_code/strek_enemy_subs.f'
X      subroutine strek_find_free_ob (object, first, free_ob, found)
Xc
Xc
Xc    *******************************************************************
Xc    *****                                                         *****
Xc    *****                STAR TREK VERSION 3.0                    *****
Xc    *****                                                         *****
Xc    *****                     written by                          *****
Xc    *****                                                         *****
Xc    *****                Justin S. Revenaugh                      *****
Xc    *****                                                         *****
Xc    *****                       7/87                              *****
Xc    *****                                                         *****
Xc    *****        Massachussetts Institute of Technology           *****
Xc    *****  Department of Earth, Atmospheric and Planetary Science *****
Xc    *****                                                         *****
Xc    *******************************************************************
X
Xc    STREK_FIND_FREE_OB finds a free (unused) object number within
Xc    the range [first, first+2]. If no such object exists then
Xc    found is false. Used for finding free photon objects numbers.
Xc
Xc
X      integer*4 first, free_ob
X      logical object(0:9), found
Xc
Xc    find first free object
Xc
X      found = .false.
X      if (.not.object(first)) then
X        found = .true.
X        free_ob = first
X      else if (.not.object(first+1)) then
X        found = .true.
X        free_ob = first + 1
X      else if (.not.object(first+2)) then
X        found = .true.
X        free_ob = first + 2
X      end if
X      return
X      end
X
X
X
X
X
X      subroutine strek_place_nemian (xc, yc, zc, obx, oby, obz, oazm,
X     &                               oangle, ospeed, seed)
Xc
Xc    STREK_PLACE_NEMIAN places a nubian freighter ship near
Xc    the players ship. It will always fall in the distance
Xc    range 600 - 1000.
Xc
Xc    version 1
Xc                                          -jsr 8/85
Xc
X      real*4 xc, yc, zc, obx, oby, obz, ospeed, oazm, oangle
X      real*4 seed, radius, theta, phi
X      real*4 pi
X      save pi
X      data pi / 3.14159265/
Xc
Xc    find azm and angle totally at random
Xc
X      call rand (seed)
X      oazm = pi * seed
X      call rand (seed)
X      oangle = pi * seed
Xc
Xc    find displacement using spherical coordinate geometry
Xc
X      call rand (seed)
X      radius = 400.0 * seed + 600.0
X      call rand (seed)
X      theta = 2.0 * pi * seed
X      call rand (seed)
X      phi = pi * seed
X      sp  = sin(phi)
X      obx = radius * cos(theta) * sp + xc
X      oby = radius * sin(theta) * sp + yc
X      obz = radius * cos(phi)        + zc    
Xc
Xc    pick a speed at random
Xc      
X      call rand (seed)
X      ospeed = 0.25 + seed * 0.15
X      return
X      end
X
X
X
X
X
X      subroutine strek_place_enemy (xc, yc, zc, obx, oby, obz, oazm,
X     &                              oangle, ospeed, seed)
Xc
Xc    STREK_PLACE_ENEMY places a single enemy ship in the vicinity of
Xc    the player ship. Initial azm and angle are random.
Xc
Xc    version 1
Xc                                             -jsr 8/85
Xc
X      real*4 xc, yc, zc, obx, oby, obz, oazm, oangle, ospeed
X      real*4 seed, radius, theta, phi, pi
X      save pi
X      data pi / 3.14159265/
Xc
Xc    find displacement
Xc
X      call rand (seed)
X      radius = 600.0 * seed + 1000.0
X      call rand (seed)
X      theta = 2.0 * pi * seed
X      call rand (seed)
X      phi = pi * seed
X      sp = sin(phi)
X      obx = radius * cos(theta) * sp + xc
X      oby = radius * sin(theta) * sp + yc
X      obz = radius * cos(phi)        + zc    
X      call rand (seed)
X      oazm = 2.0 * pi * seed
X      call rand (seed)
X      oangle = pi * seed
X      call rand (seed)
X      ospeed = 3.5 * seed
X      return
X      end
X
X
X
X
X
X
X      subroutine strek_enemy_setup (damage, agr, kling, maxd, object,
X     &                              seed, two, photons)
Xc
Xc    STREK_ENEMY_SETUP initializes many of the enemy ship variables
Xc    Ensures that there is only one klingon at a time.
Xc
Xc    version 1
Xc                                              -jsr 8/85
Xc
X      integer*4 photons(3)
X      real*4 damage(0:9), maxd(9), seed
X      logical object(0:9), kling(3), agr(3), two
Xc
Xc    set 'em up
Xc
X      i = 2
X      j = 3
Xc
Xc    set initial damage to zero
Xc
X      damage(i) = 0.0
X      damage(j) = 0.0
X      photons(i) = 3
X      photons(j) = 3
Xc
Xc    pick aggression level. Aggressive enemies come after the player
Xc    ship. Unaggressive enemies shoot nemians
Xc
X      agr(i) = .true.
X      agr(j) = .true.
X      call rand (seed)
X      if (seed.gt.0.90) agr(i) = .false.
X      call rand (seed)
X      if (seed.gt.0.90) agr(j) = .false.
X      call rand (seed)
Xc
Xc    check for klingons
Xc
X      call rand (seed)
X      if (seed.ge.0.5) then
X        kling(i) = .true.
X        maxd(i)  = 50.0
X      else
X        kling(i) = .false.
X        kling(j) = .false.
X        maxd(i)  = 40.0
X        maxd(j)  = 40.0
X      end if
Xc
Xc    determine the number of 'em
Xc
X      call rand (seed)
X      if (seed.gt.0.5) then
X        two = .true.
X        object(i) = .true.
X        object(j) = .true.
X      else
X        two = .false.
X        object(i) = .true.
X        object(j) = .false.
X      end if         
X      if (kling(i)) then
X        two = .false.
X        object(j) = .false.
X      end if
X      return
X      end
X
X
X
X
X
X      subroutine strek_move_enemy (j, obx, oby, obz, oazm, oangle,
X     &                             ospeed, xc, yc, zc, azm, angle,
X     &                             speed, agr, object, rox, roy, roz,
X     &                             odamage, photons, distance, kling,
X     &                             count_m, count_s, orange, razm, 
X     &                             rangle, brake, damage, photon_c,
X     &                             phase_c, pro_x, pro_y, seed, pcen)
Xc
Xc    STREK_MOVE_ENEMY contains the enemy ship movement and attack
Xc    logic. When chasing nemians (which is rare) there is only a
Xc    chase algorithm. When chasing player ships there are two
Xc    modes: 1. similar to chasing nemians, used when not in ships
Xc    firing arc or at a distance. 2. randomly choosen dodges which
Xc    can be: stop fast, accelerate, turn hard or a combination. 
Xc    Movement is recalculated every 10 turn. Attacks are based on
Xc    range and the same firing limitations as the player ship, i.e.
Xc    target in firing arc, in range and phasers active. Photons
Xc    follow the course of the ship when shot.
Xc
Xc    version 1
Xc                                      - jsr 8/85
Xc
X      integer*2 pcen(2)
X      integer*4 photons, j, count_m, count_s, free, photon_c(6)
X      integer*4 phase_c
X      real*4 obx(0:9), oby(0:9), obz(0:9), oangle(0:9), oazm(0:9)
X      real*4 ospeed(0:9), xc, yc, zc, azm, angle, speed, rox, pi
X      real*4 roy, roz, odamage(0:9), distance(3,0:9), orange(0:9)
X      real*4 pro_x(0:9), pro_y(0:9)
X      logical kling, agr, object(0:9), man_1, man_2, found, shoot
X      logical man_3
X      save pi
X      data pi /3.14159265/
X      ra(x) = x * pi / 180.0
Xc
Xc    increment move and shoot counters
Xc
X      count_m = count_m + 1
X      count_s = count_s + 1
Xc
Xc    if a move is indicated then do it
Xc
X      if (count_m.ge.10) then
X        count_m = 0
X        if ((.not.agr).and.(orange(j).gt.90000.0)) then
Xc
Xc    chase the nemian unless the bad guy is too close
Xc
X          if (abs(ospeed(j)).gt.1.e-3) then
X            num_forward = sqrt(distance(j,1))/ospeed(j)
X          else 
X            num_forward = 20
X          end if
X          xt = - num_forward * ospeed(1) * sin(oazm(1)) * cos(oangle(1))
X     &         + obx(1)
X          yt   = num_forward * ospeed(1) * cos(oazm(1)) * cos(oangle(1))
X     &         + oby(1)
X          zt   = num_forward * ospeed(1) * sin(oangle(1)) + obz(1)
X          dx = xt - obx(j)
X          dy = yt - oby(j)
X          dz = zt - obz(j)
X          if (abs(dy).lt.1.e-7) dy = sign(1.e-7, dy)
X          if (dy.le.0.0) then
X            tazm = - atan(dx/dy) + ra(180.0)
X          else
X            tazm = - atan(dx/dy) 
X          end if
X          dist = sqrt(dx**2 + dy**2)
X          if (abs(dist).lt.1.e-7) dist = sign(1.e-7, dist)
X          tangle = atan(dz/dist)             
X          t1 = (tazm - oazm(j))/10.0
X          t2 = (tangle - oangle(j))/10.0
X          t3 = (tazm - (oazm(j) - 360.0))/10.0
X          t4 = (tangle - (oangle(j) - 360.0))/10.0
X          if (abs(t3).lt.abs(t1)) t1 = t3
X          if (abs(t4).lt.abs(t2)) t2 = t4
X          if (abs(t1).gt.0.05) t1 = sign(.05, t1)
X          if (abs(t2).gt.0.05) t2 = sign(.05, t2)         
X          razm = t1
X          rangle = t2
Xc
Xc    adjust speed
Xc
X          if (distance(j,1).gt.3600.0) then
X            brake = (3.5 - ospeed(j))/10.0
X          else
X            brake = (ospeed(1) - ospeed(j) + 0.5)/10.0
X          end if
Xc
Xc    adjust max acceleration
Xc
X          t1 = abs(brake)
X          if (t1.gt.0.5) brake = sign (0.5, brake)
X        else
Xc
Xc    chase the bad guy. Two options here:
Xc    1. in his front arc => get out of it!
Xc    2. in his rear arc  => stay in it but approach.
Xc
X          t1 = sqrt(rox**2 + roz**2)
X          t2 = t1 / roy
X          if ((((roy.gt.0.0).and.(roy.lt.300.0)).and.(t2.lt.0.75)).or.
X     &       (((roy.gt.0.0).and.(roy.lt.820.0)).and.(t2.lt.0.18))) then
X            call rand (seed)
Xc
Xc    if seed < .10 then brake hard, .10 < seed < .25 then swerve
Xc    if .25 < seed < .50 then do both, .40 < seed < .60 then accel
Xc    else actively pursue.
Xc
X            if (seed.lt.0.10) then
X              man_1 = .true.
X              man_2 = .false.
X              man_3 = .false.
X            else if ((seed.lt.0.30).and.(seed.ge.0.10)) then
X              man_1 = .false.
X              man_2 = .true. 
X              man_3 = .false.
X            else if ((seed.lt.0.50).and.(seed.ge.0.30)) then
X              man_1 = .true.
X              man_2 = .true. 
X              man_3 = .false.
X            else if ((seed.lt.0.60).and.(seed.ge.0.50)) then 
X              man_1 = .false.
X              man_2 = .false.
X              man_3 = .true.
X            else if (t2.gt.0.33) then
X              goto 10
X            else
X              man_1 = .true.
X              man_2 = .true. 
X              man_3 = .false.
X            end if
X            if (man_1.and.((speed.gt.3.5).and.(roy.lt.75.0))) then
X              brake = (0.0 - ospeed(j))/10.0
X            end if
X            if (man_2) then
Xc
Xc     get polarity of the swerve
Xc
X              call rand (seed)
X              razm = 0.0
X              rangle = 0.0
X              if (seed.lt.0.25) then
X                razm = ra(-3.5)
X              else if ((seed.ge.0.25).and.(seed.lt.0.5)) then
X                razm = ra(3.5)
X              else if ((seed.ge.0.5).and.(seed.lt.0.75)) then
X                rangle = ra(-3.5)
X              else 
X                rangle = ra(3.5)
X              end if
X            end if
Xc
Xc     if man_3 then accelerate
Xc
X            if (man_3) then
X              brake = (3.5 - ospeed(j))/10.0
X            end if
X          else
X 10         continue
Xc
Xc     in rear arc then pursue
Xc
X            rootor = sqrt(orange(j))
X            num_forward = sqrt(orange(j)) / 20.0 
X            if (num_forward .gt. 20) num_forward = 20
X            xt = - num_forward * speed * sin(ra(azm)) * cos(ra(angle))
X     &           + xc
X            yt   = num_forward * speed * cos(ra(azm)) * cos(ra(angle))
X     &           + yc
X            zt   = num_forward * speed * sin(ra(angle)) + zc
X            dx = xt - obx(j)
X            dy = yt - oby(j)
X            dz = zt - obz(j)
X           if (abs(dy).lt.1.e-7) dy = sign(1.e-7, dy)
X           if (dy.le.0.0) then
X             tazm = - atan(dx/dy) + pi
X           else
X             tazm = - atan(dx/dy) 
X           end if
X           dist = sqrt(dx**2 + dy**2)
X           if (abs(dist).lt.1.e-7) dist = sign(1.e-7, dist)
X           tangle = atan(dz/dist)             
Xc
Xc    pick smallest angle (needed due to arctan being only in quads 
Xc    I and IV)
Xc
X           t1 = (tazm - oazm(j))/10.0
X           t2 = (tangle - oangle(j))/10.0
X           t3 = (tazm - (oazm(j) - 360.0))/10.0
X           t4 = (tangle - (oangle(j) - 360.0))/10.0
X           if (abs(t3).lt.abs(t1)) t1 = t3
X           if (abs(t4).lt.abs(t2)) t2 = t4
X           if (abs(t1).gt.0.1) t1 = sign(.1, t1)
X           if (abs(t2).gt.0.1) t2 = sign(.1, t2)            
X           razm = t1
X           rangle = t2
Xc
Xc    adjust speed
Xc
X           if (distance(j,1).gt.10000.0) then
X             brake = (4.00 - ospeed(j))/10.0
X           else
X             brake = (speed - ospeed(j) + 0.75)/10.0
X           end if
Xc
Xc    adjust max acceleration
Xc
X           t1 = abs(brake)
X           if (t1.gt.0.5) brake = sign (0.5, brake)
X          end if
X        end if
X      end if
Xc
Xc    formulate attacks
Xc
X      if (count_s.ge.20) then
X        count_s = 0
Xc
Xc    check for photon firing
Xc
X        if (kling) then
X          if ((photons.gt.0).and.orange(j).lt.102400) then
X            call strek_find_free_ob (object, 4, free, found)
X            if (found) then
X              t1 = ra(azm)
X              t2 = ra(angle)
X              call strek_aim_photons (xc, yc, zc, t1, t2, speed,
X     &                                obx(j), oby(j), obz(j), oazm(j),
X     &                                oangle(j), shoot)
X              call rand (seed)
X              if (seed.lt.0.7) then
X                if (shoot) then
X                  object(free) = .true.
X                  ospeed(free) = 11.0
X                  obx(free)    = obx(j)
X                  oby(free)    = oby(j)
X                  obz(free)    = obz(j)
X                  oazm(free)   = oazm(j)
X                  oangle(free) = oangle(j)
X                  odamage(free)= 0.0
X                  photon_c(free-3) = 0
X                  photons = photons - 1
X                end if
X              end if
X            end if
X          end if
Xc
Xc    if ship is a klingon then consider phasers
Xc
X          if (phase_c.gt.40.0.and.orange(j).lt.40000.0) then
X            xt = xc - obx(j)
X            yt = yc - oby(j)
X            zt = zc - obz(j)
X            ca = cos(oazm(j))
X            sa = sin(oazm(j))
X            cp = cos(oangle(j))
X            sp = sin(oangle(j))
X            pox =  xt*ca    + yt*sa
X            poy = -xt*sa*cp + yt*ca*cp + zt*sp
X            poz =  xt*sa*sp - yt*ca*sp + zt*cp            
X            if (poy.gt.1.e-7) then
X              t1 = pox/poy
X              t2 = poz/poy
X              if ((t1.lt.1.0).and.(t2.lt.1.0)) then
X                call rand (seed)
X                if (seed.gt.0.2) then
X                  call strek_phaser_damage (orange(j), damage, seed,
X     &                                     .true.)
X                  call strek_phaser_ship (pro_x(j), pro_y(j), pcen,
X     &                                    seed)
X                  phase_c = 0
X                end if
X              end if
X            end if
X          else if (.not.agr.and.(phase_c.gt.60.0.and.distance(j,1).lt.
X     &             10000.0)) then
X            xt = obx(1) - obx(j)
X            yt = oby(1) - oby(j)
X            zt = obz(1) - obz(j)
X            ca = cos(oazm(j))
X            sa = sin(oazm(j))
X            cp = cos(oangle(j))
X            sp = sin(oangle(j))
X            pox =  xt*ca    + yt*sa
X            poy = -xt*sa*cp + yt*ca*cp + zt*sp
X            poz =  xt*sa*sp - yt*ca*sp + zt*cp            
X            if (poy.gt.1.e-7) then
X              t1 = pox/poy
X              t2 = poz/poy
X              if ((t1.lt.1.0).and.(t2.lt.1.0)) then
X                call rand (seed)
X                if (seed.gt.0.6) then
X                  call strek_phaser_damage (distance(j,1), odamage(1),
X     &                                      seed, .false.)
X                  call strek_phaser_nemian (pro_x, pro_y)
X                  phase_c = 0
X                end if
X              end if
X            end if
X          end if
X        else
Xc
Xc    this is a romulan, either photon player or nemian
Xc
X          if ((photons.gt.0).and.orange(j).lt.90000) then
X            call strek_find_free_ob (object, 4, free, found)
X            if (found) then
X              t1 = ra(azm)
X              t2 = ra(angle)
X              call strek_aim_photons (xc, yc, zc, t1, t2, speed,
X     &                                obx(j), oby(j), obz(j), oazm(j),
X     &                                oangle(j), shoot)
X              call rand (seed)
X              if (seed.lt.0.5) then
X                if (shoot) then
X                  object(free) = .true.
X                  ospeed(free) = 11.0
X                  obx(free)    = obx(j)
X                  oby(free)    = oby(j)
X                  obz(free)    = obz(j)
X                  oazm(free)   = oazm(j)
X                  oangle(free) = oangle(j)
X                  odamage(free)= 0.0
X                  photon_c(free-3) = 0
X                end if
X              end if
X            end if
X          else if (distance(j,1).lt.40000.0) then
X            call strek_find_free_ob (object, 4, free, found)
X            if (found) then
X              call strek_aim_photons (obx(1), oby(1), obz(1), oazm(1),
X     &                                oangle(1), ospeed(1), obx(j),
X     &                                oby(j), obz(j), oazm(j),
X     &                                oangle(j), shoot)
X              call rand (seed)
X              if (seed.lt.0.4) then
X                if (shoot) then
X                  object(free) = .true.
X                  ospeed(free) = 11.0
X                  obx(free)    = obx(j)
X                  oby(free)    = oby(j)
X                  obz(free)    = obz(j)
X                  oazm(free)   = oazm(j)
X                  oangle(free) = oangle(j)
X                  odamage(free)= 0.0
X                  photon_c(free-3) = 0
X                end if
X              end if
X            end if
X          end if
X        end if
X      end if
Xc
Xc    adjust angles and stuff
Xc
X      ospeed(j) = ospeed(j) + brake
X      if (ospeed(j).gt.4.00) ospeed(j) = 4.00
X      if (ospeed(j).lt.0.0) ospeed(j) = 0.1
X      oazm(j) = oazm(j) + razm
X      oangle(j) = oangle(j) + rangle
X      phase_c = phase_c + 1
X      return
X      end
X
X
X
X
X      subroutine strek_aim_photons (xc, yc, zc, azm, angle, speed, obx,
X     &                              oby, obz, oazm, oangle, shoot)
Xc
Xc    STREK_AIM_PHOTONS projects the enemy photons, shoot is true if 
Xc    the projection falls within 40 units of the projected player
Xc    ship. Photons do not inherit the parents ship's velocity.
Xc
Xc    version 1
Xc                                  -jsr 8/85
Xc
X      real*4 xc, yc, zc, azm, angle, speed, obx, oby, obz, oazm, oangle
X      real*4 pi, a, b, c, oa, ob, oc
X      logical shoot
Xc
Xc    figure all pertinent angles (note that ship angles are converted
Xc    to radians in STREK_MOVE_ENEMY).
Xc
X      sa = sin(azm)
X      ca = cos(azm)
X      sp = sin(angle)
X      cp = cos(angle)
X      a  = -sa * cp * speed
X      b  =  ca * cp * speed
X      c  =  sp * speed
X      sa = sin(oazm)
X      ca = cos(oazm)
X      sp = sin(oangle)
X      cp = cos(oangle)
X      ospeed = 11.0
X      oa = -sa * cp * ospeed
X      ob =  ca * cp * ospeed
X      oc =  sp * ospeed
X      da = a - oa
X      db = b - ob
X      dc = c - oc
X      dx = xc - obx
X      dy = yc - oby
X      dz = zc - obz
Xc
Xc    check for an intersection within tolerance (which is 40**2 in
Xc    an all out attempt not to do sqrt's)
Xc
X      tol = 30.0**2
X      shoot = .false.
X      j = 1
X 10   continue
X      if (j.gt.50) return
X      dist = (j*(da) + dx)**2 + (j*(db) + dy)**2 + (j*(dc) + dz)**2
X      if (dist.le.tol) then
X        shoot = .true.
X        return
X      end if
X      j = j + 1
X      goto 10
X      end 
X
X
X
X
E!O!F! xstrek/original_code/strek_enemy_subs.f
exit
=====
            @work:            | Matthias Pfuetzner  |         @home:
  ZGDV, Wilhelminenstrasse 7  | 6100 Darmstadt, FRG |  Lichtenbergstrasse 73
    +49 6151 155-164 or -101  \    <- Tel.nr. ->    /     +49 6151 75717
   pfuetzner@agd.fhg.de    pfuetzner@zgdvda.UUCP    XBR1YD3U@DDATHD21.BITNET

--
Dan Heller
------------------------------------------------
O'Reilly && Associates		ZipCode Software
Senior Writer			       President
argv@ora.com			argv@zipcode.com