home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.ee.lbl.gov
/
2014.05.ftp.ee.lbl.gov.tar
/
ftp.ee.lbl.gov
/
mtrek.shar.Z
/
mtrek.shar
/
zip.ftn
< prev
next >
Wrap
Text File
|
1990-04-02
|
18KB
|
907 lines
PROGRAM ZIP
C
C Control code for the driver program
C
INCLUDE 'LEDFOR.COM/-LI'
INCLUDE 'BUFFER.COM/-LI'
BYTE HOLE
REAL*4 OVER(2)
DATA OVER/6RZIPINT,6RPHASER/
DATA HOLE/.FALSE./
CALL MNLOAD(OVER(1)) ! Load ZIPINT
CALL ZIPINT
CALL MNLOAD(OVER(2)) ! Load PHASER
C
C Here starts the actual game playing
C
10000 CALL MARK(1,60,1)
CALL WAITFR(1)
C Fire torpedoes
CALL TORPI
C Fire phasers
CALL PHASER
C Move active torpedoes
CALL MTORPS
C Move ships
CALL MSHIPS
C Move the "black hole"
CALL MHOLE(HOLE)
HOLE=.NOT.HOLE
C Handle all anti-matter transactions
CALL MANTI
C Update system time
IF(HOLE)CALL SYSTIM
IF(THRU.NE.0)GOTO 10000
C All players are gone; wait 7 seconds before exiting
THRU=-2
DO 10001 K=1,7
CALL MARK(1,60,1)
CALL WAITFR(1)
IF(THRU.LE.0)GOTO 10001
GOTO 10000
10001 CONTINUE
CALL EXIT
END
SUBROUTINE ZIPINT
C
C Set up the whole show
C
INCLUDE 'LEDFOR.COM/-LI'
INCLUDE 'BUFFER.COM/-LI'
BYTE OK,VALID,DEF,SHIP
CALL CHKPAR ! Make sure LEDFOR is set
CALL ERRSET(24,,.FALSE.,,.FALSE.)
CALL ERRSET(39,,.FALSE.,,.FALSE.)
CALL ERRSET(64,,.FALSE.,.TRUE.,.FALSE.)
C
C Get the first random number seed
C
X=SECNDS(0.0)
I1=INT((X-AINT(X))*1000.0)
WRITE(1,10000)"15
10000 FORMAT(' ',A1,'Welcome to Multi-Trek')
IF(UNIV(1,1).EQ.0)GOTO 10102
10100 WRITE(1,10001)
10001 FORMAT('$Are you continuing a game ? ')
CALL YESNO(OK,VALID)
IF(.NOT.VALID)GOTO 10100
IF(OK)GOTO 10002
10102 WRITE(1,10007)
10007 FORMAT('$Do you want to change the defaults ? ')
CALL YESNO(DEF,VALID)
IF(.NOT.VALID)GOTO 10102
OK=.FALSE.
C
C Get star density
C
IF(.NOT.DEF)GOTO 10009
10110 WRITE(1,10008)
10008 FORMAT('$Enter the star density of universe in parts
$ per one hundred (1.6) ')
CALL GETREL(STARS,OK,0.0,15.0,VALID)
IF(.NOT.VALID)GOTO 10110
10009 IF(.NOT.OK)STARS=1.6
STARS=(100.0-STARS)/100.0
C
C Get number of bases
C
IF(.NOT.DEF)GOTO 10010
10115 WRITE(1,10012)
10012 FORMAT('$Enter the number of star bases (12) ')
CALL GETINT(IBASES,OK,0,50,VALID)
IF(.NOT.VALID)GOTO 10115
10010 IF(.NOT.OK)IBASES=12
C
C Get number of random ports
C
IF(.NOT.DEF)GOTO 10015
10120 WRITE(1,10016)
10016 FORMAT('$Enter the number of random jump points (3) ')
CALL GETINT(N,OK,0,10,VALID)
IF(.NOT.VALID)GOTO 10120
10015 IF(.NOT.OK)N=3
C
C Get cloaking energy drain
C
IF(.NOT.DEF)GOTO 10075
10130 WRITE(1,10076)
10076 FORMAT('$Enter energy drain for cloaking (25.0) ')
CALL GETREL(CDRAIN,OK,0.0,2000.0,VALID)
IF(.NOT.VALID)GOTO 10130
10075 IF(.NOT.OK)CDRAIN=25.0
C
C Get speed of black hole
C
IF(.NOT.DEF)GOTO 10079
10135 WRITE(1,10080)
10080 FORMAT('$Enter warp speed of "black hole" (3.0) ')
CALL GETREL(ZW,OK,0.0,10.0,VALID)
IF(.NOT.VALID)GOTO 10135
10079 IF(.NOT.OK)ZW=3.0
C
C Get the second random number seed
C
X=SECNDS(0.0)
I2=INT((X-AINT(X))*1000.0)
C
C Now generate the universe
C
DO 10025 I=1,100
DO 10028 J=1,100
RNDOM=RAN(I1,I2)
IF(RNDOM.LE.STARS)GOTO 10036
UNIV(I,J)='*'
GOTO 10028
10036 UNIV(I,J)='.'
10028 CONTINUE
10025 CONTINUE
C
C Put in the star bases
C
DO 10034 I=1,IBASES
CALL NEWLOC(X,Y,'B')
10034 CONTINUE
C
C Put in the hyperspace ports
C
UNIV(20,25)='H'
UNIV(20,75)='H'
UNIV(50,30)='H'
UNIV(50,70)='H'
UNIV(80,25)='H'
UNIV(80,75)='H'
C
C Put in the mobile "black hole"
C
CALL NEWLOC(ZX,ZY,'#')
C
C Put in the random hyper-space ports
C
DO 10040 I=1,N
CALL NEWLOC(X,Y,'R')
10040 CONTINUE
C
C Put in and initialize the star ships
C
DO 10055 I=1,8
SHIP="60+I
CALL NEWLOC(XCORD(I),YCORD(I),SHIP)
ACTIVE(I)=.FALSE.
ALIVE(I)=.FALSE.
COURSE(I)=90.0
CLOAK(I)=.TRUE.
ENERGY(I)=10000.0
HYPER(I)=3
IPOD(I)=0
IT(I)=1
LAUNCH(I)=-1.0
PHA(I)=-1.0
SCORE(I)=0
SHIELD(I)=0.0
TORPS(I)=10
WARP(I)=0.0
DO 10074 K=1,10
ISENT(I,K)=0
TORDIR(I,K)=-1.0
TORLOC(I,K,1)=1
TORLOC(I,K,2)=1
10074 CONTINUE
10055 CONTINUE
C
C Initialize the system time
C
10002 CALL SYSTIM
C
C
C ** All initializition done by here **
C
WRITE(1,10084)(TIM(I),I=1,16)
10084 FORMAT('0Multi-Trek initialized at ',15A1,' ',A1,'m',/,'$>')
THRU=-1
RETURN
END
SUBROUTINE NEWLOC(X,Y,CHAR)
C
C Find an empty location in the universe for an object
C and put it there.
C
INCLUDE 'LEDFOR.COM/-LI'
INTEGER*2 IX,IY
REAL X,Y
BYTE CHAR
10001 IX=INT(RAN(I1,I2)*100.0)+1
IF(IX.GT.100)IX=100
IY=INT(RAN(I1,I2)*100.0)+1
IF(IY.GT.100)IY=100
IF(UNIV(IX,IY).NE.'.')GOTO 10001
X=FLOAT(IX)+0.5
Y=FLOAT(IY)+0.5
UNIV(IX,IY)=CHAR
RETURN
END
SUBROUTINE SYSTIM
C
C Set and update the current time and date
C
INCLUDE 'LEDFOR.COM/-LI'
INCLUDE 'BUFFER.COM/-LI'
INTEGER*2 OLDHR,OLDMN,NEWHR,NEWMN
BYTE AMPM
DATA OLDHR,OLDMN /0,0/
CALL TIME(IBUF)
NEWHR=10*(IBUF(1)-"60)+(IBUF(2)-"60)
NEWMN=10*(IBUF(4)-"60)+(IBUF(5)-"60)
IF((OLDMN.EQ.NEWMN).AND.(OLDHR.EQ.NEWHR))GOTO 10001
TIM(14)=IBUF(4)
TIM(15)=IBUF(5)
OLDHR=NEWHR
OLDMN=NEWMN
AMPM='a'
IF(NEWHR.GE.12)AMPM='p'
IF(NEWHR.GT.12)NEWHR=NEWHR-12
IF(NEWHR.EQ.0)NEWHR=12
CALL DATE(IBUF)
IF(IBUF(1).EQ.'0')IBUF(1)=' '
IBUF(5)=IBUF(5)+"40
IBUF(6)=IBUF(6)+"40
ENCODE(13,10010,TIM)(IBUF(I),I=1,9),NEWHR
10010 FORMAT(9A1,' ',I2,':')
TIM(16)=AMPM
10001 RETURN
END
SUBROUTINE MSHIPS
C
C Move ships - ramming an object costs 100 units (stars cost 200)
C
INCLUDE 'LEDFOR.COM/-LI'
BYTE CHAR,SHIP
INTEGER*2 HYPERX(6),HYPERY(6)
DATA HYPERX/20,50,80,20,50,80/
DATA HYPERY/75,70,75,25,30,25/
DO 10001 I=1,8
C Don't bother unmaned star ships
IF(.NOT.ALIVE(I))GOTO 10001
C Cloaked ships must pay toll
IF(.NOT.CLOAK(I))GOTO 10006
ENERGY(I)=ENERGY(I)-CDRAIN
WARP(I)=0.0
C Move ships
10006 IX=INT(XCORD(I))
IY=INT(YCORD(I))
SHIP="60+I
ENERGY(I)=ENERGY(I)-WARP(I)/2
CALL MOVE(XCORD(I),YCORD(I),X,Y,COURSE(I),WARP(I),CHAR,UNIV)
KX=INT(X)
KY=INT(Y)
C We have rammed a ship
IF(CHAR.GT.'8'.OR.CHAR.LT.'1')GOTO 10014
K=CHAR-"60
IF(I.EQ.K)GOTO 10076 ! Wipe out duplicate ships
WARP(I)=0.0
WARP(K)=0.0
CALL SENT(I,9)
ENERGY(I)=ENERGY(I)-100.0
IF(.NOT.ALIVE(K))GOTO 10013
CALL SENT(K,10)
ENERGY(K)=ENERGY(K)-100.0
GOTO 10013
C Rammed (docked) a base
10014 IF(CHAR.NE.'B')GOTO 10020
CALL SENT(I,1)
WARP(I)=0.0
ENERGY(I)=10000.0
SHIELD(I)=0.0
TORPS(I)=10
IF(IPOD(I).NE.2)GOTO 10016
IF(UNIV(INT(XPOD(I)),INT(YPOD(I))).EQ.'@')
$ UNIV(INT(XPOD(I)),INT(YPOD(I)))='.'
10016 IPOD(I)=0
GOTO 10013
C Hit a star
10020 IF(CHAR.NE.'*')GOTO 10022
WARP(I)=0.0
CALL SENT(I,2)
ENERGY(I)=ENERGY(I)-200.0
GOTO 10013
C Hit a torpedo
10022 IF(CHAR.NE.'+')GOTO 10024
CALL TFIND(K,KX,KY)
IF(K.EQ.0)GOTO 10076
CALL THIT(K,IX,IY,UNIV(IX,IY))
TORDIR(K,IT(K))=-1.0
UNIV(KX,KY)='.'
GOTO 10013
C Hit a hyperspace port
10024 IF(CHAR.NE.'H')GOTO 10032
WARP(I)=0.0
CALL SENT(I,17)
KX=HYPERX(HYPER(I))
KY=HYPERY(HYPER(I))
C Put the ship near the destination port if possible
10037 CONTINUE
DO 10052 II=KX-1,KX+1
DO 10055 IJ=KY-1,KY+1
IF((II.EQ.IX).AND.(IJ.EQ.IY))GOTO 10036 ! OK to place ship on itself
IF(UNIV(II,IJ).NE.'.')GOTO 10055
UNIV(IX,IY)='.'
UNIV(II,IJ)=SHIP
10036 XCORD(I)=FLOAT(II)+0.5
YCORD(I)=FLOAT(IJ)+0.5
GOTO 10013
10055 CONTINUE
10052 CONTINUE
C If we are here we didn't find an empty spot (very unlikely)
CALL SENT(I,18)
GOTO 10013
C Ran into the "black hole" (nice flying)
10032 IF(CHAR.NE.'#')GOTO 10060
CALL SENT(I,15)
CALL RESET(I)
GOTO 10013
C Hit a random hyperspace port
10060 IF(CHAR.NE.'R')GOTO 10062
WARP(I)=0.0
CALL SENT(I,19)
CALL NEWLOC(XCORD(I),YCORD(I),SHIP)
UNIV(IX,IY)='.'
GOTO 10013
C Bumped into an anti-matter pod
10062 IF(CHAR.NE.'@')GOTO 10076
CALL SENT(I,27)
WARP(I)=0.0
ENERGY(I)=ENERGY(I)-100.0
GOTO 10013
C Didn't hit anything
10076 XCORD(I)=X
YCORD(I)=Y
UNIV(IX,IY)='.'
UNIV(KX,KY)=SHIP
C Check if this guy has juice left
10013 IF(ENERGY(I).GT.0.0)GOTO 10001
CALL SENT(I,16)
CALL RESET(I)
10001 CONTINUE
RETURN
END
SUBROUTINE MTORPS
C
C Move all active torpedoes
C
INCLUDE 'LEDFOR.COM/-LI'
BYTE CHAR
DO 10001 I=1,8
DO 10004 K=1,10
IF(TORDIR(I,K).LT.0.0)GOTO 10004
IX=INT(TORLOC(I,K,1))
IY=INT(TORLOC(I,K,2))
C
C Make sure the torpedo is still there and active
C
IF(UNIV(IX,IY).NE.'+')GOTO 10006
CALL MOVE(TORLOC(I,K,1),TORLOC(I,K,2),X,Y,TORDIR(I,K),10.0,CHAR,UNIV)
KX=INT(X)
KY=INT(Y)
UNIV(IX,IY)='.'
IF(CHAR.EQ.'.')GOTO 10009
CALL THIT(I,KX,KY,CHAR)
10006 TORDIR(I,K)=-1.0
GOTO 10004
10009 UNIV(KX,KY)='+'
TORLOC(I,K,1)=X
TORLOC(I,K,2)=Y
10004 CONTINUE
10001 CONTINUE
RETURN
END
SUBROUTINE RESET(WHO)
C
C Re-incarnate destroyed ships
C
INCLUDE 'LEDFOR.COM/-LI'
INTEGER*2 WHO
BYTE SHIP
CALL SENT(WHO,3)
ALIVE(WHO)=.FALSE.
CLOAK(WHO)=.TRUE.
ENERGY(WHO)=10000.0
IF(IPOD(WHO).NE.2)GOTO 10001 ! Check for active pod
IF(UNIV(INT(XPOD(WHO)),INT(YPOD(WHO))).EQ.'@')
$ UNIV(INT(XPOD(WHO)),INT(YPOD(WHO)))='.'
10001 IPOD(WHO)=0
UNIV(INT(XCORD(WHO)),INT(YCORD(WHO)))='.'
SCORE(WHO)=SCORE(WHO)-1000
SHIELD(WHO)=0.0
TORPS(WHO)=10.0
WARP(WHO)=0.0
SHIP="60+WHO
CALL NEWLOC(XCORD(WHO),YCORD(WHO),SHIP)
RETURN
END
SUBROUTINE THIT(I,IX,IY,CHAR)
C
C Handle torpedo hits
C
INCLUDE 'LEDFOR.COM/-LI'
BYTE CHAR
C Torpedo hit on hyper space port
IF((CHAR.EQ.'H').OR.(CHAR.EQ.'R'))GOTO 10003
C Torpedo hit on ship
10004 IF((CHAR.LT.'1').OR.(CHAR.GT.'8'))GOTO 10006
K=CHAR-"60
IF(.NOT.ALIVE(K))GOTO 10009
CALL DAMAGE(K,500.0)
IF(I.EQ.K)GOTO 10007
SCORE(I)=SCORE(I)+500
CALL SENT(K,4)
CALL SENT(I,5)
IF(ENERGY(K).GT.0.0)GOTO 10003
CALL RESET(K)
CALL SENT(I,22)
SCORE(I)=SCORE(I)+2000
GOTO 10003
C Hit a ghost ship
10009 CALL SENT(I,21)
GOTO 10003
C Hit by his own torp
10007 CALL SENT(I,32)
IF(ENERGY(I).GT.0.0)GOTO 10003
CALL RESET(I)
GOTO 10003
C Torpedo hit on star
10006 IF(CHAR.NE.'*')GOTO 10015
CALL SENT(I,13)
GOTO 10003
C Torpedo hit on base (real fine shooting)
10015 IF(CHAR.NE.'B')GOTO 10017
CALL SENT(I,12)
SCORE(I)=SCORE(I)-200
GOTO 10003
C Torpedo hit on torpedo
10017 IF(CHAR.NE.'+')GOTO 10019
CALL SENT(I,20)
UNIV(IX,IY)='.'
GOTO 10003
C Torpedo hit on anti-matter pod
10019 IF(CHAR.NE.'@')GOTO 10021
CALL SENT(I,26)
GOTO 10003
C Anything else gets destroyed
10021 UNIV (IX,IY) = '.'
10003 RETURN
END
SUBROUTINE PHASER
C
C Fire phasers (3 band blast)
C
INCLUDE 'LEDFOR.COM/-LI'
INTEGER*2 DX(3),DY(3)
REAL PHASE
BYTE CHAR
DO 10001 I=1,8
IF(PHA(I).LT.0.0)GOTO 10001
IF(.NOT.ALIVE(I))GOTO 10001
PHASE=PHA(I)
PHA(I)=-1.0
DX(1)=INT(XCORD(I))
DY(1)=INT(YCORD(I))
C Three char wide beam
IF(((PHASE.LT.45.0).OR.(PHASE.GE.135.0)).AND.
$ ((PHASE.LT.225.0).OR.(PHASE.GE.315.0)))GOTO 10006
DX(2)=DX(1)-1
DX(3)=DX(1)+1
DY(2)=DY(1)
DY(3)=DY(1)
GOTO 10007
10006 DX(2)=DX(1)
DX(3)=DX(1)
DY(2)=DY(1)-1
DY(3)=DY(1)+1
10007 DO 10010 IZ=2,3
IF(DX(IZ).GE.101)DX(IZ)=DX(IZ)-100
IF(DY(IZ).GE.101)DY(IZ)=DY(IZ)-100
IF(DX(IZ).LT.1)DX(IZ)=DX(IZ)+100
IF(DY(IZ).LT.1)DY(IZ)=DY(IZ)+100
10010 CONTINUE
C Now fire from three places
DO 10019 IZ=1,3
X1=FLOAT(DX(IZ))+0.5
Y1=FLOAT(DY(IZ))+0.5
C Shoot ten places (warp 10) and hit the closest target
DO 10022 IK=1,10
CALL MOVE(X1,Y1,X,Y,PHASE,10.0,CHAR,UNIV)
IF(CHAR.NE.'.')GOTO 10023
X1=X
Y1=Y
10022 CONTINUE
GOTO 10049
C Hit on ship
10023 IF((CHAR.LT.'1').OR.(CHAR.GT.'8'))GOTO 10031
K=CHAR-"60
IF(.NOT.ALIVE(K))GOTO 10034 ! Don't blast a ghost
IF(K.EQ.I)GOTO 10019 ! Don't blast self
ENG=900.0/(4.0+SQRT((XCORD(I)-XCORD(K))**2+(YCORD(I)-YCORD(K))**2))
CALL DAMAGE(K,ENG)
SCORE(I)=SCORE(I)+INT(ENG)
CALL SENT(I,6)
CALL SENT(K,14)
IF(ENERGY(K).GT.0.0)GOTO 10019
SCORE(I)=SCORE(I)+2000
CALL SENT(I,22)
CALL RESET(K)
GOTO 10019
10034 CALL SENT(I,21)
GOTO 10019
C Phaser hit on torpedo
10031 IF(CHAR.NE.'+')GOTO 10043
CALL SENT(I,7)
GOTO 10019
C Phaser hit on star
10043 IF(CHAR.NE.'*')GOTO 10045
CALL SENT(I,11)
GOTO 10019
C Phaser hit on base
10045 IF(CHAR.NE.'B')GOTO 10047
CALL SENT(I,12)
GOTO 10019
C Phaser hit on anti-matter pod
10047 IF(CHAR.NE.'@')GOTO 10049
CALL SENT(I,25)
GOTO 10019
C Missed
10049 CALL SENT(I,8)
10019 CONTINUE
10001 CONTINUE
RETURN
END
SUBROUTINE TORPI
C
C Fire torpedoes
C
INCLUDE 'LEDFOR.COM/-LI'
BYTE CHAR
DO 10001 I=1,8
IF(LAUNCH(I).LT.0.0)GOTO 10001
IF(.NOT.ALIVE(I))GOTO 10001
CALL MOVE(XCORD(I),YCORD(I),X1,Y1,LAUNCH(I),10.0,CHAR,UNIV)
KX=INT(XCORD(I))
KY=INT(YCORD(I))
C Make sure it moved out of the firer's square
IF((KX.NE.INT(X1)).OR.(KY.NE.INT(Y1)))GOTO 10006
CALL MOVE(X1,Y1,X,Y,LAUNCH(I),10.0,CHAR,UNIV)
GOTO 10007
10006 X=X1
Y=Y1
10007 IX=INT(X)
IY=INT(Y)
IF(CHAR.NE.'.')GOTO 10009
UNIV(IX,IY)='+'
C Remove old torp (if it exists)
IF(TORDIR(I,IT(I)).LT.0.0)GOTO 10012
KX=INT(TORLOC(I,IT(I),1))
KY=INT(TORLOC(I,IT(I),2))
IF(UNIV(KX,KY).EQ.'+')UNIV(KX,KY)='.'
C Good launch
10012 TORLOC(I,IT(I),1)=X
TORLOC(I,IT(I),2)=Y
TORDIR(I,IT(I))=LAUNCH(I)
IT(I)=IT(I)+1
IF(IT(I).GT.10)IT(I)=1
GOTO 10010
C Hit something
10009 CALL THIT(I,IX,IY,CHAR)
10010 LAUNCH(I)=-1.0
10001 CONTINUE
RETURN
END
SUBROUTINE DAMAGE(WHO,ENG)
C
C Calculate damage done
C
INCLUDE 'LEDFOR.COM/-LI'
INTEGER*2 WHO
SABS=SHIELD(WHO)/1000.0
IF(SABS.GT.1.0)SABS=1.0
ENERGY(WHO)=ENERGY(WHO)-(1.2-SABS)*ENG*8.0
SHIELD(WHO)=SHIELD(WHO)-SABS*ENG
IF(SHIELD(WHO).LT.0.0)SHIELD(WHO)=0.0
RETURN
END
SUBROUTINE MOVE(XI,YI,XF,YF,DIR,WARP,CHAR,UNIV)
C
C Move objects with wrap around
C
BYTE UNIV(100,100),CHAR
REAL XI,YI,XF,YF,DIR,WARP
IXI=INT(XI)
IYI=INT(YI)
XF=XI+COS(DIR/180*3.1415926)/10.0*WARP
YF=YI+SIN(DIR/180*3.1415926)/10.0*WARP
IXF=INT(XF)
IYF=INT(YF)
IF(IXF.LE.100)GOTO 10010
IXF=IXF-100
XF=XF-100.0
10010 IF(IXF.GE.1)GOTO 10020
IXF=IXF+100
XF=XF+100.0
10020 IF(IYF.LE.100)GOTO 10030
IYF=IYF-100
YF=YF-100.0
10030 IF(IYF.GE.1)GOTO 10040
IYF=IYF+100
YF=YF+100.0
10040 CHAR=UNIV(IXF,IYF)
IF((IXI.EQ.IXF).AND.(IYI.EQ.IYF))CHAR='.'
END
SUBROUTINE TFIND(WHO,IX,IY)
C
C Find out who should get the credit if some one runs into a torp
C
INCLUDE 'LEDFOR.COM/-LI'
INTEGER*2 WHO
DO 10001 WHO=1,8
DO 10004 I=1,10
IF(TORDIR(WHO,I).LT.0.0)GOTO 10004
KX=INT(TORLOC(WHO,I,1))
KY=INT(TORLOC(WHO,I,2))
IF((IX.EQ.KX).AND.(IY.EQ.KY))GOTO 10003
10004 CONTINUE
10001 CONTINUE
WHO=0
10003 RETURN
END
SUBROUTINE SENT(WHO,NUM)
C
C Send messages to the players
C
INCLUDE 'LEDFOR.COM/-LI'
INTEGER*2 WHO
DO 10001 I=1,10
IF(ISENT(WHO,I).NE.0)GOTO 10001
ISENT(WHO,I)=NUM
GOTO 10002
10001 CONTINUE
C Message buffer is full so copy it up to keep most recent
DO 10007 I=1,9
ISENT(WHO,I)=ISENT(WHO,I+1)
10007 CONTINUE
ISENT(WHO,10)=NUM
10002 RETURN
END
SUBROUTINE MHOLE(HOLE)
C
C Move the "black hole" toward the nearest active ship
C
INCLUDE 'LEDFOR.COM/-LI'
BYTE CHAR,HOLE
IF(HOLE)GOTO 10002 ! Cut down extra FPU calculations
C Find closest ship
DM=1.6E37
K=0
DO 10001 I=1,8
IF(.NOT.ALIVE(I))GOTO 10001
D=(XCORD(I)-ZX)**2+(YCORD(I)-ZY)**2 ! Distance squared
IF(D.GE.DM)GOTO 10001
DM=D
K=I
10001 CONTINUE
C Find direction of closest ship
IF(K.EQ.0)GOTO 10009
D=ATAN2((YCORD(K)-ZY),(XCORD(K)-ZX))*180.0/3.1415926
10002 CALL MOVE(ZX,ZY,X,Y,D,ZW,CHAR,UNIV)
UNIV(INT(ZX),INT(ZY))='.'
C Just munch this junk down
IF((CHAR.EQ.'.').OR.(CHAR.EQ.'+').OR.(CHAR.EQ.'@'))GOTO 10011
C Caught a ship
IF((CHAR.LT.'1').OR.(CHAR.GT.'8'))GOTO 10018
I=CHAR-"60
IF(.NOT.ALIVE(I))GOTO 10011 ! Don't create new ships
CALL SENT(I,15)
CALL RESET(I)
GOTO 10009
C Swap places with bases, stars, etc.
10018 UNIV(INT(ZX),INT(ZY))=CHAR
10011 UNIV(INT(X),INT(Y))='#'
ZX=X
ZY=Y
10009 RETURN
END
SUBROUTINE MANTI
C
C Deal with anti-matter
C
INCLUDE 'LEDFOR.COM/-LI'
BYTE CHAR,HOLE
INTEGER*2 IPX(21),IPY(21)
PARAMETER POD='@'
C
C The following data descibes the explosion pattern for
C anti-matter pods
C
DATA IPX/-1,0,1,-2,-1,0,1,2,-2,-1,0,1,2,-2,-1,0,1,2,-1,0,1/
DATA IPY/2,2,2,1,1,1,1,1,0,0,0,0,0,-1,-1,-1,-1,-1,-2,-2,-2/
HOLE=.FALSE.
DO 10001 I=1,8
IF(IPOD(I).LE.0)GOTO 10001 ! Not launched yet
IF(IPOD(I).GE.4)GOTO 10001 ! Already detonated
IF(.NOT.ALIVE(I))GOTO 10001 ! Active pod from a dead ship
C Launch pod
10005 IF(IPOD(I).NE.1)GOTO 10007
CALL MOVE(XCORD(I),YCORD(I),X1,Y1,DPOD(I),10.0,CHAR,UNIV)
KX=XCORD(I)
KY=YCORD(I)
C Make sure it clears the ship
IF((KX.NE.INT(X1)).OR.(KY.NE.INT(Y1)))GOTO 10009
CALL MOVE(X1,Y1,X,Y,DPOD(I),10.0,CHAR,UNIV)
GOTO 10010
10009 X=X1
Y=Y1
10010 IX=INT(X)
IY=INT(Y)
IF(CHAR.NE.'.')GOTO 10012
C 1 Successul launch
UNIV(IX,IY)=POD
XPOD(I)=X
YPOD(I)=Y
IPOD(I)=2
CALL SENT(I,28)
GOTO 10001
C Blocked launch (good shot)
10012 CALL SENT(I,23)
IPOD(I)=0
GOTO 10001
C 2 Pod is on the move
10007 IF(IPOD(I).NE.2)GOTO 10015
IX=INT(XPOD(I))
IY=INT(YPOD(I))
IF(UNIV(IX,IY).EQ.POD)GOTO 10017
C Pod was destroyed
10016 CALL SENT(I,24)
IPOD(I)=4
GOTO 10001
10017 CALL MOVE(XPOD(I),YPOD(I),X,Y,DPOD(I),5.0,CHAR,UNIV)
IF((CHAR.NE.'.').AND.(CHAR.NE.'+'))GOTO 10020
UNIV(IX,IY)='.'
UNIV(INT(X),INT(Y))=POD
XPOD(I)=X
YPOD(I)=Y
GOTO 10001
C Ran into some object
10020 IF(RAN(I1,I2).LE.0.5)GOTO 10023
DPOD(I)=DPOD(I)+90.0
GOTO 10001
10023 DPOD(I)=DPOD(I)-90.0
GOTO 10001
C 3 Detonate pod
10015 IF(IPOD(I).NE.3)GOTO 10001
IPOD(I)=4
IX=INT(XPOD(I))
IY=INT(YPOD(I))
IF(UNIV(IX,IY).NE.POD)GOTO 10016 ! Pod was destroyed
CALL SENT(I,29)
DO 10046 L1=1,21 ! Provide wrap around blast
KX=IX+IPX(L1)
IF(KX.GE.101)KX=KX-100
IF(KX.LT.1)KX=KX+100
KY=IY+IPY(L1)
IF(KY.GE.101)KY=KY-100
IF(KY.LT.1)KY=KY+100
CHAR=UNIV(KX,KY)
IF(CHAR.EQ.'.')GOTO 10046
C Don't vaporize hyper ports or star bases
10047 IF((CHAR.EQ.'H').OR.(CHAR.EQ.'B'))GOTO 10046
C Wiped out another ship
10045 IF((CHAR.LT.'1').OR.(CHAR.GT.'8'))GOTO 10058
IZ=CHAR-"60
IF(.NOT.ALIVE(IZ))GOTO 10050
CALL SENT(IZ,30)
CALL RESET(IZ)
IF(IZ.EQ.I)GOTO 10046 ! No points for blasting self
SCORE(I)=SCORE(I)+2000
CALL SENT(I,22)
GOTO 10046
C Hit was on a ghost ship
10050 CALL SENT(I,21)
IF((INT(XCORD(IZ)).EQ.KX).AND.(INT(YCORD(IZ)).EQ.KY))GOTO 10046
GOTO 10060 ! Ghost ship should't be here
C Zap the black hole
10058 IF(CHAR.NE.'#')GOTO 10060
CALL SENT(I,31)
SCORE(I)=SCORE(I)+1000
HOLE=.TRUE.
C Erase any other junk
10060 UNIV(KX,KY)='.'
10046 CONTINUE
10001 CONTINUE
C Find a new home for the black hole
IF(HOLE)CALL NEWLOC(ZX,ZY,'#')
RETURN
END