v11i092: Another Star Trek Game, Part06/14
pfuetz at agd.fhg.de
pfuetz at agd.fhg.de
Tue Feb 26 15:15:00 AEST 1991
Submitted-by: pfuetz at 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 at agd.fhg.de pfuetzner at zgdvda.UUCP XBR1YD3U at DDATHD21.BITNET
--
Dan Heller
------------------------------------------------
O'Reilly && Associates ZipCode Software
Senior Writer President
argv at ora.com argv at zipcode.com
More information about the Comp.sources.x
mailing list